From 00cdf2de902286e54814698a1812f40b0c76d7aa Mon Sep 17 00:00:00 2001
From: Andrey Avtomonov
Date: Thu, 11 Jun 2026 13:49:45 +0200
Subject: [PATCH] refactor: enforce ktx naming and AGENTS.md compliance sweep
(#289)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Align the tree with AGENTS.md/CLAUDE.md conventions:
- Rewrite user-facing strings, docs, and tests to lowercase `ktx`
(no bare uppercase `KTX` tokens remain outside literal identifiers).
- Drop the legacy `historicSql` migration path and its now-unused
helpers, per the no-backward-compat rule.
- Remove `as unknown as` / `any` casts: narrow `BaseTool` generics to
`z.ZodObject`, add a typed `createLookerClient`, and delete the dead
`getParametersSchema`/`toAnthropicFormat` pre-AI-SDK helpers.
- Use `InvalidArgumentError` for Commander parse failures.
- Finish the adapter→connector prose conversion in the `ktx.yaml` docs
while keeping the literal `adapters` config key.
---
CONTRIBUTING.md | 10 +-
SECURITY.md | 6 +-
.../content/docs/configuration/ktx-yaml.mdx | 12 +--
.../docs/getting-started/quickstart.mdx | 4 +-
docs/release.md | 6 +-
examples/README.md | 4 +-
examples/local-warehouse/README.md | 2 +-
.../orbit-relationship-verification/README.md | 4 +-
examples/package-artifacts/README.md | 2 +-
examples/postgres-historic/README.md | 12 +--
packages/cli/src/admin.ts | 2 +-
.../cli/src/claude-code-prompt-caching.ts | 2 +-
packages/cli/src/cli-program.ts | 6 +-
packages/cli/src/cli-runtime.ts | 4 +-
.../cli/src/commands/connection-commands.ts | 2 +-
packages/cli/src/commands/ingest-commands.ts | 8 +-
packages/cli/src/commands/mcp-commands.ts | 24 ++---
packages/cli/src/commands/runtime-commands.ts | 8 +-
packages/cli/src/commands/setup-commands.ts | 8 +-
packages/cli/src/commands/sl-commands.ts | 2 +-
packages/cli/src/commands/sql-commands.ts | 2 +-
packages/cli/src/commands/status-commands.ts | 2 +-
packages/cli/src/connection.ts | 2 +-
.../src/connectors/clickhouse/connector.ts | 2 +-
.../cli/src/connectors/mysql/connector.ts | 2 +-
.../cli/src/connectors/snowflake/connector.ts | 2 +-
.../cli/src/connectors/sqlite/connector.ts | 2 +-
.../cli/src/connectors/sqlserver/connector.ts | 2 +-
packages/cli/src/context-build-view.ts | 10 +-
.../context/ingest/adapters/looker/client.ts | 9 +-
.../context/ingest/adapters/looker/factory.ts | 10 ++
.../context/ingest/adapters/looker/mapping.ts | 2 +-
.../ingest/adapters/metabase/client.ts | 2 +-
.../metabase/local-metabase.adapter.ts | 2 +-
.../ingest/adapters/metabase/mapping.ts | 12 +--
.../src/context/ingest/final-gate-repair.ts | 2 +-
.../textual-conflict-resolver.ts | 2 +-
.../context/ingest/local-bundle-runtime.ts | 11 +-
.../context/ingest/memory-flow/view-model.ts | 2 +-
.../discover-data.tool.ts | 10 +-
.../cli/src/context/llm/ai-sdk-runtime.ts | 6 +-
.../src/context/llm/claude-code-runtime.ts | 4 +-
packages/cli/src/context/llm/local-config.ts | 2 +-
packages/cli/src/context/llm/runtime-tools.ts | 4 +-
packages/cli/src/context/mcp/context-tools.ts | 14 +--
.../cli/src/context/memory/local-memory.ts | 2 +-
packages/cli/src/context/project/config.ts | 10 +-
.../cli/src/context/project/driver-schemas.ts | 2 +-
.../context/project/mappings-yaml-schema.ts | 4 +-
packages/cli/src/context/project/project.ts | 2 +-
.../context/scan/description-generation.ts | 8 +-
packages/cli/src/context/scan/local-scan.ts | 4 +-
.../scan/local-structural-artifacts.ts | 10 +-
.../scan/relationship-benchmark-report.ts | 2 +-
.../context/scan/relationship-discovery.ts | 6 +-
.../context/scan/relationship-llm-proposal.ts | 6 +-
.../src/context/sl/semantic-layer.service.ts | 2 +-
.../sl/tools/base-semantic-layer.tool.ts | 6 +-
packages/cli/src/context/tools/base-tool.ts | 46 ++------
packages/cli/src/doctor.ts | 10 +-
packages/cli/src/llm/embedding-health.ts | 2 +-
packages/cli/src/llm/embedding-provider.ts | 6 +-
packages/cli/src/llm/model-provider.ts | 2 +-
packages/cli/src/local-scan-connectors.ts | 2 +-
packages/cli/src/managed-local-embeddings.ts | 2 +-
packages/cli/src/managed-mcp-daemon.ts | 6 +-
packages/cli/src/managed-python-command.ts | 12 +--
packages/cli/src/managed-python-daemon.ts | 4 +-
packages/cli/src/managed-python-http.ts | 6 +-
packages/cli/src/managed-python-runtime.ts | 4 +-
packages/cli/src/mcp-http-server.ts | 8 +-
packages/cli/src/mcp-server-factory.ts | 2 +-
packages/cli/src/mcp-stdio-server.ts | 2 +-
packages/cli/src/memory-flow-hud.tsx | 8 +-
packages/cli/src/next-steps.ts | 4 +-
.../memory_agent_bundle_ingest_work_unit.md | 4 +-
.../prompts/memory_agent_external_ingest.md | 4 +-
packages/cli/src/public-ingest-copy.ts | 2 +-
packages/cli/src/public-ingest.ts | 6 +-
packages/cli/src/release-version.ts | 2 +-
packages/cli/src/runtime-requirements.ts | 2 +-
packages/cli/src/runtime.ts | 18 ++--
packages/cli/src/scan.ts | 2 +-
packages/cli/src/setup-agents.ts | 40 +++----
packages/cli/src/setup-context.ts | 18 ++--
packages/cli/src/setup-databases.ts | 53 ++-------
packages/cli/src/setup-demo-tour.ts | 14 +--
packages/cli/src/setup-embeddings.ts | 14 +--
packages/cli/src/setup-interrupt.ts | 2 +-
packages/cli/src/setup-models.ts | 12 +--
packages/cli/src/setup-project.ts | 10 +-
packages/cli/src/setup-ready-menu.ts | 2 +-
packages/cli/src/setup-sources.ts | 10 +-
packages/cli/src/setup.ts | 26 ++---
packages/cli/src/skills/analytics/SKILL.md | 6 +-
packages/cli/src/skills/dbt_ingest/SKILL.md | 6 +-
.../cli/src/skills/looker_ingest/SKILL.md | 6 +-
.../cli/src/skills/lookml_ingest/SKILL.md | 12 +--
.../cli/src/skills/metabase_ingest/SKILL.md | 8 +-
.../cli/src/skills/metricflow_ingest/SKILL.md | 26 ++---
.../cli/src/skills/notion_synthesize/SKILL.md | 2 +-
packages/cli/src/skills/sl/SKILL.md | 4 +-
packages/cli/src/skills/sl_capture/SKILL.md | 2 +-
packages/cli/src/skills/wiki_capture/SKILL.md | 2 +-
packages/cli/src/source-mapping.ts | 4 +-
packages/cli/src/startup-profile.ts | 2 +-
packages/cli/src/status-project.ts | 2 +-
packages/cli/src/text-ingest.ts | 2 +-
packages/cli/test/admin.test.ts | 6 +-
packages/cli/test/command-tree.test.ts | 4 +-
.../cli/test/commands/mcp-commands.test.ts | 14 +--
.../connectors/clickhouse/dialect.test.ts | 2 +-
.../cli/test/connectors/mysql/dialect.test.ts | 2 +-
.../test/connectors/postgres/dialect.test.ts | 2 +-
.../test/connectors/sqlite/dialect.test.ts | 2 +-
.../test/connectors/sqlserver/dialect.test.ts | 2 +-
packages/cli/test/context-build-view.test.ts | 28 ++---
.../context/core/config-reference.test.ts | 2 +-
.../local-ingest-acceptance.test.ts | 4 +-
.../ingest/adapters/looker/factory.test.ts | 2 +-
.../ingest/adapters/looker/mapping.test.ts | 6 +-
.../ingest/adapters/looker/types.test.ts | 4 +-
.../adapters/metabase/client-boundary.test.ts | 6 +-
.../ingest/adapters/metabase/client.test.ts | 4 +-
.../metabase/local-metabase.adapter.test.ts | 2 +-
.../ingest/adapters/metabase/mapping.test.ts | 10 +-
...ingest-bundle.runner.isolated-diff.test.ts | 68 ++++++------
.../ingest/ingest-bundle.runner.test.ts | 4 +-
.../context/ingest/ingest-prompts.test.ts | 6 +-
.../ingest/ingest-runtime-assets.test.ts | 8 +-
.../isolated-diff/patch-integrator.test.ts | 12 +--
.../isolated-diff/work-unit-executor.test.ts | 2 +-
.../ingest/local-bundle-ingest.test.ts | 10 +-
.../context/ingest/local-stage-ingest.test.ts | 2 +-
.../ingest/memory-flow/acceptance.test.ts | 4 +-
.../ingest/memory-flow/interaction.test.ts | 2 +-
.../memory-flow/interactive-render.test.ts | 4 +-
.../context/ingest/memory-flow/render.test.ts | 4 +-
.../ingest/memory-flow/view-model.test.ts | 4 +-
.../ingest/memory-flow/visuals.test.ts | 2 +-
.../page-triage/page-triage.service.test.ts | 4 +-
.../test/context/ingest/repo-fetch.test.ts | 2 +-
.../context/llm/claude-code-runtime.test.ts | 6 +-
.../test/context/llm/embedding-port.test.ts | 2 +-
.../cli/test/context/llm/local-config.test.ts | 4 +-
.../context/llm/runtime-local-config.test.ts | 2 +-
.../mcp/__snapshots__/mcp-tools-list.json | 12 +--
packages/cli/test/context/mcp/server.test.ts | 10 +-
.../memory/memory-runtime-assets.test.ts | 10 +-
.../cli/test/context/project/config.test.ts | 2 +-
.../cli/test/context/project/project.test.ts | 2 +-
.../test/context/project/setup-config.test.ts | 2 +-
.../cli/test/context/scan/credentials.test.ts | 2 +-
.../test/context/scan/data-dictionary.test.ts | 2 +-
.../scan/description-generation.test.ts | 2 +-
.../test/context/scan/embedding-text.test.ts | 2 +-
.../context/scan/enrichment-summary.test.ts | 2 +-
.../context/scan/enrichment-types.test.ts | 2 +-
.../context/scan/local-enrichment.test.ts | 2 +-
.../cli/test/context/scan/local-scan.test.ts | 2 +-
.../relationship-benchmark-report.test.ts | 2 +-
.../scan/relationship-diagnostics.test.ts | 2 +-
.../scan/relationship-discovery.test.ts | 2 +-
.../scan/relationship-llm-proposal.test.ts | 6 +-
.../context/scan/type-normalization.test.ts | 2 +-
packages/cli/test/context/scan/types.test.ts | 2 +-
.../context/sl/semantic-layer.service.test.ts | 2 +-
.../test/context/test/make-local-git-repo.ts | 2 +-
packages/cli/test/doctor.test.ts | 26 ++---
packages/cli/test/index.test.ts | 6 +-
packages/cli/test/ingest-viz.test.ts | 40 +++----
packages/cli/test/ingest.test.ts | 2 +-
.../cli/test/llm/embedding-health.test.ts | 2 +-
.../cli/test/llm/embedding-provider.test.ts | 4 +-
packages/cli/test/llm/model-health.test.ts | 2 +-
.../cli/test/managed-local-embeddings.test.ts | 8 +-
.../cli/test/managed-python-command.test.ts | 26 ++---
.../cli/test/managed-python-daemon.test.ts | 2 +-
packages/cli/test/managed-python-http.test.ts | 12 +--
packages/cli/test/mcp-http-server.test.ts | 8 +-
packages/cli/test/mcp-server-factory.test.ts | 2 +-
packages/cli/test/memory-flow-tui.test.tsx | 6 +-
packages/cli/test/next-steps.test.ts | 8 +-
packages/cli/test/print-command-tree.test.ts | 2 +-
packages/cli/test/prompt-navigation.test.ts | 14 +--
packages/cli/test/public-ingest-copy.test.ts | 4 +-
packages/cli/test/public-ingest.test.ts | 22 ++--
packages/cli/test/runtime.test.ts | 20 ++--
packages/cli/test/scan.test.ts | 14 +--
packages/cli/test/setup-agents.test.ts | 46 ++++----
packages/cli/test/setup-context.test.ts | 6 +-
packages/cli/test/setup-databases.test.ts | 101 ++----------------
packages/cli/test/setup-demo-tour.test.ts | 2 +-
packages/cli/test/setup-embeddings.test.ts | 18 ++--
packages/cli/test/setup-models.test.ts | 34 +++---
packages/cli/test/setup-project.test.ts | 16 +--
packages/cli/test/setup-prompts.test.ts | 12 +--
packages/cli/test/setup-ready-menu.test.ts | 4 +-
packages/cli/test/setup-runtime.test.ts | 4 +-
packages/cli/test/setup-sources.test.ts | 18 ++--
packages/cli/test/setup.test.ts | 52 ++++-----
packages/cli/test/standalone-smoke.test.ts | 4 +-
packages/cli/test/text-ingest.test.ts | 14 +--
python/ktx-daemon/README.md | 4 +-
python/ktx-daemon/pyproject.toml | 2 +-
python/ktx-daemon/src/ktx_daemon/__init__.py | 2 +-
python/ktx-daemon/src/ktx_daemon/__main__.py | 4 +-
python/ktx-daemon/src/ktx_daemon/app.py | 6 +-
.../src/ktx_daemon/code_execution.py | 2 +-
.../src/ktx_daemon/database_introspection.py | 2 +-
.../ktx-daemon/src/ktx_daemon/embeddings.py | 2 +-
.../src/ktx_daemon/semantic_layer.py | 2 +-
scripts/build-python-runtime-wheel.mjs | 4 +-
scripts/build-python-runtime-wheel.test.mjs | 4 +-
scripts/check-boundaries.test.mjs | 4 +-
scripts/ci-artifact-upload.test.mjs | 4 +-
scripts/conductor-run.sh | 8 +-
scripts/conductor-scripts.test.mjs | 2 +-
scripts/conductor-setup.sh | 12 +--
.../installed-live-database-smoke.test.mjs | 2 +-
scripts/link-dev-cli.mjs | 6 +-
scripts/local-embeddings-runtime-smoke.mjs | 14 +--
.../local-embeddings-runtime-smoke.test.mjs | 4 +-
scripts/package-artifacts.mjs | 12 +--
scripts/package-artifacts.test.mjs | 8 +-
scripts/prepare-cli-bin.mjs | 2 +-
scripts/published-package-smoke.mjs | 2 +-
scripts/relationship-orbit-verification.mjs | 6 +-
.../relationship-orbit-verification.test.mjs | 12 +--
scripts/release-readiness.mjs | 6 +-
scripts/release-readiness.test.mjs | 2 +-
scripts/run-ktx.mjs | 6 +-
scripts/run-ktx.test.mjs | 12 +--
scripts/standalone-ci-workflow.test.mjs | 2 +-
.../update-public-release-version.test.mjs | 2 +-
skills/ktx/SKILL.md | 2 +-
skills/ktx/troubleshooting.md | 2 +-
237 files changed, 844 insertions(+), 974 deletions(-)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index a4fb3040..212dd9e6 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,6 +1,6 @@
-# Contributing to KTX
+# Contributing to ktx
-Thanks for your interest in KTX. This page covers **how to contribute** and
+Thanks for your interest in **ktx**. This page covers **how to contribute** and
the **contributor rewards program**. For development setup, repository
layout, and verification commands, see the
[Contributing guide in the docs](https://docs.kaelio.com/ktx/docs/community/contributing).
@@ -23,7 +23,7 @@ layout, and verification commands, see the
## Contributor rewards program
We send merch to contributors whose pull requests get merged. The goal is
-to thank the people building KTX with us, not to drive volume.
+to thank the people building **ktx** with us, not to drive volume.
### How it works
@@ -76,7 +76,7 @@ See the [Community & Support](https://docs.kaelio.com/ktx/docs/community/support
page for the full guide. The short version:
- **Questions, "how do I...", setup help, sharing patterns**: join the
- [KTX Slack](https://join.slack.com/t/ktxcommunity/shared_invite/zt-3y9b44m1x-LVyNNJD5nwaZHq4XS29LMQ).
+ [**ktx** Slack](https://join.slack.com/t/ktxcommunity/shared_invite/zt-3y9b44m1x-LVyNNJD5nwaZHq4XS29LMQ).
- **Bugs**: use the [Bug report](.github/ISSUE_TEMPLATE/bug_report.yml)
template.
- **Feature requests**: use the
@@ -87,7 +87,7 @@ page for the full guide. The short version:
## Code of conduct
-KTX follows the
+**ktx** follows the
[Contributor Covenant](https://www.contributor-covenant.org/version/2/1/code_of_conduct/).
Be respectful, assume good intent, and keep discussion focused on the
project. Report concerns to the maintainers in Slack or by email at
diff --git a/SECURITY.md b/SECURITY.md
index da90c1a5..2b9dee1d 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -2,20 +2,20 @@
## Reporting a vulnerability
-If you believe you've found a security vulnerability in KTX, please report it
+If you believe you've found a security vulnerability in **ktx**, please report it
**privately** through GitHub Security Advisories:
[Report a vulnerability](https://github.com/Kaelio/ktx/security/advisories/new)
If you cannot use GitHub Security Advisories, email `support@kaelio.com`
-instead. Please do **not** open a public issue, post in the KTX Slack, or
+instead. Please do **not** open a public issue, post in the **ktx** Slack, or
share details elsewhere until we have published a fix.
When reporting, please include:
- A description of the issue and its impact
- Steps to reproduce
-- The KTX version affected
+- The **ktx** version affected
## What to expect
diff --git a/docs-site/content/docs/configuration/ktx-yaml.mdx b/docs-site/content/docs/configuration/ktx-yaml.mdx
index d5dd18c8..9e985eba 100644
--- a/docs-site/content/docs/configuration/ktx-yaml.mdx
+++ b/docs-site/content/docs/configuration/ktx-yaml.mdx
@@ -46,7 +46,7 @@ read, how to think, and where to put the results.
llm - provider, models, prompt cache
- ingest - adapters, embeddings, work units
+ ingest - connectors, embeddings, work units
scan - enrichment, relationships
agent - research-agent feature flags
@@ -440,7 +440,7 @@ provider-specific model identifiers.
## `ingest`
`ingest` controls how **ktx** builds context from your stack. It lists the
-adapters to run, the embedding provider used when adapters embed documents,
+connectors to run, the embedding provider used when connectors embed documents,
and the concurrency and failure policy for work units.
```yaml
@@ -471,12 +471,12 @@ ingest:
jitter: true
```
-### Adapters
+### Connectors
-`adapters` is a list of adapter IDs that should run. Each ID matches a
+`adapters` is a list of connector IDs that should run. Each ID matches a
connector that **ktx** ships locally:
-| Adapter ID | What it ingests |
+| Connector ID | What it ingests |
|------------|-----------------|
| `live-database` | Live warehouse introspection (schemas, tables, columns, samples). |
| `historic-sql` | Query history from Postgres `pg_stat_statements`, BigQuery `INFORMATION_SCHEMA.JOBS`, or Snowflake query history. |
@@ -486,7 +486,7 @@ connector that **ktx** ships locally:
| `looker` | Looker dashboards and looks via the API. |
| `metabase` | Metabase cards, dashboards, and database mappings. |
| `notion` | Notion pages and databases for wiki context. |
-| `fake` | Test/demo adapter. Useful in fixtures. |
+| `fake` | Test/demo connector. Useful in fixtures. |
### Embeddings
diff --git a/docs-site/content/docs/getting-started/quickstart.mdx b/docs-site/content/docs/getting-started/quickstart.mdx
index ecd2fbe7..2b8cbdfb 100644
--- a/docs-site/content/docs/getting-started/quickstart.mdx
+++ b/docs-site/content/docs/getting-started/quickstart.mdx
@@ -307,12 +307,12 @@ connection is unreachable or misconfigured the build is blocked up front and
**ktx** names the failing connection by id and connector type:
```text
-KTX cannot build context: a required connection failed its live test.
+ktx cannot build context: a required connection failed its live test.
Failed connections:
warehouse (postgres)
-Each connection must be reachable before KTX builds context.
+Each connection must be reachable before ktx builds context.
Run `ktx connection test ` to see the error, fix the connection, then retry.
```
diff --git a/docs/release.md b/docs/release.md
index 3a72f54e..c1d93fc3 100644
--- a/docs/release.md
+++ b/docs/release.md
@@ -1,4 +1,4 @@
-# KTX release runbook
+# ktx release runbook
This runbook covers the maintainer workflow for publishing `@kaelio/ktx` to
npm through GitHub Actions. The workflow uses semantic-release to choose the
@@ -36,7 +36,7 @@ Before you publish, confirm these requirements:
publish the first stable version as `0.1.0`.
semantic-release doesn't support choosing an arbitrary first `0.x` stable
-release. If KTX has no stable tag yet and you need the first stable release to
+release. If **ktx** has no stable tag yet and you need the first stable release to
be `0.1.0`, create and push the baseline tag once before running the live
stable workflow:
@@ -46,7 +46,7 @@ git tag v0.0.0 "${root_commit}"
git push origin v0.0.0
```
-KTX follows the same versioning schema as the main Kaelio release workflow:
+**ktx** follows the same versioning schema as the main Kaelio release workflow:
breaking-change and `major` commit markers create a minor release, not an
automatic major release. A major version requires an intentional manual release
path.
diff --git a/examples/README.md b/examples/README.md
index f18440b2..e84594fe 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -17,7 +17,7 @@ The copied project initializes its own Git repository on first use.
## orbit-relationship-verification
-`orbit-relationship-verification/` is a checked-in KTX project used by
+`orbit-relationship-verification/` is a checked-in **ktx** project used by
`pnpm run relationships:verify-orbit`. It points the `orbit` SQLite connection
at the Orbit-style no-declared-constraint relationship fixture and verifies that
relationship enrichment writes nine accepted joins without requiring a local
@@ -27,7 +27,7 @@ warehouse credential.
`postgres-historic/` is a manual Docker-backed smoke for Postgres
query-history ingest via `pg_stat_statements`. It verifies setup, staged
-query-history artifacts, KTX daemon batch SQL analysis, bounded pattern
+query-history artifacts, **ktx** daemon batch SQL analysis, bounded pattern
WorkUnit shards, and no-WorkUnit idempotency for unchanged bucketed table
inputs and pattern shards.
diff --git a/examples/local-warehouse/README.md b/examples/local-warehouse/README.md
index 2b9dbcf9..4fd4a814 100644
--- a/examples/local-warehouse/README.md
+++ b/examples/local-warehouse/README.md
@@ -1,6 +1,6 @@
# local-warehouse fixture
-This directory is a contributor fixture for KTX CLI smoke tests. It uses the
+This directory is a contributor fixture for **ktx** CLI smoke tests. It uses the
internal fake ingest adapter so tests can run without a live database or
external service.
diff --git a/examples/orbit-relationship-verification/README.md b/examples/orbit-relationship-verification/README.md
index 126488a2..d99c8fea 100644
--- a/examples/orbit-relationship-verification/README.md
+++ b/examples/orbit-relationship-verification/README.md
@@ -1,11 +1,11 @@
# Orbit-style relationship discovery verification
-This KTX project backs the default `relationships:verify-orbit` command. It uses
+This **ktx** project backs the default `relationships:verify-orbit` command. It uses
the checked-in Orbit-style SQLite fixture from the relationship discovery
benchmark corpus, with no declared primary keys or foreign keys in the database
schema.
-Run from the KTX workspace root:
+Run from the **ktx** workspace root:
```bash
pnpm run relationships:verify-orbit
diff --git a/examples/package-artifacts/README.md b/examples/package-artifacts/README.md
index 7fa39fb3..b5813b0c 100644
--- a/examples/package-artifacts/README.md
+++ b/examples/package-artifacts/README.md
@@ -14,7 +14,7 @@ generated local project.
The managed Python runtime smoke requires `uv` on `PATH`, isolates
`KTX_RUNTIME_ROOT`, verifies `ktx admin runtime status`, runs `ktx sl query --yes` to
install the core runtime from the bundled wheel, checks `ktx admin runtime status`,
-starts and reuses the KTX daemon, and stops it.
+starts and reuses the **ktx** daemon, and stops it.
The artifact manifest contains the public `@kaelio/ktx` npm tarball and the
bundled `kaelio-ktx` runtime wheel. The smoke does not install standalone
diff --git a/examples/postgres-historic/README.md b/examples/postgres-historic/README.md
index 64fc2593..aadd3cd4 100644
--- a/examples/postgres-historic/README.md
+++ b/examples/postgres-historic/README.md
@@ -17,19 +17,19 @@ unchanged bounded pattern shards do not schedule LLM work.
## Prerequisites
- Docker with Compose v2
-- Node and pnpm matching the KTX workspace
-- `uv` on `PATH` so the KTX-managed Python runtime can install the bundled
+- Node and pnpm matching the **ktx** workspace
+- `uv` on `PATH` so the **ktx**-managed Python runtime can install the bundled
runtime wheel
## Run
-From the KTX repository root:
+From the **ktx** repository root:
```bash
examples/postgres-historic/scripts/smoke.sh
```
-The smoke creates a temporary KTX project, isolates the managed Python runtime
+The smoke creates a temporary **ktx** project, isolates the managed Python runtime
under the temporary project parent, starts Postgres on `127.0.0.1:55432`, and
uses this connection URL:
@@ -41,7 +41,7 @@ Set `KTX_POSTGRES_HISTORIC_KEEP_DOCKER=1` to leave the container running after
the script exits.
The smoke validates the query-history raw snapshot path without requiring LLM
-credentials. It uses KTX's local stage-only ingest API after `ktx setup`, so the
+credentials. It uses **ktx**'s local stage-only ingest API after `ktx setup`, so the
deterministic reader, batch SQL parser, stable artifact writer, and diff-based
WorkUnit planning are checked independently from curation.
@@ -124,6 +124,6 @@ table.
- Missing grants: confirm `GRANT pg_read_all_stats TO ktx_reader;`.
- Empty snapshot: rerun `scripts/generate-workload.sh base` and keep
`--query-history-min-executions 2` for the smoke.
-- SQL-analysis failures: run `pnpm run ktx -- dev runtime status` from the KTX
+- SQL-analysis failures: run `pnpm run ktx -- dev runtime status` from the **ktx**
repository root and confirm `uv`, the bundled Python wheel, and the managed
runtime all pass.
diff --git a/packages/cli/src/admin.ts b/packages/cli/src/admin.ts
index 6c04f82f..d4b63ac1 100644
--- a/packages/cli/src/admin.ts
+++ b/packages/cli/src/admin.ts
@@ -24,7 +24,7 @@ export function registerAdminCommands(program: Command, context: KtxCliCommandCo
admin
.command('init')
- .description('Initialize a Git-backed KTX project directory for maintenance scripts')
+ .description('Initialize a Git-backed ktx project directory for maintenance scripts')
.argument('[directory]', 'Project directory')
.option('--force', 'Rewrite ktx.yaml and scaffold files in an existing project', false)
.action(
diff --git a/packages/cli/src/claude-code-prompt-caching.ts b/packages/cli/src/claude-code-prompt-caching.ts
index a7c0fa54..0d696579 100644
--- a/packages/cli/src/claude-code-prompt-caching.ts
+++ b/packages/cli/src/claude-code-prompt-caching.ts
@@ -21,7 +21,7 @@ export function formatClaudeCodePromptCachingWarning(fields: string[]): string |
if (fields.length === 0) {
return null;
}
- return `claude-code ignores ${fields.join(', ')} because the Claude Agent SDK does not expose KTX prompt-cache TTL, tool, or history markers.`;
+ return `claude-code ignores ${fields.join(', ')} because the Claude Agent SDK does not expose ktx prompt-cache TTL, tool, or history markers.`;
}
export function formatClaudeCodePromptCachingFix(): string {
diff --git a/packages/cli/src/cli-program.ts b/packages/cli/src/cli-program.ts
index 07010f07..f9da6552 100644
--- a/packages/cli/src/cli-program.ts
+++ b/packages/cli/src/cli-program.ts
@@ -252,8 +252,8 @@ export function resolveCommandProjectDirOverride(command: CommandWithGlobalOptio
function createBaseProgram(info: KtxCliPackageInfo, io: KtxCliIo): Command {
return new Command()
.name('ktx')
- .description('KTX data agent context layer CLI')
- .option('--project-dir ', 'KTX project directory (default: KTX_PROJECT_DIR, nearest ktx.yaml, or cwd)')
+ .description('ktx data agent context layer CLI')
+ .option('--project-dir ', 'ktx project directory (default: KTX_PROJECT_DIR, nearest ktx.yaml, or cwd)')
.option('--debug', 'Enable diagnostic logging to stderr')
.version(`${info.name} ${info.version}`, '-v, --version', 'Show CLI version')
.helpOption('-h, --help', 'Show this help text')
@@ -466,7 +466,7 @@ export function buildKtxProgram(options: BuildKtxProgramOptions): Command {
const attachProjectGroup = shouldAttachCommandProjectGroup(path, hasProject);
telemetry.beginCommandSpan({
commandPath: path,
- flagsPresent: collectCommandFlagsPresent(commandNode as unknown as CommandUnknownOpts),
+ flagsPresent: collectCommandFlagsPresent(actionCommand),
projectDir: attachProjectGroup ? projectDir : undefined,
hasProject,
attachProjectGroup,
diff --git a/packages/cli/src/cli-runtime.ts b/packages/cli/src/cli-runtime.ts
index 69416006..89c7c11d 100644
--- a/packages/cli/src/cli-runtime.ts
+++ b/packages/cli/src/cli-runtime.ts
@@ -61,7 +61,7 @@ export function packageInfoFromJson(packageJson: unknown): KtxCliPackageInfo {
typeof packageJson.name !== 'string' ||
typeof packageJson.version !== 'string'
) {
- throw new Error('Invalid KTX CLI package metadata');
+ throw new Error('Invalid ktx CLI package metadata');
}
return {
@@ -77,7 +77,7 @@ async function runInit(args: { projectDir: string; force: boolean }, io: KtxCliI
force: args.force,
});
- io.stdout.write(`Initialized KTX project at ${result.projectDir}\n`);
+ io.stdout.write(`Initialized ktx project at ${result.projectDir}\n`);
io.stdout.write(`Config: ${result.configPath}\n`);
io.stdout.write(`Commit: ${result.commitHash ?? 'none'}\n`);
return 0;
diff --git a/packages/cli/src/commands/connection-commands.ts b/packages/cli/src/commands/connection-commands.ts
index 213bf608..579575d1 100644
--- a/packages/cli/src/commands/connection-commands.ts
+++ b/packages/cli/src/commands/connection-commands.ts
@@ -37,7 +37,7 @@ export function registerConnectionCommands(program: Command, context: KtxCliComm
connection
.command('test')
.description('Test one or all configured connections (default: all)')
- .argument('[connectionId]', 'KTX connection id to test (omit to test all)')
+ .argument('[connectionId]', 'ktx connection id to test (omit to test all)')
.option('--all', 'Test every configured connection and print a summary list')
.action(async (connectionId: string | undefined, options: { all?: boolean }, command) => {
if (options.all === true && connectionId !== undefined) {
diff --git a/packages/cli/src/commands/ingest-commands.ts b/packages/cli/src/commands/ingest-commands.ts
index b5efe443..d7e09596 100644
--- a/packages/cli/src/commands/ingest-commands.ts
+++ b/packages/cli/src/commands/ingest-commands.ts
@@ -25,16 +25,16 @@ export function registerIngestCommands(
): void {
const ingest = program
.command('ingest')
- .description('Build or inspect KTX context, or capture text into memory')
+ .description('Build or inspect ktx context, or capture text into memory')
.usage('[options] [connectionId]')
.argument('[connectionId]', 'Configured connection id to ingest (omit to ingest all)')
.option('--all', 'Ingest all configured connections', false)
.addOption(new Option('--query-history', 'Include database query-history usage patterns').conflicts('noQueryHistory'))
.addOption(new Option('--no-query-history', 'Skip database query-history usage patterns'))
.option('--query-history-window-days ', 'Query-history lookback window for this run', parsePositiveIntegerOption)
- .option('--text ', 'Capture inline text into KTX memory; repeatable', collectOption, [])
- .option('--file ', 'Capture a text file into KTX memory; use - for stdin; repeatable', collectOption, [])
- .option('--connection-id ', 'KTX connection id to tag captured text/file notes')
+ .option('--text ', 'Capture inline text into ktx memory; repeatable', collectOption, [])
+ .option('--file ', 'Capture a text file into ktx memory; use - for stdin; repeatable', collectOption, [])
+ .option('--connection-id ', 'ktx connection id to tag captured text/file notes')
.option('--user-id ', 'Memory user id for text/file capture attribution', 'local-cli')
.option('--fail-fast', 'Stop after the first failed text/file item', false)
.addOption(new Option('--plain', 'Print plain text output').conflicts(['json']))
diff --git a/packages/cli/src/commands/mcp-commands.ts b/packages/cli/src/commands/mcp-commands.ts
index 94b17498..6978d2b7 100644
--- a/packages/cli/src/commands/mcp-commands.ts
+++ b/packages/cli/src/commands/mcp-commands.ts
@@ -27,11 +27,11 @@ function binPath(): string {
function formatMcpStartResultMessage(input: { status: 'started' | 'already-running'; url: string }): string {
return [
- input.status === 'started' ? `KTX MCP daemon started: ${input.url}` : `KTX MCP daemon already running: ${input.url}`,
+ input.status === 'started' ? `ktx MCP daemon started: ${input.url}` : `ktx MCP daemon already running: ${input.url}`,
'',
- 'KTX is ready for configured agents.',
- 'Open your agent for this KTX project and ask a data question, for example:',
- ' "Use KTX to show me the available tables and metrics."',
+ 'ktx is ready for configured agents.',
+ 'Open your agent for this ktx project and ask a data question, for example:',
+ ' "Use ktx to show me the available tables and metrics."',
'',
].join('\n');
}
@@ -50,14 +50,14 @@ async function printMcpStatus(context: KtxCliCommandContext, projectDir: string)
export function registerMcpCommands(program: Command, context: KtxCliCommandContext): void {
const mcp = program
.command('mcp')
- .description('Manage the KTX MCP HTTP server (bare command: show status)')
+ .description('Manage the ktx MCP HTTP server (bare command: show status)')
.action(async (_options, command) => {
await printMcpStatus(context, resolveCommandProjectDir(command));
});
mcp
.command('stdio')
- .description('Run the KTX MCP server over stdio')
+ .description('Run the ktx MCP server over stdio')
.action(async (_options, command) => {
await (context.deps.mcp?.runStdioServer ?? runKtxMcpStdioServer)({
projectDir: resolveCommandProjectDir(command),
@@ -68,7 +68,7 @@ export function registerMcpCommands(program: Command, context: KtxCliCommandCont
mcp
.command('start')
- .description('Start the KTX MCP HTTP server')
+ .description('Start the ktx MCP HTTP server')
.option('--host ', 'Host to bind', '127.0.0.1')
.option('--port ', 'Port to bind', parsePositiveIntegerOption, 7878)
.option('--token ', 'Bearer token required for non-loopback binding')
@@ -96,7 +96,7 @@ export function registerMcpCommands(program: Command, context: KtxCliCommandCont
allowedOrigins: options.allowedOrigin,
io: context.io,
});
- context.io.stdout.write(`KTX MCP server listening at http://${options.host}:${options.port}/mcp\n`);
+ context.io.stdout.write(`ktx MCP server listening at http://${options.host}:${options.port}/mcp\n`);
return;
}
const result = await (context.deps.mcp?.startDaemon ?? startKtxMcpDaemon)({
@@ -114,24 +114,24 @@ export function registerMcpCommands(program: Command, context: KtxCliCommandCont
mcp
.command('stop')
- .description('Stop the KTX MCP daemon')
+ .description('Stop the ktx MCP daemon')
.action(async (_options, command) => {
const result = await (context.deps.mcp?.stopDaemon ?? stopKtxMcpDaemon)({
projectDir: resolveCommandProjectDir(command),
});
- context.io.stdout.write(result.status === 'stopped' ? 'KTX MCP daemon stopped.\n' : 'KTX MCP daemon is not running.\n');
+ context.io.stdout.write(result.status === 'stopped' ? 'ktx MCP daemon stopped.\n' : 'ktx MCP daemon is not running.\n');
});
mcp
.command('status')
- .description('Show KTX MCP daemon status')
+ .description('Show ktx MCP daemon status')
.action(async (_options, command) => {
await printMcpStatus(context, resolveCommandProjectDir(command));
});
mcp
.command('logs')
- .description('Print the KTX MCP daemon log')
+ .description('Print the ktx MCP daemon log')
.option('--follow', 'Follow log output', false)
.action(async (options, command) => {
const logPath = mcpDaemonLayout(resolveCommandProjectDir(command)).logPath;
diff --git a/packages/cli/src/commands/runtime-commands.ts b/packages/cli/src/commands/runtime-commands.ts
index ef0d06cc..441cceda 100644
--- a/packages/cli/src/commands/runtime-commands.ts
+++ b/packages/cli/src/commands/runtime-commands.ts
@@ -18,7 +18,7 @@ async function runRuntimeArgs(context: KtxCliCommandContext, args: KtxRuntimeArg
export function registerRuntimeCommands(program: Command, context: KtxCliCommandContext): void {
const runtime = program
.command('runtime')
- .description('Install, start, stop, and inspect the KTX-managed Python runtime')
+ .description('Install, start, stop, and inspect the ktx-managed Python runtime')
.showHelpAfterError();
runtime
@@ -38,7 +38,7 @@ export function registerRuntimeCommands(program: Command, context: KtxCliCommand
runtime
.command('start')
- .description('Start the KTX daemon')
+ .description('Start the ktx daemon')
.addOption(createRuntimeFeatureOption())
.option('--force', 'Restart even when a matching daemon is already running', false)
.action(async (options: { feature: RuntimeFeature; force?: boolean }, command: CommandWithGlobalOptions) => {
@@ -53,8 +53,8 @@ export function registerRuntimeCommands(program: Command, context: KtxCliCommand
runtime
.command('stop')
- .description('Stop the KTX daemon')
- .option('--all', 'Stop all KTX daemon processes recorded or discoverable on this machine', false)
+ .description('Stop the ktx daemon')
+ .option('--all', 'Stop all ktx daemon processes recorded or discoverable on this machine', false)
.action(async (options: { all?: boolean }, command: CommandWithGlobalOptions) => {
await runRuntimeArgs(context, {
command: 'stop',
diff --git a/packages/cli/src/commands/setup-commands.ts b/packages/cli/src/commands/setup-commands.ts
index e8510210..27a65b85 100644
--- a/packages/cli/src/commands/setup-commands.ts
+++ b/packages/cli/src/commands/setup-commands.ts
@@ -16,7 +16,7 @@ async function runSetupArgs(
function positiveInteger(value: string): number {
const parsed = Number.parseInt(value, 10);
if (!Number.isInteger(parsed) || parsed <= 0) {
- throw new Error(`Expected a positive integer, received ${value}`);
+ throw new InvalidArgumentError(`Expected a positive integer, received ${value}`);
}
return parsed;
}
@@ -202,8 +202,8 @@ function shouldShowSetupEntryMenu(
export function registerSetupCommands(program: Command, context: KtxCliCommandContext): void {
const setup = program
.command('setup')
- .description('Set up or resume a local KTX project')
- .addOption(new Option('--project-dir ', 'KTX project directory').hideHelp())
+ .description('Set up or resume a local ktx project')
+ .addOption(new Option('--project-dir ', 'ktx project directory').hideHelp())
.option('--agents', 'Install agent integration only', false)
.addOption(
new Option('--target ', 'Agent target').choices([
@@ -295,7 +295,7 @@ export function registerSetupCommands(program: Command, context: KtxCliCommandCo
.hideHelp(),
)
.addOption(
- new Option('--skip-databases', 'Leave database setup incomplete; KTX cannot work until a database is added')
+ new Option('--skip-databases', 'Leave database setup incomplete; ktx cannot work until a database is added')
.hideHelp()
.default(false),
)
diff --git a/packages/cli/src/commands/sl-commands.ts b/packages/cli/src/commands/sl-commands.ts
index 8f2f05a3..7b99e593 100644
--- a/packages/cli/src/commands/sl-commands.ts
+++ b/packages/cli/src/commands/sl-commands.ts
@@ -44,7 +44,7 @@ export function registerSlCommands(program: Command, context: KtxCliCommandConte
.description('List, search, validate, or query local semantic-layer sources')
.usage('[options] [query...]')
.argument('[query...]', 'Search query; omit to list all sources')
- .option('--connection-id ', 'KTX connection id')
+ .option('--connection-id ', 'ktx connection id')
.option('--limit ', 'Maximum search results (search mode only)', parsePositiveIntegerOption)
.addOption(
new Option('--output ', 'Output mode: pretty (default in TTY), plain (TSV), or json').choices([
diff --git a/packages/cli/src/commands/sql-commands.ts b/packages/cli/src/commands/sql-commands.ts
index 0c73df6a..213ab059 100644
--- a/packages/cli/src/commands/sql-commands.ts
+++ b/packages/cli/src/commands/sql-commands.ts
@@ -26,7 +26,7 @@ export function registerSqlCommands(program: Command, context: KtxCliCommandCont
.command('sql')
.description('Execute parser-validated read-only SQL against a configured connection')
.argument('', 'SQL query to execute')
- .requiredOption('-c, --connection ', 'KTX connection id')
+ .requiredOption('-c, --connection ', 'ktx connection id')
.option('--max-rows ', 'Maximum rows to return', parseSqlMaxRowsOption, DEFAULT_MAX_ROWS)
.addOption(
new Option('--output ', 'Output mode: pretty (default), plain (TSV), or json').choices([
diff --git a/packages/cli/src/commands/status-commands.ts b/packages/cli/src/commands/status-commands.ts
index ec429576..1f72a385 100644
--- a/packages/cli/src/commands/status-commands.ts
+++ b/packages/cli/src/commands/status-commands.ts
@@ -15,7 +15,7 @@ function inputMode(options: { input?: boolean }): { inputMode?: 'disabled' } {
export function registerStatusCommands(program: Command, context: KtxCliCommandContext): void {
program
.command('status')
- .description('Check current KTX setup and project readiness')
+ .description('Check current ktx setup and project readiness')
.option('--json', 'Print JSON output', false)
.option('-v, --verbose', 'Show every check, including passing ones', false)
.option('--validate', 'Only validate the ktx.yaml schema; skip readiness checks', false)
diff --git a/packages/cli/src/connection.ts b/packages/cli/src/connection.ts
index 9b6b4294..1e267833 100644
--- a/packages/cli/src/connection.ts
+++ b/packages/cli/src/connection.ts
@@ -134,7 +134,7 @@ async function createDefaultLookerClient(
connectionId: string,
): Promise {
const factory = new DefaultLookerConnectionClientFactory(createLocalLookerCredentialResolver(project));
- return (await factory.createClient(connectionId)) as unknown as LookerTestPort;
+ return factory.createLookerClient(connectionId);
}
async function testLookerConnection(
diff --git a/packages/cli/src/connectors/clickhouse/connector.ts b/packages/cli/src/connectors/clickhouse/connector.ts
index 23622701..c0d8c9a6 100644
--- a/packages/cli/src/connectors/clickhouse/connector.ts
+++ b/packages/cli/src/connectors/clickhouse/connector.ts
@@ -645,7 +645,7 @@ export class KtxClickHouseScanConnector implements KtxScanConnector {
private assertConnection(connectionId: string): void {
if (connectionId !== this.connectionId) {
- throw new Error(`KTX ClickHouse connector ${this.id} cannot serve connection ${connectionId}`);
+ throw new Error(`ktx ClickHouse connector ${this.id} cannot serve connection ${connectionId}`);
}
}
}
diff --git a/packages/cli/src/connectors/mysql/connector.ts b/packages/cli/src/connectors/mysql/connector.ts
index 080c5cdd..2675fa2c 100644
--- a/packages/cli/src/connectors/mysql/connector.ts
+++ b/packages/cli/src/connectors/mysql/connector.ts
@@ -794,7 +794,7 @@ export class KtxMysqlScanConnector implements KtxScanConnector {
private assertConnection(connectionId: string): void {
if (connectionId !== this.connectionId) {
- throw new Error(`KTX MySQL connector ${this.id} cannot serve connection ${connectionId}`);
+ throw new Error(`ktx MySQL connector ${this.id} cannot serve connection ${connectionId}`);
}
}
}
diff --git a/packages/cli/src/connectors/snowflake/connector.ts b/packages/cli/src/connectors/snowflake/connector.ts
index 51a91e52..56c3b2f3 100644
--- a/packages/cli/src/connectors/snowflake/connector.ts
+++ b/packages/cli/src/connectors/snowflake/connector.ts
@@ -107,7 +107,7 @@ export interface KtxSnowflakeScanConnectorOptions {
connectionId: string;
connection: KtxSnowflakeConnectionConfig | undefined;
/**
- * KTX project directory. When provided, snowflake-sdk's logger is redirected to
+ * ktx project directory. When provided, snowflake-sdk's logger is redirected to
* `/.ktx/logs/snowflake.log` so its JSON output does not bleed into
* the CLI's TTY. Tests that use a fake driverFactory can leave this undefined.
*/
diff --git a/packages/cli/src/connectors/sqlite/connector.ts b/packages/cli/src/connectors/sqlite/connector.ts
index 4cbeeada..4cae8f99 100644
--- a/packages/cli/src/connectors/sqlite/connector.ts
+++ b/packages/cli/src/connectors/sqlite/connector.ts
@@ -355,7 +355,7 @@ export class KtxSqliteScanConnector implements KtxScanConnector {
private assertConnection(connectionId: string): void {
if (connectionId !== this.connectionId) {
- throw new Error(`KTX SQLite connector ${this.id} cannot serve connection ${connectionId}`);
+ throw new Error(`ktx SQLite connector ${this.id} cannot serve connection ${connectionId}`);
}
}
}
diff --git a/packages/cli/src/connectors/sqlserver/connector.ts b/packages/cli/src/connectors/sqlserver/connector.ts
index fa7531ba..0d0136be 100644
--- a/packages/cli/src/connectors/sqlserver/connector.ts
+++ b/packages/cli/src/connectors/sqlserver/connector.ts
@@ -833,7 +833,7 @@ export class KtxSqlServerScanConnector implements KtxScanConnector {
private assertConnection(connectionId: string): void {
if (connectionId !== this.connectionId) {
- throw new Error(`KTX SQL Server connector ${this.id} cannot serve connection ${connectionId}`);
+ throw new Error(`ktx SQL Server connector ${this.id} cannot serve connection ${connectionId}`);
}
}
}
diff --git a/packages/cli/src/context-build-view.ts b/packages/cli/src/context-build-view.ts
index 0991cecb..042a517a 100644
--- a/packages/cli/src/context-build-view.ts
+++ b/packages/cli/src/context-build-view.ts
@@ -415,7 +415,7 @@ export function renderContextBuildView(
const hasActive = allTargets.some((t) => t.status === 'running' || t.status === 'queued');
const allDone = totalCount > 0 && !hasActive;
- const headerParts = [options.title ?? 'Building KTX context'];
+ const headerParts = [options.title ?? 'Building ktx context'];
if (totalCount > 0) {
const progressParts: string[] = [`${doneCount}/${totalCount}`];
if (state.totalElapsedMs > 0) progressParts.push(formatDuration(state.totalElapsedMs));
@@ -738,7 +738,7 @@ function failedStepDetail(result: KtxPublicIngestTargetResult): string | null {
const INTERNAL_FAILURE_LINE_RE =
/^(Report|Run|Job|Status|Adapter|Connection|Sync|Mode|Dry run|Diff|Tasks|Work units|Failed tasks|Saved memory|Provenance rows):\s*/;
const ACTIONABLE_FAILURE_LINE_RE =
- /^(Missing bundled Python runtime manifest|KTX Python runtime is required|KTX daemon HTTP|Error:|Failed\b|Could not\b|Cannot\b)/;
+ /^(Missing bundled Python runtime manifest|ktx Python runtime is required|ktx daemon HTTP|Error:|Failed\b|Could not\b|Cannot\b)/;
function trimErrorPrefix(line: string): string {
return line.replace(/^Error:\s*/, '');
@@ -749,7 +749,7 @@ function firstCapturedFailureLine(output: string | undefined): string | null {
.split(/\r?\n/)
.map((candidate) => candidate.trim())
.filter((candidate) => candidate.length > 0)
- .filter((candidate) => !candidate.startsWith('KTX scan completed'))
+ .filter((candidate) => !candidate.startsWith('ktx scan completed'))
.filter((candidate) => !INTERNAL_FAILURE_LINE_RE.test(candidate));
const line = lines.find((candidate) => ACTIONABLE_FAILURE_LINE_RE.test(candidate)) ?? lines.at(-1) ?? null;
return line ? trimErrorPrefix(line) : null;
@@ -789,7 +789,7 @@ function failureTextForTarget(input: {
const code = networkErrorCode(input.error, input.capturedOutput);
if (code && isLocalSqlAnalysisConnectionRefused({ capturedOutput: input.capturedOutput, fallback: input.fallback })) {
return [
- `KTX could not reach the local SQL analysis runtime while processing query history for ${input.target.connectionId}.`,
+ `ktx could not reach the local SQL analysis runtime while processing query history for ${input.target.connectionId}.`,
`Reason: ${NETWORK_ERROR_REASONS[code]} (${code}).`,
`Retry: ${retryCommand({
projectDir: input.projectDir,
@@ -803,7 +803,7 @@ function failureTextForTarget(input: {
if (code) {
const operation = input.target.operation === 'database-ingest' ? 'reading schema for' : 'ingesting';
return [
- `KTX lost its connection to ${friendlyDriverName(input.target.driver)} while ${operation} ${input.target.connectionId}.`,
+ `ktx lost its connection to ${friendlyDriverName(input.target.driver)} while ${operation} ${input.target.connectionId}.`,
`Reason: ${NETWORK_ERROR_REASONS[code]} (${code}).`,
`Retry: ${retryCommand({
projectDir: input.projectDir,
diff --git a/packages/cli/src/context/ingest/adapters/looker/client.ts b/packages/cli/src/context/ingest/adapters/looker/client.ts
index 90f9f466..c31145d0 100644
--- a/packages/cli/src/context/ingest/adapters/looker/client.ts
+++ b/packages/cli/src/context/ingest/adapters/looker/client.ts
@@ -88,13 +88,18 @@ const defaultLogger: LookerClientLogger = {
class InlineLookerSettings extends NodeSettings {
constructor(private readonly params: LookerConnectionParams) {
- super('', {
+ // @looker/sdk-rtl boundary: NodeSettings consumes a string-valued config
+ // section (read back via the readConfig override below), but its constructor
+ // is typed to accept a fully-realized IApiSettings. The string record is the
+ // shape the library actually reads, so narrow to IApiSection first.
+ const settings: IApiSection = {
base_url: normalizeBaseUrl(params.base_url),
client_id: params.client_id,
client_secret: params.client_secret, // pragma: allowlist secret
verify_ssl: 'true',
timeout: '120',
- } as unknown as IApiSettings);
+ };
+ super('', settings as IApiSection & IApiSettings);
}
override readConfig(_section?: string): IApiSection {
diff --git a/packages/cli/src/context/ingest/adapters/looker/factory.ts b/packages/cli/src/context/ingest/adapters/looker/factory.ts
index 64fdfa42..edb1dcbe 100644
--- a/packages/cli/src/context/ingest/adapters/looker/factory.ts
+++ b/packages/cli/src/context/ingest/adapters/looker/factory.ts
@@ -19,6 +19,16 @@ export class DefaultLookerConnectionClientFactory implements LookerConnectionCli
) {}
async createClient(lookerConnectionId: string): Promise {
+ return this.createLookerClient(lookerConnectionId);
+ }
+
+ /**
+ * Like {@link createClient} but preserves the concrete {@link LookerClient}
+ * type, so callers that need methods outside the `LookerRuntimeClient`
+ * contract (e.g. `listLookerConnections`, `testConnection`) keep them without
+ * a cast.
+ */
+ async createLookerClient(lookerConnectionId: string): Promise {
const credentials = await this.resolver.resolve(lookerConnectionId);
return new LookerClient(credentials, this.deps);
}
diff --git a/packages/cli/src/context/ingest/adapters/looker/mapping.ts b/packages/cli/src/context/ingest/adapters/looker/mapping.ts
index 4da6344d..3e451aca 100644
--- a/packages/cli/src/context/ingest/adapters/looker/mapping.ts
+++ b/packages/cli/src/context/ingest/adapters/looker/mapping.ts
@@ -214,7 +214,7 @@ export function validateLookerMappings(args: {
if (!args.knownKtxConnectionIds.has(mapping.ktxConnectionId)) {
errors.push({
key: mapping.lookerConnectionName,
- reason: `KTX connection ${mapping.ktxConnectionId} does not exist`,
+ reason: `ktx connection ${mapping.ktxConnectionId} does not exist`,
});
continue;
}
diff --git a/packages/cli/src/context/ingest/adapters/metabase/client.ts b/packages/cli/src/context/ingest/adapters/metabase/client.ts
index 7b075991..5a48d0c6 100644
--- a/packages/cli/src/context/ingest/adapters/metabase/client.ts
+++ b/packages/cli/src/context/ingest/adapters/metabase/client.ts
@@ -81,7 +81,7 @@ class MetabaseApiError extends Error {
* Strip Metabase `[[ ... {{ var }} ... ]]` optional-clause blocks from native SQL.
*
* The bracketed blocks are emitted only when the embedded `{{ var }}` is supplied at
- * Metabase query time. For KTX semantic-layer ingest there's no such runtime
+ * Metabase query time. For ktx semantic-layer ingest there's no such runtime
* parameter — chat-time filters are composed by the SL query planner — so the optional
* block must be removed before the SQL becomes a permanent SL source. Substituting a
* dummy value (the alternative) bakes a placeholder filter into the source and silently
diff --git a/packages/cli/src/context/ingest/adapters/metabase/local-metabase.adapter.ts b/packages/cli/src/context/ingest/adapters/metabase/local-metabase.adapter.ts
index 7cb3d843..f581c5e3 100644
--- a/packages/cli/src/context/ingest/adapters/metabase/local-metabase.adapter.ts
+++ b/packages/cli/src/context/ingest/adapters/metabase/local-metabase.adapter.ts
@@ -34,7 +34,7 @@ export function metabaseRuntimeConfigFromLocalConnection(
}
if (hasNetworkProxy(connection)) {
throw new Error(
- `Standalone KTX does not support proxy-bearing Metabase connections yet. Use hosted Metabase ingest for "${connectionId}" until the KTX Metabase proxy support spec lands.`,
+ `Standalone ktx does not support proxy-bearing Metabase connections yet. Use hosted Metabase ingest for "${connectionId}" until the ktx Metabase proxy support spec lands.`,
);
}
diff --git a/packages/cli/src/context/ingest/adapters/metabase/mapping.ts b/packages/cli/src/context/ingest/adapters/metabase/mapping.ts
index 788ae43b..b5ba67a7 100644
--- a/packages/cli/src/context/ingest/adapters/metabase/mapping.ts
+++ b/packages/cli/src/context/ingest/adapters/metabase/mapping.ts
@@ -186,7 +186,7 @@ export function validateMetabaseMappings(args: {
continue;
}
if (!args.knownKtxConnectionIds.has(connectionId)) {
- errors.push({ key, reason: `KTX connection ${connectionId} does not exist` });
+ errors.push({ key, reason: `ktx connection ${connectionId} does not exist` });
}
}
return errors.length === 0 ? { ok: true } : { ok: false, errors };
@@ -207,7 +207,7 @@ export function validateMappingPhysicalMatch(
}
if (target.connection_type !== expectedType) {
- return `Metabase database engine '${engine}' does not match KTX connection type '${target.connection_type}'`;
+ return `Metabase database engine '${engine}' does not match ktx connection type '${target.connection_type}'`;
}
const metabaseDb = normalizeName(mapping.metabaseDbName);
@@ -215,7 +215,7 @@ export function validateMappingPhysicalMatch(
if (engine === 'snowflake' || engine === 'bigquery' || engine === 'bigquery-cloud-sdk') {
if (metabaseDb && targetDb && metabaseDb !== targetDb) {
- return `Metabase database '${mapping.metabaseDbName}' does not match KTX connection database '${displayValue(
+ return `Metabase database '${mapping.metabaseDbName}' does not match ktx connection database '${displayValue(
getTargetDatabase(target),
)}'`;
}
@@ -227,12 +227,12 @@ export function validateMappingPhysicalMatch(
const targetHost = normalizeHost(target.host);
if (metabaseHost && targetHost && metabaseHost !== targetHost) {
- return `Metabase host '${mapping.metabaseHost}' does not match KTX connection host '${displayValue(
+ return `Metabase host '${mapping.metabaseHost}' does not match ktx connection host '${displayValue(
target.host,
)}'`;
}
if (metabaseDb && targetDb && metabaseDb !== targetDb) {
- return `Metabase database '${mapping.metabaseDbName}' does not match KTX connection database '${displayValue(
+ return `Metabase database '${mapping.metabaseDbName}' does not match ktx connection database '${displayValue(
getTargetDatabase(target),
)}'`;
}
@@ -274,7 +274,7 @@ export async function refreshMetabaseMapping(args: {
if (!target) {
physicalMismatches.push({
mappingId: String(mapping.id),
- reason: `KTX connection ${mapping.ktxConnectionId} does not exist`,
+ reason: `ktx connection ${mapping.ktxConnectionId} does not exist`,
});
continue;
}
diff --git a/packages/cli/src/context/ingest/final-gate-repair.ts b/packages/cli/src/context/ingest/final-gate-repair.ts
index 2b8e5c33..d6d05e41 100644
--- a/packages/cli/src/context/ingest/final-gate-repair.ts
+++ b/packages/cli/src/context/ingest/final-gate-repair.ts
@@ -62,7 +62,7 @@ async function readOptionalFile(path: string): Promise<{ exists: boolean; conten
function buildGateRepairSystemPrompt(): string {
return `
-You repair one KTX isolated-diff artifact gate failure inside the integration worktree.
+You repair one ktx isolated-diff artifact gate failure inside the integration worktree.
diff --git a/packages/cli/src/context/ingest/isolated-diff/textual-conflict-resolver.ts b/packages/cli/src/context/ingest/isolated-diff/textual-conflict-resolver.ts
index c4a00448..8c5bb097 100644
--- a/packages/cli/src/context/ingest/isolated-diff/textual-conflict-resolver.ts
+++ b/packages/cli/src/context/ingest/isolated-diff/textual-conflict-resolver.ts
@@ -65,7 +65,7 @@ async function readOptionalFile(path: string): Promise<{ exists: boolean; conten
function buildResolverSystemPrompt(): string {
return `
-You repair one failed KTX isolated-diff patch inside the integration worktree.
+You repair one failed ktx isolated-diff patch inside the integration worktree.
diff --git a/packages/cli/src/context/ingest/local-bundle-runtime.ts b/packages/cli/src/context/ingest/local-bundle-runtime.ts
index 90f1b3ae..46847646 100644
--- a/packages/cli/src/context/ingest/local-bundle-runtime.ts
+++ b/packages/cli/src/context/ingest/local-bundle-runtime.ts
@@ -77,7 +77,7 @@ import type { SourceAdapter } from './types.js';
const promptsDir = fileURLToPath(new URL('../../prompts', import.meta.url));
const skillsDir = fileURLToPath(new URL('../../skills', import.meta.url));
-const LOCAL_AUTHOR = { name: 'KTX Local', email: 'local@ktx.local' };
+const LOCAL_AUTHOR = { name: 'ktx Local', email: 'local@ktx.local' };
const LOCAL_SHAPE_WARNING = 'Local ingest validates semantic-layer YAML shape only.';
const INGEST_TRACE_LEVELS = new Set(['error', 'info', 'debug', 'trace']);
@@ -232,8 +232,9 @@ class LocalSlPythonPort implements SlPythonPort {
}
class LocalShapeOnlySlValidator implements SlValidatorPort {
- private validateParsedSource(sourceName: string, parsed: Record) {
- const isOverlay = parsed.table == null && parsed.sql == null;
+ private validateParsedSource(sourceName: string, parsed: unknown) {
+ const fields = (parsed ?? {}) as { table?: unknown; sql?: unknown };
+ const isOverlay = fields.table == null && fields.sql == null;
const result = (isOverlay ? sourceOverlaySchema : sourceDefinitionSchema).safeParse(parsed);
return result.success
? { errors: [], warnings: [LOCAL_SHAPE_WARNING] }
@@ -255,7 +256,7 @@ class LocalShapeOnlySlValidator implements SlValidatorPort {
const { sources, loadErrors } = await deps.semanticLayerService.loadAllSources(connectionId);
const source = sources.find((candidate) => candidate.name === sourceName);
if (source) {
- return this.validateParsedSource(sourceName, source as unknown as Record);
+ return this.validateParsedSource(sourceName, source);
}
const detail =
loadErrors.length > 0
@@ -279,7 +280,7 @@ class LocalShapeOnlySlValidator implements SlValidatorPort {
}
try {
- const parsed = YAML.parse(file.content) as unknown as Record;
+ const parsed = YAML.parse(file.content) as Record;
return this.validateParsedSource(sourceName, parsed);
} catch (error) {
return {
diff --git a/packages/cli/src/context/ingest/memory-flow/view-model.ts b/packages/cli/src/context/ingest/memory-flow/view-model.ts
index c8f784b8..028cb53f 100644
--- a/packages/cli/src/context/ingest/memory-flow/view-model.ts
+++ b/packages/cli/src/context/ingest/memory-flow/view-model.ts
@@ -513,7 +513,7 @@ export function buildMemoryFlowViewModel(input: MemoryFlowReplayInput): MemoryFl
: `${input.connectionId}/${input.adapter}`;
return {
- title: `KTX memory flow ${titleSources} ${input.status}`,
+ title: `ktx memory flow ${titleSources} ${input.status}`,
subtitle: `Run ${input.runId} Sync ${input.syncId}`,
status: input.status,
activeLine: activeLine(input),
diff --git a/packages/cli/src/context/ingest/tools/warehouse-verification/discover-data.tool.ts b/packages/cli/src/context/ingest/tools/warehouse-verification/discover-data.tool.ts
index e358e970..6c3380bc 100644
--- a/packages/cli/src/context/ingest/tools/warehouse-verification/discover-data.tool.ts
+++ b/packages/cli/src/context/ingest/tools/warehouse-verification/discover-data.tool.ts
@@ -70,10 +70,10 @@ export class DiscoverDataTool extends BaseTool {
}
if (input.sourceName) {
- const sl = await this.deps.slDiscoverTool.call(
+ const sl = (await this.deps.slDiscoverTool.call(
{ sourceName: input.sourceName, connectionId: input.connectionId },
context,
- );
+ )) as ToolOutput;
return { markdown: sl.markdown, structured: { wiki: null, sl: sl.structured, raw: null } };
}
@@ -85,17 +85,17 @@ export class DiscoverDataTool extends BaseTool {
let raw: DiscoverDataStructured['raw'] = null;
if (query) {
- const wikiResult = await this.deps.wikiSearchTool.call({ query, limit }, context);
+ const wikiResult = (await this.deps.wikiSearchTool.call({ query, limit }, context)) as ToolOutput;
if (totalFound(wikiResult.structured) > 0) {
parts.push('## Wiki Pages', '> use `wiki_read(blockKey)` for full content', wikiResult.markdown, '');
wiki = wikiResult.structured;
}
}
- const slResult = await this.deps.slDiscoverTool.call(
+ const slResult = (await this.deps.slDiscoverTool.call(
{ query: query || undefined, connectionId: input.connectionId },
context,
- );
+ )) as ToolOutput;
if (totalSources(slResult.structured) > 0) {
parts.push(
'## Semantic Layer Sources',
diff --git a/packages/cli/src/context/llm/ai-sdk-runtime.ts b/packages/cli/src/context/llm/ai-sdk-runtime.ts
index 81ada6ea..a6776f49 100644
--- a/packages/cli/src/context/llm/ai-sdk-runtime.ts
+++ b/packages/cli/src/context/llm/ai-sdk-runtime.ts
@@ -239,7 +239,7 @@ export class AiSdkKtxLlmRuntime implements KtxLlmRuntimePort {
const result = await this.generateTextWithRateLimitRetry(modelProviderName(model), input.abortSignal, () => generateText(request));
input.onMetrics?.({ totalMs: Date.now() - startedAt, usage: toLlmTokenUsage(result.totalUsage ?? result.usage) });
if (typeof result.text !== 'string') {
- throw new Error('KTX LLM text generation returned no text');
+ throw new Error('ktx LLM text generation returned no text');
}
return result.text;
}
@@ -271,12 +271,12 @@ export class AiSdkKtxLlmRuntime implements KtxLlmRuntimePort {
}),
}
: {}),
- output: Output.object({ schema: input.schema as unknown as FlexibleSchema }),
+ output: Output.object({ schema: input.schema as FlexibleSchema }),
};
const result = await this.generateTextWithRateLimitRetry(modelProviderName(model), input.abortSignal, () => generateText(request));
input.onMetrics?.({ totalMs: Date.now() - startedAt, usage: toLlmTokenUsage(result.totalUsage ?? result.usage) });
if (result.output == null) {
- throw new Error('KTX LLM object generation returned no output');
+ throw new Error('ktx LLM object generation returned no output');
}
return result.output as TOutput;
}
diff --git a/packages/cli/src/context/llm/claude-code-runtime.ts b/packages/cli/src/context/llm/claude-code-runtime.ts
index 9d0cff70..633b024f 100644
--- a/packages/cli/src/context/llm/claude-code-runtime.ts
+++ b/packages/cli/src/context/llm/claude-code-runtime.ts
@@ -193,7 +193,7 @@ function isClaudeRateLimitResult(result: SDKResultMessage, rejectedSignal: RateL
}
function claudeRateLimitSignal(message: SDKMessage): RateLimitSignal | null {
- const record = message as unknown as Record;
+ const record = message as Record;
if (record.type === 'rate_limit_event') {
const info = record.rate_limit_info as Record | undefined;
if (!info) return null;
@@ -253,7 +253,7 @@ function baseOptions(input: {
? { behavior: 'allow', toolUseID: options.toolUseID }
: {
behavior: 'deny',
- message: `KTX claude-code runtime only permits current KTX MCP tools; denied ${toolName}.`,
+ message: `ktx claude-code runtime only permits current ktx MCP tools; denied ${toolName}.`,
toolUseID: options.toolUseID,
},
permissionMode: 'dontAsk',
diff --git a/packages/cli/src/context/llm/local-config.ts b/packages/cli/src/context/llm/local-config.ts
index 4c2502d1..0d64a27f 100644
--- a/packages/cli/src/context/llm/local-config.ts
+++ b/packages/cli/src/context/llm/local-config.ts
@@ -198,7 +198,7 @@ export function resolveLocalKtxEmbeddingConfig(
batchSize: config.batchSize,
};
}
- throw new Error(`Unsupported KTX embedding backend: ${String((config as { backend?: string }).backend)}`);
+ throw new Error(`Unsupported ktx embedding backend: ${String((config as { backend?: string }).backend)}`);
}
/** @internal */
diff --git a/packages/cli/src/context/llm/runtime-tools.ts b/packages/cli/src/context/llm/runtime-tools.ts
index 4a52bdd1..4afac4bc 100644
--- a/packages/cli/src/context/llm/runtime-tools.ts
+++ b/packages/cli/src/context/llm/runtime-tools.ts
@@ -28,7 +28,7 @@ export function normalizeKtxRuntimeToolOutput(value: unknown): KtxRuntimeToolOut
function assertObjectSchema(name: string, schema: z.ZodType): asserts schema is z.ZodObject {
if (!(schema instanceof z.ZodObject)) {
- throw new Error(`KTX runtime tool "${name}" must use z.object input schema for claude-code`);
+ throw new Error(`ktx runtime tool "${name}" must use z.object input schema for claude-code`);
}
}
@@ -75,7 +75,7 @@ export function createRuntimeToolDescriptorFromAiTool(name: string, aiSdkTool: T
inputSchema: aiSdkTool.inputSchema as KtxRuntimeToolDescriptor['inputSchema'],
execute: async (input) => {
if (typeof aiSdkTool.execute !== 'function') {
- throw new Error(`KTX runtime tool "${name}" has no execute function`);
+ throw new Error(`ktx runtime tool "${name}" has no execute function`);
}
return normalizeKtxRuntimeToolOutput(
await aiSdkTool.execute(input as never, { toolCallId: `runtime-${name}` } as never),
diff --git a/packages/cli/src/context/mcp/context-tools.ts b/packages/cli/src/context/mcp/context-tools.ts
index 2d07d121..71ed3a14 100644
--- a/packages/cli/src/context/mcp/context-tools.ts
+++ b/packages/cli/src/context/mcp/context-tools.ts
@@ -56,12 +56,12 @@ const toolAnnotations = {
const toolDescriptions = {
connection_list:
- 'List configured read-only data connections available to this KTX project. Use this before connection-scoped tools when the project may have multiple warehouses.',
+ 'List configured read-only data connections available to this ktx project. Use this before connection-scoped tools when the project may have multiple warehouses.',
discover_data:
- 'Search across KTX wiki pages, semantic-layer sources, measures, dimensions, raw tables, and columns. Example: discover_data({ query: "monthly orders by customer", connectionId: "warehouse", kinds: ["sl_source", "table"] }).',
+ 'Search across ktx wiki pages, semantic-layer sources, measures, dimensions, raw tables, and columns. Example: discover_data({ query: "monthly orders by customer", connectionId: "warehouse", kinds: ["sl_source", "table"] }).',
wiki_search:
- 'Search KTX wiki pages for reusable business context. Example: wiki_search({ query: "revenue recognition", limit: 5 }).',
- wiki_read: 'Read a KTX wiki page by key returned from wiki_search. Example: wiki_read({ key: "global/revenue" }).',
+ 'Search ktx wiki pages for reusable business context. Example: wiki_search({ query: "revenue recognition", limit: 5 }).',
+ wiki_read: 'Read a ktx wiki page by key returned from wiki_search. Example: wiki_read({ key: "global/revenue" }).',
entity_details:
'Read table and column metadata from the latest live-database scan snapshot. Example: entity_details({ connectionId: "warehouse", entities: [{ table: { catalog: null, db: "public", name: "orders" }, columns: ["id"] }] }).',
dictionary_search:
@@ -71,9 +71,9 @@ const toolDescriptions = {
sl_query:
'Execute a semantic-layer query and return headers, rows, and total row count, plus correctness notes (e.g. compile-only or fan-out) when relevant. The generated SQL and full query plan are omitted by default; request them with include: ["sql"] and/or include: ["plan"]. Example: sl_query({ connectionId: "warehouse", measures: ["orders.order_count"], dimensions: [{ field: "orders.created_at", granularity: "month" }], include: ["sql"] }).',
sql_execution:
- 'Execute one parser-validated read-only SQL query against a configured KTX connection. Example: sql_execution({ connectionId: "warehouse", sql: "select count(*) from public.orders", maxRows: 100 }).',
+ 'Execute one parser-validated read-only SQL query against a configured ktx connection. Example: sql_execution({ connectionId: "warehouse", sql: "select count(*) from public.orders", maxRows: 100 }).',
memory_ingest:
- 'Ingest free-form markdown knowledge into durable KTX memory. Use this for business rules, metric definitions, schema gotchas, recurring findings, or explicit user requests to remember something. Example: memory_ingest({ connectionId: "warehouse", content: "ARR is reported in cents in this warehouse." }).',
+ 'Ingest free-form markdown knowledge into durable ktx memory. Use this for business rules, metric definitions, schema gotchas, recurring findings, or explicit user requests to remember something. Example: memory_ingest({ connectionId: "warehouse", content: "ARR is reported in cents in this warehouse." }).',
memory_ingest_status:
'Read the current or final status for a memory ingest run. Example: memory_ingest_status({ runId: "memory-run-1" }).',
} satisfies Record;
@@ -856,7 +856,7 @@ export function registerKtxContextTools(deps: RegisterKtxContextToolsDeps): void
const ingestInput: MemoryAgentInput = {
userId: userContext.userId,
chatId: `mcp-${randomUUID()}`,
- userMessage: 'Ingest external knowledge into KTX memory.',
+ userMessage: 'Ingest external knowledge into ktx memory.',
assistantMessage: input.content,
connectionId: input.connectionId,
sourceType: 'external_ingest',
diff --git a/packages/cli/src/context/memory/local-memory.ts b/packages/cli/src/context/memory/local-memory.ts
index 92bb5b78..2d8cb5c8 100644
--- a/packages/cli/src/context/memory/local-memory.ts
+++ b/packages/cli/src/context/memory/local-memory.ts
@@ -52,7 +52,7 @@ import type {
const promptsDir = fileURLToPath(new URL('../../prompts', import.meta.url));
const skillsDir = fileURLToPath(new URL('../../skills', import.meta.url));
-const LOCAL_AUTHOR = { name: 'KTX Local', email: 'local@ktx.local' };
+const LOCAL_AUTHOR = { name: 'ktx Local', email: 'local@ktx.local' };
const LOCAL_SHAPE_WARNING = 'Local memory ingest validates semantic-layer YAML shape only.';
export interface CreateLocalProjectMemoryIngestOptions {
diff --git a/packages/cli/src/context/project/config.ts b/packages/cli/src/context/project/config.ts
index 2c0b075d..51d9c4e7 100644
--- a/packages/cli/src/context/project/config.ts
+++ b/packages/cli/src/context/project/config.ts
@@ -62,7 +62,7 @@ const llmSchema = z
models: z
.partialRecord(z.enum(KTX_MODEL_ROLES), z.string().min(1))
.default({})
- .describe('Per-role model overrides keyed by KTX model role (e.g. "default", "triage"). Values are provider-specific model identifiers.'),
+ .describe('Per-role model overrides keyed by ktx model role (e.g. "default", "triage"). Values are provider-specific model identifiers.'),
promptCaching: promptCachingSchema.optional().describe('Optional prompt-caching tunables.'),
})
.describe('LLM provider, per-role model overrides, and prompt-caching tunables.');
@@ -243,14 +243,14 @@ const storageSchema = z
state: z
.enum(KTX_STORAGE_STATES)
.default('sqlite')
- .describe('Backend for KTX state storage. "sqlite" uses .ktx/db.sqlite; "postgres" expects a configured Postgres connection.'),
+ .describe('Backend for ktx state storage. "sqlite" uses .ktx/db.sqlite; "postgres" expects a configured Postgres connection.'),
search: z
.enum(KTX_SEARCH_BACKENDS)
.default('sqlite-fts5')
.describe('Backend for search indexes. "sqlite-fts5" uses SQLite FTS5; "postgres-hybrid" uses Postgres lexical + vector hybrid search.'),
git: storageGitSchema.prefault({}).describe('Git-backed storage commit policy.'),
})
- .describe('Storage backends and commit policy for KTX state and search indexes.');
+ .describe('Storage backends and commit policy for ktx state and search indexes.');
const connectionSchema = connectionConfigSchema;
@@ -282,13 +282,13 @@ const ktxProjectConfigSchema = z
.record(z.string(), connectionSchema)
.default({})
.describe('Map of connection ID to connector configuration. Keys are user-chosen names referenced elsewhere in the config.'),
- storage: storageSchema.prefault({}).describe('Storage backends and commit policy for KTX state and search indexes.'),
+ storage: storageSchema.prefault({}).describe('Storage backends and commit policy for ktx state and search indexes.'),
llm: llmSchema.prefault({}).describe('LLM provider, per-role model overrides, and prompt-caching tunables.'),
ingest: ingestSchema.prefault({}).describe('Ingest pipeline configuration.'),
agent: agentSchema.prefault({}).describe('Agent feature configuration.'),
scan: scanSchema.prefault({}).describe('Schema-scan configuration: enrichment and relationship discovery.'),
})
- .describe('Configuration schema for KTX project files (ktx.yaml).');
+ .describe('Configuration schema for ktx project files (ktx.yaml).');
export type KtxProjectConfig = z.infer;
export type KtxProjectLlmConfig = z.infer;
diff --git a/packages/cli/src/context/project/driver-schemas.ts b/packages/cli/src/context/project/driver-schemas.ts
index f9a3639f..72b4344e 100644
--- a/packages/cli/src/context/project/driver-schemas.ts
+++ b/packages/cli/src/context/project/driver-schemas.ts
@@ -102,7 +102,7 @@ const lookerConnectionSchema = z
.min(1)
.optional()
.describe('Reference to Looker OAuth client secret (e.g. env:LOOKER_CLIENT_SECRET).'),
- mappings: lookerMappingsSchema.optional().describe('Looker connection-name to KTX warehouse mappings.'),
+ mappings: lookerMappingsSchema.optional().describe('Looker connection-name to ktx warehouse mappings.'),
})
.describe('Looker context-source connection.');
diff --git a/packages/cli/src/context/project/mappings-yaml-schema.ts b/packages/cli/src/context/project/mappings-yaml-schema.ts
index 9c69e1b3..6e27e8ca 100644
--- a/packages/cli/src/context/project/mappings-yaml-schema.ts
+++ b/packages/cli/src/context/project/mappings-yaml-schema.ts
@@ -15,7 +15,7 @@ export const metabaseMappingsSchema = z
databaseMappings: z
.record(z.string(), stringTargetSchema)
.default({})
- .describe('Map of Metabase database ID (positive integer string) to KTX connection ID. Use null to explicitly unmap.'),
+ .describe('Map of Metabase database ID (positive integer string) to ktx connection ID. Use null to explicitly unmap.'),
syncEnabled: z
.record(z.string(), z.boolean())
.default({})
@@ -38,7 +38,7 @@ export const lookerMappingsSchema = z
connectionMappings: z
.record(z.string().min(1), stringTargetSchema)
.default({})
- .describe('Map of Looker connection name to KTX connection ID. Use null to explicitly unmap.'),
+ .describe('Map of Looker connection name to ktx connection ID. Use null to explicitly unmap.'),
})
.describe('Looker connection-to-warehouse mapping configuration.');
diff --git a/packages/cli/src/context/project/project.ts b/packages/cli/src/context/project/project.ts
index 56fca5b2..6ca27d10 100644
--- a/packages/cli/src/context/project/project.ts
+++ b/packages/cli/src/context/project/project.ts
@@ -123,7 +123,7 @@ export async function initKtxProject(options: InitKtxProjectOptions): Promise file.path)],
- `Initialize KTX project: ${projectName}`,
+ `Initialize ktx project: ${projectName}`,
authorName,
authorEmail,
);
diff --git a/packages/cli/src/context/scan/description-generation.ts b/packages/cli/src/context/scan/description-generation.ts
index c6a41449..7125a8a4 100644
--- a/packages/cli/src/context/scan/description-generation.ts
+++ b/packages/cli/src/context/scan/description-generation.ts
@@ -569,7 +569,7 @@ export class KtxDescriptionGenerator {
if (!connector.sampleTable) {
fallbackReason = 'capability_missing';
- this.logger?.warn('KTX scan connector does not support table sampling; falling back to metadata-only prompt', {
+ this.logger?.warn('ktx scan connector does not support table sampling; falling back to metadata-only prompt', {
connectorId: input.connector.id,
table: input.table.name,
});
@@ -690,7 +690,7 @@ export class KtxDescriptionGenerator {
let fallbackReason: 'capability_missing' | 'sampling_failed' | 'empty_sample' | null = null;
if (!input.connector.sampleTable) {
fallbackReason = 'capability_missing';
- this.logger?.warn('KTX scan connector does not support table sampling; falling back to metadata-only prompt', {
+ this.logger?.warn('ktx scan connector does not support table sampling; falling back to metadata-only prompt', {
connectorId: input.connector.id,
table: input.table.name,
});
@@ -846,7 +846,7 @@ export class KtxDescriptionGenerator {
}
if (!input.connector.sampleTable) {
- this.logger?.warn('KTX scan connector does not support table sampling for data-source description generation', {
+ this.logger?.warn('ktx scan connector does not support table sampling for data-source description generation', {
connectorId: input.connector.id,
});
return 'No accessible tables found in database';
@@ -927,7 +927,7 @@ export class KtxDescriptionGenerator {
let columnValues = column.sampleValues;
if (!columnValues || columnValues.length === 0) {
if (!input.connector.sampleColumn) {
- this.logger?.warn('KTX scan connector does not support column sampling; using available metadata only', {
+ this.logger?.warn('ktx scan connector does not support column sampling; using available metadata only', {
connectorId: input.connector.id,
table: input.table.name,
column: column.name,
diff --git a/packages/cli/src/context/scan/local-scan.ts b/packages/cli/src/context/scan/local-scan.ts
index 703ef73f..8529b7b7 100644
--- a/packages/cli/src/context/scan/local-scan.ts
+++ b/packages/cli/src/context/scan/local-scan.ts
@@ -154,7 +154,7 @@ function scanReportPath(connectionId: string, syncId: string): string {
function assertSupportedMode(mode: KtxScanMode): void {
if (mode !== 'structural' && mode !== 'relationships' && mode !== 'enriched') {
- throw new Error(`Unsupported KTX scan mode: ${mode}`);
+ throw new Error(`Unsupported ktx scan mode: ${mode}`);
}
}
@@ -544,7 +544,7 @@ export async function runLocalScan(options: RunLocalScanOptions): Promise parseWarning(warning, path));
} catch (error) {
@@ -102,7 +102,7 @@ function parseColumn(rawColumn: unknown, path: string): KtxSchemaColumn {
rawColumn.dimensionType !== 'number' &&
rawColumn.dimensionType !== 'boolean')
) {
- throw new Error(`Invalid KTX schema column artifact: ${path}`);
+ throw new Error(`Invalid ktx schema column artifact: ${path}`);
}
return {
name: rawColumn.name,
@@ -122,7 +122,7 @@ function parseForeignKey(rawForeignKey: unknown, path: string): KtxSchemaForeign
typeof rawForeignKey.toTable !== 'string' ||
typeof rawForeignKey.toColumn !== 'string'
) {
- throw new Error(`Invalid KTX schema foreign key artifact: ${path}`);
+ throw new Error(`Invalid ktx schema foreign key artifact: ${path}`);
}
return {
fromColumn: rawForeignKey.fromColumn,
@@ -137,7 +137,7 @@ function parseForeignKey(rawForeignKey: unknown, path: string): KtxSchemaForeign
function parseTable(raw: string, path: string): KtxSchemaTable {
const parsed = JSON.parse(raw) as unknown;
if (!isRecord(parsed) || typeof parsed.name !== 'string' || !Array.isArray(parsed.columns)) {
- throw new Error(`Invalid KTX schema table artifact: ${path}`);
+ throw new Error(`Invalid ktx schema table artifact: ${path}`);
}
return {
catalog: optionalStringOrNull(parsed.catalog) ?? null,
diff --git a/packages/cli/src/context/scan/relationship-benchmark-report.ts b/packages/cli/src/context/scan/relationship-benchmark-report.ts
index 626d08f8..aeb75a08 100644
--- a/packages/cli/src/context/scan/relationship-benchmark-report.ts
+++ b/packages/cli/src/context/scan/relationship-benchmark-report.ts
@@ -317,7 +317,7 @@ function compositeSkipBlocks(report: KtxRelationshipBenchmarkReport): string[] {
export function formatKtxRelationshipBenchmarkReportMarkdown(report: KtxRelationshipBenchmarkReport): string {
const lines = [
- '# KTX Relationship Discovery Benchmark Evidence',
+ '# ktx Relationship Discovery Benchmark Evidence',
'',
`Generated: ${report.generatedAt}`,
'',
diff --git a/packages/cli/src/context/scan/relationship-discovery.ts b/packages/cli/src/context/scan/relationship-discovery.ts
index fc755536..c2917aa8 100644
--- a/packages/cli/src/context/scan/relationship-discovery.ts
+++ b/packages/cli/src/context/scan/relationship-discovery.ts
@@ -153,7 +153,7 @@ async function detectCompositeRelationships(input: {
} catch (error) {
input.warnings.push({
code: 'relationship_validation_failed',
- message: `KTX composite relationship detection failed: ${error instanceof Error ? error.message : String(error)}`,
+ message: `ktx composite relationship detection failed: ${error instanceof Error ? error.message : String(error)}`,
recoverable: true,
metadata: { source: 'composite_relationship_detection' },
});
@@ -185,7 +185,7 @@ function sqlExecutor(input: DiscoverKtxRelationshipsInput): {
warnings: [
{
code: 'connector_capability_missing',
- message: 'KTX scan connector cannot run read-only SQL relationship validation',
+ message: 'ktx scan connector cannot run read-only SQL relationship validation',
recoverable: true,
metadata: { capability: 'readOnlySql' },
},
@@ -199,7 +199,7 @@ function sqlExecutor(input: DiscoverKtxRelationshipsInput): {
warnings: [
{
code: 'relationship_validation_failed',
- message: 'KTX scan connector advertises readOnlySql but does not expose executeReadOnly',
+ message: 'ktx scan connector advertises readOnlySql but does not expose executeReadOnly',
recoverable: true,
metadata: { capability: 'readOnlySql' },
},
diff --git a/packages/cli/src/context/scan/relationship-llm-proposal.ts b/packages/cli/src/context/scan/relationship-llm-proposal.ts
index 04b36abe..4a10d852 100644
--- a/packages/cli/src/context/scan/relationship-llm-proposal.ts
+++ b/packages/cli/src/context/scan/relationship-llm-proposal.ts
@@ -182,7 +182,7 @@ function mapValidProposals(
const toColumn = toTable ? findColumn(toTable, item.toColumn) : null;
if (!fromTable || !toTable || !fromColumn || !toColumn) {
warnings.push(
- invalidReferenceWarning('KTX relationship LLM proposal referenced a table or column that is not in the schema.', {
+ invalidReferenceWarning('ktx relationship LLM proposal referenced a table or column that is not in the schema.', {
proposal: item,
}),
);
@@ -218,7 +218,7 @@ function generationFailureWarning(error: unknown): KtxScanWarning {
const message = error instanceof Error ? error.message : String(error);
return {
code: 'relationship_llm_proposal_failed',
- message: `KTX relationship LLM proposal failed: ${message}`,
+ message: `ktx relationship LLM proposal failed: ${message}`,
recoverable: true,
};
}
@@ -233,7 +233,7 @@ export async function proposeKtxRelationshipCandidatesWithLlm(
const settings = mergeSettings(input.settings);
const evidence = buildEvidencePacket(input.schema, input.profile, settings);
const system = [
- 'You are helping KTX review possible SQL relationships before validation.',
+ 'You are helping ktx review possible SQL relationships before validation.',
'Use only the compact schema evidence. Propose likely primary keys and foreign keys for later SQL validation.',
'Return structured output only; never assume a join is accepted.',
].join('\n');
diff --git a/packages/cli/src/context/sl/semantic-layer.service.ts b/packages/cli/src/context/sl/semantic-layer.service.ts
index 797a8bf7..56a082c8 100644
--- a/packages/cli/src/context/sl/semantic-layer.service.ts
+++ b/packages/cli/src/context/sl/semantic-layer.service.ts
@@ -115,7 +115,7 @@ export class SemanticLayerService {
async listConnectionIds(): Promise {
try {
const result = await this.configService.listFiles(SL_DIR_PREFIX);
- // Directories under semantic-layer/ are connectionIds. Local KTX projects use
+ // Directories under semantic-layer/ are connectionIds. Local ktx projects use
// readable ids like "warehouse" and "dbt-main", not only UUIDs.
return result.files
.map((f) => f.replace(`${SL_DIR_PREFIX}/`, '').split('/')[0])
diff --git a/packages/cli/src/context/sl/tools/base-semantic-layer.tool.ts b/packages/cli/src/context/sl/tools/base-semantic-layer.tool.ts
index 2c14ec1a..84f54030 100644
--- a/packages/cli/src/context/sl/tools/base-semantic-layer.tool.ts
+++ b/packages/cli/src/context/sl/tools/base-semantic-layer.tool.ts
@@ -1,4 +1,4 @@
-import type { ZodType } from 'zod';
+import type { z } from 'zod';
import type { GitAuthorResolverPort } from '../../../context/tools/authors.js';
import type { ToolContext, ToolOutput } from '../../../context/tools/base-tool.js';
import { BaseTool } from '../../../context/tools/base-tool.js';
@@ -27,7 +27,9 @@ export interface BaseSemanticLayerToolDeps {
// ── Abstract base class ──
-export abstract class BaseSemanticLayerTool extends BaseTool {
+export abstract class BaseSemanticLayerTool<
+ TInput extends z.ZodObject = z.ZodObject,
+> extends BaseTool {
protected readonly semanticLayerService: SemanticLayerService;
protected readonly slSearchService: SlSearchService;
protected readonly authorResolver: GitAuthorResolverPort;
diff --git a/packages/cli/src/context/tools/base-tool.ts b/packages/cli/src/context/tools/base-tool.ts
index d002ac42..a2a14d93 100644
--- a/packages/cli/src/context/tools/base-tool.ts
+++ b/packages/cli/src/context/tools/base-tool.ts
@@ -1,5 +1,5 @@
-import { tool } from 'ai';
-import { z, type ZodType } from 'zod';
+import { tool, type Tool } from 'ai';
+import { z } from 'zod';
import { noopLogger, type KtxLogger } from '../../context/core/config.js';
import type { KtxRuntimeToolDescriptor } from '../llm/runtime-port.js';
import { normalizeKtxRuntimeToolOutput } from '../llm/runtime-tools.js';
@@ -73,7 +73,7 @@ interface MethodologyEntry {
/**
* SECURITY: All tools require authentication. userId must always be provided in ToolContext.
*/
-export abstract class BaseTool {
+export abstract class BaseTool = z.ZodObject> {
protected readonly logger: KtxLogger;
abstract readonly name: string;
@@ -86,37 +86,9 @@ export abstract class BaseTool {
abstract get inputSchema(): TInput;
- abstract call(input: z.infer, context: ToolContext): Promise;
+ abstract call(input: z.infer, context: ToolContext): Promise;
- getParametersSchema(): {
- type: 'object';
- properties: Record;
- required?: string[];
- } {
- const jsonSchema = z.toJSONSchema(this.inputSchema, {
- target: 'draft-7',
- });
-
- return jsonSchema as any;
- }
-
- toAnthropicFormat(): {
- name: string;
- description: string;
- input_schema: {
- type: 'object';
- properties: Record;
- required?: string[];
- };
- } {
- return {
- name: this.name,
- description: this.description,
- input_schema: this.getParametersSchema(),
- };
- }
-
- toAiSdkTool(context: ToolContext): any {
+ toAiSdkTool(context: ToolContext): Tool {
const toolName = this.name;
const logger = this.logger;
@@ -137,7 +109,7 @@ export abstract class BaseTool {
if (!callContext.userId) {
throw new Error('Authentication required: userId must be provided in ToolContext');
}
- const parsedInput = this.parseInput(params as Record);
+ const parsedInput = this.parseInput(params as Record);
const result = await this.call(parsedInput, callContext);
return result;
} catch (error) {
@@ -171,19 +143,19 @@ export abstract class BaseTool {
return {
name: toolName,
description: this.description,
- inputSchema: this.inputSchema as unknown as KtxRuntimeToolDescriptor['inputSchema'],
+ inputSchema: this.inputSchema,
execute: async (params) => {
const callContext = { ...context };
if (!callContext.userId) {
throw new Error('Authentication required: userId must be provided in ToolContext');
}
- const parsedInput = this.parseInput(params as Record);
+ const parsedInput = this.parseInput(params as Record);
return normalizeKtxRuntimeToolOutput(await this.call(parsedInput, callContext));
},
};
}
- parseInput(input: Record): z.infer {
+ parseInput(input: Record): z.infer {
return this.inputSchema.parse(input);
}
diff --git a/packages/cli/src/doctor.ts b/packages/cli/src/doctor.ts
index 7db51492..8b32b527 100644
--- a/packages/cli/src/doctor.ts
+++ b/packages/cli/src/doctor.ts
@@ -482,7 +482,7 @@ export function renderInvalidConfigMessage(
const abbreviated = abbreviateHome(projectDir) ?? projectDir;
const lines: string[] = [];
- lines.push(`${bold('KTX status')} ${dim('·')} ${abbreviated}`);
+ lines.push(`${bold('ktx status')} ${dim('·')} ${abbreviated}`);
lines.push('');
lines.push(` ${status('fail', '✗')} ${bold('Config')} ktx.yaml has ${issues.length} schema issue${issues.length === 1 ? '' : 's'}`);
for (const issue of issues) {
@@ -524,7 +524,7 @@ export function renderValidConfigMessage(
const abbreviated = abbreviateHome(projectDir) ?? projectDir;
const lines: string[] = [];
- lines.push(`${bold('KTX status')} ${dim('·')} ${abbreviated}`);
+ lines.push(`${bold('ktx status')} ${dim('·')} ${abbreviated}`);
lines.push('');
lines.push(` ${status('pass', '✓')} ${bold('Config')} ${dim('ktx.yaml schema valid')}`);
lines.push('');
@@ -559,9 +559,9 @@ export function renderMissingProjectMessage(
const envProjectDir = process.env.KTX_PROJECT_DIR;
const lines: string[] = [];
- lines.push(`${bold('KTX status')} ${dim('·')} ${abbreviated}`);
+ lines.push(`${bold('ktx status')} ${dim('·')} ${abbreviated}`);
lines.push('');
- lines.push(` No KTX project here yet. ${dim('(ktx.yaml not found)')}`);
+ lines.push(` No ktx project here yet. ${dim('(ktx.yaml not found)')}`);
lines.push('');
lines.push(` Run ${bold('ktx setup')} to create one.`);
if (envProjectDir !== undefined) {
@@ -643,7 +643,7 @@ export async function runKtxDoctor(
}
const setupChecks = await runSetupChecks();
- const report: DoctorReport = { title: 'KTX status', checks: setupChecks };
+ const report: DoctorReport = { title: 'ktx status', checks: setupChecks };
const renderOptions: RenderOptions = {
verbose: args.verbose ?? false,
useColor: shouldUseColorOutput(io.stdout),
diff --git a/packages/cli/src/llm/embedding-health.ts b/packages/cli/src/llm/embedding-health.ts
index 47d3f14f..b6b090df 100644
--- a/packages/cli/src/llm/embedding-health.ts
+++ b/packages/cli/src/llm/embedding-health.ts
@@ -38,7 +38,7 @@ export async function runKtxEmbeddingHealthCheck(
try {
const provider = createKtxEmbeddingProvider(config, options.deps);
const embedding = await withTimeout(
- provider.embed(options.text ?? 'KTX embedding health check'),
+ provider.embed(options.text ?? 'ktx embedding health check'),
options.timeoutMs ?? 15_000,
);
if (embedding.length !== config.dimensions) {
diff --git a/packages/cli/src/llm/embedding-provider.ts b/packages/cli/src/llm/embedding-provider.ts
index 5290c044..6bb7e911 100644
--- a/packages/cli/src/llm/embedding-provider.ts
+++ b/packages/cli/src/llm/embedding-provider.ts
@@ -77,7 +77,7 @@ class OpenAIEmbeddingProvider implements KtxEmbeddingProvider {
this.dimensions = config.dimensions;
this.maxBatchSize = config.batchSize ?? DEFAULT_BATCH_SIZE;
if (!config.openai?.apiKey) {
- throw new Error('openai.apiKey is required when KTX embedding backend is openai');
+ throw new Error('openai.apiKey is required when ktx embedding backend is openai');
}
this.client = deps.createOpenAIClient
? deps.createOpenAIClient({ apiKey: config.openai.apiKey, baseURL: config.openai.baseURL })
@@ -122,7 +122,7 @@ class SentenceTransformersEmbeddingProvider implements KtxEmbeddingProvider {
constructor(config: KtxEmbeddingConfig, deps: KtxEmbeddingProviderDeps) {
if (!config.sentenceTransformers?.baseURL) {
- throw new Error('sentenceTransformers.baseURL is required when KTX embedding backend is sentence-transformers');
+ throw new Error('sentenceTransformers.baseURL is required when ktx embedding backend is sentence-transformers');
}
this.dimensions = config.dimensions;
this.maxBatchSize = config.batchSize ?? DEFAULT_BATCH_SIZE;
@@ -207,6 +207,6 @@ export function createKtxEmbeddingProvider(
case 'sentence-transformers':
return new SentenceTransformersEmbeddingProvider(config, deps);
default:
- throw new Error(`Unsupported KTX embedding backend: ${String((config as { backend?: string }).backend)}`);
+ throw new Error(`Unsupported ktx embedding backend: ${String((config as { backend?: string }).backend)}`);
}
}
diff --git a/packages/cli/src/llm/model-provider.ts b/packages/cli/src/llm/model-provider.ts
index 207faa93..8322c35c 100644
--- a/packages/cli/src/llm/model-provider.ts
+++ b/packages/cli/src/llm/model-provider.ts
@@ -166,7 +166,7 @@ class DefaultKtxLlmProvider implements KtxLlmProvider {
if (config.backend === 'vertex') {
if (!config.vertex?.location) {
- throw new Error('vertex.location is required when KTX LLM backend is vertex');
+ throw new Error('vertex.location is required when ktx LLM backend is vertex');
}
const vertex = (deps.createVertexAnthropic ?? createVertexAnthropic)({
...(config.vertex.project ? { project: config.vertex.project } : {}),
diff --git a/packages/cli/src/local-scan-connectors.ts b/packages/cli/src/local-scan-connectors.ts
index 4d98bc0c..d9941921 100644
--- a/packages/cli/src/local-scan-connectors.ts
+++ b/packages/cli/src/local-scan-connectors.ts
@@ -25,7 +25,7 @@ export async function createKtxCliScanConnector(
const registration = getDriverRegistration(driver);
if (!registration) {
throw new Error(
- `Connection "${connectionId}" uses driver "${driver}", which has no native standalone KTX scan connector. Supported drivers: ${SUPPORTED_DRIVERS}.`,
+ `Connection "${connectionId}" uses driver "${driver}", which has no native standalone ktx scan connector. Supported drivers: ${SUPPORTED_DRIVERS}.`,
);
}
diff --git a/packages/cli/src/managed-local-embeddings.ts b/packages/cli/src/managed-local-embeddings.ts
index 768648c1..2ce5274d 100644
--- a/packages/cli/src/managed-local-embeddings.ts
+++ b/packages/cli/src/managed-local-embeddings.ts
@@ -74,7 +74,7 @@ export async function ensureManagedLocalEmbeddingsDaemon(
});
const verb = daemon.status === 'started' ? 'Started' : 'Using';
- writePrefixedLines((chunk) => options.io.stderr.write(chunk), `${verb} KTX daemon: ${daemon.baseUrl}`);
+ writePrefixedLines((chunk) => options.io.stderr.write(chunk), `${verb} ktx daemon: ${daemon.baseUrl}`);
return {
baseUrl: daemon.baseUrl,
diff --git a/packages/cli/src/managed-mcp-daemon.ts b/packages/cli/src/managed-mcp-daemon.ts
index 881574de..7c685e77 100644
--- a/packages/cli/src/managed-mcp-daemon.ts
+++ b/packages/cli/src/managed-mcp-daemon.ts
@@ -139,7 +139,7 @@ export async function startKtxMcpDaemon(options: {
};
}
throw new Error(
- `KTX MCP daemon is already running at http://${existing.host}:${existing.port}/mcp ` +
+ `ktx MCP daemon is already running at http://${existing.host}:${existing.port}/mcp ` +
'with a different configuration. Run `ktx mcp stop` first, then start again.',
);
}
@@ -175,7 +175,7 @@ export async function startKtxMcpDaemon(options: {
}),
});
if (!child.pid) {
- throw new Error('Failed to start KTX MCP daemon: child process pid was not available.');
+ throw new Error('Failed to start ktx MCP daemon: child process pid was not available.');
}
child.unref();
const state: KtxMcpDaemonState = {
@@ -219,7 +219,7 @@ export async function readKtxMcpDaemonStatus(options: {
}
return {
kind: 'running',
- detail: `KTX MCP daemon running at http://${state.host}:${state.port}/mcp`,
+ detail: `ktx MCP daemon running at http://${state.host}:${state.port}/mcp`,
state,
url: `http://${state.host}:${state.port}/mcp`,
};
diff --git a/packages/cli/src/managed-python-command.ts b/packages/cli/src/managed-python-command.ts
index 37cda4f3..cdc4e510 100644
--- a/packages/cli/src/managed-python-command.ts
+++ b/packages/cli/src/managed-python-command.ts
@@ -62,11 +62,11 @@ export function managedRuntimeInstallCommand(feature: KtxRuntimeFeature): string
function installPrompt(feature: KtxRuntimeFeature): string {
const label = feature === 'local-embeddings' ? 'local embeddings Python runtime' : 'core Python runtime';
- return `KTX needs to install the ${label}. This downloads Python dependencies with uv. Continue?`;
+ return `ktx needs to install the ${label}. This downloads Python dependencies with uv. Continue?`;
}
function runtimeRequiredMessage(feature: KtxRuntimeFeature): string {
- return `KTX Python runtime is required for this command. Run: ${managedRuntimeInstallCommand(feature)}`;
+ return `ktx Python runtime is required for this command. Run: ${managedRuntimeInstallCommand(feature)}`;
}
function hasFeature(manifest: InstalledKtxRuntimeManifest, feature: KtxRuntimeFeature): boolean {
@@ -101,22 +101,22 @@ export async function ensureManagedPythonCommandRuntime(
const confirmInstall = options.confirmInstall ?? defaultConfirmInstall;
const confirmed = await confirmInstall(installPrompt(feature), options.io);
if (!confirmed) {
- throw new Error(`KTX Python runtime installation was cancelled. Run: ${managedRuntimeInstallCommand(feature)}`);
+ throw new Error(`ktx Python runtime installation was cancelled. Run: ${managedRuntimeInstallCommand(feature)}`);
}
}
const progress = (options.spinner ?? (() => createStaticCliSpinner(options.io)))();
- progress.start(`Installing KTX Python runtime (${feature}) with uv...`);
+ progress.start(`Installing ktx Python runtime (${feature}) with uv...`);
try {
const installed = await installRuntime({
cliVersion: options.cliVersion,
features: [feature],
force: false,
});
- progress.stop(`KTX Python runtime ready: ${installed.layout.versionDir}`);
+ progress.stop(`ktx Python runtime ready: ${installed.layout.versionDir}`);
return { layout: installed.layout, manifest: installed.manifest };
} catch (error) {
- progress.error(`KTX Python runtime install failed: ${error instanceof Error ? error.message : String(error)}`);
+ progress.error(`ktx Python runtime install failed: ${error instanceof Error ? error.message : String(error)}`);
throw error;
}
}
diff --git a/packages/cli/src/managed-python-daemon.ts b/packages/cli/src/managed-python-daemon.ts
index 4e56ca47..0ccbf453 100644
--- a/packages/cli/src/managed-python-daemon.ts
+++ b/packages/cli/src/managed-python-daemon.ts
@@ -21,7 +21,7 @@ export class ManagedPythonDaemonStartError extends Error {
readonly detail: string;
readonly stderrLog: string;
constructor(detail: string, stderrLog: string) {
- super(`KTX daemon failed to start: ${detail}. stderr: ${stderrLog}`);
+ super(`ktx daemon failed to start: ${detail}. stderr: ${stderrLog}`);
this.name = 'ManagedPythonDaemonStartError';
this.detail = detail;
this.stderrLog = stderrLog;
@@ -720,7 +720,7 @@ export async function startManagedPythonDaemon(
);
child.unref();
if (!child.pid) {
- throw new Error(`KTX daemon did not report a pid. stderr: ${layout.daemonStderrPath}`);
+ throw new Error(`ktx daemon did not report a pid. stderr: ${layout.daemonStderrPath}`);
}
const state: ManagedPythonDaemonState = {
schemaVersion: 1,
diff --git a/packages/cli/src/managed-python-http.ts b/packages/cli/src/managed-python-http.ts
index 728aa3ca..392f375c 100644
--- a/packages/cli/src/managed-python-http.ts
+++ b/packages/cli/src/managed-python-http.ts
@@ -65,7 +65,7 @@ function normalizedBaseUrl(baseUrl: string): string {
function parseJsonObject(raw: string, path: string): Record {
const parsed = JSON.parse(raw) as unknown;
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
- throw new Error(`KTX daemon HTTP ${path} returned non-object JSON`);
+ throw new Error(`ktx daemon HTTP ${path} returned non-object JSON`);
}
return parsed as Record;
}
@@ -96,7 +96,7 @@ async function postManagedDaemonJson(
const text = Buffer.concat(chunks).toString('utf8');
const statusCode = response.statusCode ?? 0;
if (statusCode < 200 || statusCode >= 300) {
- reject(new Error(`KTX daemon HTTP ${path} failed with ${statusCode}: ${text}`));
+ reject(new Error(`ktx daemon HTTP ${path} failed with ${statusCode}: ${text}`));
return;
}
try {
@@ -138,7 +138,7 @@ export function createManagedPythonDaemonBaseUrlResolver(
force: false,
});
const verb = daemon.status === 'started' ? 'Started' : 'Using existing';
- writePrefixedLines((chunk) => options.io.stderr.write(chunk), `${verb} KTX daemon: ${daemon.baseUrl}`);
+ writePrefixedLines((chunk) => options.io.stderr.write(chunk), `${verb} ktx daemon: ${daemon.baseUrl}`);
cachedBaseUrl = daemon.baseUrl;
return cachedBaseUrl;
};
diff --git a/packages/cli/src/managed-python-runtime.ts b/packages/cli/src/managed-python-runtime.ts
index 5aef2b32..b65f7fb3 100644
--- a/packages/cli/src/managed-python-runtime.ts
+++ b/packages/cli/src/managed-python-runtime.ts
@@ -124,7 +124,7 @@ export interface ManagedPythonRuntimeDoctorCheck {
/** @internal */
export const MISSING_UV_RUNTIME_INSTALL_MESSAGE =
- 'uv is required to install the KTX Python runtime. KTX does not download uv automatically. Install uv, make sure it is on PATH, and retry: ktx admin runtime install --yes';
+ 'uv is required to install the ktx Python runtime. ktx does not download uv automatically. Install uv, make sure it is on PATH, and retry: ktx admin runtime install --yes';
function defaultAssetDir(): string {
return fileURLToPath(new URL('../assets/python/', import.meta.url));
@@ -250,7 +250,7 @@ export async function verifyRuntimeAsset(input: { assetDir: string }): Promise(DEFAULT_ALLOWED_HOSTS);
if (!isLoopbackHost(input.host)) {
@@ -94,16 +94,16 @@ export function isMcpRequestAuthorized(
): McpAuthorizationResult {
const host = headerValue(request.headers, 'host');
if (!host || !config.allowedHosts.includes(normalizeHostHeader(host))) {
- return { ok: false, status: 403, message: 'Host header is not allowed for KTX MCP.' };
+ return { ok: false, status: 403, message: 'Host header is not allowed for ktx MCP.' };
}
const origin = headerValue(request.headers, 'origin');
if (origin && !config.allowedOrigins.includes(origin)) {
- return { ok: false, status: 403, message: 'Origin header is not allowed for KTX MCP.' };
+ return { ok: false, status: 403, message: 'Origin header is not allowed for ktx MCP.' };
}
if (request.path === '/mcp' && config.token) {
const auth = headerValue(request.headers, 'authorization');
if (auth !== `Bearer ${config.token}`) {
- return { ok: false, status: 401, message: 'Missing or invalid KTX MCP bearer token.' };
+ return { ok: false, status: 401, message: 'Missing or invalid ktx MCP bearer token.' };
}
}
return { ok: true };
diff --git a/packages/cli/src/mcp-server-factory.ts b/packages/cli/src/mcp-server-factory.ts
index 1ff44270..fbecccd8 100644
--- a/packages/cli/src/mcp-server-factory.ts
+++ b/packages/cli/src/mcp-server-factory.ts
@@ -65,7 +65,7 @@ export async function createKtxMcpServerFactory(input: {
embeddingProvider,
});
} catch (error) {
- io.stderr.write(`KTX MCP memory_ingest disabled: ${error instanceof Error ? error.message : String(error)}\n`);
+ io.stderr.write(`ktx MCP memory_ingest disabled: ${error instanceof Error ? error.message : String(error)}\n`);
}
return () =>
diff --git a/packages/cli/src/mcp-stdio-server.ts b/packages/cli/src/mcp-stdio-server.ts
index 93b5a155..840e2db9 100644
--- a/packages/cli/src/mcp-stdio-server.ts
+++ b/packages/cli/src/mcp-stdio-server.ts
@@ -52,7 +52,7 @@ export async function runKtxMcpStdioServer(options: RunKtxMcpStdioServerOptions)
};
transport.onclose = () => settle(resolve);
transport.onerror = (error) => {
- options.io?.stderr.write(`KTX MCP stdio transport error: ${error.message}\n`);
+ options.io?.stderr.write(`ktx MCP stdio transport error: ${error.message}\n`);
settle(() => reject(error));
};
stdin.once('end', closeTransport);
diff --git a/packages/cli/src/memory-flow-hud.tsx b/packages/cli/src/memory-flow-hud.tsx
index 5a09bf08..f00e8902 100644
--- a/packages/cli/src/memory-flow-hud.tsx
+++ b/packages/cli/src/memory-flow-hud.tsx
@@ -363,7 +363,7 @@ export function ActivityFeed(props: {
)}
- {/* Results — what KTX has created */}
+ {/* Results — what ktx has created */}
{insights.length > 0 && (
Created so far:
@@ -395,7 +395,7 @@ export function ActivityFeed(props: {
{spinner(props.frame)} Saving to context layer...
)}
{savedEvent && (
- ✓ Saved — your agents can now use the KTX context layer
+ ✓ Saved — your agents can now use the ktx context layer
)}
{/* Phase 7: Completion */}
@@ -430,12 +430,12 @@ function CompletionSummary(props: {
<>
{'─'.repeat(60)}
- ★ KTX finished ingesting your data
+ ★ ktx finished ingesting your data
{(sl > 0 || wiki > 0) && (
<>
- KTX created:
+ ktx created:
{sl > 0 && (
{' '}📊 {sl} query definition{sl === 1 ? '' : 's'} — so agents can write accurate SQL for your data
diff --git a/packages/cli/src/next-steps.ts b/packages/cli/src/next-steps.ts
index b6726e3c..971a483d 100644
--- a/packages/cli/src/next-steps.ts
+++ b/packages/cli/src/next-steps.ts
@@ -45,7 +45,7 @@ function commandLines(commands: ReadonlyArray<{ command: string; description: st
export function formatNextStepLines(indent = ' '): string[] {
return [
- `${indent}KTX context is ready for agents. Open your coding agent from the KTX project directory and ask a data question.`,
+ `${indent}ktx context is ready for agents. Open your coding agent from the ktx project directory and ask a data question.`,
`${indent}Verify with:`,
...commandLines(KTX_NEXT_STEP_DIRECT_COMMANDS, indent),
];
@@ -77,7 +77,7 @@ export function formatSetupNextStepLines(state: KtxSetupNextStepState, indent =
if (!state.agentIntegrationReady) {
return [
- `${indent}KTX context is built. Install agent rules when you want your coding agent to use it.`,
+ `${indent}ktx context is built. Install agent rules when you want your coding agent to use it.`,
`${indent}$ ${'ktx setup --agents'.padEnd(KTX_NEXT_STEP_COMMAND_WIDTH)} Install CLI-based agent rules`,
`${indent}$ ${'ktx status'.padEnd(KTX_NEXT_STEP_COMMAND_WIDTH)} Check setup and context readiness`,
];
diff --git a/packages/cli/src/prompts/memory_agent_bundle_ingest_work_unit.md b/packages/cli/src/prompts/memory_agent_bundle_ingest_work_unit.md
index a0952293..a63d9b62 100644
--- a/packages/cli/src/prompts/memory_agent_bundle_ingest_work_unit.md
+++ b/packages/cli/src/prompts/memory_agent_bundle_ingest_work_unit.md
@@ -2,7 +2,7 @@
You are processing ONE WorkUnit of a multi-file ingest bundle. The WorkUnit
gives you a slice of raw source files (LookML views, dbt/MetricFlow YAMLs,
Metabase card JSONs, Notion pages, or similar) and you must translate that
-slice into KTX semantic-layer sources and/or knowledge wiki pages, in one pass.
+slice into ktx semantic-layer sources and/or knowledge wiki pages, in one pass.
You run in an isolated WorkUnit worktree. Deterministic projection output,
existing project memory, and listed dependency paths are visible; sibling
WorkUnit edits from this same job are not visible until the runner integrates
@@ -10,7 +10,7 @@ accepted patches.
-Assertive. The bundle was explicitly submitted for ingest. Default to capturing everything the raw files declare that maps cleanly to KTX: one SL source per table/view, one wiki page per non-obvious business rule or alias. Do not abandon a WorkUnit because "some content overlaps with another WU"; use `ingest_triage` to reconcile, do not skip.
+Assertive. The bundle was explicitly submitted for ingest. Default to capturing everything the raw files declare that maps cleanly to ktx: one SL source per table/view, one wiki page per non-obvious business rule or alias. Do not abandon a WorkUnit because "some content overlaps with another WU"; use `ingest_triage` to reconcile, do not skip.
diff --git a/packages/cli/src/prompts/memory_agent_external_ingest.md b/packages/cli/src/prompts/memory_agent_external_ingest.md
index 6f81ae0a..5c17bd39 100644
--- a/packages/cli/src/prompts/memory_agent_external_ingest.md
+++ b/packages/cli/src/prompts/memory_agent_external_ingest.md
@@ -1,5 +1,5 @@
-You are ingesting an external technical artifact (a LookML view, dbt model, schema description, business glossary, or other reference document) into KTX organizational memory. The user has explicitly submitted this content for bulk ingest. Assume it is intentional and worth capturing.
+You are ingesting an external technical artifact (a LookML view, dbt model, schema description, business glossary, or other reference document) into ktx organizational memory. The user has explicitly submitted this content for bulk ingest. Assume it is intentional and worth capturing.
@@ -18,7 +18,7 @@ A single artifact typically produces multiple actions: one SL source per table/v
-All wiki writes go to the GLOBAL scope - they will be visible to every user of this KTX project. Phrase wiki pages as objective business knowledge, not personal preference. The `wiki_write` tool handles scope selection automatically for external ingest.
+All wiki writes go to the GLOBAL scope - they will be visible to every user of this ktx project. Phrase wiki pages as objective business knowledge, not personal preference. The `wiki_write` tool handles scope selection automatically for external ingest.
diff --git a/packages/cli/src/public-ingest-copy.ts b/packages/cli/src/public-ingest-copy.ts
index 86423f74..0fd44452 100644
--- a/packages/cli/src/public-ingest-copy.ts
+++ b/packages/cli/src/public-ingest-copy.ts
@@ -8,7 +8,7 @@ const DATABASE_INGEST_REPLACEMENTS: Array<[RegExp, string]> = [
[/\bWriting schema artifacts\b/gi, 'Writing schema context'],
[/\bEnriching schema metadata\b/gi, 'Building enriched schema context'],
[
- /\bKTX scan enrichment failed after structural scan completed\b/gi,
+ /\bktx scan enrichment failed after structural scan completed\b/gi,
'Database enrichment failed after schema context completed',
],
[/\bstructural scan\b/gi, 'schema context'],
diff --git a/packages/cli/src/public-ingest.ts b/packages/cli/src/public-ingest.ts
index 07f805b8..997cc0cc 100644
--- a/packages/cli/src/public-ingest.ts
+++ b/packages/cli/src/public-ingest.ts
@@ -875,8 +875,8 @@ function createPlainPublicIngestProgress(io: KtxCliIo, options: PlainPublicInges
const INTERNAL_STATUS_LINE_RE =
/^(Report|Run|Job|Status|Adapter|Connection|Sync|Diff|Tasks|Work units|Failed tasks|Saved memory|Provenance rows):\s*/;
const ACTIONABLE_FAILURE_LINE_RE =
- /^(Missing bundled Python runtime manifest|KTX Python runtime is required|KTX daemon HTTP|Error:|Failed\b|Could not\b|Cannot\b)/;
-const RUNTIME_BACKED_RETRY_LINE_RE = /^Then retry the runtime-backed KTX command\.?$/;
+ /^(Missing bundled Python runtime manifest|ktx Python runtime is required|ktx daemon HTTP|Error:|Failed\b|Could not\b|Cannot\b)/;
+const RUNTIME_BACKED_RETRY_LINE_RE = /^Then retry the runtime-backed ktx command\.?$/;
function trimErrorPrefix(line: string): string {
return line.replace(/^Error:\s*/, '');
@@ -887,7 +887,7 @@ function capturedFailureMessage(output: string): string | undefined {
.split(/\r?\n/)
.map((line) => line.trim())
.filter((line) => line.length > 0)
- .filter((line) => !line.startsWith('KTX scan completed'))
+ .filter((line) => !line.startsWith('ktx scan completed'))
.filter((line) => !INTERNAL_STATUS_LINE_RE.test(line))
.map(publicIngestOutputLine);
diff --git a/packages/cli/src/release-version.ts b/packages/cli/src/release-version.ts
index 145349f0..a734a009 100644
--- a/packages/cli/src/release-version.ts
+++ b/packages/cli/src/release-version.ts
@@ -3,7 +3,7 @@ const semverPattern =
export function assertCliVersion(value: unknown, source: string): string {
if (typeof value !== 'string' || !semverPattern.test(value)) {
- throw new Error(`Invalid KTX CLI version in ${source}`);
+ throw new Error(`Invalid ktx CLI version in ${source}`);
}
return value;
}
diff --git a/packages/cli/src/runtime-requirements.ts b/packages/cli/src/runtime-requirements.ts
index 0253db8c..a3588385 100644
--- a/packages/cli/src/runtime-requirements.ts
+++ b/packages/cli/src/runtime-requirements.ts
@@ -90,7 +90,7 @@ export function resolveProjectRuntimeRequirements(
requirements.push({
feature: 'core',
reason: 'database-introspection',
- detail: 'Database introspection fallback uses the KTX daemon.',
+ detail: 'Database introspection fallback uses the ktx daemon.',
});
}
diff --git a/packages/cli/src/runtime.ts b/packages/cli/src/runtime.ts
index ad978bd5..19f9f89a 100644
--- a/packages/cli/src/runtime.ts
+++ b/packages/cli/src/runtime.ts
@@ -45,7 +45,7 @@ function writeJson(io: KtxCliIo, value: unknown): void {
function writeInstallResult(io: KtxCliIo, result: ManagedPythonRuntimeInstallResult): void {
const verb = result.status === 'ready' ? 'Using existing' : 'Installed';
- io.stdout.write(`${verb} KTX Python runtime\n`);
+ io.stdout.write(`${verb} ktx Python runtime\n`);
io.stdout.write(`version: ${result.manifest.cliVersion}\n`);
io.stdout.write(`features: ${result.manifest.features.join(', ')}\n`);
io.stdout.write(`python: ${result.manifest.python.executable}\n`);
@@ -56,7 +56,7 @@ function writeInstallResult(io: KtxCliIo, result: ManagedPythonRuntimeInstallRes
function writeDaemonStart(io: KtxCliIo, result: ManagedPythonDaemonStartResult): void {
const verb = result.status === 'reused' ? 'Using existing' : 'Started';
- io.stdout.write(`${verb} KTX daemon\n`);
+ io.stdout.write(`${verb} ktx daemon\n`);
io.stdout.write(`url: ${result.baseUrl}\n`);
io.stdout.write(`pid: ${result.state.pid}\n`);
io.stdout.write(`version: ${result.state.version}\n`);
@@ -68,10 +68,10 @@ function writeDaemonStart(io: KtxCliIo, result: ManagedPythonDaemonStartResult):
function writeDaemonStop(io: KtxCliIo, result: ManagedPythonDaemonStopResult): void {
if (result.status === 'already-stopped') {
- io.stdout.write('KTX daemon already stopped\n');
+ io.stdout.write('ktx daemon already stopped\n');
return;
}
- io.stdout.write('Stopped KTX daemon\n');
+ io.stdout.write('Stopped ktx daemon\n');
io.stdout.write(`pid: ${result.state?.pid ?? 'unknown'}\n`);
io.stdout.write(`state: ${result.layout.daemonStatePath}\n`);
}
@@ -94,11 +94,11 @@ function writeDaemonStopAll(io: KtxCliIo, result: ManagedPythonDaemonStopAllResu
result.failed.length === 0 &&
result.scanErrors.length === 0
) {
- io.stdout.write('No KTX daemons found\n');
+ io.stdout.write('No ktx daemons found\n');
return 0;
}
if (failed === 0) {
- io.stdout.write(`Stopped ${result.stopped.length} KTX daemons\n`);
+ io.stdout.write(`Stopped ${result.stopped.length} ktx daemons\n`);
if (result.stale.length > 0) {
io.stdout.write(`Cleaned ${result.stale.length} stale daemon states\n`);
}
@@ -111,7 +111,7 @@ function writeDaemonStopAll(io: KtxCliIo, result: ManagedPythonDaemonStopAllResu
return 0;
}
io.stderr.write(
- `Stopped ${result.stopped.length} KTX daemons; failed ${result.failed.length}${
+ `Stopped ${result.stopped.length} ktx daemons; failed ${result.failed.length}${
result.stale.length > 0 ? `; cleaned stale ${result.stale.length}` : ''
}\n`,
);
@@ -129,7 +129,7 @@ function writeDaemonStopAll(io: KtxCliIo, result: ManagedPythonDaemonStopAllResu
}
function writeStatus(io: KtxCliIo, status: ManagedPythonRuntimeStatus): void {
- io.stdout.write('KTX Python runtime\n');
+ io.stdout.write('ktx Python runtime\n');
io.stdout.write(`status: ${status.kind}\n`);
io.stdout.write(`detail: ${status.detail}\n`);
io.stdout.write(`runtime root: ${status.layout.runtimeRoot}\n`);
@@ -142,7 +142,7 @@ function writeStatus(io: KtxCliIo, status: ManagedPythonRuntimeStatus): void {
}
function writeRuntimeChecks(io: KtxCliIo, checks: ManagedPythonRuntimeDoctorCheck[]): void {
- io.stdout.write('KTX Python runtime checks\n');
+ io.stdout.write('ktx Python runtime checks\n');
for (const check of checks) {
io.stdout.write(`${check.status.toUpperCase()} ${check.label}: ${check.detail}\n`);
if (check.fix) {
diff --git a/packages/cli/src/scan.ts b/packages/cli/src/scan.ts
index 5961e3f1..055f2e69 100644
--- a/packages/cli/src/scan.ts
+++ b/packages/cli/src/scan.ts
@@ -259,7 +259,7 @@ function writeHumanReportBody(report: KtxScanReport, io: KtxCliIo): void {
function writeRunSummary(report: KtxScanReport, projectDir: string, io: KtxCliIo): void {
const styled = shouldUseStyledOutput(io);
- io.stdout.write(`${styled ? green('✓') : ''}${styled ? ' ' : ''}KTX scan completed\n`);
+ io.stdout.write(`${styled ? green('✓') : ''}${styled ? ' ' : ''}ktx scan completed\n`);
io.stdout.write('Status: done\n');
writeHumanReportBody(report, io);
const projectDirArg = quoteCliArg(projectDir);
diff --git a/packages/cli/src/setup-agents.ts b/packages/cli/src/setup-agents.ts
index 3c7e5bad..8804cacf 100644
--- a/packages/cli/src/setup-agents.ts
+++ b/packages/cli/src/setup-agents.ts
@@ -234,7 +234,7 @@ function codexSnippet(endpoint: KtxMcpEndpointInfo): string {
if (endpoint.tokenAuth) {
return [
'Codex MCP config does not currently document HTTP headers.',
- 'Run KTX on loopback without token auth for Codex, or configure headers after Codex documents support.',
+ 'Run ktx on loopback without token auth for Codex, or configure headers after Codex documents support.',
].join('\n');
}
return [`[mcp_servers.ktx]`, `url = "${endpoint.url}"`].join('\n');
@@ -538,16 +538,16 @@ function cliInstructionContent(input: { projectDir: string; launcher: KtxCliLaun
return [
'---',
'name: ktx',
- 'description: Use local KTX semantic context and wiki knowledge for this project.',
+ 'description: Use local ktx semantic context and wiki knowledge for this project.',
'---',
'',
- '# KTX Local Context',
+ '# ktx Local Context',
'',
- 'This is an admin/developer CLI helper. End-user data agents should use the KTX MCP tools when available.',
+ 'This is an admin/developer CLI helper. End-user data agents should use the ktx MCP tools when available.',
'',
`Use this project with \`--project-dir ${input.projectDir}\`.`,
- 'Commands are pinned to the local KTX CLI path that created this file, so agents do not need `ktx` in PATH.',
- 'If the CLI path no longer exists after moving this checkout or reinstalling KTX, rerun `ktx setup --agents`.',
+ 'Commands are pinned to the local ktx CLI path that created this file, so agents do not need `ktx` in PATH.',
+ 'If the CLI path no longer exists after moving this checkout or reinstalling ktx, rerun `ktx setup --agents`.',
'',
'Agents must not print secrets, credential references, environment variable values, or file contents from ' +
'`.ktx/secrets`.',
@@ -676,7 +676,7 @@ function mergeManifest(
export async function removeKtxAgentInstall(projectDir: string, io: KtxCliIo): Promise {
const manifest = await readKtxAgentInstallManifest(projectDir);
if (!manifest) {
- io.stdout.write('No KTX agent installation manifest found.\n');
+ io.stdout.write('No ktx agent installation manifest found.\n');
return 0;
}
for (const entry of manifest.entries) {
@@ -684,7 +684,7 @@ export async function removeKtxAgentInstall(projectDir: string, io: KtxCliIo): P
if (entry.kind === 'json-key') await removeJsonKey(entry.path, entry.jsonPath).catch(() => undefined);
}
await rm(agentInstallManifestPath(projectDir), { force: true });
- io.stdout.write('Removed KTX agent integration files from manifest.\n');
+ io.stdout.write('Removed ktx agent integration files from manifest.\n');
return 0;
}
@@ -990,7 +990,7 @@ function formatAgentNextActions(input: {
if (claudeCodeInstall) {
lines.push(`${step}. Open Claude Code`);
if (claudeCodeInstall.scope === 'project') {
- lines.push(' Open Claude Code from the KTX project directory:');
+ lines.push(' Open Claude Code from the ktx project directory:');
lines.push('');
lines.push(' RUN:');
lines.push(` cd ${shellScriptQuote(projectDir)}`);
@@ -1007,7 +1007,7 @@ function formatAgentNextActions(input: {
if (cursorInstall) {
lines.push(`${step}. Open Cursor`);
if (cursorInstall.scope === 'project') {
- lines.push(' Open Cursor from the KTX project directory:');
+ lines.push(' Open Cursor from the ktx project directory:');
lines.push('');
lines.push(' OPEN:');
lines.push(` ${projectDir}`);
@@ -1020,7 +1020,7 @@ function formatAgentNextActions(input: {
if (input.installs.some((install) => install.target === 'claude-desktop')) {
lines.push(`${step}. Restart Claude Desktop`);
- lines.push(' Claude Desktop loads KTX MCP after restart.');
+ lines.push(' Claude Desktop loads ktx MCP after restart.');
pushBlankLine(lines);
step += 1;
@@ -1032,7 +1032,7 @@ function formatAgentNextActions(input: {
for (const path of skillBundlePaths) {
lines.push(` ${path}`);
}
- lines.push(' Toggle the uploaded KTX skills on.');
+ lines.push(' Toggle the uploaded ktx skills on.');
pushBlankLine(lines);
step += 1;
}
@@ -1104,16 +1104,16 @@ export async function runKtxSetupAgentsStep(
args.inputMode === 'disabled'
? args.mode
: ((await prompts.select({
- message: 'What should agents be allowed to do with this KTX project?',
+ message: 'What should agents be allowed to do with this ktx project?',
options: [
{
value: 'mcp',
- label: 'Ask data questions with KTX MCP',
+ label: 'Ask data questions with ktx MCP',
hint: 'Installs the MCP connection and analytics workflow skill. Best for normal use.',
},
{
value: 'mcp-cli',
- label: 'Ask data questions + manage KTX with CLI commands',
+ label: 'Ask data questions + manage ktx with CLI commands',
hint: 'Adds an admin CLI skill so agents can run ktx status, sl, wiki, and setup commands.',
},
{
@@ -1135,7 +1135,7 @@ export async function runKtxSetupAgentsStep(
: args.inputMode === 'disabled'
? []
: ((await prompts.multiselect({
- message: 'Which agent targets should KTX install?',
+ message: 'Which agent targets should ktx install?',
options: [
{ value: 'claude-code', label: 'Claude Code' },
{ value: 'claude-desktop', label: 'Claude Desktop' },
@@ -1163,17 +1163,17 @@ export async function runKtxSetupAgentsStep(
scopeTargets.length > 0 &&
scopeTargets.every(targetSupportsGlobalScope)
? ((await prompts.select({
- message: `Where should KTX install supported agent config?\n\nKTX project: ${resolve(args.projectDir)}`,
+ message: `Where should ktx install supported agent config?\n\nktx project: ${resolve(args.projectDir)}`,
options: [
{
value: 'project',
- label: 'Project scope (KTX project directory)',
- hint: 'Only agents opened from this KTX project path load the project-scoped config.',
+ label: 'Project scope (ktx project directory)',
+ hint: 'Only agents opened from this ktx project path load the project-scoped config.',
},
{
value: 'global',
label: 'Global scope (user config)',
- hint: 'Agents can load this KTX project from any working directory.',
+ hint: 'Agents can load this ktx project from any working directory.',
},
],
})) as KtxAgentScope | 'back')
diff --git a/packages/cli/src/setup-context.ts b/packages/cli/src/setup-context.ts
index be458d2a..f7fc7a25 100644
--- a/packages/cli/src/setup-context.ts
+++ b/packages/cli/src/setup-context.ts
@@ -345,7 +345,7 @@ async function prepareBuildTargets(args: KtxSetupContextStepArgs, io: KtxCliIo):
if (args.allowEmpty === true) {
return { kind: 'result', result: { status: 'skipped', projectDir: args.projectDir } };
}
- io.stderr.write('No databases or context sources are configured for a KTX context build.\n');
+ io.stderr.write('No databases or context sources are configured for a ktx context build.\n');
return { kind: 'result', result: { status: 'failed', projectDir: args.projectDir } };
}
const preflightPlan = buildPublicIngestPlan(project, { projectDir: project.projectDir, all: true });
@@ -367,12 +367,12 @@ function writeConnectionGateFailureLines(
projectDir: string,
failures: ConnectionGateFailure[],
): void {
- io.stderr.write('KTX cannot build context: a required connection failed its live test.\n\n');
+ io.stderr.write('ktx cannot build context: a required connection failed its live test.\n\n');
io.stderr.write('Failed connections:\n');
for (const failure of failures) {
io.stderr.write(` ${failure.connectionId} (${failure.driver})\n`);
}
- io.stderr.write('\nEach connection must be reachable before KTX builds context.\n');
+ io.stderr.write('\nEach connection must be reachable before ktx builds context.\n');
io.stderr.write(
`Run \`ktx connection test --project-dir ${resolve(projectDir)}\` to see the error, fix the connection, then retry.\n`,
);
@@ -570,7 +570,7 @@ async function markContextComplete(projectDir: string): Promise {
}
function writeMissingCapabilities(missing: string[], io: KtxCliIo): void {
- io.stderr.write('KTX cannot build agent-ready context yet.\n\n');
+ io.stderr.write('ktx cannot build agent-ready context yet.\n\n');
io.stderr.write('Missing:\n');
for (const item of missing) {
io.stderr.write(` ${item}\n`);
@@ -589,7 +589,7 @@ function writeSuccess(
targets: KtxSetupContextTargets,
io: KtxCliIo,
): void {
- io.stdout.write('\nKTX context is ready for agents.\n\n');
+ io.stdout.write('\nktx context is ready for agents.\n\n');
io.stdout.write('Databases:\n');
if (targets.primarySourceConnectionIds.length === 0) {
io.stdout.write(' none\n');
@@ -612,7 +612,7 @@ function writeSuccess(
}
function writeExistingContextSuccess(readiness: KtxSetupContextReadiness, io: KtxCliIo): void {
- io.stdout.write('\nKTX context is ready for agents.\n\n');
+ io.stdout.write('\nktx context is ready for agents.\n\n');
io.stdout.write('Existing context artifacts were found from setup ingest.\n\n');
io.stdout.write('Verification:\n');
io.stdout.write(` Agent context: ${readiness.agentContextReady ? 'ready' : 'not ready'}\n`);
@@ -622,8 +622,8 @@ function writeExistingContextSuccess(readiness: KtxSetupContextReadiness, io: Kt
async function promptForBuild(prompts: KtxSetupContextPromptAdapter): Promise<'build' | 'skip' | 'back'> {
return (await prompts.select({
message:
- 'Build KTX context for agents?\n\n' +
- 'KTX is fully configured and ready to build context. This may take a few minutes to a few hours.',
+ 'Build ktx context for agents?\n\n' +
+ 'ktx is fully configured and ready to build context. This may take a few minutes to a few hours.',
options: [
{ value: 'build', label: 'Build context now (recommended)' },
{ value: 'skip', label: 'Leave context unbuilt and exit setup' },
@@ -716,7 +716,7 @@ async function runBuild(
failureReason: readiness.details.join(' '),
...(lastSourceProgress ? { sourceProgress: lastSourceProgress } : {}),
});
- io.stderr.write('KTX context build did not pass agent-readiness verification.\n');
+ io.stderr.write('ktx context build did not pass agent-readiness verification.\n');
for (const detail of readiness.details) {
io.stderr.write(` ${detail}\n`);
}
diff --git a/packages/cli/src/setup-databases.ts b/packages/cli/src/setup-databases.ts
index 987b28ee..9b7aa189 100644
--- a/packages/cli/src/setup-databases.ts
+++ b/packages/cli/src/setup-databases.ts
@@ -270,7 +270,7 @@ function driverLabel(driver: KtxSetupDatabaseDriver): string {
}
function connectionNamePrompt(label: string): string {
- return `Name this ${label} connection\nKTX will use this short name in commands and config. You can rename it now.`;
+ return `Name this ${label} connection\nktx will use this short name in commands and config. You can rename it now.`;
}
function missingConnectionDetailsPrompt(
@@ -324,13 +324,6 @@ function numberConfigField(connection: KtxProjectConnectionConfig | undefined, f
return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
}
-function historicSqlConfigRecord(connection: KtxProjectConnectionConfig | undefined): Record | null {
- const historicSql = connection?.historicSql;
- return historicSql && typeof historicSql === 'object' && !Array.isArray(historicSql)
- ? (historicSql as Record)
- : null;
-}
-
function contextRecord(connection: KtxProjectConnectionConfig | undefined): Record {
const context = connection?.context;
return context && typeof context === 'object' && !Array.isArray(context) ? (context as Record) : {};
@@ -343,19 +336,12 @@ function queryHistoryConfigRecord(connection: KtxProjectConnectionConfig | undef
: null;
}
-function stripLegacyHistoricSql(connection: KtxProjectConnectionConfig): KtxProjectConnectionConfig {
- const { historicSql: _historicSql, ...rest } = connection as KtxProjectConnectionConfig & {
- historicSql?: unknown;
- };
- return rest;
-}
-
function withQueryHistoryConfig(
connection: KtxProjectConnectionConfig,
queryHistory: Record,
): KtxProjectConnectionConfig {
return {
- ...stripLegacyHistoricSql(connection),
+ ...connection,
context: {
...contextRecord(connection),
queryHistory,
@@ -363,16 +349,6 @@ function withQueryHistoryConfig(
};
}
-function migrateLegacyHistoricSqlConnection(connection: KtxProjectConnectionConfig): KtxProjectConnectionConfig {
- const existingQueryHistory = queryHistoryConfigRecord(connection);
- const legacy = historicSqlConfigRecord(connection);
- if (existingQueryHistory || !legacy) {
- return existingQueryHistory ? stripLegacyHistoricSql(connection) : connection;
- }
- const { dialect: _dialect, ...queryHistory } = legacy;
- return withQueryHistoryConfig(connection, queryHistory);
-}
-
function setupHistoricSqlProbeResult(
outcome: HistoricSqlProbeOutcome | null,
): KtxSetupHistoricSqlProbeResult {
@@ -1203,7 +1179,7 @@ async function disableConnectionQueryHistory(projectDir: string, connectionId: s
if (!connection) {
return;
}
- const existing = queryHistoryConfigRecord(connection) ?? historicSqlConfigRecord(connection) ?? {};
+ const existing = queryHistoryConfigRecord(connection) ?? {};
await writeConnectionConfig({
projectDir,
connectionId,
@@ -1560,18 +1536,7 @@ async function ensureHistoricSqlIngestDefaults(projectDir: string): Promise {
const project = await loadKtxProject({ projectDir });
- const config = setKtxSetupDatabaseConnectionIds(
- {
- ...project.config,
- connections: Object.fromEntries(
- Object.entries(project.config.connections).map(([connectionId, connection]) => [
- connectionId,
- migrateLegacyHistoricSqlConnection(connection),
- ]),
- ),
- },
- unique(connectionIds),
- );
+ const config = setKtxSetupDatabaseConnectionIds(project.config, unique(connectionIds));
await writeFile(project.configPath, serializeKtxProjectConfig(config), 'utf-8');
await markKtxSetupStateStepComplete(projectDir, 'databases');
}
@@ -1584,7 +1549,7 @@ async function maybeRunHistoricSqlSetupProbe(input: {
}): Promise {
const project = await loadKtxProject({ projectDir: input.projectDir });
const connection = project.config.connections[input.connectionId];
- const queryHistory = queryHistoryConfigRecord(connection) ?? historicSqlConfigRecord(connection);
+ const queryHistory = queryHistoryConfigRecord(connection);
if (queryHistory?.enabled !== true) {
return true;
}
@@ -1994,7 +1959,7 @@ async function chooseDrivers(
}
if (args.inputMode === 'disabled') {
io.stderr.write(
- 'KTX cannot work without a database. Pass --database or --database-connection-id, or pass --skip-databases to leave setup incomplete.\n',
+ 'ktx cannot work without a database. Pass --database or --database-connection-id, or pass --skip-databases to leave setup incomplete.\n',
);
return 'missing-input';
}
@@ -2005,7 +1970,7 @@ async function chooseDrivers(
io,
);
const choices = await prompts.multiselect({
- message: withMultiselectNavigation('Which databases should KTX connect to?'),
+ message: withMultiselectNavigation('Which databases should ktx connect to?'),
options: [...DRIVER_OPTIONS],
...(initialValues.length > 0 ? { initialValues } : {}),
required: true,
@@ -2285,7 +2250,7 @@ export async function runKtxSetupDatabasesStep(
deps: KtxSetupDatabasesDeps = {},
): Promise {
if (args.skipDatabases) {
- io.stdout.write('│ Database setup skipped. KTX cannot work until you add a database.\n');
+ io.stdout.write('│ Database setup skipped. ktx cannot work until you add a database.\n');
return { status: 'skipped', projectDir: args.projectDir };
}
@@ -2404,7 +2369,7 @@ export async function runKtxSetupDatabasesStep(
if (drivers === 'missing-input') return { status: 'missing-input', projectDir: args.projectDir };
if (drivers.length === 0) {
await markDatabasesComplete(args.projectDir, []);
- io.stdout.write('│ KTX cannot work without a database.\n');
+ io.stdout.write('│ ktx cannot work without a database.\n');
return { status: 'skipped', projectDir: args.projectDir };
}
diff --git a/packages/cli/src/setup-demo-tour.ts b/packages/cli/src/setup-demo-tour.ts
index ca891167..19c4806d 100644
--- a/packages/cli/src/setup-demo-tour.ts
+++ b/packages/cli/src/setup-demo-tour.ts
@@ -68,7 +68,7 @@ function createTargetState(target: KtxPublicIngestPlanTarget): ContextBuildTarge
export function renderDemoBanner(projectDir?: string): string {
const lines = [
'',
- `┌ ${cyan('Demo mode')} — data has been pre-processed and KTX context is already built.`,
+ `┌ ${cyan('Demo mode')} — data has been pre-processed and ktx context is already built.`,
'│ This walkthrough illustrates the setup steps. Selections are pre-filled and read-only.',
];
if (projectDir) {
@@ -95,7 +95,7 @@ export function renderDemoAgentTransition(): string {
const lines = [
'┌ Demo project is ready — let\'s connect your agent',
'│',
- '│ Your KTX context has been built with demo data.',
+ '│ Your ktx context has been built with demo data.',
'│ Select an agent to start using it.',
'└',
];
@@ -106,12 +106,12 @@ export function renderDemoAgentTransition(): string {
export function renderDemoCompletionSummary(projectDir: string, agentInstalled: boolean): string {
const lines: string[] = [
'',
- `${cyan('★')} KTX demo is ready`,
+ `${cyan('★')} ktx demo is ready`,
'',
];
if (agentInstalled) {
- lines.push(' Your agent is connected to a demo KTX project.');
+ lines.push(' Your agent is connected to a demo ktx project.');
} else {
lines.push(' Demo project created. Connect an agent to start using it:');
lines.push(` $ ${cyan(`ktx setup --agents --project-dir ${projectDir}`)}`);
@@ -120,7 +120,7 @@ export function renderDemoCompletionSummary(projectDir: string, agentInstalled:
lines.push(
'',
` ${dim('⚠')} This project is in a temporary directory and will be`,
- ' cleaned up by your system. To set up KTX with your own',
+ ' cleaned up by your system. To set up ktx with your own',
' data, run: ktx setup',
'',
` Project: ${projectDir}`,
@@ -234,9 +234,9 @@ export function buildDemoReplayTimeline(): DemoReplayEvent[] {
function renderDemoContextCompletionSummary(): string {
const lines = [
'',
- `${cyan('★')} KTX finished building context`,
+ `${cyan('★')} ktx finished building context`,
'',
- ' KTX created:',
+ ' ktx created:',
` ${cyan('📊')} 46 semantic layer definitions`,
` ${cyan('📝')} 28 wiki pages`,
'',
diff --git a/packages/cli/src/setup-embeddings.ts b/packages/cli/src/setup-embeddings.ts
index 5d02e3e4..7e254f06 100644
--- a/packages/cli/src/setup-embeddings.ts
+++ b/packages/cli/src/setup-embeddings.ts
@@ -80,7 +80,7 @@ const DEFAULTS: Record<
const LOCAL_EMBEDDING_BACKEND: KtxSetupEmbeddingBackend = 'sentence-transformers';
const EMBEDDING_OPTION_PROMPT_CONTEXT =
- 'KTX uses embeddings for semantic search over semantic-layer sources, wiki context, schema metadata, ' +
+ 'ktx uses embeddings for semantic search over semantic-layer sources, wiki context, schema metadata, ' +
'and relationship evidence.';
const LOCAL_EMBEDDING_HEALTH_TIMEOUT_MS = 120_000;
const LOCAL_EMBEDDING_STDERR_TAIL_LINES = 40;
@@ -220,7 +220,7 @@ async function chooseCredentialRef(
const defaultEnv = DEFAULTS[backend].envName ?? 'EMBEDDING_API_KEY';
const prompts = deps.prompts ?? createPromptAdapter();
const choice = await prompts.select({
- message: `How should KTX find your ${embeddingBackendDisplayName(backend)} embedding API key?`,
+ message: `How should ktx find your ${embeddingBackendDisplayName(backend)} embedding API key?`,
options: [
{ value: 'paste', label: 'Paste a key and save it as a local secret file' },
{ value: 'env', label: `Use ${defaultEnv} from the environment` },
@@ -233,7 +233,7 @@ async function chooseCredentialRef(
if (choice === 'paste') {
io.stdout.write(
`│ ${[
- `KTX will save the key in .ktx/secrets/${backend}-api-key with local file permissions,`,
+ `ktx will save the key in .ktx/secrets/${backend}-api-key with local file permissions,`,
'then write a file: reference in ktx.yaml.',
].join(' ')}\n`,
);
@@ -272,7 +272,7 @@ async function chooseEmbeddingBackend(
return LOCAL_EMBEDDING_BACKEND;
}
const choice = await (deps.prompts ?? createPromptAdapter()).select({
- message: `Which embedding option should KTX use?\n\n${EMBEDDING_OPTION_PROMPT_CONTEXT}`,
+ message: `Which embedding option should ktx use?\n\n${EMBEDDING_OPTION_PROMPT_CONTEXT}`,
options: [
{ value: 'sentence-transformers', label: 'Local sentence-transformers embeddings' },
{ value: 'openai', label: 'OpenAI embeddings', hint: 'recommended' },
@@ -303,13 +303,13 @@ async function readLocalEmbeddingDaemonStderrTail(stderrLog: string | undefined)
function localEmbeddingSetupMessage(message: string, stderrTail: string[] = []): string {
const lines = [
`Local embedding health check failed: ${message}`,
- 'Local embeddings use the KTX-managed Python runtime.',
+ 'Local embeddings use the ktx-managed Python runtime.',
'Prepare the runtime with: ktx admin runtime start --feature local-embeddings',
'Use --yes with setup to install and start the runtime without prompting.',
'The first run may download Python packages and the all-MiniLM-L6-v2 model.',
];
if (stderrTail.length > 0) {
- lines.push('Recent KTX daemon stderr:', ...stderrTail);
+ lines.push('Recent ktx daemon stderr:', ...stderrTail);
}
return lines.join('\n');
}
@@ -318,7 +318,7 @@ async function promptAfterLocalEmbeddingFailure(
deps: KtxSetupEmbeddingsDeps,
): Promise<'retry' | Extract | 'back'> {
const choice = await (deps.prompts ?? createPromptAdapter()).select({
- message: 'Local embeddings are not reachable. Start the local KTX daemon, then retry.',
+ message: 'Local embeddings are not reachable. Start the local ktx daemon, then retry.',
options: [
{ value: 'retry', label: 'Retry' },
{ value: 'openai', label: 'Use OpenAI embeddings' },
diff --git a/packages/cli/src/setup-interrupt.ts b/packages/cli/src/setup-interrupt.ts
index 782abbf5..ab3ff9ea 100644
--- a/packages/cli/src/setup-interrupt.ts
+++ b/packages/cli/src/setup-interrupt.ts
@@ -4,7 +4,7 @@ import { cancel, confirm, isCancel as isClackCancel } from '@clack/prompts';
export class KtxSetupExitError extends Error {
constructor() {
- super('KTX setup exit requested');
+ super('ktx setup exit requested');
this.name = 'KtxSetupExitError';
}
}
diff --git a/packages/cli/src/setup-models.ts b/packages/cli/src/setup-models.ts
index fbbabbdb..b89d27ff 100644
--- a/packages/cli/src/setup-models.ts
+++ b/packages/cli/src/setup-models.ts
@@ -102,12 +102,12 @@ export interface KtxSetupModelDeps {
}
const ANTHROPIC_CREDENTIAL_PROMPT_CONTEXT =
- 'KTX uses the key to verify Anthropic model access now and to run ingest agents that turn schemas, SQL, ' +
+ 'ktx uses the key to verify Anthropic model access now and to run ingest agents that turn schemas, SQL, ' +
'BI metadata, and docs into semantic-layer sources and wiki context. ktx.yaml stores an env: or file: ' +
'reference, not the raw key.';
const VERTEX_PROJECT_PROMPT_CONTEXT =
- 'KTX stores the selected Google Cloud project ID in ktx.yaml and uses Application Default Credentials for ' +
+ 'ktx stores the selected Google Cloud project ID in ktx.yaml and uses Application Default Credentials for ' +
'access. Project visibility depends on the signed-in Google account and organization permissions.';
const DEFAULT_VERTEX_LOCATION = 'us-east5';
@@ -415,7 +415,7 @@ async function chooseCredentialRef(
}
while (true) {
const choice = await prompts.select({
- message: `How should KTX find your Anthropic API key?\n\n${ANTHROPIC_CREDENTIAL_PROMPT_CONTEXT}`,
+ message: `How should ktx find your Anthropic API key?\n\n${ANTHROPIC_CREDENTIAL_PROMPT_CONTEXT}`,
options: [
{ value: 'paste', label: 'Paste a key and save it as a local secret file' },
{ value: 'env', label: 'Use ANTHROPIC_API_KEY from the environment' },
@@ -427,7 +427,7 @@ async function chooseCredentialRef(
}
if (choice === 'paste') {
io.stdout.write(
- '│ KTX will save the key in .ktx/secrets/anthropic-api-key with local file permissions, then write a file: reference in ktx.yaml.\n',
+ '│ ktx will save the key in .ktx/secrets/anthropic-api-key with local file permissions, then write a file: reference in ktx.yaml.\n',
);
const value = await prompts.password({ message: withTextInputNavigation('Anthropic API key') });
if (value === undefined) {
@@ -488,7 +488,7 @@ async function chooseBackend(
);
}
const choice = await prompts.select({
- message: 'Which LLM provider should KTX use?',
+ message: 'Which LLM provider should ktx use?',
options: [
...KTX_SETUP_LLM_BACKENDS.map((backend) => ({ value: backend, label: KTX_SETUP_LLM_BACKEND_LABELS[backend] })),
{ value: 'back', label: 'Back' },
@@ -599,7 +599,7 @@ async function chooseInteractiveVertexProject(
}
const choice = await prompts.autocomplete({
- message: `Which Google Cloud project should KTX use for Vertex AI?\n\n${[
+ message: `Which Google Cloud project should ktx use for Vertex AI?\n\n${[
VERTEX_PROJECT_PROMPT_CONTEXT,
listFailureMessage,
]
diff --git a/packages/cli/src/setup-project.ts b/packages/cli/src/setup-project.ts
index 3f36fb24..ee7fdeb7 100644
--- a/packages/cli/src/setup-project.ts
+++ b/packages/cli/src/setup-project.ts
@@ -144,7 +144,7 @@ async function confirmProjectDir(
const action = await prompts.select({
message: `That folder already exists and is not empty: ${selectedDir}`,
options: [
- { value: 'use-existing', label: 'Yes, create KTX files there' },
+ { value: 'use-existing', label: 'Yes, create ktx files there' },
{ value: 'choose-another', label: 'Choose another folder' },
{ value: 'back', label: 'Back' },
],
@@ -155,9 +155,9 @@ async function confirmProjectDir(
return { status: 'confirmed', confirmedCreation: true };
}
- io.stdout.write(`│ KTX will create:\n│ ${selectedDir}\n`);
+ io.stdout.write(`│ ktx will create:\n│ ${selectedDir}\n`);
const action = await prompts.select({
- message: `Create KTX project at ${selectedDir}?`,
+ message: `Create ktx project at ${selectedDir}?`,
options: [
{ value: 'create', label: 'Create project' },
{ value: 'choose-another', label: 'Choose another folder' },
@@ -210,7 +210,7 @@ async function promptForNewProjectDir(
while (true) {
const destinationChoice = await prompts.select({
- message: 'Where should KTX create the project?',
+ message: 'Where should ktx create the project?',
options: [
{ value: 'default', label: `Create the default project folder: ${defaultProjectDir}` },
{ value: 'custom', label: 'Enter a custom path' },
@@ -337,7 +337,7 @@ export async function runKtxSetupProjectStep(
);
while (true) {
const choice = await prompts.select({
- message: 'Where should KTX create the project?',
+ message: 'Where should ktx create the project?',
options: [
{ value: 'current', label: `Current directory (${projectDir})` },
{ value: 'new-default', label: `New subfolder (${defaultProjectDirLabel})` },
diff --git a/packages/cli/src/setup-ready-menu.ts b/packages/cli/src/setup-ready-menu.ts
index de0f5a45..d138ef8d 100644
--- a/packages/cli/src/setup-ready-menu.ts
+++ b/packages/cli/src/setup-ready-menu.ts
@@ -99,7 +99,7 @@ export async function runKtxSetupReadyChangeMenu(
{ value: 'databases', label: 'Databases' },
{ value: 'sources', label: 'Context sources' },
...(status.runtime.required ? [{ value: 'runtime', label: 'Runtime' }] : []),
- { value: 'context', label: 'Rebuild KTX context' },
+ { value: 'context', label: 'Rebuild ktx context' },
{ value: 'agents', label: 'Agent integration' },
{ value: 'exit', label: 'Exit' },
],
diff --git a/packages/cli/src/setup-sources.ts b/packages/cli/src/setup-sources.ts
index 25552fbf..c38ff113 100644
--- a/packages/cli/src/setup-sources.ts
+++ b/packages/cli/src/setup-sources.ts
@@ -166,7 +166,7 @@ function sourceAdapter(source: KtxSetupSourceType): string {
}
function connectionNamePrompt(label: string): string {
- return `Name this ${label} connection\nKTX will use this short name in commands and config. You can rename it now.`;
+ return `Name this ${label} connection\nktx will use this short name in commands and config. You can rename it now.`;
}
function sourceSubpathPrompt(source: KtxSetupSourceType): string {
@@ -266,7 +266,7 @@ async function chooseSourceCredentialRef(input: {
}): Promise {
while (true) {
const choice = await input.prompts.select({
- message: `How should KTX find your ${input.label}?`,
+ message: `How should ktx find your ${input.label}?`,
options: [
...(input.existingRef ? [{ value: 'keep', label: 'Keep existing credential' }] : []),
{ value: 'paste', label: 'Paste a key and save it as a local secret file' },
@@ -1179,7 +1179,7 @@ async function promptForInteractiveSource(
}
if (subpaths.length > 1) {
const selected = await prompts.select({
- message: 'Multiple dbt projects found — which one should KTX use?',
+ message: 'Multiple dbt projects found — which one should ktx use?',
options: [
...subpaths.map((p) => ({ value: p || '.', label: p || '(project root)' })),
{ value: 'back', label: 'Back' },
@@ -1341,7 +1341,7 @@ async function promptForInteractiveSource(
},
async (currentState) => {
const crawlMode = await prompts.select({
- message: 'Which Notion pages should KTX ingest?',
+ message: 'Which Notion pages should ktx ingest?',
options: [
{ value: 'all_accessible', label: 'All pages the integration can access' },
{ value: 'selected_roots', label: 'Specific pages and their subpages (choose them in a picker)' },
@@ -1979,7 +1979,7 @@ export async function runKtxSetupSourcesStep(
: args.inputMode === 'disabled'
? []
: await prompts.multiselect({
- message: withMultiselectNavigation('Which context sources should KTX ingest?'),
+ message: withMultiselectNavigation('Which context sources should ktx ingest?'),
options: contextSourceChecklist.options,
...(contextSourceChecklist.initialValues.length > 0
? { initialValues: contextSourceChecklist.initialValues }
diff --git a/packages/cli/src/setup.ts b/packages/cli/src/setup.ts
index 2208d2b4..6bbcf90b 100644
--- a/packages/cli/src/setup.ts
+++ b/packages/cli/src/setup.ts
@@ -318,16 +318,16 @@ async function runKtxSetupEntryMenu(
const options = status.project.ready
? [
{ value: 'setup', label: 'Resume or change an existing setup' },
- { value: 'new-project', label: 'Create a new KTX project' },
- { value: 'agents', label: 'Connect a coding agent to KTX' },
+ { value: 'new-project', label: 'Create a new ktx project' },
+ { value: 'agents', label: 'Connect a coding agent to ktx' },
{ value: 'status', label: 'Check setup status' },
- { value: 'demo', label: 'Explore a pre-built KTX project' },
+ { value: 'demo', label: 'Explore a pre-built ktx project' },
{ value: 'exit', label: 'Exit' },
]
: [
- { value: 'setup', label: 'Set up KTX for my data' },
+ { value: 'setup', label: 'Set up ktx for my data' },
{ value: 'status', label: 'Check setup status' },
- { value: 'demo', label: 'Explore a pre-built KTX project' },
+ { value: 'demo', label: 'Explore a pre-built ktx project' },
{ value: 'exit', label: 'Exit' },
];
const action = (await prompts.select({
@@ -523,17 +523,17 @@ function formatContextBuilt(status: KtxSetupContextStatusSummary): string {
export function formatKtxSetupStatus(status: KtxSetupStatus): string {
if (!status.project.ready) {
return [
- `No KTX project found at ${status.project.path}.`,
+ `No ktx project found at ${status.project.path}.`,
'',
'Check another project: ktx --project-dir status',
'Or from that folder: ktx status',
- 'Create a new KTX project here: ktx setup',
+ 'Create a new ktx project here: ktx setup',
'',
].join('\n');
}
const lines = [
- `KTX project: ${status.project.path}`,
+ `ktx project: ${status.project.path}`,
`Project ready: ${formatReady(status.project.ready)}`,
`LLM ready: ${formatReady(status.llm.ready)}${status.llm.model ? ` (${status.llm.model})` : ''}`,
`Embeddings ready: ${formatReady(status.embeddings.ready)}${
@@ -548,7 +548,7 @@ export function formatKtxSetupStatus(status: KtxSetupStatus): string {
}`,
]
: []),
- `KTX context built: ${formatContextBuilt(status.context)}`,
+ `ktx context built: ${formatContextBuilt(status.context)}`,
`Agent integration ready: ${formatReady(status.agents.some((agent) => agent.ready))}${
status.agents.length > 0 ? ` (${status.agents.map((agent) => `${agent.target}:${agent.scope}`).join(', ')})` : ''
}`,
@@ -585,7 +585,7 @@ export function formatKtxSetupCompletionSummary(
);
}
lines.push('', agentNextActions ? 'After that, try' : 'Try it');
- lines.push(' Ask your agent: "Use KTX to show me the available tables."');
+ lines.push(' Ask your agent: "Use ktx to show me the available tables."');
return lines.join('\n');
}
@@ -622,7 +622,7 @@ function setupRuntimeInstallPolicy(args: Extract {
const project = await loadKtxProject({ projectDir });
- await project.git.commitFile('ktx.yaml', 'setup: update KTX project config', 'ktx setup', 'setup@ktx.local');
+ await project.git.commitFile('ktx.yaml', 'setup: update ktx project config', 'ktx setup', 'setup@ktx.local');
}
export async function runKtxSetup(args: KtxSetupArgs, io: KtxCliIo, deps: KtxSetupDeps = {}): Promise {
@@ -638,7 +638,7 @@ export async function runKtxSetup(args: KtxSetupArgs, io: KtxCliIo, deps: KtxSet
async function runKtxSetupInner(args: KtxSetupArgs, io: KtxCliIo, deps: KtxSetupDeps = {}): Promise {
const setupUi = deps.setupUi ?? createKtxSetupUiAdapter();
- setupUi.intro('KTX setup', io);
+ setupUi.intro('ktx setup', io);
setupUi.note(KTX_DOCS_URL, '📚 Docs', io);
let entryAction: KtxSetupEntryAction | undefined;
let projectResult: Awaited>;
@@ -989,7 +989,7 @@ async function runKtxSetupInner(args: KtxSetupArgs, io: KtxCliIo, deps: KtxSetup
if (shouldPrintConciseReadySummary(status)) {
setupUi.note(
formatKtxSetupCompletionSummary(status, { agentNextActions }),
- agentNextActions ? 'Finish KTX agent setup' : 'KTX project ready',
+ agentNextActions ? 'Finish ktx agent setup' : 'ktx project ready',
io,
{
format: (line) => line,
diff --git a/packages/cli/src/skills/analytics/SKILL.md b/packages/cli/src/skills/analytics/SKILL.md
index e6857e56..3fe82b1c 100644
--- a/packages/cli/src/skills/analytics/SKILL.md
+++ b/packages/cli/src/skills/analytics/SKILL.md
@@ -1,11 +1,11 @@
---
name: ktx-analytics
-description: Use when answering a question that needs data from a KTX-connected database - investigating, analyzing, "how many", "show me", "what's the breakdown of", finding records by value, exploring tables, comparing periods, explaining metrics, or any data-analysis request. Triggers even when the user does not say "analytics"; if the answer requires querying a configured KTX connection, this skill applies.
+description: Use when answering a question that needs data from a ktx-connected database - investigating, analyzing, "how many", "show me", "what's the breakdown of", finding records by value, exploring tables, comparing periods, explaining metrics, or any data-analysis request. Triggers even when the user does not say "analytics"; if the answer requires querying a configured ktx connection, this skill applies.
---
-# KTX Analytics Workflow
+# ktx Analytics Workflow
-You have access to KTX MCP tools for data discovery, semantic-layer analysis, raw read-only SQL, wiki context, and memory ingest. Follow this workflow.
+You have access to ktx MCP tools for data discovery, semantic-layer analysis, raw read-only SQL, wiki context, and memory ingest. Follow this workflow.
1. **Discover** - call `discover_data` first to see what exists across wiki pages, semantic-layer sources, metrics, dimensions, raw tables, and columns. Returns refs only.
diff --git a/packages/cli/src/skills/dbt_ingest/SKILL.md b/packages/cli/src/skills/dbt_ingest/SKILL.md
index fdaf586f..51d4f97a 100644
--- a/packages/cli/src/skills/dbt_ingest/SKILL.md
+++ b/packages/cli/src/skills/dbt_ingest/SKILL.md
@@ -1,16 +1,16 @@
---
name: dbt_ingest
-description: Map dbt `schema.yml` / `properties.yml` models and sources into KTX semantic-layer overlays and column notes. Covers `sources:` vs `models:`, column `data_tests` (not_null, unique, accepted_values, relationships), and how bundle-time writes complement manifest backfill from git sync. Load when the WorkUnit's `skillNames` includes `dbt_ingest` or when raw files are dbt YAML under `models/` / `sources/`.
+description: Map dbt `schema.yml` / `properties.yml` models and sources into ktx semantic-layer overlays and column notes. Covers `sources:` vs `models:`, column `data_tests` (not_null, unique, accepted_values, relationships), and how bundle-time writes complement manifest backfill from git sync. Load when the WorkUnit's `skillNames` includes `dbt_ingest` or when raw files are dbt YAML under `models/` / `sources/`.
callers: [memory_agent]
---
-# dbt → KTX (bundle ingest)
+# dbt → ktx (bundle ingest)
Use this skill for **uploaded** dbt projects (`dbt_project.yml` at stage root, `models/**`, `sources/**`, `schema.yml`). There is **no** `fetch()` in v1 - scheduled `dbt parse` / `manifest.json` pulls are out of scope; host-provided dbt sync may still backfill structured test metadata into `_schema` on the next sync.
## Mapping (models / sources → SL)
-| dbt | KTX | Notes |
+| dbt | ktx | Notes |
|-----|--------|--------|
| `models:` entry with `columns:` | **Overlay** on the manifest table with the same name (after `discover_data` / `entity_details`) | One SL source per physical table; model name may differ from DB name - resolve with `read_raw_file` + warehouse context. |
| `sources:` → `tables:` | Same as models; use `identifier` when present instead of logical `name`. | Schema + name must match how the connection sees tables. |
diff --git a/packages/cli/src/skills/looker_ingest/SKILL.md b/packages/cli/src/skills/looker_ingest/SKILL.md
index 45e0f906..91c4aa85 100644
--- a/packages/cli/src/skills/looker_ingest/SKILL.md
+++ b/packages/cli/src/skills/looker_ingest/SKILL.md
@@ -1,12 +1,12 @@
---
name: looker_ingest
-description: Extract durable KTX knowledge and semantic-layer contribution proposals from staged Looker runtime dashboard, Look, and explore JSON. Load for WorkUnits whose raw files are under explores/, dashboards/, or looks/.
+description: Extract durable ktx knowledge and semantic-layer contribution proposals from staged Looker runtime dashboard, Look, and explore JSON. Load for WorkUnits whose raw files are under explores/, dashboards/, or looks/.
callers: [memory_agent]
---
# Looker Runtime Ingest
-Looker runtime ingest turns API-staged dashboards, Looks, and explores into durable KTX memory. Runtime entities are evidence. They are not themselves the final knowledge shape.
+Looker runtime ingest turns API-staged dashboards, Looks, and explores into durable ktx memory. Runtime entities are evidence. They are not themselves the final knowledge shape.
## Required Workflow
@@ -103,7 +103,7 @@ The staged explore file carries warehouse target fields populated before the WU
- `rawSqlTableName`: Looker's verbatim `sql_table_name`. Keep it as provenance only.
- `targetTable`: the parsed target-table union. Use this as the sole branch condition.
-When `targetTable.ok === true`, the explore has a complete KTX backing target. Before writing:
+When `targetTable.ok === true`, the explore has a complete ktx backing target. Before writing:
1. Use `targetTable.catalog`, `targetTable.schema`, and `targetTable.name` for `source_tables` preflight matching through `sl_discover` or `sl_read_source`.
2. Use Looker field `sql`, labels, descriptions, and type metadata to derive source columns, measures, segments, joins, and grain.
diff --git a/packages/cli/src/skills/lookml_ingest/SKILL.md b/packages/cli/src/skills/lookml_ingest/SKILL.md
index 8f5afc61..155ec672 100644
--- a/packages/cli/src/skills/lookml_ingest/SKILL.md
+++ b/packages/cli/src/skills/lookml_ingest/SKILL.md
@@ -1,16 +1,16 @@
---
name: lookml_ingest
-description: Map a LookML view/model/explore into KTX semantic layer sources. Covers the LookML to KTX primitive table, provenance tagging, and three worked examples (overlay, standalone from derived_table, standalone with sql_always_where). Load when the turn contains `.lkml` content.
+description: Map a LookML view/model/explore into ktx semantic layer sources. Covers the LookML to ktx primitive table, provenance tagging, and three worked examples (overlay, standalone from derived_table, standalone with sql_always_where). Load when the turn contains `.lkml` content.
callers: [memory_agent]
---
-# LookML to KTX Semantic Layer
+# LookML to ktx Semantic Layer
LookML views map to SL sources, `measure:` to measures, `explore: { join: }` to the join graph. This skill lays out the mapping and the three capture shapes.
## Mapping table
-| LookML | KTX form | Notes |
+| LookML | ktx form | Notes |
|---|---|---|
| `view: X { sql_table_name: …; measure:/dimension:/join: }` | **Overlay** named `X` with `measures`, computed-only `columns`, `column_overrides`, `joins`, `segments` | Manifest-backed; inherit grain/columns |
| `view: X { derived_table: { sql: … } }` | **Standalone** with top-level `sql:`, explicit `grain:` + `columns:` | No manifest entry exists |
@@ -23,7 +23,7 @@ Type map: `date`/`datetime`/`timestamp` → `time`; `yesno` → `boolean`; `numb
## Decision rules
-LookML writes target the run connection directly. Unlike Looker runtime ingestion, the LookML adapter is configured on the warehouse KTX connection, so do not look for `targetWarehouseConnectionId` and do not route through a mapping array.
+LookML writes target the run connection directly. Unlike Looker runtime ingestion, the LookML adapter is configured on the warehouse ktx connection, so do not look for `targetWarehouseConnectionId` and do not route through a mapping array.
Before any SL write, inspect the WorkUnit notes.
@@ -94,7 +94,7 @@ SL source, `tables:` frontmatter, `sl_refs`, or `emit_unmapped_fallback`:
schema or dataset, and table from the WorkUnit evidence.
3. Use only those names in `sql:`, `columns:`, and `grain:`. Map each `dimension_group` to ONE `{ name: , type: time, role: time }` entry - never one per timeframe.
-| LookML input | KTX `columns:` entry |
+| LookML input | ktx `columns:` entry |
|---|---|
| `dimension_group: month { type: time; timeframes: [month]; sql: ${TABLE}.month_date ;; }` | `{ name: month_date, type: time, role: time }` |
| `dimension_group: date { type: time; timeframes: [raw, date, week, month]; sql: ${TABLE}.date ;; }` | `{ name: date, type: time, role: time }` - single entry, NOT `date_raw`/`date_date`/`date_week` |
@@ -132,7 +132,7 @@ explore: fct_labs {
}
```
-KTX overlay at `/fct_labs.yaml`:
+ktx overlay at `/fct_labs.yaml`:
```yaml
name: fct_labs
diff --git a/packages/cli/src/skills/metabase_ingest/SKILL.md b/packages/cli/src/skills/metabase_ingest/SKILL.md
index 921d0c50..651bb1ef 100644
--- a/packages/cli/src/skills/metabase_ingest/SKILL.md
+++ b/packages/cli/src/skills/metabase_ingest/SKILL.md
@@ -1,12 +1,12 @@
---
name: metabase_ingest
-description: Convert Metabase questions, models, and metrics into KTX Semantic Layer source definitions. Covers result-metadata to KSL column type mapping, FK/PK detection, near-duplicate deduplication, pre-aggregation decomposition, join-graph connectivity, and how to react to priorProvenance from earlier ingest syncs. Load when the WorkUnit contains `cards/.json` files under a Metabase bundle.
+description: Convert Metabase questions, models, and metrics into ktx Semantic Layer source definitions. Covers result-metadata to KSL column type mapping, FK/PK detection, near-duplicate deduplication, pre-aggregation decomposition, join-graph connectivity, and how to react to priorProvenance from earlier ingest syncs. Load when the WorkUnit contains `cards/.json` files under a Metabase bundle.
callers: [memory_agent]
---
-# Metabase to KTX Semantic Layer
+# Metabase to ktx Semantic Layer
-Each WorkUnit represents one Metabase collection's cards for one Metabase database (mapped to exactly one KTX connection). Every `cards/.json` file carries the resolved SQL, result_metadata, card type, collection path, and referenced-card ids. The WU's `sync-config.json` tells you which sync mode is active and which selections apply. `databases/.json` tells you the target KTX connection.
+Each WorkUnit represents one Metabase collection's cards for one Metabase database (mapped to exactly one ktx connection). Every `cards/.json` file carries the resolved SQL, result_metadata, card type, collection path, and referenced-card ids. The WU's `sync-config.json` tells you which sync mode is active and which selections apply. `databases/.json` tells you the target ktx connection.
## Context format
@@ -100,7 +100,7 @@ measures:
Overlay shape: `name:` plus any of `measures:`, `segments:`, `descriptions:`, `joins:`, `disable_joins:`, `exclude_columns:`, `column_overrides:`, or computed-only `columns:` entries with `expr` + `type`. Never include `sql:`, `table:`, `grain:`, or base-table `columns:` on a manifest-backed name — those would shadow the manifest's schema and drop its joins. Use `column_overrides:` for inherited column descriptions. Overlay `joins:` are merged additively with the manifest's joins (deduped by `to` + `on`); use `disable_joins: [""]` to suppress a specific manifest join. After the overlay exists, use `sl_edit_source` for further tweaks. See `sl_capture` skill for the canonical overlay rule.
-**Join discovery:** When your card's SQL references warehouse tables (e.g. in `FROM` or `JOIN` clauses), call `sl_discover({ query: '' })` before writing. The matching manifest entry's `name` is the value you use in `joins: [- to: ]` only when the card output exposes a local key that matches the target source grain (for example `account_id = mart_account_segments.account_id`). Do not declare a KTX join just because the card SQL joins that table internally. If the output only exposes display fields such as `account_name`, keep the SQL source self-contained or project the key before adding the join. Use `many_to_one` for FK-to-dimension joins, `one_to_many` for the reverse.
+**Join discovery:** When your card's SQL references warehouse tables (e.g. in `FROM` or `JOIN` clauses), call `sl_discover({ query: '' })` before writing. The matching manifest entry's `name` is the value you use in `joins: [- to: ]` only when the card output exposes a local key that matches the target source grain (for example `account_id = mart_account_segments.account_id`). Do not declare a ktx join just because the card SQL joins that table internally. If the output only exposes display fields such as `account_name`, keep the SQL source self-contained or project the key before adding the join. Use `many_to_one` for FK-to-dimension joins, `one_to_many` for the reverse.
**Hard rule on join columns (prevents broken joins):** For every join you declare, the local column on the left of `on:` MUST be (a) present in your source's projected output and (b) a key/ID column, never a display value. If the natural FK isn't in your SELECT, add it to SELECT before declaring the join. Joining `account_name = mart_account_segments.account_id` is always wrong - names are not identifiers and the equality produces zero matches. The validator rejects this with a "display value to identifier" error; the tool will refuse to save it. Add `account_id` to your SELECT and join on `account_id = mart_account_segments.account_id`, or omit the join entirely.
diff --git a/packages/cli/src/skills/metricflow_ingest/SKILL.md b/packages/cli/src/skills/metricflow_ingest/SKILL.md
index ab26bb3e..3bedf000 100644
--- a/packages/cli/src/skills/metricflow_ingest/SKILL.md
+++ b/packages/cli/src/skills/metricflow_ingest/SKILL.md
@@ -1,16 +1,16 @@
---
name: metricflow_ingest
-description: Map a MetricFlow semantic_model or metric into KTX semantic layer sources. Covers the MetricFlow to KTX primitive table, `extends:` inheritance flattening, metric-type handling (simple / derived / ratio / cumulative / conversion), `model: ref('x')` resolution, and four worked examples. Load when the turn contains `.yml`/`.yaml` files with top-level `semantic_models:` or `metrics:`.
+description: Map a MetricFlow semantic_model or metric into ktx semantic layer sources. Covers the MetricFlow to ktx primitive table, `extends:` inheritance flattening, metric-type handling (simple / derived / ratio / cumulative / conversion), `model: ref('x')` resolution, and four worked examples. Load when the turn contains `.yml`/`.yaml` files with top-level `semantic_models:` or `metrics:`.
callers: [memory_agent]
---
-# MetricFlow to KTX Semantic Layer
+# MetricFlow to ktx Semantic Layer
-A MetricFlow `semantic_model` maps to an SL source; MetricFlow `measures` map to KTX measures; MetricFlow `entities` map to KTX `joins`; MetricFlow `metrics` (top-level) map to KTX measures OR to cross-model derived measures. Files in one WorkUnit are ALWAYS part of the same logical entity (a connected component, possibly spanning `extends:` + cross-model metric refs). Flatten inheritance and cross-file references at write time.
+A MetricFlow `semantic_model` maps to an SL source; MetricFlow `measures` map to ktx measures; MetricFlow `entities` map to ktx `joins`; MetricFlow `metrics` (top-level) map to ktx measures OR to cross-model derived measures. Files in one WorkUnit are ALWAYS part of the same logical entity (a connected component, possibly spanning `extends:` + cross-model metric refs). Flatten inheritance and cross-file references at write time.
## Mapping table
-| MetricFlow | KTX form | Notes |
+| MetricFlow | ktx form | Notes |
|---|---|---|
| `semantic_model: X { model: ref('t') }` with measures + dimensions | **Overlay** named `X` with `measures`, computed-only `columns`, `column_overrides`, `joins` | The `model:` ref resolves to a manifest table. |
| `semantic_model: X { model: source('s','t') }` | **Overlay** named `X` over table `t`. | Same shape; `source()` still resolves to a physical table. |
@@ -23,11 +23,11 @@ A MetricFlow `semantic_model` maps to an SL source; MetricFlow `measures` map to
| `metrics: [{ type: simple, filter: }]` | **New measure** on the same source, with the filter translated to SQL and attached via `filter:` | Translate Jinja `{{ Dimension('x__y') }}` to the column name `y`. |
| `metrics: [{ type: derived, type_params: { expr, metrics } }]` | **Derived measure** on whichever source owns the referenced measures, with `expr:` referencing measure names | If the metric spans models, still write it once on the source owning the "primary" measure (the one the agent judges most central). Mention the cross-model chain in the description. |
| `metrics: [{ type: ratio, type_params: { numerator, denominator } }]` | Same as derived; `expr: "numerator / NULLIF(denominator, 0)"` if no explicit expr | Safe-division by default. |
-| `metrics: [{ type: cumulative, type_params: { window, grain_to_date } }]` | **Standalone** source with a window-function SQL; reference the resulting column as a normal measure | KTX SL has no first-class cumulative primitive (spec Non-goals). |
-| `metrics: [{ type: conversion }]` | **Flag for human** - do NOT write. Emit a wiki note describing the intended semantics. | No KTX equivalent in v1. |
+| `metrics: [{ type: cumulative, type_params: { window, grain_to_date } }]` | **Standalone** source with a window-function SQL; reference the resulting column as a normal measure | ktx SL has no first-class cumulative primitive (spec Non-goals). |
+| `metrics: [{ type: conversion }]` | **Flag for human** - do NOT write. Emit a wiki note describing the intended semantics. | No ktx equivalent in v1. |
| Metric not mappable | Wiki page `-definition.md` with the full YAML body quoted | Capture the intent even if we can't emit SL. |
-Type map: MetricFlow `time` to KTX `time`; `categorical` to `string`; `number` to `number`; `boolean` to `boolean`. Follow `expr` over `name` when both differ - `expr` is the physical column.
+Type map: MetricFlow `time` to ktx `time`; `categorical` to `string`; `number` to `number`; `boolean` to `boolean`. Follow `expr` over `name` when both differ - `expr` is the physical column.
Verify each MetricFlow model source table with entity_details before producing
the corresponding sl_write_source.
@@ -92,7 +92,7 @@ After every `sl_write_source`, call `sl_validate`. The warehouse will reject inv
## Cumulative metrics - sql-standalone fallback
-KTX SL has no first-class `window:` or `grain_to_date:` primitive in v1 (spec Non-goals). Translate a MetricFlow cumulative metric to a standalone SL source with a window-function SQL:
+ktx SL has no first-class `window:` or `grain_to_date:` primitive in v1 (spec Non-goals). Translate a MetricFlow cumulative metric to a standalone SL source with a window-function SQL:
```yaml
# MetricFlow input:
@@ -105,7 +105,7 @@ metrics:
```
```yaml
-# KTX standalone output:
+# ktx standalone output:
name: cum_revenue_7d
source_type: sql
sql: |
@@ -143,7 +143,7 @@ Do NOT emit SL for this. Instead:
- Write a wiki page at `wiki/global/-intent.md` quoting the full YAML body and a one-line explanation of the intended semantics (base event → conversion event within window).
- Call `emit_unmapped_fallback` with `rawPath` set to the MetricFlow file path, `reason: "conversion_metric_unsupported"`, and `fallback: "flagged"`.
-When KTX SL gains conversion primitives, re-ingesting will find the prior wiki note (via `priorProvenance`) and replace it with an SL source.
+When ktx SL gains conversion primitives, re-ingesting will find the prior wiki note (via `priorProvenance`) and replace it with an SL source.
## Provenance markers
@@ -174,7 +174,7 @@ semantic_models:
```
```yaml
-# KTX overlay at /orders.yaml:
+# ktx overlay at /orders.yaml:
#
name: orders
descriptions:
@@ -217,7 +217,7 @@ metrics:
```
```yaml
-# KTX overlay at /orders_ext.yaml (one file; inheritance flattened):
+# ktx overlay at /orders_ext.yaml (one file; inheritance flattened):
#
#
#
@@ -256,7 +256,7 @@ metrics:
metrics: [{name: revenue}, {name: cost}]
```
-Because the WorkUnit bundles all three files (cross-component union via the metric), write the derived measure on ONE of the two sources - pick the source whose domain "owns" the metric (here, `sales` - margin is inherently a sales metric). Cross-source references aren't native in KTX SL; treat the metric's operands as already-resolvable in the target source's query context OR emit a standalone SQL that joins the two tables:
+Because the WorkUnit bundles all three files (cross-component union via the metric), write the derived measure on ONE of the two sources - pick the source whose domain "owns" the metric (here, `sales` - margin is inherently a sales metric). Cross-source references aren't native in ktx SL; treat the metric's operands as already-resolvable in the target source's query context OR emit a standalone SQL that joins the two tables:
```yaml
# /sales.yaml
diff --git a/packages/cli/src/skills/notion_synthesize/SKILL.md b/packages/cli/src/skills/notion_synthesize/SKILL.md
index 877b568b..b2d32fa9 100644
--- a/packages/cli/src/skills/notion_synthesize/SKILL.md
+++ b/packages/cli/src/skills/notion_synthesize/SKILL.md
@@ -1,6 +1,6 @@
---
name: notion_synthesize
-description: Synthesize durable KTX wiki pages and semantic-layer sources from staged Notion pages, databases, data-source rows, and clustered Notion evidence. Load when a WorkUnit contains Notion raw files or Notion evidence chunks.
+description: Synthesize durable ktx wiki pages and semantic-layer sources from staged Notion pages, databases, data-source rows, and clustered Notion evidence. Load when a WorkUnit contains Notion raw files or Notion evidence chunks.
callers: [memory_agent]
---
diff --git a/packages/cli/src/skills/sl/SKILL.md b/packages/cli/src/skills/sl/SKILL.md
index bb072e14..ea0e2dcf 100644
--- a/packages/cli/src/skills/sl/SKILL.md
+++ b/packages/cli/src/skills/sl/SKILL.md
@@ -1,11 +1,11 @@
---
name: sl
-description: KTX's semantic layer - a structured catalog of sources (tables/views), measures, joins, and segments expressed as YAML. Covers the schema and how to query it via `sl_query`. Use when the task involves querying pre-defined metrics (ARR, churn, retention, LTV, MAU) or reading SL source YAML to understand the catalog. Capture is handled by the `sl_capture` skill (memory-agent only).
+description: ktx's semantic layer - a structured catalog of sources (tables/views), measures, joins, and segments expressed as YAML. Covers the schema and how to query it via `sl_query`. Use when the task involves querying pre-defined metrics (ARR, churn, retention, LTV, MAU) or reading SL source YAML to understand the catalog. Capture is handled by the `sl_capture` skill (memory-agent only).
---
# Semantic Layer
-KTX's semantic layer (SL) is a structured catalog. Each **source** represents a table, a SQL view, or an overlay that enriches a manifest-backed table with measures, computed columns, joins, and named segments. The catalog is the single source of truth for reusable business metrics.
+ktx's semantic layer (SL) is a structured catalog. Each **source** represents a table, a SQL view, or an overlay that enriches a manifest-backed table with measures, computed columns, joins, and named segments. The catalog is the single source of truth for reusable business metrics.
This skill covers two parts:
- **Part 1** - Schema reference (what an SL source looks like).
diff --git a/packages/cli/src/skills/sl_capture/SKILL.md b/packages/cli/src/skills/sl_capture/SKILL.md
index 272f6860..b24ba810 100644
--- a/packages/cli/src/skills/sl_capture/SKILL.md
+++ b/packages/cli/src/skills/sl_capture/SKILL.md
@@ -1,6 +1,6 @@
---
name: sl_capture
-description: How to capture new reusable patterns into KTX's semantic layer - when a measure, segment, or join belongs in the catalog and how to write it generically so it stays small and useful over time. Loaded by the post-turn memory-agent only. The research agent does not write to the SL.
+description: How to capture new reusable patterns into ktx's semantic layer - when a measure, segment, or join belongs in the catalog and how to write it generically so it stays small and useful over time. Loaded by the post-turn memory-agent only. The research agent does not write to the SL.
callers: [memory_agent]
---
diff --git a/packages/cli/src/skills/wiki_capture/SKILL.md b/packages/cli/src/skills/wiki_capture/SKILL.md
index 831161c5..bf006dab 100644
--- a/packages/cli/src/skills/wiki_capture/SKILL.md
+++ b/packages/cli/src/skills/wiki_capture/SKILL.md
@@ -1,6 +1,6 @@
---
name: wiki_capture
-description: KTX's knowledge base - wiki pages for durable, reusable business knowledge. Covers capture workflow for user preferences, metric definitions, organizational conventions, and cross-references between wiki pages and semantic-layer sources. Loaded by the post-turn memory-agent only. The research agent reads wiki via `wiki_read`/`wiki_search` but does not write it.
+description: ktx's knowledge base - wiki pages for durable, reusable business knowledge. Covers capture workflow for user preferences, metric definitions, organizational conventions, and cross-references between wiki pages and semantic-layer sources. Loaded by the post-turn memory-agent only. The research agent reads wiki via `wiki_read`/`wiki_search` but does not write it.
callers: [memory_agent]
---
diff --git a/packages/cli/src/source-mapping.ts b/packages/cli/src/source-mapping.ts
index 5227ceab..e91e3906 100644
--- a/packages/cli/src/source-mapping.ts
+++ b/packages/cli/src/source-mapping.ts
@@ -54,9 +54,7 @@ async function createDefaultLookerClient(
return lookerCredentialsFromLocalConnection(lookerConnectionId, project.config.connections[lookerConnectionId]);
},
});
- return factory.createClient(connectionId) as unknown as Pick & {
- cleanup?(): Promise;
- };
+ return factory.createLookerClient(connectionId);
}
function isLookerConnection(project: KtxLocalProject, connectionId: string): boolean {
diff --git a/packages/cli/src/startup-profile.ts b/packages/cli/src/startup-profile.ts
index ccfde538..2702f706 100644
--- a/packages/cli/src/startup-profile.ts
+++ b/packages/cli/src/startup-profile.ts
@@ -39,7 +39,7 @@ export function installStartupProfileReporter(): void {
process.once('beforeExit', () => {
const total = now();
- process.stderr.write('\nKTX startup profile\n');
+ process.stderr.write('\nktx startup profile\n');
for (const event of events) {
const elapsed = event.at.toFixed(1).padStart(7);
if (event.duration === undefined) {
diff --git a/packages/cli/src/status-project.ts b/packages/cli/src/status-project.ts
index 569ec79f..3a9dc1ee 100644
--- a/packages/cli/src/status-project.ts
+++ b/packages/cli/src/status-project.ts
@@ -1141,7 +1141,7 @@ export function renderProjectStatus(status: ProjectStatus, options: RenderProjec
const lines: string[] = [];
const dirStr = abbreviateHome(status.projectDir, env);
- lines.push(`${bold('KTX status')} ${dim('·')} ${status.projectName} ${dim(`(${dirStr})`)}`);
+ lines.push(`${bold('ktx status')} ${dim('·')} ${status.projectName} ${dim(`(${dirStr})`)}`);
lines.push('');
const labelPad = 'Connections'.length;
diff --git a/packages/cli/src/text-ingest.ts b/packages/cli/src/text-ingest.ts
index 388e58d6..edb59923 100644
--- a/packages/cli/src/text-ingest.ts
+++ b/packages/cli/src/text-ingest.ts
@@ -298,7 +298,7 @@ export async function runKtxTextIngest(
const ingestInput: MemoryAgentInput = {
userId: args.userId,
chatId: `cli-text-ingest-${batchId}-${index + 1}`,
- userMessage: `Ingest external text artifact ${artifactReference(item.label)} into KTX memory.`,
+ userMessage: `Ingest external text artifact ${artifactReference(item.label)} into ktx memory.`,
assistantMessage: item.content.trim(),
...(args.connectionId ? { connectionId: args.connectionId } : {}),
sourceType: 'external_ingest',
diff --git a/packages/cli/test/admin.test.ts b/packages/cli/test/admin.test.ts
index 4f425e14..dc82c725 100644
--- a/packages/cli/test/admin.test.ts
+++ b/packages/cli/test/admin.test.ts
@@ -82,7 +82,7 @@ describe('admin Commander tree', () => {
try {
await expect(runKtxCli(['admin', 'init', projectDir], testIo.io)).resolves.toBe(0);
- expect(testIo.stdout()).toContain(`Initialized KTX project at ${projectDir}`);
+ expect(testIo.stdout()).toContain(`Initialized ktx project at ${projectDir}`);
await expect(readFile(join(projectDir, 'ktx.yaml'), 'utf-8')).resolves.not.toContain('project:');
expect(testIo.stderr()).toBe('');
} finally {
@@ -103,14 +103,14 @@ describe('admin Commander tree', () => {
runKtxCli(['--project-dir', projectDir, 'admin', 'init'], testIo.io),
).resolves.toBe(0);
- expect(testIo.stdout()).toContain(`Initialized KTX project at ${projectDir}`);
+ expect(testIo.stdout()).toContain(`Initialized ktx project at ${projectDir}`);
expect(testIo.stderr()).toBe('');
} finally {
await rm(tempDir, { recursive: true, force: true });
}
});
- it('prints config schema without requiring a KTX project directory', async () => {
+ it('prints config schema without requiring a ktx project directory', async () => {
const { mkdtemp, rm } = await import('node:fs/promises');
const { tmpdir } = await import('node:os');
const { join } = await import('node:path');
diff --git a/packages/cli/test/command-tree.test.ts b/packages/cli/test/command-tree.test.ts
index 2a9d4f87..592aae1b 100644
--- a/packages/cli/test/command-tree.test.ts
+++ b/packages/cli/test/command-tree.test.ts
@@ -47,7 +47,7 @@ describe('walkCommandTree', () => {
it('captures required, optional, and variadic arguments', () => {
const command = new Command('scan')
- .argument('', 'KTX connection id')
+ .argument('', 'ktx connection id')
.argument('[schemas...]', 'Schemas');
expect(walkCommandTree(command).arguments).toEqual(['', '[schemas...]']);
@@ -56,7 +56,7 @@ describe('walkCommandTree', () => {
it('walks registered commands without applying hidden-command policy', () => {
const root = new Command('ktx');
root.command('scan', { hidden: true }).description('Run a standalone connection scan');
- const ingest = root.command('ingest').description('Build or inspect KTX context');
+ const ingest = root.command('ingest').description('Build or inspect ktx context');
ingest.command('run', { hidden: true }).description('Run local ingest by adapter');
ingest.command('watch', { hidden: true }).description('Open a stored visual report');
ingest.command('status').description('Print status');
diff --git a/packages/cli/test/commands/mcp-commands.test.ts b/packages/cli/test/commands/mcp-commands.test.ts
index cf9c0cd5..4827c4e6 100644
--- a/packages/cli/test/commands/mcp-commands.test.ts
+++ b/packages/cli/test/commands/mcp-commands.test.ts
@@ -51,7 +51,7 @@ describe('registerMcpCommands', () => {
registerMcpCommands(program, context);
await expect(program.parseAsync(['mcp', 'start', '--host', '0.0.0.0'], { from: 'user' })).rejects.toThrow(
- 'Binding KTX MCP to 0.0.0.0 requires --token or KTX_MCP_TOKEN',
+ 'Binding ktx MCP to 0.0.0.0 requires --token or KTX_MCP_TOKEN',
);
expect(startDaemon).not.toHaveBeenCalled();
});
@@ -80,11 +80,11 @@ describe('registerMcpCommands', () => {
expect(startDaemon).toHaveBeenCalledTimes(1);
expect(context.io.stdout.write).toHaveBeenCalledWith(
[
- 'KTX MCP daemon already running: http://127.0.0.1:7878/mcp',
+ 'ktx MCP daemon already running: http://127.0.0.1:7878/mcp',
'',
- 'KTX is ready for configured agents.',
- 'Open your agent for this KTX project and ask a data question, for example:',
- ' "Use KTX to show me the available tables and metrics."',
+ 'ktx is ready for configured agents.',
+ 'Open your agent for this ktx project and ask a data question, for example:',
+ ' "Use ktx to show me the available tables and metrics."',
'',
].join('\n'),
);
@@ -112,10 +112,10 @@ describe('registerMcpCommands', () => {
await program.parseAsync(['--project-dir', '/tmp/ktx-started', 'mcp', 'start'], { from: 'user' });
expect(context.io.stdout.write).toHaveBeenCalledWith(
- expect.stringContaining('KTX MCP daemon started: http://127.0.0.1:7878/mcp\n\nKTX is ready for configured agents.'),
+ expect.stringContaining('ktx MCP daemon started: http://127.0.0.1:7878/mcp\n\nktx is ready for configured agents.'),
);
expect(context.io.stdout.write).toHaveBeenCalledWith(
- expect.stringContaining('"Use KTX to show me the available tables and metrics."'),
+ expect.stringContaining('"Use ktx to show me the available tables and metrics."'),
);
});
diff --git a/packages/cli/test/connectors/clickhouse/dialect.test.ts b/packages/cli/test/connectors/clickhouse/dialect.test.ts
index 809b1304..389cd2eb 100644
--- a/packages/cli/test/connectors/clickhouse/dialect.test.ts
+++ b/packages/cli/test/connectors/clickhouse/dialect.test.ts
@@ -13,7 +13,7 @@ describe('KtxClickHouseDialect', () => {
expect(dialect.formatTableName({ catalog: null, db: null, name: 'events' })).toBe('`events`');
});
- it('maps nullable and low-cardinality ClickHouse types to KTX dimension types', () => {
+ it('maps nullable and low-cardinality ClickHouse types to ktx dimension types', () => {
expect(dialect.mapToDimensionType('Nullable(DateTime64(3))')).toBe('time');
expect(dialect.mapToDimensionType('LowCardinality(Nullable(String))')).toBe('string');
expect(dialect.mapToDimensionType('UInt64')).toBe('number');
diff --git a/packages/cli/test/connectors/mysql/dialect.test.ts b/packages/cli/test/connectors/mysql/dialect.test.ts
index 26fade92..3f4dc8ab 100644
--- a/packages/cli/test/connectors/mysql/dialect.test.ts
+++ b/packages/cli/test/connectors/mysql/dialect.test.ts
@@ -13,7 +13,7 @@ describe('KtxMysqlDialect', () => {
expect(dialect.formatTableName({ catalog: null, db: null, name: 'orders' })).toBe('`orders`');
});
- it('maps native MySQL types to KTX dimension types', () => {
+ it('maps native MySQL types to ktx dimension types', () => {
expect(dialect.mapToDimensionType('tinyint(1)')).toBe('boolean');
expect(dialect.mapToDimensionType('int')).toBe('number');
expect(dialect.mapToDimensionType('decimal(10,2)')).toBe('number');
diff --git a/packages/cli/test/connectors/postgres/dialect.test.ts b/packages/cli/test/connectors/postgres/dialect.test.ts
index 1a1d4768..76f5cccb 100644
--- a/packages/cli/test/connectors/postgres/dialect.test.ts
+++ b/packages/cli/test/connectors/postgres/dialect.test.ts
@@ -10,7 +10,7 @@ describe('KtxPostgresDialect', () => {
expect(dialect.formatTableName({ catalog: null, db: null, name: 'orders' })).toBe('"orders"');
});
- it('maps native PostgreSQL types to KTX dimension types', () => {
+ it('maps native PostgreSQL types to ktx dimension types', () => {
expect(dialect.mapToDimensionType('timestamp with time zone')).toBe('time');
expect(dialect.mapToDimensionType('numeric(12,2)')).toBe('number');
expect(dialect.mapToDimensionType('uuid')).toBe('string');
diff --git a/packages/cli/test/connectors/sqlite/dialect.test.ts b/packages/cli/test/connectors/sqlite/dialect.test.ts
index 879d133c..e14cfe23 100644
--- a/packages/cli/test/connectors/sqlite/dialect.test.ts
+++ b/packages/cli/test/connectors/sqlite/dialect.test.ts
@@ -10,7 +10,7 @@ describe('KtxSqliteDialect', () => {
expect(dialect.formatTableName({ catalog: 'ignored', db: 'ignored', name: 'orders' })).toBe('"orders"');
});
- it('maps native SQLite types to KTX dimension types', () => {
+ it('maps native SQLite types to ktx dimension types', () => {
expect(dialect.mapToDimensionType('INTEGER')).toBe('number');
expect(dialect.mapToDimensionType('numeric(10,2)')).toBe('number');
expect(dialect.mapToDimensionType('timestamp')).toBe('time');
diff --git a/packages/cli/test/connectors/sqlserver/dialect.test.ts b/packages/cli/test/connectors/sqlserver/dialect.test.ts
index f019991c..ee099f00 100644
--- a/packages/cli/test/connectors/sqlserver/dialect.test.ts
+++ b/packages/cli/test/connectors/sqlserver/dialect.test.ts
@@ -13,7 +13,7 @@ describe('KtxSqlServerDialect', () => {
expect(dialect.formatTableName({ catalog: null, db: null, name: 'events' })).toBe('[events]');
});
- it('maps SQL Server types to KTX dimension types', () => {
+ it('maps SQL Server types to ktx dimension types', () => {
expect(dialect.mapToDimensionType('datetime2')).toBe('time');
expect(dialect.mapToDimensionType('decimal(18, 2)')).toBe('number');
expect(dialect.mapToDimensionType('bigint')).toBe('number');
diff --git a/packages/cli/test/context-build-view.test.ts b/packages/cli/test/context-build-view.test.ts
index ad3a54cc..5d1cb892 100644
--- a/packages/cli/test/context-build-view.test.ts
+++ b/packages/cli/test/context-build-view.test.ts
@@ -98,7 +98,7 @@ describe('extractProgressMessage', () => {
});
it('returns null for non-progress output', () => {
- expect(extractProgressMessage('KTX scan completed\n')).toBeNull();
+ expect(extractProgressMessage('ktx scan completed\n')).toBeNull();
});
});
@@ -165,7 +165,7 @@ describe('renderContextBuildView', () => {
]);
const output = renderContextBuildView(state, { styled: false });
- expect(output).toContain('Building KTX context');
+ expect(output).toContain('Building ktx context');
expect(output).toContain('(0/2)');
expect(output).toContain('○');
expect(output).toContain('Databases:');
@@ -271,7 +271,7 @@ describe('renderContextBuildView', () => {
const output = renderContextBuildView(state, { styled: false });
const lines = output.split('\n');
- const headerLine = lines.find((l) => l.includes('Building KTX context'))!;
+ const headerLine = lines.find((l) => l.includes('Building ktx context'))!;
const separatorLine = lines.find((l) => /^─+$/.test(l))!;
expect(separatorLine.length).toBeGreaterThanOrEqual(headerLine.length);
});
@@ -394,11 +394,11 @@ describe('renderContextBuildView', () => {
{ connectionId: 'warehouse', driver: 'postgres', operation: 'database-ingest', debugCommand: '', steps: ['database-schema'] },
]);
state.primarySources[0].status = 'failed';
- state.primarySources[0].failureText = 'KTX lost its connection to PostgreSQL while reading schema for warehouse.';
+ state.primarySources[0].failureText = 'ktx lost its connection to PostgreSQL while reading schema for warehouse.';
const output = renderContextBuildView(state, { styled: false });
expect(output).toContain('✗');
- expect(output).toContain('KTX lost its connection to PostgreSQL while reading schema for warehouse.');
+ expect(output).toContain('ktx lost its connection to PostgreSQL while reading schema for warehouse.');
});
it('omits empty groups', () => {
@@ -897,7 +897,7 @@ describe('runContextBuild', () => {
);
expect(result).toEqual({ exitCode: 1 });
- expect(io.stdout()).toContain('KTX lost its connection to PostgreSQL while reading schema for warehouse.');
+ expect(io.stdout()).toContain('ktx lost its connection to PostgreSQL while reading schema for warehouse.');
expect(io.stdout()).toContain('network address unavailable (EADDRNOTAVAIL)');
expect(io.stdout()).toContain('Retry: ktx setup --project-dir /tmp/project');
expect(io.stdout()).not.toContain('BoundPool');
@@ -931,11 +931,11 @@ describe('runContextBuild', () => {
expect(result).toEqual({ exitCode: 1 });
expect(io.stdout()).toContain(
- 'KTX could not reach the local SQL analysis runtime while processing query history for warehouse.',
+ 'ktx could not reach the local SQL analysis runtime while processing query history for warehouse.',
);
expect(io.stdout()).toContain('connection refused (ECONNREFUSED)');
expect(io.stdout()).toContain('Retry: ktx setup --project-dir /tmp/project');
- expect(io.stdout()).not.toContain('KTX lost its connection to PostgreSQL');
+ expect(io.stdout()).not.toContain('ktx lost its connection to PostgreSQL');
});
it('uses captured query-history stderr instead of generic failed-at detail', async () => {
@@ -944,11 +944,11 @@ describe('runContextBuild', () => {
warehouse: { driver: 'postgres', context: { queryHistory: { enabled: true } } },
});
const executeTarget = vi.fn(async (target, _args, targetIo) => {
- targetIo.stdout.write('KTX scan completed\n');
+ targetIo.stdout.write('ktx scan completed\n');
targetIo.stdout.write('Mode: enriched\n');
targetIo.stderr.write('Missing bundled Python runtime manifest: /tmp/assets/python/manifest.json\n');
targetIo.stderr.write('In a source checkout, build the local runtime assets with: pnpm run artifacts:build\n');
- targetIo.stderr.write('Then retry the runtime-backed KTX command.\n');
+ targetIo.stderr.write('Then retry the runtime-backed ktx command.\n');
return {
connectionId: target.connectionId,
driver: target.driver,
@@ -976,7 +976,7 @@ describe('runContextBuild', () => {
expect(result).toEqual({ exitCode: 1 });
expect(io.stdout()).toContain('Missing bundled Python runtime manifest: /tmp/assets/python/manifest.json.');
expect(io.stdout()).toContain('Retry: ktx ingest warehouse --project-dir /tmp/project --query-history');
- expect(io.stdout()).not.toContain('Then retry the runtime-backed KTX command');
+ expect(io.stdout()).not.toContain('Then retry the runtime-backed ktx command');
expect(io.stdout()).not.toContain('warehouse failed at query-history');
expect(io.stdout().match(/Retry: /g)).toHaveLength(1);
});
@@ -999,7 +999,7 @@ describe('runContextBuild', () => {
);
expect(result).toEqual({ exitCode: 1 });
- expect(io.stdout()).toContain('KTX lost its connection to PostgreSQL while reading schema for warehouse.');
+ expect(io.stdout()).toContain('ktx lost its connection to PostgreSQL while reading schema for warehouse.');
expect(io.stdout()).toContain('connection reset (ECONNRESET)');
});
@@ -1149,7 +1149,7 @@ describe('runContextBuild', () => {
);
const output = io.stdout();
- expect(output).toContain('Building KTX context');
+ expect(output).toContain('Building ktx context');
expect(output).toContain('Project: /tmp/project');
expect(output).toContain('Databases:');
expect(output).toContain('warehouse');
@@ -1397,7 +1397,7 @@ describe('viewStateFromSourceProgress', () => {
);
const output = renderContextBuildView(state, { styled: false });
- expect(output).toContain('Building KTX context');
+ expect(output).toContain('Building ktx context');
expect(output).toContain('Databases:');
expect(output).toContain('warehouse');
expect(output).toContain('42 tables');
diff --git a/packages/cli/test/context/core/config-reference.test.ts b/packages/cli/test/context/core/config-reference.test.ts
index c4b7c848..d7871cc7 100644
--- a/packages/cli/test/context/core/config-reference.test.ts
+++ b/packages/cli/test/context/core/config-reference.test.ts
@@ -4,7 +4,7 @@ import { join } from 'node:path';
import { describe, expect, it } from 'vitest';
import { resolveKtxConfigReference, resolveKtxHomePath } from '../../../src/context/core/config-reference.js';
-describe('KTX config references', () => {
+describe('ktx config references', () => {
it('resolves env references without returning empty values', () => {
expect(resolveKtxConfigReference('env:AI_GATEWAY_API_KEY', { AI_GATEWAY_API_KEY: ' gateway-key ' })).toBe(
'gateway-key',
diff --git a/packages/cli/test/context/ingest/adapters/historic-sql/local-ingest-acceptance.test.ts b/packages/cli/test/context/ingest/adapters/historic-sql/local-ingest-acceptance.test.ts
index f3d70c0f..ce7b4a8c 100644
--- a/packages/cli/test/context/ingest/adapters/historic-sql/local-ingest-acceptance.test.ts
+++ b/packages/cli/test/context/ingest/adapters/historic-sql/local-ingest-acceptance.test.ts
@@ -165,7 +165,7 @@ async function writeHistoricSqlProject(project: KtxLocalProject): Promise',
+ ' author: ktx Test ',
'',
].join('\n'),
'utf-8',
@@ -193,7 +193,7 @@ async function writeHistoricSqlProject(project: KtxLocalProject): Promise {
- it('resolves credentials by Looker connection id and creates a KTX Looker client', async () => {
+ it('resolves credentials by Looker connection id and creates a ktx Looker client', async () => {
const fakeSdk = sdk();
const resolver: LookerCredentialResolver = {
resolve: vi.fn().mockResolvedValue({
diff --git a/packages/cli/test/context/ingest/adapters/looker/mapping.test.ts b/packages/cli/test/context/ingest/adapters/looker/mapping.test.ts
index 0ac9c067..a5186a75 100644
--- a/packages/cli/test/context/ingest/adapters/looker/mapping.test.ts
+++ b/packages/cli/test/context/ingest/adapters/looker/mapping.test.ts
@@ -69,7 +69,7 @@ describe('discoverLookerConnections', () => {
});
describe('looker dialect and target validation helpers', () => {
- it('maps Looker dialect names to KTX connection types', () => {
+ it('maps Looker dialect names to ktx connection types', () => {
expect(lookerDialectToConnectionType('bigquery_standard_sql')).toBe('BIGQUERY');
expect(lookerDialectToConnectionType('postgres')).toBe('POSTGRESQL');
expect(lookerDialectToConnectionType('mssql')).toBeNull();
@@ -224,7 +224,7 @@ describe('computeLookerMappingDrift and validateLookerMappings', () => {
).toEqual({
ok: false,
errors: [
- { key: 'b2b_sandbox_bq', reason: 'KTX connection missing does not exist' },
+ { key: 'b2b_sandbox_bq', reason: 'ktx connection missing does not exist' },
{
key: 'pg_runtime',
reason: 'Connection type LOOKER cannot be used as a Looker warehouse mapping target',
@@ -259,7 +259,7 @@ describe('collectExploreParseItems and projectParsedIdentifier', () => {
});
});
- it('projects successful and failed parser rows into KTX parsed target tables', () => {
+ it('projects successful and failed parser rows into ktx parsed target tables', () => {
expect(
projectParsedIdentifier({
ok: true,
diff --git a/packages/cli/test/context/ingest/adapters/looker/types.test.ts b/packages/cli/test/context/ingest/adapters/looker/types.test.ts
index 113f9fe3..9393691c 100644
--- a/packages/cli/test/context/ingest/adapters/looker/types.test.ts
+++ b/packages/cli/test/context/ingest/adapters/looker/types.test.ts
@@ -255,7 +255,7 @@ describe('Looker staged runtime schemas', () => {
});
});
- it('accepts slug-shaped connection ids inside KTX Looker runtime schemas', () => {
+ it('accepts slug-shaped connection ids inside ktx Looker runtime schemas', () => {
const parsedTargetTable = {
ok: true as const,
catalog: 'proj',
@@ -313,7 +313,7 @@ describe('Looker staged runtime schemas', () => {
});
});
- it('rejects unsafe KTX Looker connection ids', () => {
+ it('rejects unsafe ktx Looker connection ids', () => {
expect(() =>
parseLookerPullConfig({
lookerConnectionId: '../prod-looker',
diff --git a/packages/cli/test/context/ingest/adapters/metabase/client-boundary.test.ts b/packages/cli/test/context/ingest/adapters/metabase/client-boundary.test.ts
index 7e8a0e2e..4cce82e0 100644
--- a/packages/cli/test/context/ingest/adapters/metabase/client-boundary.test.ts
+++ b/packages/cli/test/context/ingest/adapters/metabase/client-boundary.test.ts
@@ -9,8 +9,8 @@ async function readMetabaseFile(name: string): Promise {
return readFile(join(metabaseDir, name), 'utf-8');
}
-describe('KTX Metabase client boundary', () => {
- it('keeps NestJS, server data-source base classes, and server-relative imports out of the KTX client', async () => {
+describe('ktx Metabase client boundary', () => {
+ it('keeps NestJS, server data-source base classes, and server-relative imports out of the ktx client', async () => {
const client = await readMetabaseFile('client.ts');
expect(client).not.toContain(`@${'nestjs'}`);
expect(client).not.toContain(`DataSource${'Client'}`);
@@ -19,7 +19,7 @@ describe('KTX Metabase client boundary', () => {
expect(client).not.toContain('../../types/brand');
});
- it('keeps proxy implementation code out of the KTX v1 client', async () => {
+ it('keeps proxy implementation code out of the ktx v1 client', async () => {
const client = await readMetabaseFile('client.ts');
expect(client).not.toContain(`network-${'proxy'}`);
expect(client).not.toContain(`ssh${'2'}`);
diff --git a/packages/cli/test/context/ingest/adapters/metabase/client.test.ts b/packages/cli/test/context/ingest/adapters/metabase/client.test.ts
index 5ab2fd09..a78dbe6a 100644
--- a/packages/cli/test/context/ingest/adapters/metabase/client.test.ts
+++ b/packages/cli/test/context/ingest/adapters/metabase/client.test.ts
@@ -232,7 +232,7 @@ describe('MetabaseClient admin auth helpers', () => {
);
await expect(client.getPermissionGroups()).resolves.toEqual([{ id: 2, name: 'Administrators' }]);
- await expect(client.createApiKey({ name: 'KTX CLI test', groupId: 2 })).resolves.toBe(mintedMetabaseCredential);
+ await expect(client.createApiKey({ name: 'ktx CLI test', groupId: 2 })).resolves.toBe(mintedMetabaseCredential);
expect(fetchMock).toHaveBeenNthCalledWith(
1,
@@ -247,7 +247,7 @@ describe('MetabaseClient admin auth helpers', () => {
'https://metabase.example.test/api/api-key',
expect.objectContaining({
method: 'POST',
- body: JSON.stringify({ name: 'KTX CLI test', group_id: 2 }),
+ body: JSON.stringify({ name: 'ktx CLI test', group_id: 2 }),
}),
);
});
diff --git a/packages/cli/test/context/ingest/adapters/metabase/local-metabase.adapter.test.ts b/packages/cli/test/context/ingest/adapters/metabase/local-metabase.adapter.test.ts
index 1f860557..0b9f4d97 100644
--- a/packages/cli/test/context/ingest/adapters/metabase/local-metabase.adapter.test.ts
+++ b/packages/cli/test/context/ingest/adapters/metabase/local-metabase.adapter.test.ts
@@ -57,7 +57,7 @@ describe('metabaseRuntimeConfigFromLocalConnection', () => {
};
expect(() => metabaseRuntimeConfigFromLocalConnection('prod-metabase', connection)).toThrow(
- 'Standalone KTX does not support proxy-bearing Metabase connections yet',
+ 'Standalone ktx does not support proxy-bearing Metabase connections yet',
);
});
diff --git a/packages/cli/test/context/ingest/adapters/metabase/mapping.test.ts b/packages/cli/test/context/ingest/adapters/metabase/mapping.test.ts
index b6f1f354..3fb56442 100644
--- a/packages/cli/test/context/ingest/adapters/metabase/mapping.test.ts
+++ b/packages/cli/test/context/ingest/adapters/metabase/mapping.test.ts
@@ -87,7 +87,7 @@ describe('validateMetabaseMappings', () => {
}),
).toEqual({
ok: false,
- errors: [{ key: '2', reason: 'KTX connection missing-target does not exist' }],
+ errors: [{ key: '2', reason: 'ktx connection missing-target does not exist' }],
});
});
});
@@ -149,7 +149,7 @@ describe('validateMappingPhysicalMatch', () => {
).toBeNull();
});
- it('returns null for unknown engines because KTX cannot validate them', () => {
+ it('returns null for unknown engines because ktx cannot validate them', () => {
expect(
validateMappingPhysicalMatch(
{ metabaseEngine: 'unknown-engine', metabaseDbName: 'X', metabaseHost: 'host' },
@@ -177,7 +177,7 @@ describe('computeMetabaseMappingPhysicalMismatches', () => {
).toEqual([
{
mappingId: 'mapping-bad',
- reason: "Metabase database 'app' does not match KTX connection database 'other_app'",
+ reason: "Metabase database 'app' does not match ktx connection database 'other_app'",
},
]);
});
@@ -216,7 +216,7 @@ describe('refreshMetabaseMapping', () => {
physicalMismatches: [
{
mappingId: '2',
- reason: "Metabase database 'analytics' does not match KTX connection database 'wrong_database'",
+ reason: "Metabase database 'analytics' does not match ktx connection database 'wrong_database'",
},
],
});
@@ -282,7 +282,7 @@ describe('findBestMatch', () => {
});
describe('METABASE_ENGINE_TO_CONNECTION_TYPE', () => {
- it('keeps the server-supported Metabase engine table in KTX', () => {
+ it('keeps the server-supported Metabase engine table in ktx', () => {
expect(METABASE_ENGINE_TO_CONNECTION_TYPE).toMatchObject({
postgres: 'POSTGRESQL',
bigquery: 'BIGQUERY',
diff --git a/packages/cli/test/context/ingest/ingest-bundle.runner.isolated-diff.test.ts b/packages/cli/test/context/ingest/ingest-bundle.runner.isolated-diff.test.ts
index f5d5822b..55e1bc08 100644
--- a/packages/cli/test/context/ingest/ingest-bundle.runner.isolated-diff.test.ts
+++ b/packages/cli/test/context/ingest/ingest-bundle.runner.isolated-diff.test.ts
@@ -213,7 +213,7 @@ function makeDeps(
lockingService: { withLock: vi.fn(async (_key, fn) => fn()) },
storage: {
homeDir: join(runtime.configDir, '.ktx'),
- systemGitAuthor: { name: 'KTX Test', email: 'system@ktx.local' },
+ systemGitAuthor: { name: 'ktx Test', email: 'system@ktx.local' },
resolveUploadDir: (id) => join(runtime.homeDir, 'upload', id),
resolvePullDir: (id) => join(runtime.homeDir, 'pull', id),
resolveTranscriptDir: (id) => join(runtime.configDir, '.ktx/ingest-transcripts', id),
@@ -308,7 +308,7 @@ describe('IngestBundleRunner isolated diff path', () => {
await currentSession.gitService.commitFiles(
['wiki/global/custom-isolated.md'],
'custom wiki',
- 'KTX Test',
+ 'ktx Test',
'system@ktx.local',
);
return { stopReason: 'natural' };
@@ -395,7 +395,7 @@ describe('IngestBundleRunner isolated diff path', () => {
await currentSession.gitService.commitFiles(
['wiki/global/legacy-isolated.md'],
'legacy isolated wiki',
- 'KTX Test',
+ 'ktx Test',
'system@ktx.local',
);
return { stopReason: 'natural' };
@@ -486,7 +486,7 @@ describe('IngestBundleRunner isolated diff path', () => {
await currentSession.gitService.commitFiles(
['semantic-layer/warehouse/good.yaml'],
'test: add good source',
- 'KTX Test',
+ 'ktx Test',
'system@ktx.local',
);
}
@@ -504,7 +504,7 @@ describe('IngestBundleRunner isolated diff path', () => {
await currentSession.gitService.commitFiles(
['semantic-layer/warehouse/bad.yaml'],
'test: add bad source',
- 'KTX Test',
+ 'ktx Test',
'system@ktx.local',
);
}
@@ -606,7 +606,7 @@ describe('IngestBundleRunner isolated diff path', () => {
await currentSession.gitService.commitFiles(
[`wiki/global/${sourceKey}-isolated.md`],
`${sourceKey} wiki`,
- 'KTX Test',
+ 'ktx Test',
'system@ktx.local',
);
return { stopReason: 'natural' };
@@ -682,7 +682,7 @@ describe('IngestBundleRunner isolated diff path', () => {
'---\nsummary: Account segments\nusage_mode: auto\nsl_refs:\n - mart_account_segments\n---\n\nARR is `mart_account_segments.total_contract_arr_cents`.\n',
);
currentSession.actions.push({ target: 'wiki', type: 'created', key: 'account-segments', detail: 'Account segments' });
- await currentSession.gitService.commitFiles(['wiki/global/account-segments.md'], 'wu wiki', 'KTX Test', 'system@ktx.local');
+ await currentSession.gitService.commitFiles(['wiki/global/account-segments.md'], 'wu wiki', 'ktx Test', 'system@ktx.local');
}
if (params.telemetryTags.unitKey === 'card-source') {
await writeFile(
@@ -697,7 +697,7 @@ describe('IngestBundleRunner isolated diff path', () => {
detail: 'Dollar measure',
targetConnectionId: 'warehouse',
});
- await currentSession.gitService.commitFiles(['semantic-layer/warehouse/mart_account_segments.yaml'], 'wu source', 'KTX Test', 'system@ktx.local');
+ await currentSession.gitService.commitFiles(['semantic-layer/warehouse/mart_account_segments.yaml'], 'wu source', 'ktx Test', 'system@ktx.local');
}
return { stopReason: 'natural' };
}) as never;
@@ -740,7 +740,7 @@ describe('IngestBundleRunner isolated diff path', () => {
await runtime.git.commitFiles(
['semantic-layer/warehouse/mart_account_segments.yaml', 'wiki/global/account-segments.md'],
'seed existing wiki body ref',
- 'KTX Test',
+ 'ktx Test',
'system@ktx.local',
);
const preRunHead = await runtime.git.revParseHead();
@@ -773,7 +773,7 @@ describe('IngestBundleRunner isolated diff path', () => {
await currentSession.gitService.commitFiles(
['semantic-layer/warehouse/mart_account_segments.yaml'],
'wu source rename',
- 'KTX Test',
+ 'ktx Test',
'system@ktx.local',
);
return { stopReason: 'natural' };
@@ -903,7 +903,7 @@ describe('IngestBundleRunner isolated diff path', () => {
await mkdir(join(root, 'wiki/global'), { recursive: true });
await writeFile(join(root, `wiki/global/${unitKey}.md`), `---\nsummary: ${unitKey}\nusage_mode: auto\n---\n\n${unitKey}\n`);
currentSession.actions.push({ target: 'wiki', type: 'created', key: unitKey, detail: unitKey });
- await currentSession.gitService.commitFiles([`wiki/global/${unitKey}.md`], `wu ${unitKey}`, 'KTX Test', 'system@ktx.local');
+ await currentSession.gitService.commitFiles([`wiki/global/${unitKey}.md`], `wu ${unitKey}`, 'ktx Test', 'system@ktx.local');
return { stopReason: 'natural' };
}) as never;
const runner = new IngestBundleRunner(deps);
@@ -950,7 +950,7 @@ describe('IngestBundleRunner isolated diff path', () => {
);
addTouchedSlSource(currentSession.touchedSlSources, 'warehouse', 'orders');
currentSession.actions.push({ target: 'sl', type: 'updated', key: 'orders', detail: suffix, targetConnectionId: 'warehouse' });
- await currentSession.gitService.commitFiles(['semantic-layer/warehouse/orders.yaml'], `wu ${suffix}`, 'KTX Test', 'system@ktx.local');
+ await currentSession.gitService.commitFiles(['semantic-layer/warehouse/orders.yaml'], `wu ${suffix}`, 'ktx Test', 'system@ktx.local');
return { stopReason: 'natural' };
}) as never;
const runner = new IngestBundleRunner(deps);
@@ -1006,7 +1006,7 @@ describe('IngestBundleRunner isolated diff path', () => {
'---\nsummary: Projected orders\nusage_mode: auto\nsl_refs:\n - mart_account_segments\n---\n\nARR `mart_account_segments.total_contract_arr`.\n',
);
currentSession.actions.push({ target: 'wiki', type: 'created', key: 'projected-orders', detail: 'Projected orders' });
- await currentSession.gitService.commitFiles(['wiki/global/projected-orders.md'], 'wu projected wiki', 'KTX Test', 'system@ktx.local');
+ await currentSession.gitService.commitFiles(['wiki/global/projected-orders.md'], 'wu projected wiki', 'ktx Test', 'system@ktx.local');
return { stopReason: 'natural' };
}) as never;
const runner = new IngestBundleRunner(deps);
@@ -1042,7 +1042,7 @@ describe('IngestBundleRunner isolated diff path', () => {
await mkdir(join(root, 'wiki/global'), { recursive: true });
await writeFile(join(root, 'wiki/global/notion-page.md'), '---\nsummary: Notion page\nusage_mode: auto\nsl_refs:\n - missing_source\n---\n\nBody\n');
currentSession.actions.push({ target: 'wiki', type: 'created', key: 'notion-page', detail: 'Notion page' });
- await currentSession.gitService.commitFiles(['wiki/global/notion-page.md'], 'wu notion', 'KTX Test', 'system@ktx.local');
+ await currentSession.gitService.commitFiles(['wiki/global/notion-page.md'], 'wu notion', 'ktx Test', 'system@ktx.local');
return { stopReason: 'natural' };
}) as never;
const runner = new IngestBundleRunner(deps);
@@ -1088,7 +1088,7 @@ describe('IngestBundleRunner isolated diff path', () => {
await currentSession.gitService.commitFiles(
['semantic-layer/warehouse/mart_account_segments.yaml'],
'wu source',
- 'KTX Test',
+ 'ktx Test',
'system@ktx.local',
);
} else {
@@ -1104,7 +1104,7 @@ describe('IngestBundleRunner isolated diff path', () => {
detail: 'Stale reconcile wiki page',
rawPaths: ['cards/source.json'],
});
- await currentSession.gitService.commitFiles(['wiki/global/account-segments.md'], 'reconcile wiki', 'KTX Test', 'system@ktx.local');
+ await currentSession.gitService.commitFiles(['wiki/global/account-segments.md'], 'reconcile wiki', 'ktx Test', 'system@ktx.local');
}
return { stopReason: 'natural' };
}) as never;
@@ -1167,7 +1167,7 @@ describe('IngestBundleRunner isolated diff path', () => {
detail: 'Account segments',
rawPaths: ['cards/wiki.json'],
});
- await currentSession.gitService.commitFiles(['wiki/global/account-segments.md'], 'wu wiki', 'KTX Test', 'system@ktx.local');
+ await currentSession.gitService.commitFiles(['wiki/global/account-segments.md'], 'wu wiki', 'ktx Test', 'system@ktx.local');
}
if (params.telemetryTags.unitKey === 'card-source') {
await mkdir(join(root, 'semantic-layer/warehouse'), { recursive: true });
@@ -1187,7 +1187,7 @@ describe('IngestBundleRunner isolated diff path', () => {
await currentSession.gitService.commitFiles(
['semantic-layer/warehouse/mart_account_segments.yaml'],
'wu source',
- 'KTX Test',
+ 'ktx Test',
'system@ktx.local',
);
}
@@ -1302,7 +1302,7 @@ describe('IngestBundleRunner isolated diff path', () => {
await currentSession.gitService.commitFiles(
['semantic-layer/warehouse/mart_account_segments.yaml', 'wiki/global/account-segments.md'],
'valid artifacts with invalid provenance',
- 'KTX Test',
+ 'ktx Test',
'system@ktx.local',
);
return { stopReason: 'natural' };
@@ -1444,7 +1444,7 @@ describe('IngestBundleRunner isolated diff path', () => {
'name: orders\ngrain: [id]\ncolumns: [{name: id, type: string}]\njoins: []\nmeasures: []\n',
);
currentSession.actions.push({ target: 'sl', type: 'created', key: 'orders', detail: 'forbidden', targetConnectionId: 'warehouse' });
- await currentSession.gitService.commitFiles(['semantic-layer/warehouse/orders.yaml'], 'forbidden sl', 'KTX Test', 'system@ktx.local');
+ await currentSession.gitService.commitFiles(['semantic-layer/warehouse/orders.yaml'], 'forbidden sl', 'ktx Test', 'system@ktx.local');
return { stopReason: 'natural' };
}) as never;
const runner = new IngestBundleRunner(deps);
@@ -1469,7 +1469,7 @@ describe('IngestBundleRunner isolated diff path', () => {
join(runtime.configDir, 'wiki/global/source-page.md'),
'---\nsummary: Source page\nusage_mode: auto\n---\n\nSource page\n',
);
- await runtime.git.commitFiles(['wiki/global/source-page.md'], 'seed source page', 'KTX Test', 'system@ktx.local');
+ await runtime.git.commitFiles(['wiki/global/source-page.md'], 'seed source page', 'ktx Test', 'system@ktx.local');
const preRunHead = await runtime.git.revParseHead();
const { deps, adapter } = makeDeps(runtime);
adapter.chunk.mockResolvedValue({
@@ -1501,7 +1501,7 @@ describe('IngestBundleRunner isolated diff path', () => {
await currentSession.gitService.commitFiles(
['wiki/global/account-segments.md'],
'wu page ref',
- 'KTX Test',
+ 'ktx Test',
'system@ktx.local',
);
}
@@ -1517,7 +1517,7 @@ describe('IngestBundleRunner isolated diff path', () => {
await currentSession.gitService.commitFiles(
['wiki/global/source-page.md'],
'wu delete source page',
- 'KTX Test',
+ 'ktx Test',
'system@ktx.local',
);
}
@@ -1582,7 +1582,7 @@ describe('IngestBundleRunner isolated diff path', () => {
await runtime.git.commitFiles(
['wiki/global/source-page.md', 'wiki/global/account-segments.md'],
'seed inbound wiki refs',
- 'KTX Test',
+ 'ktx Test',
'system@ktx.local',
);
const preRunHead = await runtime.git.revParseHead();
@@ -1613,7 +1613,7 @@ describe('IngestBundleRunner isolated diff path', () => {
await currentSession.gitService.commitFiles(
['wiki/global/source-page.md'],
'wu delete target page',
- 'KTX Test',
+ 'ktx Test',
'system@ktx.local',
);
return { stopReason: 'natural' };
@@ -1751,7 +1751,7 @@ describe('IngestBundleRunner isolated diff path', () => {
await currentSession.gitService.commitFiles(
['semantic-layer/finance/orders.yaml'],
'wu unauthorized target',
- 'KTX Test',
+ 'ktx Test',
'system@ktx.local',
);
return { stopReason: 'natural' };
@@ -1822,7 +1822,7 @@ describe('IngestBundleRunner isolated diff path', () => {
detail: 'Valid page',
rawPaths: ['pages/source.json'],
});
- await currentSession.gitService.commitFiles(['wiki/global/valid-page.md'], 'wu valid page', 'KTX Test', 'system@ktx.local');
+ await currentSession.gitService.commitFiles(['wiki/global/valid-page.md'], 'wu valid page', 'ktx Test', 'system@ktx.local');
} else {
await mkdir(join(root, 'semantic-layer/finance'), { recursive: true });
await writeFile(
@@ -1841,7 +1841,7 @@ describe('IngestBundleRunner isolated diff path', () => {
await currentSession.gitService.commitFiles(
['semantic-layer/finance/reconcile_orders.yaml'],
'reconcile unauthorized target',
- 'KTX Test',
+ 'ktx Test',
'system@ktx.local',
);
}
@@ -1959,7 +1959,7 @@ describe('IngestBundleRunner isolated diff path', () => {
await currentSession.gitService.commitFiles(
['semantic-layer/warehouse/mart_account_segments.yaml'],
`wu ${params.telemetryTags.unitKey}`,
- 'KTX Test',
+ 'ktx Test',
'system@ktx.local',
);
return { stopReason: 'natural' };
@@ -2025,7 +2025,7 @@ describe('IngestBundleRunner isolated diff path', () => {
await runtime.git.commitFiles(
['semantic-layer/warehouse/mart_account_segments.yaml', 'wiki/global/account-segments.md'],
'seed stale wiki body ref',
- 'KTX Test',
+ 'ktx Test',
'system@ktx.local',
);
@@ -2073,7 +2073,7 @@ describe('IngestBundleRunner isolated diff path', () => {
await currentSession.gitService.commitFiles(
['semantic-layer/warehouse/mart_account_segments.yaml'],
'wu source rename',
- 'KTX Test',
+ 'ktx Test',
'system@ktx.local',
);
return { stopReason: 'natural' as const };
@@ -2128,7 +2128,7 @@ describe('IngestBundleRunner isolated diff path', () => {
await runtime.git.commitFiles(
['semantic-layer/warehouse/mart_account_segments.yaml', 'wiki/global/account-segments.md'],
'seed stale wiki body ref',
- 'KTX Test',
+ 'ktx Test',
'system@ktx.local',
);
const preRunHead = await runtime.git.revParseHead();
@@ -2168,7 +2168,7 @@ describe('IngestBundleRunner isolated diff path', () => {
await currentSession.gitService.commitFiles(
['semantic-layer/warehouse/mart_account_segments.yaml'],
'wu source rename',
- 'KTX Test',
+ 'ktx Test',
'system@ktx.local',
);
return { stopReason: 'natural' as const };
@@ -2302,7 +2302,7 @@ describe('IngestBundleRunner isolated diff path', () => {
await currentSession.gitService.commitFiles(
['wiki/global/orders.md'],
'wu orders',
- 'KTX Test',
+ 'ktx Test',
'system@ktx.local',
);
return { stopReason: 'natural' as const };
diff --git a/packages/cli/test/context/ingest/ingest-bundle.runner.test.ts b/packages/cli/test/context/ingest/ingest-bundle.runner.test.ts
index 9f668b7b..105d8ad1 100644
--- a/packages/cli/test/context/ingest/ingest-bundle.runner.test.ts
+++ b/packages/cli/test/context/ingest/ingest-bundle.runner.test.ts
@@ -261,7 +261,7 @@ const buildRunner = (deps: ReturnType = makeDeps(), overrides:
lockingService: deps.lockingService as any,
storage: {
homeDir: '/tmp/ktx-test',
- systemGitAuthor: { name: 'KTX Test', email: 'system@ktx.local' },
+ systemGitAuthor: { name: 'ktx Test', email: 'system@ktx.local' },
resolveUploadDir: (uploadId) => `/tmp/ktx-test/ingest-uploads/${uploadId}`,
resolvePullDir: (jobId) => `/tmp/ktx-test/ingest-pulls/${jobId}`,
resolveTranscriptDir: (jobId) => `/tmp/ktx-test/run/wu-transcripts/${jobId}`,
@@ -1518,7 +1518,7 @@ describe('IngestBundleRunner — Stages 1 → 7', () => {
...(buildRunner(deps) as any).deps,
storage: {
homeDir: tempRoot,
- systemGitAuthor: { name: 'KTX Test', email: 'system@ktx.local' },
+ systemGitAuthor: { name: 'ktx Test', email: 'system@ktx.local' },
resolveUploadDir: (uploadId: string) => join(tempRoot, 'ingest-uploads', uploadId),
resolvePullDir: (jobId: string) => join(tempRoot, 'ingest-pulls', jobId),
resolveTranscriptDir: (jobId: string) => join(tempRoot, 'run', 'wu-transcripts', jobId),
diff --git a/packages/cli/test/context/ingest/ingest-prompts.test.ts b/packages/cli/test/context/ingest/ingest-prompts.test.ts
index 54617eb2..7f5a3f5d 100644
--- a/packages/cli/test/context/ingest/ingest-prompts.test.ts
+++ b/packages/cli/test/context/ingest/ingest-prompts.test.ts
@@ -18,14 +18,14 @@ describe('ingest prompt assets', () => {
expect(prompt).toContain('Do not create a duplicate contested artifact');
});
- it('uses product-neutral KTX runtime wording', async () => {
+ it('uses product-neutral ktx runtime wording', async () => {
const prompt = await readFile(
new URL('../../../src/prompts/memory_agent_bundle_ingest_work_unit.md', import.meta.url),
'utf-8',
);
- expect(prompt).toContain('KTX semantic-layer sources and/or knowledge wiki pages');
- expect(prompt).toContain('maps cleanly to KTX');
+ expect(prompt).toContain('ktx semantic-layer sources and/or knowledge wiki pages');
+ expect(prompt).toContain('maps cleanly to ktx');
expect(prompt).not.toMatch(forbiddenProductPattern());
});
diff --git a/packages/cli/test/context/ingest/ingest-runtime-assets.test.ts b/packages/cli/test/context/ingest/ingest-runtime-assets.test.ts
index ad77e692..083934c6 100644
--- a/packages/cli/test/context/ingest/ingest-runtime-assets.test.ts
+++ b/packages/cli/test/context/ingest/ingest-runtime-assets.test.ts
@@ -34,7 +34,7 @@ function forbiddenProductPattern() {
}
describe('ingest runtime assets', () => {
- it('resolves every reusable ingest skill from packaged KTX assets without server fallback', async () => {
+ it('resolves every reusable ingest skill from packaged ktx assets without server fallback', async () => {
const registry = new SkillsRegistryService({ skillsDir });
const expected = [...new Set([...adapterSkillNames, ...adapterReconcileSkillNames])].sort();
@@ -48,7 +48,7 @@ describe('ingest runtime assets', () => {
}
});
- it('loads page-triage and light-extraction prompts from packaged KTX prompt assets', async () => {
+ it('loads page-triage and light-extraction prompts from packaged ktx prompt assets', async () => {
const prompts = new PromptService({ promptsDir, partials: [] });
for (const promptName of pageTriagePromptNames) {
@@ -61,7 +61,7 @@ describe('ingest runtime assets', () => {
await expect(prompts.loadPrompt('skills/light_extraction')).resolves.toContain('# Light Context Extraction');
});
- it('packages historic-SQL table digest guidance from KTX assets', async () => {
+ it('packages historic-SQL table digest guidance from ktx assets', async () => {
const registry = new SkillsRegistryService({ skillsDir });
const skills = await registry.listSkills(['historic_sql_table_digest'], 'memory_agent');
@@ -77,7 +77,7 @@ describe('ingest runtime assets', () => {
expect(body).not.toMatch(forbiddenProductPattern());
});
- it('packages historic-SQL patterns guidance from KTX assets', async () => {
+ it('packages historic-SQL patterns guidance from ktx assets', async () => {
const registry = new SkillsRegistryService({ skillsDir });
const skills = await registry.listSkills(['historic_sql_patterns'], 'memory_agent');
diff --git a/packages/cli/test/context/ingest/isolated-diff/patch-integrator.test.ts b/packages/cli/test/context/ingest/isolated-diff/patch-integrator.test.ts
index e822472d..545b2ba0 100644
--- a/packages/cli/test/context/ingest/isolated-diff/patch-integrator.test.ts
+++ b/packages/cli/test/context/ingest/isolated-diff/patch-integrator.test.ts
@@ -49,7 +49,7 @@ describe('integrateWorkUnitPatch', () => {
patchPath,
integrationGit: git,
trace,
- author: { name: 'KTX Test', email: 'system@ktx.local' },
+ author: { name: 'ktx Test', email: 'system@ktx.local' },
validateAppliedTree: vi.fn().mockResolvedValue(undefined),
slDisallowed: false,
allowedTargetConnectionIds: new Set(['c1']),
@@ -82,7 +82,7 @@ describe('integrateWorkUnitPatch', () => {
patchPath,
integrationGit: git,
trace,
- author: { name: 'KTX Test', email: 'system@ktx.local' },
+ author: { name: 'ktx Test', email: 'system@ktx.local' },
validateAppliedTree: vi.fn().mockRejectedValue(new Error('final artifact gates failed')),
slDisallowed: false,
allowedTargetConnectionIds: new Set(['c1']),
@@ -117,7 +117,7 @@ describe('integrateWorkUnitPatch', () => {
patchPath,
integrationGit: git,
trace,
- author: { name: 'KTX Test', email: 'system@ktx.local' },
+ author: { name: 'ktx Test', email: 'system@ktx.local' },
validateAppliedTree: vi.fn().mockResolvedValue(undefined),
slDisallowed: true,
allowedTargetConnectionIds: new Set(['c1']),
@@ -158,7 +158,7 @@ describe('integrateWorkUnitPatch', () => {
patchPath,
integrationGit: git,
trace,
- author: { name: 'KTX Test', email: 'system@ktx.local' },
+ author: { name: 'ktx Test', email: 'system@ktx.local' },
validateAppliedTree: vi.fn().mockResolvedValue(undefined),
slDisallowed: false,
allowedTargetConnectionIds: new Set(['warehouse']),
@@ -325,7 +325,7 @@ describe('integrateWorkUnitPatch', () => {
patchPath,
integrationGit: git,
trace,
- author: { name: 'KTX Test', email: 'system@ktx.local' },
+ author: { name: 'ktx Test', email: 'system@ktx.local' },
validateAppliedTree,
slDisallowed: false,
allowedTargetConnectionIds: new Set(['c1']),
@@ -380,7 +380,7 @@ describe('integrateWorkUnitPatch', () => {
patchPath,
integrationGit: git,
trace,
- author: { name: 'KTX Test', email: 'system@ktx.local' },
+ author: { name: 'ktx Test', email: 'system@ktx.local' },
validateAppliedTree: vi.fn().mockRejectedValue(new Error('final artifact gates failed')),
slDisallowed: false,
allowedTargetConnectionIds: new Set(['c1']),
diff --git a/packages/cli/test/context/ingest/isolated-diff/work-unit-executor.test.ts b/packages/cli/test/context/ingest/isolated-diff/work-unit-executor.test.ts
index cc06ba61..8993fdf7 100644
--- a/packages/cli/test/context/ingest/isolated-diff/work-unit-executor.test.ts
+++ b/packages/cli/test/context/ingest/isolated-diff/work-unit-executor.test.ts
@@ -65,7 +65,7 @@ describe('runIsolatedWorkUnit', () => {
run: async (child) => {
await mkdir(join(child.workdir, 'wiki/global'), { recursive: true });
await writeFile(join(child.workdir, 'wiki/global/a.md'), '---\nsummary: A\nusage_mode: auto\n---\n\nBody\n');
- await child.git.commitFiles(['wiki/global/a.md'], 'test: write wiki', 'KTX Test', 'system@ktx.local');
+ await child.git.commitFiles(['wiki/global/a.md'], 'test: write wiki', 'ktx Test', 'system@ktx.local');
return {
unitKey: 'wu-1',
status: 'success',
diff --git a/packages/cli/test/context/ingest/local-bundle-ingest.test.ts b/packages/cli/test/context/ingest/local-bundle-ingest.test.ts
index 75f6e387..08429e0e 100644
--- a/packages/cli/test/context/ingest/local-bundle-ingest.test.ts
+++ b/packages/cli/test/context/ingest/local-bundle-ingest.test.ts
@@ -521,7 +521,7 @@ describe('canonical local ingest', () => {
' state: sqlite',
' search: sqlite-fts5',
' git:',
- ' author: KTX Test ',
+ ' author: ktx Test ',
'',
].join('\n'),
'utf-8',
@@ -530,7 +530,7 @@ describe('canonical local ingest', () => {
await historicProject.fileStore.writeFile(
'semantic-layer/warehouse/_schema/public.yaml',
YAML.stringify({ tables: { orders: { table: 'public.orders', columns: [{ name: 'id', type: 'string' }] } } }),
- 'KTX Test',
+ 'ktx Test',
'system@ktx.local',
'Seed schema shard',
);
@@ -682,7 +682,7 @@ describe('canonical local ingest', () => {
' state: sqlite',
' search: sqlite-fts5',
' git:',
- ' author: KTX Test ',
+ ' author: ktx Test ',
'',
].join('\n'),
'utf-8',
@@ -765,7 +765,7 @@ describe('canonical local ingest', () => {
' state: sqlite',
' search: sqlite-fts5',
' git:',
- ' author: KTX Test ',
+ ' author: ktx Test ',
'',
].join('\n'),
'utf-8',
@@ -808,7 +808,7 @@ describe('canonical local ingest', () => {
' state: sqlite',
' search: sqlite-fts5',
' git:',
- ' author: KTX Test ',
+ ' author: ktx Test ',
'',
].join('\n'),
'utf-8',
diff --git a/packages/cli/test/context/ingest/local-stage-ingest.test.ts b/packages/cli/test/context/ingest/local-stage-ingest.test.ts
index c57d18b4..d3371395 100644
--- a/packages/cli/test/context/ingest/local-stage-ingest.test.ts
+++ b/packages/cli/test/context/ingest/local-stage-ingest.test.ts
@@ -596,7 +596,7 @@ describe('local ingest', () => {
});
});
- it('includes upload-capable KTX adapters in default local ingest adapters', () => {
+ it('includes upload-capable ktx adapters in default local ingest adapters', () => {
expect(createDefaultLocalIngestAdapters(project).map((adapter) => adapter.source)).toEqual(
expect.arrayContaining(['dbt', 'metricflow', 'notion']),
);
diff --git a/packages/cli/test/context/ingest/memory-flow/acceptance.test.ts b/packages/cli/test/context/ingest/memory-flow/acceptance.test.ts
index 04e7fa46..6bff36cd 100644
--- a/packages/cli/test/context/ingest/memory-flow/acceptance.test.ts
+++ b/packages/cli/test/context/ingest/memory-flow/acceptance.test.ts
@@ -17,7 +17,7 @@ describe('memory-flow acceptance scenarios', () => {
it('renders a completed replay with a clear saved-memory completion line', () => {
const output = renderScenario(successfulReplayScenario());
- expect(output).toContain('KTX memory flow warehouse/metricflow done');
+ expect(output).toContain('ktx memory flow warehouse/metricflow done');
expect(output).toContain('Saved 3 memories from 4 raw files: 2 wiki pages, 1 SL updates.');
expect(output).toContain('Commit: abc12345 Run: run-success Report: ingest-report.json');
});
@@ -48,7 +48,7 @@ describe('memory-flow acceptance scenarios', () => {
it('renders no ANSI color codes in the text fallback for terminals without color support', () => {
const output = renderScenario(successfulReplayScenario(), 80);
- expect(output).toContain('KTX memory flow warehouse/metricflow done');
+ expect(output).toContain('ktx memory flow warehouse/metricflow done');
expect(output).not.toMatch(/\u001b\[[0-9;]*m/);
});
diff --git a/packages/cli/test/context/ingest/memory-flow/interaction.test.ts b/packages/cli/test/context/ingest/memory-flow/interaction.test.ts
index 012373f7..80711a22 100644
--- a/packages/cli/test/context/ingest/memory-flow/interaction.test.ts
+++ b/packages/cli/test/context/ingest/memory-flow/interaction.test.ts
@@ -13,7 +13,7 @@ import type { MemoryFlowInteractionState, MemoryFlowViewModel } from '../../../.
function view(): MemoryFlowViewModel {
return {
- title: 'KTX memory flow warehouse/metricflow running',
+ title: 'ktx memory flow warehouse/metricflow running',
subtitle: 'Run run-1 Sync sync-1',
status: 'running',
activeLine: 'active: WorkUnit orders step 2/4',
diff --git a/packages/cli/test/context/ingest/memory-flow/interactive-render.test.ts b/packages/cli/test/context/ingest/memory-flow/interactive-render.test.ts
index 8c9a6a52..d15e0766 100644
--- a/packages/cli/test/context/ingest/memory-flow/interactive-render.test.ts
+++ b/packages/cli/test/context/ingest/memory-flow/interactive-render.test.ts
@@ -5,7 +5,7 @@ import type { MemoryFlowViewModel } from '../../../../src/context/ingest/memory-
function view(): MemoryFlowViewModel {
return {
- title: 'KTX memory flow warehouse/metricflow done',
+ title: 'ktx memory flow warehouse/metricflow done',
subtitle: 'Run run-1 Sync sync-1',
status: 'done',
activeLine: 'active: complete',
@@ -128,7 +128,7 @@ describe('renderMemoryFlowInteractive', () => {
const output = renderMemoryFlowInteractive(view(), state, { terminalWidth: 140 });
- expect(output).toContain('KTX memory flow warehouse/metricflow done');
+ expect(output).toContain('ktx memory flow warehouse/metricflow done');
expect(output).toContain('OK SOURCE -> OK CHUNKS -> !! WORKUNITS -> OK ACTIONS -> !! GATES -> OK SAVED');
expect(output).toContain('[WORKUNITS]');
expect(output).toContain('> orders');
diff --git a/packages/cli/test/context/ingest/memory-flow/render.test.ts b/packages/cli/test/context/ingest/memory-flow/render.test.ts
index adcc89f0..2d5ce106 100644
--- a/packages/cli/test/context/ingest/memory-flow/render.test.ts
+++ b/packages/cli/test/context/ingest/memory-flow/render.test.ts
@@ -4,7 +4,7 @@ import { renderMemoryFlowReplay } from '../../../../src/context/ingest/memory-fl
function view(): MemoryFlowViewModel {
return {
- title: 'KTX memory flow warehouse/metricflow done',
+ title: 'ktx memory flow warehouse/metricflow done',
subtitle: 'Run run-1 Sync sync-1',
status: 'done',
activeLine: 'active: complete',
@@ -79,7 +79,7 @@ describe('renderMemoryFlowReplay', () => {
'OK SOURCE -> OK CHUNKS -> !! WORKUNITS -> OK ACTIONS -> !! GATES -> OK SAVED',
);
expect(renderMemoryFlowReplay(view(), { terminalWidth: 140 })).toMatchInlineSnapshot(`
- "KTX memory flow warehouse/metricflow done
+ "ktx memory flow warehouse/metricflow done
active: complete
Run run-1 Sync sync-1
OK SOURCE -> OK CHUNKS -> !! WORKUNITS -> OK ACTIONS -> !! GATES -> OK SAVED
diff --git a/packages/cli/test/context/ingest/memory-flow/view-model.test.ts b/packages/cli/test/context/ingest/memory-flow/view-model.test.ts
index 5d3c7778..915376a0 100644
--- a/packages/cli/test/context/ingest/memory-flow/view-model.test.ts
+++ b/packages/cli/test/context/ingest/memory-flow/view-model.test.ts
@@ -93,7 +93,7 @@ describe('buildMemoryFlowViewModel', () => {
it('builds six readable columns from replay events', () => {
const view = buildMemoryFlowViewModel(replayInput());
- expect(view.title).toBe('KTX memory flow warehouse/metricflow done');
+ expect(view.title).toBe('ktx memory flow warehouse/metricflow done');
expect(view.activeLine).toBe('active: complete');
expect(view.columns.map((column) => column.id)).toEqual([
'source',
@@ -179,7 +179,7 @@ describe('buildMemoryFlowViewModel', () => {
details: { actions: [], provenance: [], transcripts: [] },
});
- expect(view.title).toBe('KTX memory flow Warehouse + dbt + BI + Docs done');
+ expect(view.title).toBe('ktx memory flow Warehouse + dbt + BI + Docs done');
expect(view.columns.find((column) => column.id === 'source')?.counters[0]).toBe('Warehouse, dbt, BI, Docs');
expect(view.completionLine).toContain('Saved 16 memories from 29 raw files');
});
diff --git a/packages/cli/test/context/ingest/memory-flow/visuals.test.ts b/packages/cli/test/context/ingest/memory-flow/visuals.test.ts
index da271248..0701fa25 100644
--- a/packages/cli/test/context/ingest/memory-flow/visuals.test.ts
+++ b/packages/cli/test/context/ingest/memory-flow/visuals.test.ts
@@ -11,7 +11,7 @@ function viewWithStatuses(statuses: Array<'waiting' | 'active' | 'complete' | 'w
const ids = ['source', 'chunks', 'workUnits', 'actions', 'gates', 'saved'] as const;
return {
- title: 'KTX memory flow warehouse/metricflow running',
+ title: 'ktx memory flow warehouse/metricflow running',
subtitle: 'Run run-1 Sync sync-1',
status: 'running',
activeLine: 'active: WorkUnit orders',
diff --git a/packages/cli/test/context/ingest/page-triage/page-triage.service.test.ts b/packages/cli/test/context/ingest/page-triage/page-triage.service.test.ts
index 33aa2979..f7ea5133 100644
--- a/packages/cli/test/context/ingest/page-triage/page-triage.service.test.ts
+++ b/packages/cli/test/context/ingest/page-triage/page-triage.service.test.ts
@@ -198,7 +198,7 @@ describe('PageTriageService', () => {
'Reusable outbound sequence:',
'',
'- Ask about current customer success expansion workflow.',
- '- Position KTX as AI search visibility for CS teams.',
+ '- Position ktx as AI search visibility for CS teams.',
'- Close with a discovery call request.',
].join('\n'),
'utf-8',
@@ -233,7 +233,7 @@ describe('PageTriageService', () => {
{
candidateKey: 'cold-call-script',
topic: 'Cold Call Script',
- assertion: 'Cold call outreach should position KTX around AI search visibility for CS teams.',
+ assertion: 'Cold call outreach should position ktx around AI search visibility for CS teams.',
rationale: 'The script gives a reusable outbound call sequence and positioning language.',
evidenceChunkIds: ['00000000-0000-0000-0000-000000000101'],
suggestedPageKey: 'cold-call-script',
diff --git a/packages/cli/test/context/ingest/repo-fetch.test.ts b/packages/cli/test/context/ingest/repo-fetch.test.ts
index d9e66e33..b9b5a4f1 100644
--- a/packages/cli/test/context/ingest/repo-fetch.test.ts
+++ b/packages/cli/test/context/ingest/repo-fetch.test.ts
@@ -106,7 +106,7 @@ describe('repo-fetch', () => {
const cacheGit = createSimpleGit(cacheDir);
await cacheGit.addConfig('user.email', 'test@ktx.local');
- await cacheGit.addConfig('user.name', 'KTX Test');
+ await cacheGit.addConfig('user.name', 'ktx Test');
await writeFile(join(cacheDir, 'local-only.txt'), 'local commit\n', 'utf-8');
await cacheGit.add('.');
await cacheGit.commit('local-only divergent commit');
diff --git a/packages/cli/test/context/llm/claude-code-runtime.test.ts b/packages/cli/test/context/llm/claude-code-runtime.test.ts
index 182fdbc5..4e7a8e48 100644
--- a/packages/cli/test/context/llm/claude-code-runtime.test.ts
+++ b/packages/cli/test/context/llm/claude-code-runtime.test.ts
@@ -362,7 +362,7 @@ describe('ClaudeCodeKtxLlmRuntime', () => {
});
});
- it('registers only exact KTX MCP tool ids and denies non-KTX tools', async () => {
+ it('registers only exact ktx MCP tool ids and denies non-ktx tools', async () => {
const query = vi.fn((_input: any) =>
stream([
initMessage({ tools: ['mcp__ktx__load_skill'], mcp_servers: [{ name: 'ktx', status: 'connected' }] }),
@@ -487,7 +487,7 @@ describe('ClaudeCodeKtxLlmRuntime', () => {
);
});
- it('allows host-discovered context during agent loops while requiring exact KTX MCP tools and servers', async () => {
+ it('allows host-discovered context during agent loops while requiring exact ktx MCP tools and servers', async () => {
const query = vi.fn((_input: any) =>
stream([
initMessage({
@@ -553,7 +553,7 @@ describe('ClaudeCodeKtxLlmRuntime', () => {
});
});
- it('still rejects unexpected tools, missing KTX tools, plugins, and non-KTX MCP servers from init messages', async () => {
+ it('still rejects unexpected tools, missing ktx tools, plugins, and non-ktx MCP servers from init messages', async () => {
const query = vi.fn((_input: any) =>
stream([
initMessage({
diff --git a/packages/cli/test/context/llm/embedding-port.test.ts b/packages/cli/test/context/llm/embedding-port.test.ts
index 6bde1f2a..df8549db 100644
--- a/packages/cli/test/context/llm/embedding-port.test.ts
+++ b/packages/cli/test/context/llm/embedding-port.test.ts
@@ -1,7 +1,7 @@
import { describe, expect, it, vi } from 'vitest';
import { KtxIngestEmbeddingPortAdapter, KtxScanEmbeddingPortAdapter } from '../../../src/context/llm/embedding-port.js';
-describe('KTX embedding port adapters', () => {
+describe('ktx embedding port adapters', () => {
it('adapts LLM modules embeddings to ingest embedding port shape', async () => {
const provider = {
dimensions: 3,
diff --git a/packages/cli/test/context/llm/local-config.test.ts b/packages/cli/test/context/llm/local-config.test.ts
index eed66261..d89cf385 100644
--- a/packages/cli/test/context/llm/local-config.test.ts
+++ b/packages/cli/test/context/llm/local-config.test.ts
@@ -12,7 +12,7 @@ import {
resolveLocalKtxLlmConfig,
} from '../../../src/context/llm/local-config.js';
-describe('local KTX LLM config', () => {
+describe('local ktx LLM config', () => {
it('resolves env and file references into a KtxLlmConfig', () => {
const config: KtxProjectLlmConfig = {
provider: {
@@ -190,7 +190,7 @@ describe('local KTX LLM config', () => {
});
});
-describe('local KTX embedding config', () => {
+describe('local ktx embedding config', () => {
it('resolves sentence-transformers config', () => {
const config: KtxProjectEmbeddingConfig = {
backend: 'sentence-transformers',
diff --git a/packages/cli/test/context/llm/runtime-local-config.test.ts b/packages/cli/test/context/llm/runtime-local-config.test.ts
index 14adca7c..a9418930 100644
--- a/packages/cli/test/context/llm/runtime-local-config.test.ts
+++ b/packages/cli/test/context/llm/runtime-local-config.test.ts
@@ -1,7 +1,7 @@
import { describe, expect, it, vi } from 'vitest';
import { createLocalKtxLlmProviderFromConfig, createLocalKtxLlmRuntimeFromConfig } from '../../../src/context/llm/local-config.js';
-describe('local KTX LLM runtime config', () => {
+describe('local ktx LLM runtime config', () => {
it('creates a Claude Code runtime for claude-code backend without creating an AI SDK provider', () => {
const runtime = createLocalKtxLlmRuntimeFromConfig(
{
diff --git a/packages/cli/test/context/mcp/__snapshots__/mcp-tools-list.json b/packages/cli/test/context/mcp/__snapshots__/mcp-tools-list.json
index b38851f4..3ffca96b 100644
--- a/packages/cli/test/context/mcp/__snapshots__/mcp-tools-list.json
+++ b/packages/cli/test/context/mcp/__snapshots__/mcp-tools-list.json
@@ -2,7 +2,7 @@
{
"name": "connection_list",
"title": "Connection List",
- "description": "List configured read-only data connections available to this KTX project. Use this before connection-scoped tools when the project may have multiple warehouses.",
+ "description": "List configured read-only data connections available to this ktx project. Use this before connection-scoped tools when the project may have multiple warehouses.",
"inputSchema": {
"type": "object",
"properties": {},
@@ -54,7 +54,7 @@
{
"name": "wiki_search",
"title": "Wiki Search",
- "description": "Search KTX wiki pages for reusable business context. Example: wiki_search({ query: \"revenue recognition\", limit: 5 }).",
+ "description": "Search ktx wiki pages for reusable business context. Example: wiki_search({ query: \"revenue recognition\", limit: 5 }).",
"inputSchema": {
"type": "object",
"properties": {
@@ -181,7 +181,7 @@
{
"name": "wiki_read",
"title": "Wiki Read",
- "description": "Read a KTX wiki page by key returned from wiki_search. Example: wiki_read({ key: \"global/revenue\" }).",
+ "description": "Read a ktx wiki page by key returned from wiki_search. Example: wiki_read({ key: \"global/revenue\" }).",
"inputSchema": {
"type": "object",
"properties": {
@@ -1227,7 +1227,7 @@
{
"name": "discover_data",
"title": "Discover Data",
- "description": "Search across KTX wiki pages, semantic-layer sources, measures, dimensions, raw tables, and columns. Example: discover_data({ query: \"monthly orders by customer\", connectionId: \"warehouse\", kinds: [\"sl_source\", \"table\"] }).",
+ "description": "Search across ktx wiki pages, semantic-layer sources, measures, dimensions, raw tables, and columns. Example: discover_data({ query: \"monthly orders by customer\", connectionId: \"warehouse\", kinds: [\"sl_source\", \"table\"] }).",
"inputSchema": {
"type": "object",
"properties": {
@@ -1398,7 +1398,7 @@
{
"name": "sql_execution",
"title": "SQL Execution",
- "description": "Execute one parser-validated read-only SQL query against a configured KTX connection. Example: sql_execution({ connectionId: \"warehouse\", sql: \"select count(*) from public.orders\", maxRows: 100 }).",
+ "description": "Execute one parser-validated read-only SQL query against a configured ktx connection. Example: sql_execution({ connectionId: \"warehouse\", sql: \"select count(*) from public.orders\", maxRows: 100 }).",
"inputSchema": {
"type": "object",
"properties": {
@@ -1472,7 +1472,7 @@
{
"name": "memory_ingest",
"title": "Memory Ingest",
- "description": "Ingest free-form markdown knowledge into durable KTX memory. Use this for business rules, metric definitions, schema gotchas, recurring findings, or explicit user requests to remember something. Example: memory_ingest({ connectionId: \"warehouse\", content: \"ARR is reported in cents in this warehouse.\" }).",
+ "description": "Ingest free-form markdown knowledge into durable ktx memory. Use this for business rules, metric definitions, schema gotchas, recurring findings, or explicit user requests to remember something. Example: memory_ingest({ connectionId: \"warehouse\", content: \"ARR is reported in cents in this warehouse.\" }).",
"inputSchema": {
"type": "object",
"properties": {
diff --git a/packages/cli/test/context/mcp/server.test.ts b/packages/cli/test/context/mcp/server.test.ts
index 1359d346..6b52bd66 100644
--- a/packages/cli/test/context/mcp/server.test.ts
+++ b/packages/cli/test/context/mcp/server.test.ts
@@ -987,7 +987,7 @@ describe('createKtxMcpServer', () => {
expect(ingest.ingest).toHaveBeenCalledWith({
userId: 'mcp-user',
chatId: expect.stringMatching(/^mcp-/),
- userMessage: 'Ingest external knowledge into KTX memory.',
+ userMessage: 'Ingest external knowledge into ktx memory.',
assistantMessage: content,
connectionId: '00000000-0000-4000-8000-000000000001',
sourceType: 'external_ingest',
@@ -996,7 +996,7 @@ describe('createKtxMcpServer', () => {
const cliEquivalentInput: MemoryAgentInput = {
userId: 'mcp-user',
chatId: 'cli-text-ingest-test-1',
- userMessage: 'Ingest external text artifact "orders lookml" into KTX memory.',
+ userMessage: 'Ingest external text artifact "orders lookml" into ktx memory.',
assistantMessage: content,
connectionId: '00000000-0000-4000-8000-000000000001',
sourceType: 'external_ingest',
@@ -1101,7 +1101,7 @@ describe('createKtxMcpServer', () => {
expect(ingestSpy).toHaveBeenCalledWith({
userId: 'local',
chatId: expect.stringMatching(/^mcp-/),
- userMessage: 'Ingest external knowledge into KTX memory.',
+ userMessage: 'Ingest external knowledge into ktx memory.',
assistantMessage: 'Revenue means paid order value.',
connectionId: 'warehouse',
sourceType: 'external_ingest',
@@ -1127,7 +1127,7 @@ describe('createKtxMcpServer', () => {
}
});
- it('registers KTX context MCP tools when context ports are supplied', async () => {
+ it('registers ktx context MCP tools when context ports are supplied', async () => {
const fake = makeFakeServer();
const contextTools: KtxMcpContextPorts = {
connections: {
@@ -1298,7 +1298,7 @@ describe('createKtxMcpServer', () => {
expect(jsonToolResult({ ok: true }).structuredContent).toEqual({ ok: true });
if (false) {
- // @ts-expect-error bare arrays are not valid MCP structuredContent objects in KTX
+ // @ts-expect-error bare arrays are not valid MCP structuredContent objects in ktx
jsonToolResult([]);
}
});
diff --git a/packages/cli/test/context/memory/memory-runtime-assets.test.ts b/packages/cli/test/context/memory/memory-runtime-assets.test.ts
index ab6ff324..d07da604 100644
--- a/packages/cli/test/context/memory/memory-runtime-assets.test.ts
+++ b/packages/cli/test/context/memory/memory-runtime-assets.test.ts
@@ -20,9 +20,9 @@ const expectedAdapterSkillHeadings: Record = {
historic_sql_table_digest: '# Historic SQL Table Digest',
live_database_ingest: '# Live Database Ingest',
looker_ingest: '# Looker Runtime Ingest',
- lookml_ingest: '# LookML to KTX Semantic Layer',
- metabase_ingest: '# Metabase to KTX Semantic Layer',
- metricflow_ingest: '# MetricFlow to KTX Semantic Layer',
+ lookml_ingest: '# LookML to ktx Semantic Layer',
+ metabase_ingest: '# Metabase to ktx Semantic Layer',
+ metricflow_ingest: '# MetricFlow to ktx Semantic Layer',
};
const verificationWriterSkills = [
'notion_synthesize',
@@ -125,7 +125,7 @@ describe('memory runtime assets', () => {
it('ships Metabase guidance that avoids invalid joins for SQL-only card outputs', async () => {
const body = await readFile(join(skillsDir, 'metabase_ingest', 'SKILL.md'), 'utf-8');
- expect(body).toContain('Do not declare a KTX join just because the card SQL joins that table internally');
+ expect(body).toContain('Do not declare a ktx join just because the card SQL joins that table internally');
expect(body).toContain('only when the card output exposes a local key that matches the target source grain');
expect(body).toContain('If `sl_discover` resolves the table, it is not outside the manifest');
expect(body).toContain('reason: "parse_error"');
@@ -167,7 +167,7 @@ describe('memory runtime assets', () => {
}
});
- it('ships only the KTX connectionId sql_execution call shape in writer guidance', async () => {
+ it('ships only the ktx connectionId sql_execution call shape in writer guidance', async () => {
const shared = await readFile(join(skillsDir, '_shared', 'identifier-verification.md'), 'utf-8');
const bodies = [{ name: '_shared/identifier-verification.md', body: shared }];
diff --git a/packages/cli/test/context/project/config.test.ts b/packages/cli/test/context/project/config.test.ts
index ef8c6681..3fa2cb8e 100644
--- a/packages/cli/test/context/project/config.test.ts
+++ b/packages/cli/test/context/project/config.test.ts
@@ -9,7 +9,7 @@ import {
const removedAutoCommitKey = ['auto', 'commit'].join('_');
-describe('KTX project config', () => {
+describe('ktx project config', () => {
it.each(['status', 'replay', 'run', 'watch'])('accepts former ingest subcommand name "%s" as a connection id', (connectionId) => {
expect(
parseKtxProjectConfig(`
diff --git a/packages/cli/test/context/project/project.test.ts b/packages/cli/test/context/project/project.test.ts
index 1027d174..253a4cf1 100644
--- a/packages/cli/test/context/project/project.test.ts
+++ b/packages/cli/test/context/project/project.test.ts
@@ -5,7 +5,7 @@ import { join } from 'node:path';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import { initKtxProject, loadKtxProject } from '../../../src/context/project/project.js';
-describe('KTX local project runtime', () => {
+describe('ktx local project runtime', () => {
let tempDir: string;
beforeEach(async () => {
diff --git a/packages/cli/test/context/project/setup-config.test.ts b/packages/cli/test/context/project/setup-config.test.ts
index 948d9d54..f3c2553b 100644
--- a/packages/cli/test/context/project/setup-config.test.ts
+++ b/packages/cli/test/context/project/setup-config.test.ts
@@ -10,7 +10,7 @@ import {
setKtxSetupDatabaseConnectionIds,
} from '../../../src/context/project/setup-config.js';
-describe('KTX setup config helpers', () => {
+describe('ktx setup config helpers', () => {
let tempDir: string;
beforeEach(async () => {
diff --git a/packages/cli/test/context/scan/credentials.test.ts b/packages/cli/test/context/scan/credentials.test.ts
index 62ee2952..5ad2ce48 100644
--- a/packages/cli/test/context/scan/credentials.test.ts
+++ b/packages/cli/test/context/scan/credentials.test.ts
@@ -9,7 +9,7 @@ import {
} from '../../../src/context/scan/credentials.js';
import type { KtxCredentialEnvelope, KtxScanReport, KtxScanWarning } from '../../../src/context/scan/types.js';
-describe('KTX scan credential redaction', () => {
+describe('ktx scan credential redaction', () => {
it('keeps credential references inspectable', () => {
const envReference: KtxCredentialEnvelope = { kind: 'env', name: 'DATABASE_URL' };
const fileReference: KtxCredentialEnvelope = { kind: 'file', path: '~/.config/ktx/warehouse' };
diff --git a/packages/cli/test/context/scan/data-dictionary.test.ts b/packages/cli/test/context/scan/data-dictionary.test.ts
index daf20559..70ce2d3e 100644
--- a/packages/cli/test/context/scan/data-dictionary.test.ts
+++ b/packages/cli/test/context/scan/data-dictionary.test.ts
@@ -7,7 +7,7 @@ import {
const defaultPatterns = defaultKtxDataDictionarySettings.excludePatterns;
-describe('KTX scan data dictionary policy', () => {
+describe('ktx scan data dictionary policy', () => {
it('includes text-like and boolean categorical types', () => {
expect(isKtxDataDictionaryCandidate('varchar(50)', 'status', defaultPatterns)).toBe(true);
expect(isKtxDataDictionaryCandidate('VARCHAR', 'category', defaultPatterns)).toBe(true);
diff --git a/packages/cli/test/context/scan/description-generation.test.ts b/packages/cli/test/context/scan/description-generation.test.ts
index 811752e5..9925f857 100644
--- a/packages/cli/test/context/scan/description-generation.test.ts
+++ b/packages/cli/test/context/scan/description-generation.test.ts
@@ -90,7 +90,7 @@ function createConnector(): KtxScanConnector {
};
}
-describe('KTX description prompt builders', () => {
+describe('ktx description prompt builders', () => {
it('builds column prompts with sample values, source descriptions, and nested BigQuery guidance', () => {
const { system, user } = buildKtxColumnDescriptionPrompt({
columnName: 'payload',
diff --git a/packages/cli/test/context/scan/embedding-text.test.ts b/packages/cli/test/context/scan/embedding-text.test.ts
index 523d1d5c..a3a046f2 100644
--- a/packages/cli/test/context/scan/embedding-text.test.ts
+++ b/packages/cli/test/context/scan/embedding-text.test.ts
@@ -1,7 +1,7 @@
import { describe, expect, it } from 'vitest';
import { buildKtxColumnEmbeddingText } from '../../../src/context/scan/embedding-text.js';
-describe('KTX scan embedding text', () => {
+describe('ktx scan embedding text', () => {
it('builds column embedding text with table, description, FK, and sample-value context', () => {
expect(
buildKtxColumnEmbeddingText({
diff --git a/packages/cli/test/context/scan/enrichment-summary.test.ts b/packages/cli/test/context/scan/enrichment-summary.test.ts
index 783e18cd..45d595a1 100644
--- a/packages/cli/test/context/scan/enrichment-summary.test.ts
+++ b/packages/cli/test/context/scan/enrichment-summary.test.ts
@@ -5,7 +5,7 @@ import {
skippedKtxScanEnrichmentSummary,
} from '../../../src/context/scan/enrichment-summary.js';
-describe('KTX scan enrichment summaries', () => {
+describe('ktx scan enrichment summaries', () => {
it('keeps structural scans skipped when no enrichment was requested', () => {
expect(failedKtxScanEnrichmentSummary('structural', false)).toEqual(skippedKtxScanEnrichmentSummary);
});
diff --git a/packages/cli/test/context/scan/enrichment-types.test.ts b/packages/cli/test/context/scan/enrichment-types.test.ts
index 72e7b247..3db0089e 100644
--- a/packages/cli/test/context/scan/enrichment-types.test.ts
+++ b/packages/cli/test/context/scan/enrichment-types.test.ts
@@ -11,7 +11,7 @@ import type {
KtxStructuralSyncPlan,
} from '../../../src/context/scan/enrichment-types.js';
-describe('KTX scan enrichment contracts', () => {
+describe('ktx scan enrichment contracts', () => {
it('models an enriched schema with reusable table, column, and relationship metadata', () => {
const schema: KtxEnrichedSchema = {
connectionId: 'warehouse',
diff --git a/packages/cli/test/context/scan/local-enrichment.test.ts b/packages/cli/test/context/scan/local-enrichment.test.ts
index 9704d071..dd2d6133 100644
--- a/packages/cli/test/context/scan/local-enrichment.test.ts
+++ b/packages/cli/test/context/scan/local-enrichment.test.ts
@@ -373,7 +373,7 @@ describe('local scan enrichment', () => {
expect(result.summary.statisticalValidation).toBe('skipped');
expect(result.warnings).toContainEqual({
code: 'relationship_validation_failed',
- message: 'KTX scan connector advertises readOnlySql but does not expose executeReadOnly',
+ message: 'ktx scan connector advertises readOnlySql but does not expose executeReadOnly',
recoverable: true,
metadata: { capability: 'readOnlySql' },
});
diff --git a/packages/cli/test/context/scan/local-scan.test.ts b/packages/cli/test/context/scan/local-scan.test.ts
index 931fd6b0..1021a139 100644
--- a/packages/cli/test/context/scan/local-scan.test.ts
+++ b/packages/cli/test/context/scan/local-scan.test.ts
@@ -1644,7 +1644,7 @@ describe('local scan', () => {
expect(result.report.warnings).toEqual([
{
code: 'enrichment_failed',
- message: 'KTX scan enrichment failed after structural scan completed: embedding service timed out',
+ message: 'ktx scan enrichment failed after structural scan completed: embedding service timed out',
recoverable: true,
metadata: {
mode: 'enriched',
diff --git a/packages/cli/test/context/scan/relationship-benchmark-report.test.ts b/packages/cli/test/context/scan/relationship-benchmark-report.test.ts
index 0837ed3c..e7848516 100644
--- a/packages/cli/test/context/scan/relationship-benchmark-report.test.ts
+++ b/packages/cli/test/context/scan/relationship-benchmark-report.test.ts
@@ -258,7 +258,7 @@ describe('relationship benchmark report', () => {
}),
);
- expect(markdown).toContain('# KTX Relationship Discovery Benchmark Evidence');
+ expect(markdown).toContain('# ktx Relationship Discovery Benchmark Evidence');
expect(markdown).toContain(
'| demo_b2b_no_declared_constraints | smoke | declared_pks_and_declared_fks_removed | run | no | 0.500 | 0.000 | 0.000 | 0 |',
);
diff --git a/packages/cli/test/context/scan/relationship-diagnostics.test.ts b/packages/cli/test/context/scan/relationship-diagnostics.test.ts
index 647ac931..8bad3b4f 100644
--- a/packages/cli/test/context/scan/relationship-diagnostics.test.ts
+++ b/packages/cli/test/context/scan/relationship-diagnostics.test.ts
@@ -279,7 +279,7 @@ describe('relationship diagnostics artifacts', () => {
warnings: [
{
code: 'connector_capability_missing',
- message: 'KTX scan connector cannot run standalone statistical relationship validation',
+ message: 'ktx scan connector cannot run standalone statistical relationship validation',
recoverable: true,
metadata: { capability: 'readOnlySql' },
},
diff --git a/packages/cli/test/context/scan/relationship-discovery.test.ts b/packages/cli/test/context/scan/relationship-discovery.test.ts
index 55341645..f840a08e 100644
--- a/packages/cli/test/context/scan/relationship-discovery.test.ts
+++ b/packages/cli/test/context/scan/relationship-discovery.test.ts
@@ -449,7 +449,7 @@ describe('production relationship discovery', () => {
});
expect(result.warnings).toContainEqual({
code: 'connector_capability_missing',
- message: 'KTX scan connector cannot run read-only SQL relationship validation',
+ message: 'ktx scan connector cannot run read-only SQL relationship validation',
recoverable: true,
metadata: { capability: 'readOnlySql' },
});
diff --git a/packages/cli/test/context/scan/relationship-llm-proposal.test.ts b/packages/cli/test/context/scan/relationship-llm-proposal.test.ts
index 0713a1c6..3c4cb5f0 100644
--- a/packages/cli/test/context/scan/relationship-llm-proposal.test.ts
+++ b/packages/cli/test/context/scan/relationship-llm-proposal.test.ts
@@ -146,12 +146,12 @@ describe('relationship LLM proposals', () => {
expect(runtime.generateObject).toHaveBeenCalledWith(
expect.objectContaining({
role: 'candidateExtraction',
- system: expect.stringContaining('You are helping KTX review possible SQL relationships'),
+ system: expect.stringContaining('You are helping ktx review possible SQL relationships'),
prompt: expect.stringContaining('"tables"'),
}),
);
const call = vi.mocked(runtime.generateObject).mock.calls[0]?.[0];
- expect(call?.prompt).not.toContain('You are helping KTX review possible SQL relationships');
+ expect(call?.prompt).not.toContain('You are helping ktx review possible SQL relationships');
});
it('skips when no runtime is configured', async () => {
@@ -207,7 +207,7 @@ describe('relationship LLM proposals', () => {
expect(failed).toMatchObject({ candidates: [], llmCalls: 1, summary: 'failed' });
expect(failed.warnings[0]).toMatchObject({
code: 'relationship_llm_proposal_failed',
- message: 'KTX relationship LLM proposal failed: model unavailable',
+ message: 'ktx relationship LLM proposal failed: model unavailable',
recoverable: true,
});
});
diff --git a/packages/cli/test/context/scan/type-normalization.test.ts b/packages/cli/test/context/scan/type-normalization.test.ts
index fa19df32..5771c54f 100644
--- a/packages/cli/test/context/scan/type-normalization.test.ts
+++ b/packages/cli/test/context/scan/type-normalization.test.ts
@@ -1,7 +1,7 @@
import { describe, expect, it } from 'vitest';
import { inferKtxDimensionType, ktxColumnTypeMappingFromNative, normalizeKtxNativeType } from '../../../src/context/scan/type-normalization.js';
-describe('KTX scan type normalization', () => {
+describe('ktx scan type normalization', () => {
it('normalizes native database type strings', () => {
expect(normalizeKtxNativeType(' NUMERIC(12, 2) ')).toBe('numeric');
expect(normalizeKtxNativeType('TIMESTAMP WITH TIME ZONE')).toBe('timestamp with time zone');
diff --git a/packages/cli/test/context/scan/types.test.ts b/packages/cli/test/context/scan/types.test.ts
index 8aa55dba..fcf1c20b 100644
--- a/packages/cli/test/context/scan/types.test.ts
+++ b/packages/cli/test/context/scan/types.test.ts
@@ -17,7 +17,7 @@ import {
type KtxSchemaSnapshot,
} from '../../../src/context/scan/types.js';
-describe('KTX scan contract types', () => {
+describe('ktx scan contract types', () => {
it('defaults to structural-only connector capabilities', () => {
expect(createKtxConnectorCapabilities()).toEqual({
structuralIntrospection: true,
diff --git a/packages/cli/test/context/sl/semantic-layer.service.test.ts b/packages/cli/test/context/sl/semantic-layer.service.test.ts
index b004e635..8e61ec22 100644
--- a/packages/cli/test/context/sl/semantic-layer.service.test.ts
+++ b/packages/cli/test/context/sl/semantic-layer.service.test.ts
@@ -47,7 +47,7 @@ const baseTable: SemanticLayerSource = {
};
describe('listConnectionIdsWithNames', () => {
- it('discovers local KTX connection ids from semantic-layer directories', async () => {
+ it('discovers local ktx connection ids from semantic-layer directories', async () => {
const configService = {
listFiles: vi.fn().mockResolvedValue({
files: [
diff --git a/packages/cli/test/context/test/make-local-git-repo.ts b/packages/cli/test/context/test/make-local-git-repo.ts
index c60187ac..b3a2c538 100644
--- a/packages/cli/test/context/test/make-local-git-repo.ts
+++ b/packages/cli/test/context/test/make-local-git-repo.ts
@@ -20,7 +20,7 @@ export async function makeLocalGitRepo(fixtureDir: string, destRoot: string): Pr
await git.init();
await git.raw(['checkout', '-B', 'main']);
await git.addConfig('user.email', 'test@ktx.local');
- await git.addConfig('user.name', 'KTX Test');
+ await git.addConfig('user.name', 'ktx Test');
await git.add('.');
await git.commit('initial');
const commit = async (message: string): Promise => {
diff --git a/packages/cli/test/doctor.test.ts b/packages/cli/test/doctor.test.ts
index 242331e8..fb61b8d5 100644
--- a/packages/cli/test/doctor.test.ts
+++ b/packages/cli/test/doctor.test.ts
@@ -68,8 +68,8 @@ describe('formatDoctorReport', () => {
},
];
- const output = formatDoctorReport({ title: 'KTX status', checks });
- expect(output).toContain('KTX status');
+ const output = formatDoctorReport({ title: 'ktx status', checks });
+ expect(output).toContain('ktx status');
expect(output).toContain('✗ Environment');
expect(output).toContain('1 of 2 need attention');
expect(output).toContain('✗ Native SQLite: Cannot load better-sqlite3');
@@ -83,7 +83,7 @@ describe('formatDoctorReport', () => {
{ id: 'pnpm', label: 'pnpm 10.20+', status: 'pass', detail: '10.28.0', group: 'toolchain' },
];
- const output = formatDoctorReport({ title: 'KTX status', checks });
+ const output = formatDoctorReport({ title: 'ktx status', checks });
expect(output).toContain('✓ Environment');
expect(output).toContain('Node 22+ · pnpm 10.20+');
expect(output).not.toContain('v22.16.0');
@@ -106,7 +106,7 @@ describe('formatDoctorReport', () => {
},
];
- const output = formatDoctorReport({ title: 'KTX status', checks });
+ const output = formatDoctorReport({ title: 'ktx status', checks });
expect(output).toContain('✓ Semantic search');
expect(output).toContain('openai/text-embedding-3-small (1536d) probe succeeded');
});
@@ -116,7 +116,7 @@ describe('formatDoctorReport', () => {
{ id: 'node', label: 'Node 22+', status: 'pass', detail: 'v22.16.0', group: 'toolchain' },
];
- const output = formatDoctorReport({ title: 'KTX status', checks }, { verbose: true });
+ const output = formatDoctorReport({ title: 'ktx status', checks }, { verbose: true });
expect(output).toContain('✓ Node 22+: v22.16.0');
});
});
@@ -249,7 +249,7 @@ describe('runKtxDoctor', () => {
),
).resolves.toBe(1);
- expect(testIo.stdout()).toContain('KTX status');
+ expect(testIo.stdout()).toContain('ktx status');
expect(testIo.stdout()).toContain('No project here yet.');
expect(testIo.stdout()).toContain('Before you can run');
expect(testIo.stdout()).toContain('✗ TypeScript package build: Missing packages/cli/dist/bin.js');
@@ -304,7 +304,7 @@ describe('runKtxDoctor', () => {
).resolves.toBe(0);
expect(JSON.parse(testIo.stdout())).toEqual({
- title: 'KTX status',
+ title: 'ktx status',
checks: [{ id: 'node', label: 'Node 22+', status: 'pass', detail: 'v22.16.0 ABI 127' }],
});
});
@@ -323,8 +323,8 @@ describe('runKtxDoctor', () => {
).resolves.toBe(1);
const out = testIo.stdout();
- expect(out).toContain('KTX status');
- expect(out).toContain('No KTX project here yet.');
+ expect(out).toContain('ktx status');
+ expect(out).toContain('No ktx project here yet.');
expect(out).toContain('ktx setup');
expect(out).toContain('KTX_PROJECT_DIR');
expect(out).not.toContain('ENOENT');
@@ -377,7 +377,7 @@ describe('runKtxDoctor', () => {
).resolves.toBe(1);
const out = testIo.stdout();
- expect(out).toContain('KTX status');
+ expect(out).toContain('ktx status');
expect(out).toContain('Config');
expect(out).toContain('Unsupported storrage: unknown field');
expect(out).toContain('Unsupported ingest.llm: unknown field');
@@ -479,7 +479,7 @@ describe('runKtxDoctor', () => {
).resolves.toBe(0);
const out = testIo.stdout();
- expect(out).toContain('KTX status');
+ expect(out).toContain('ktx status');
expect(out).toContain(`· ${basename(tempDir)}`);
expect(out).toContain('Connections (1)');
expect(out).toContain('LLM');
@@ -759,7 +759,7 @@ describe('runKtxDoctor', () => {
).resolves.toBe(0);
const out = testIo.stdout();
- expect(out).toContain('KTX status');
+ expect(out).toContain('ktx status');
expect(out).toContain('Config');
expect(out).toContain('ktx.yaml schema valid');
expect(out).not.toContain('LLM');
@@ -855,7 +855,7 @@ describe('runKtxDoctor', () => {
),
).resolves.toBe(1);
- expect(testIo.stdout()).toContain('No KTX project here yet.');
+ expect(testIo.stdout()).toContain('No ktx project here yet.');
});
it('does not invoke the Postgres query-history probe in validate mode', async () => {
diff --git a/packages/cli/test/index.test.ts b/packages/cli/test/index.test.ts
index eef511fb..55af622b 100644
--- a/packages/cli/test/index.test.ts
+++ b/packages/cli/test/index.test.ts
@@ -126,7 +126,7 @@ describe('runKtxCli', () => {
await expect(runKtxCli(['--help'], testIo.io)).resolves.toBe(0);
expect(testIo.stdout()).toContain('Usage: ktx [options] [command]');
- expect(testIo.stdout()).toContain('KTX data agent context layer CLI');
+ expect(testIo.stdout()).toContain('ktx data agent context layer CLI');
for (const command of ['setup', 'connection', 'ingest', 'wiki', 'sl', 'status', 'admin']) {
expect(testIo.stdout()).toContain(`${command}`);
}
@@ -407,7 +407,7 @@ describe('runKtxCli', () => {
await expect(runKtxCli(['admin', 'runtime', 'stop', '--help'], testIo.io)).resolves.toBe(0);
expect(testIo.stdout()).toContain('--all');
- expect(testIo.stdout()).toContain('Stop all KTX daemon processes recorded or discoverable');
+ expect(testIo.stdout()).toContain('Stop all ktx daemon processes recorded or discoverable');
expect(testIo.stdout()).toContain('on this machine');
expect(testIo.stderr()).toBe('');
});
@@ -913,7 +913,7 @@ describe('runKtxCli', () => {
await expect(runKtxCli(['ingest', '--help'], testIo.io, { publicIngest })).resolves.toBe(0);
expect(testIo.stdout()).toContain('Usage: ktx ingest');
- expect(testIo.stdout()).toContain('Build or inspect KTX context');
+ expect(testIo.stdout()).toContain('Build or inspect ktx context');
expect(testIo.stdout()).toContain('--all');
expect(testIo.stdout()).toContain('--query-history');
expect(testIo.stdout()).toContain('--no-query-history');
diff --git a/packages/cli/test/ingest-viz.test.ts b/packages/cli/test/ingest-viz.test.ts
index a794043f..15564663 100644
--- a/packages/cli/test/ingest-viz.test.ts
+++ b/packages/cli/test/ingest-viz.test.ts
@@ -90,8 +90,8 @@ describe('runKtxIngest viz and replay', () => {
expect(runLocal).toHaveBeenCalledWith(expect.objectContaining({ memoryFlow: expect.any(Object) }));
expect(io.stdout()).toContain('\u001b[2J\u001b[H');
- expect((io.stdout().match(/KTX memory flow/g) ?? []).length).toBeGreaterThan(1);
- expect(io.stdout()).toContain('KTX memory flow warehouse/fake done');
+ expect((io.stdout().match(/ktx memory flow/g) ?? []).length).toBeGreaterThan(1);
+ expect(io.stdout()).toContain('ktx memory flow warehouse/fake done');
expect(io.stdout()).toContain('fake-orders');
expect(io.stderr()).toBe('');
});
@@ -145,7 +145,7 @@ describe('runKtxIngest viz and replay', () => {
expect(liveSession.update).toHaveBeenCalled();
expect(liveSession.close).toHaveBeenCalledTimes(1);
expect(io.stdout()).not.toContain('\u001b[2J\u001b[H');
- expect(io.stdout()).not.toContain('KTX memory flow');
+ expect(io.stdout()).not.toContain('ktx memory flow');
expect(io.stderr()).toBe('');
});
@@ -303,7 +303,7 @@ describe('runKtxIngest viz and replay', () => {
expect(startLiveMemoryFlow).toHaveBeenCalledTimes(1);
expect(io.stdout()).toContain('\u001b[2J\u001b[H');
- expect(io.stdout()).toContain('KTX memory flow warehouse/fake done');
+ expect(io.stdout()).toContain('ktx memory flow warehouse/fake done');
});
it('falls back to text live rendering when TUI startup fails with a redacted warning', async () => {
@@ -345,7 +345,7 @@ describe('runKtxIngest viz and replay', () => {
).resolves.toBe(0);
expect(io.stderr()).toContain('TUI visualization unavailable: Failed [redacted-url] [redacted]');
- expect(io.stdout()).toContain('KTX memory flow warehouse/fake done');
+ expect(io.stdout()).toContain('ktx memory flow warehouse/fake done');
expect(io.stdout()).toContain('\u001b[2J\u001b[H');
});
@@ -384,7 +384,7 @@ describe('runKtxIngest viz and replay', () => {
expect(startLiveMemoryFlow).not.toHaveBeenCalled();
expect(runLocal).toHaveBeenCalledWith(expect.not.objectContaining({ memoryFlow: expect.anything() }));
- expect(io.stdout()).toContain('KTX memory flow warehouse/fake done');
+ expect(io.stdout()).toContain('ktx memory flow warehouse/fake done');
});
it('attaches a plain progress memory-flow sink for interactive plain run output', async () => {
@@ -416,7 +416,7 @@ describe('runKtxIngest viz and replay', () => {
expect(io.stderr()).toContain('[5%] Fetching source files for warehouse/fake');
expect(io.stdout()).toContain('Job: plain-run');
expect(io.stdout()).not.toContain('[5%]');
- expect(io.stdout()).not.toContain('KTX memory flow');
+ expect(io.stdout()).not.toContain('ktx memory flow');
});
it('falls back to plain run output for run --viz when stdout is not interactive', async () => {
@@ -447,7 +447,7 @@ describe('runKtxIngest viz and replay', () => {
).resolves.toBe(0);
expect(io.stdout()).toContain('Job: non-tty-viz-run');
- expect(io.stdout()).not.toContain('KTX memory flow');
+ expect(io.stdout()).not.toContain('ktx memory flow');
expect(io.stderr()).toContain(
'Visualization requested but stdout is not an interactive terminal; printing plain output.',
);
@@ -493,7 +493,7 @@ describe('runKtxIngest viz and replay', () => {
expect(io.stderr()).toContain('[5%] Fetching source files for warehouse/fake');
expect(io.stdout()).toContain('Job: raw-missing-viz-run');
expect(io.stdout()).not.toContain('[5%]');
- expect(io.stdout()).not.toContain('KTX memory flow');
+ expect(io.stdout()).not.toContain('ktx memory flow');
expect(io.stderr()).toContain(
'Visualization requested but stdin raw mode is unavailable; printing plain output.',
);
@@ -547,7 +547,7 @@ describe('runKtxIngest viz and replay', () => {
runKtxIngest({ command: 'watch', projectDir, outputMode: 'viz', inputMode: 'disabled' }, io.io),
).resolves.toBe(0);
- expect(io.stdout()).toContain('KTX memory flow warehouse/fake done');
+ expect(io.stdout()).toContain('ktx memory flow warehouse/fake done');
expect(io.stdout()).toContain('Run: run-watch-latest');
expect(io.stderr()).toBe('');
});
@@ -572,7 +572,7 @@ describe('runKtxIngest viz and replay', () => {
),
).resolves.toBe(0);
- expect(io.stdout()).toContain('KTX memory flow warehouse/metabase done');
+ expect(io.stdout()).toContain('ktx memory flow warehouse/metabase done');
expect(io.stdout()).toContain('Saved 2 memories from 2 raw files');
expect(io.stdout()).toContain('Commit: abc12345 Run: run-1 Report: report-1');
expect(io.stdout()).toContain('SOURCE');
@@ -667,7 +667,7 @@ describe('runKtxIngest viz and replay', () => {
),
).resolves.toBe(0);
- expect(io.stdout()).toContain('KTX memory flow warehouse/fake done');
+ expect(io.stdout()).toContain('ktx memory flow warehouse/fake done');
expect(io.stdout()).toContain('SOURCE');
expect(io.stdout()).toContain('CHUNKS');
expect(io.stdout()).toContain('WORKUNITS');
@@ -736,7 +736,7 @@ describe('runKtxIngest viz and replay', () => {
).resolves.toBe(0);
expect(renderStoredMemoryFlow).toHaveBeenCalledTimes(1);
- expect(io.stdout()).toContain('KTX memory flow warehouse/fake done');
+ expect(io.stdout()).toContain('ktx memory flow warehouse/fake done');
});
it('does not use TUI for stored --viz when input is disabled', async () => {
@@ -766,7 +766,7 @@ describe('runKtxIngest viz and replay', () => {
).resolves.toBe(0);
expect(renderStoredMemoryFlow).not.toHaveBeenCalled();
- expect(io.stdout()).toContain('KTX memory flow warehouse/fake done');
+ expect(io.stdout()).toContain('ktx memory flow warehouse/fake done');
});
it('falls back to plain status for stored --viz when stdin raw mode is unavailable', async () => {
@@ -797,7 +797,7 @@ describe('runKtxIngest viz and replay', () => {
expect(renderStoredMemoryFlow).not.toHaveBeenCalled();
expect(io.stdout()).toContain('Run: run-raw-missing-stored-viz-run');
expect(io.stdout()).toContain('Job: raw-missing-stored-viz-run');
- expect(io.stdout()).not.toContain('KTX memory flow');
+ expect(io.stdout()).not.toContain('ktx memory flow');
expect(io.stderr()).toContain(
'Visualization requested but stdin raw mode is unavailable; printing plain output.',
);
@@ -826,7 +826,7 @@ describe('runKtxIngest viz and replay', () => {
),
).resolves.toBe(0);
- expect(io.stdout()).toContain('KTX memory flow warehouse/fake done');
+ expect(io.stdout()).toContain('ktx memory flow warehouse/fake done');
expect(io.stdout()).not.toContain('\u001b[2J\u001b[H');
expect(io.stderr()).toBe('');
});
@@ -854,7 +854,7 @@ describe('runKtxIngest viz and replay', () => {
),
).resolves.toBe(0);
- expect(io.stdout()).toContain('KTX memory flow warehouse/fake done');
+ expect(io.stdout()).toContain('ktx memory flow warehouse/fake done');
expect(io.stdout()).not.toContain('\u001b[2J\u001b[H');
expect(io.stderr()).toBe('');
});
@@ -884,7 +884,7 @@ describe('runKtxIngest viz and replay', () => {
expect(io.stdout()).toContain('Run: run-redirected-no-input-viz-run');
expect(io.stdout()).toContain('Job: redirected-no-input-viz-run');
- expect(io.stdout()).not.toContain('KTX memory flow');
+ expect(io.stdout()).not.toContain('ktx memory flow');
expect(io.stderr()).toContain(
'Visualization requested but stdout is not an interactive terminal; printing plain output.',
);
@@ -910,7 +910,7 @@ describe('runKtxIngest viz and replay', () => {
expect(io.stdout()).toContain('Run: run-dumb-terminal-viz-run');
expect(io.stdout()).toContain('Job: dumb-terminal-viz-run');
- expect(io.stdout()).not.toContain('KTX memory flow');
+ expect(io.stdout()).not.toContain('ktx memory flow');
expect(io.stderr()).toContain(
'Visualization requested but TERM=dumb does not support the visual renderer; printing plain output.',
);
@@ -932,7 +932,7 @@ describe('runKtxIngest viz and replay', () => {
expect(io.stdout()).toContain('Run: run-viz-run-2');
expect(io.stdout()).toContain('Job: viz-run-2');
- expect(io.stdout()).not.toContain('KTX memory flow');
+ expect(io.stdout()).not.toContain('ktx memory flow');
expect(io.stderr()).toContain(
'Visualization requested but stdout is not an interactive terminal; printing plain output.',
);
diff --git a/packages/cli/test/ingest.test.ts b/packages/cli/test/ingest.test.ts
index 35385156..febc91ab 100644
--- a/packages/cli/test/ingest.test.ts
+++ b/packages/cli/test/ingest.test.ts
@@ -1507,7 +1507,7 @@ describe('runKtxIngest', () => {
);
});
- it('passes KTX daemon options to adapters and pull-config options when no explicit daemon URL is set', async () => {
+ it('passes ktx daemon options to adapters and pull-config options when no explicit daemon URL is set', async () => {
const projectDir = join(tempDir, 'managed-daemon-ingest-project');
await initKtxProject({ projectDir });
await writeWarehouseConfig(projectDir);
diff --git a/packages/cli/test/llm/embedding-health.test.ts b/packages/cli/test/llm/embedding-health.test.ts
index f659b2d6..e310bf51 100644
--- a/packages/cli/test/llm/embedding-health.test.ts
+++ b/packages/cli/test/llm/embedding-health.test.ts
@@ -1,7 +1,7 @@
import { describe, expect, it, vi } from 'vitest';
import { runKtxEmbeddingHealthCheck } from '../../src/llm/embedding-health.js';
-describe('KTX embedding health check', () => {
+describe('ktx embedding health check', () => {
it('runs a one-shot OpenAI embedding check through the configured provider', async () => {
const createOpenAIClient = vi.fn(() => ({
embeddings: {
diff --git a/packages/cli/test/llm/embedding-provider.test.ts b/packages/cli/test/llm/embedding-provider.test.ts
index 071a17b0..a46cb16f 100644
--- a/packages/cli/test/llm/embedding-provider.test.ts
+++ b/packages/cli/test/llm/embedding-provider.test.ts
@@ -12,7 +12,7 @@ describe('createKtxEmbeddingProvider', () => {
}),
) as KtxEmbeddingConfig;
- expect(() => createKtxEmbeddingProvider(config)).toThrow('Unsupported KTX embedding backend: deterministic');
+ expect(() => createKtxEmbeddingProvider(config)).toThrow('Unsupported ktx embedding backend: deterministic');
});
it('rejects gateway embeddings', () => {
@@ -25,7 +25,7 @@ describe('createKtxEmbeddingProvider', () => {
}),
) as KtxEmbeddingConfig;
- expect(() => createKtxEmbeddingProvider(config)).toThrow('Unsupported KTX embedding backend: gateway');
+ expect(() => createKtxEmbeddingProvider(config)).toThrow('Unsupported ktx embedding backend: gateway');
});
it('uses OpenAI embeddings with configured dimensions', async () => {
diff --git a/packages/cli/test/llm/model-health.test.ts b/packages/cli/test/llm/model-health.test.ts
index 0af6f8e8..5b0b0cc4 100644
--- a/packages/cli/test/llm/model-health.test.ts
+++ b/packages/cli/test/llm/model-health.test.ts
@@ -4,7 +4,7 @@ import { runKtxLlmHealthCheck } from '../../src/llm/model-health.js';
const anthropicModel = { modelId: 'claude-sonnet-4-6' } as never;
-describe('KTX LLM health check', () => {
+describe('ktx LLM health check', () => {
it('runs a minimal non-streaming model call through the configured provider', async () => {
const generateText = vi.fn(async () => ({ text: 'ok' }));
const createAnthropic = vi.fn(() => vi.fn(() => anthropicModel));
diff --git a/packages/cli/test/managed-local-embeddings.test.ts b/packages/cli/test/managed-local-embeddings.test.ts
index 9c78e177..004e9302 100644
--- a/packages/cli/test/managed-local-embeddings.test.ts
+++ b/packages/cli/test/managed-local-embeddings.test.ts
@@ -95,7 +95,7 @@ function daemonResult(status: 'started' | 'reused' = 'reused'): ManagedPythonDae
}
describe('managedLocalEmbeddingHealthConfig', () => {
- it('uses the active KTX daemon URL for the immediate health check', () => {
+ it('uses the active ktx daemon URL for the immediate health check', () => {
expect(
managedLocalEmbeddingHealthConfig({
baseUrl: 'http://127.0.0.1:61234',
@@ -112,7 +112,7 @@ describe('managedLocalEmbeddingHealthConfig', () => {
});
describe('ensureManagedLocalEmbeddingsDaemon', () => {
- it('ensures the local-embeddings feature and starts the KTX daemon', async () => {
+ it('ensures the local-embeddings feature and starts the ktx daemon', async () => {
const io = makeIo();
const ensureRuntime = vi.fn(async () => runtime());
const startDaemon = vi.fn(async () => daemonResult('started'));
@@ -144,7 +144,7 @@ describe('ensureManagedLocalEmbeddingsDaemon', () => {
features: ['local-embeddings'],
force: false,
});
- expect(io.stderr()).toContain('Started KTX daemon: http://127.0.0.1:61234');
+ expect(io.stderr()).toContain('Started ktx daemon: http://127.0.0.1:61234');
});
it('reuses an already running daemon without reporting a new start', async () => {
@@ -159,7 +159,7 @@ describe('ensureManagedLocalEmbeddingsDaemon', () => {
startDaemon: vi.fn(async () => daemonResult('reused')),
});
- expect(io.stderr()).toContain('Using KTX daemon: http://127.0.0.1:61234');
+ expect(io.stderr()).toContain('Using ktx daemon: http://127.0.0.1:61234');
});
});
diff --git a/packages/cli/test/managed-python-command.test.ts b/packages/cli/test/managed-python-command.test.ts
index f08589f1..a782ae43 100644
--- a/packages/cli/test/managed-python-command.test.ts
+++ b/packages/cli/test/managed-python-command.test.ts
@@ -157,9 +157,9 @@ describe('createManagedPythonSemanticLayerComputePort', () => {
layout: { versionDir: '/runtime/0.2.0' },
});
- expect(io.stderr()).toContain('Installing KTX Python runtime (local-embeddings) with uv...');
- expect(io.stderr()).toContain('KTX Python runtime ready: /runtime/0.2.0');
- expect(io.stderr().match(/Installing KTX Python runtime/g)).toHaveLength(1);
+ expect(io.stderr()).toContain('Installing ktx Python runtime (local-embeddings) with uv...');
+ expect(io.stderr()).toContain('ktx Python runtime ready: /runtime/0.2.0');
+ expect(io.stderr().match(/Installing ktx Python runtime/g)).toHaveLength(1);
});
it('shows runtime installation progress with the CLI spinner', async () => {
@@ -181,8 +181,8 @@ describe('createManagedPythonSemanticLayerComputePort', () => {
});
expect(events).toEqual([
- 'start:Installing KTX Python runtime (local-embeddings) with uv...',
- 'stop:KTX Python runtime ready: /runtime/0.2.0',
+ 'start:Installing ktx Python runtime (local-embeddings) with uv...',
+ 'stop:ktx Python runtime ready: /runtime/0.2.0',
]);
});
@@ -221,7 +221,7 @@ describe('createManagedPythonSemanticLayerComputePort', () => {
readStatus: vi.fn(async () => missingStatus()),
installRuntime,
}),
- ).rejects.toThrow('KTX Python runtime is required for this command. Run: ktx admin runtime install --yes');
+ ).rejects.toThrow('ktx Python runtime is required for this command. Run: ktx admin runtime install --yes');
expect(installRuntime).not.toHaveBeenCalled();
});
@@ -251,8 +251,8 @@ describe('createManagedPythonSemanticLayerComputePort', () => {
force: false,
});
expect(events).toEqual([
- 'start:Installing KTX Python runtime (core) with uv...',
- 'stop:KTX Python runtime ready: /runtime/0.2.0',
+ 'start:Installing ktx Python runtime (core) with uv...',
+ 'stop:ktx Python runtime ready: /runtime/0.2.0',
]);
});
@@ -274,7 +274,7 @@ describe('createManagedPythonSemanticLayerComputePort', () => {
});
expect(confirmInstall).toHaveBeenCalledWith(
- 'KTX needs to install the core Python runtime. This downloads Python dependencies with uv. Continue?',
+ 'ktx needs to install the core Python runtime. This downloads Python dependencies with uv. Continue?',
io.io,
);
expect(installRuntime).toHaveBeenCalledWith({
@@ -282,7 +282,7 @@ describe('createManagedPythonSemanticLayerComputePort', () => {
features: ['core'],
force: false,
});
- expect(events).toContainEqual('start:Installing KTX Python runtime (core) with uv...');
+ expect(events).toContainEqual('start:Installing ktx Python runtime (core) with uv...');
});
it('uses injected runtime confirmation instead of reading process TTY directly', async () => {
@@ -306,10 +306,10 @@ describe('createManagedPythonSemanticLayerComputePort', () => {
).resolves.toBe(compute);
expect(confirmInstall).toHaveBeenCalledWith(
- 'KTX needs to install the core Python runtime. This downloads Python dependencies with uv. Continue?',
+ 'ktx needs to install the core Python runtime. This downloads Python dependencies with uv. Continue?',
io.io,
);
- expect(events).toContainEqual('start:Installing KTX Python runtime (core) with uv...');
+ expect(events).toContainEqual('start:Installing ktx Python runtime (core) with uv...');
});
it('can decide default runtime prompting from injected io capabilities', async () => {
@@ -325,6 +325,6 @@ describe('createManagedPythonSemanticLayerComputePort', () => {
installRuntime: vi.fn(),
createPythonCompute: () => ({ query: vi.fn(), validateSources: vi.fn(), generateSources: vi.fn() }),
}),
- ).rejects.toThrow('KTX Python runtime installation was cancelled');
+ ).rejects.toThrow('ktx Python runtime installation was cancelled');
});
});
diff --git a/packages/cli/test/managed-python-daemon.test.ts b/packages/cli/test/managed-python-daemon.test.ts
index 4684c731..6cb82710 100644
--- a/packages/cli/test/managed-python-daemon.test.ts
+++ b/packages/cli/test/managed-python-daemon.test.ts
@@ -126,7 +126,7 @@ function daemonOptionsBase(root: string) {
} as const;
}
-describe('KTX daemon lifecycle', () => {
+describe('ktx daemon lifecycle', () => {
let tempDir: string;
beforeEach(async () => {
diff --git a/packages/cli/test/managed-python-http.test.ts b/packages/cli/test/managed-python-http.test.ts
index 74334042..ef06960f 100644
--- a/packages/cli/test/managed-python-http.test.ts
+++ b/packages/cli/test/managed-python-http.test.ts
@@ -57,7 +57,7 @@ describe('createManagedPythonDaemonBaseUrlResolver', () => {
features: ['core'],
force: false,
});
- expect(testIo.stderr()).toContain('Started KTX daemon: http://127.0.0.1:61234');
+ expect(testIo.stderr()).toContain('Started ktx daemon: http://127.0.0.1:61234');
});
it('reports daemon reuse without reinstalling after the first resolved URL', async () => {
@@ -86,7 +86,7 @@ describe('createManagedPythonDaemonBaseUrlResolver', () => {
expect(ensureRuntime).toHaveBeenCalledTimes(1);
expect(startDaemon).toHaveBeenCalledTimes(1);
- expect(testIo.stderr()).toContain('Using existing KTX daemon: http://127.0.0.1:61234');
+ expect(testIo.stderr()).toContain('Using existing ktx daemon: http://127.0.0.1:61234');
});
});
@@ -104,8 +104,8 @@ describe('createManagedDaemonHttpJsonRunner', () => {
});
});
-describe('KTX daemon ingest ports', () => {
- it('creates a Looker table parser backed by the KTX daemon runner', async () => {
+describe('ktx daemon ingest ports', () => {
+ it('creates a Looker table parser backed by the ktx daemon runner', async () => {
const requestJson = vi.fn(async () => ({
results: {
'model.explore': {
@@ -135,7 +135,7 @@ describe('KTX daemon ingest ports', () => {
});
});
- it('creates a SQL analysis port backed by the KTX daemon runner', async () => {
+ it('creates a SQL analysis port backed by the ktx daemon runner', async () => {
const requestJson = vi.fn(async () => ({
fingerprint: 'select-orders',
normalized_sql: 'SELECT * FROM public.orders WHERE id = ?',
@@ -157,7 +157,7 @@ describe('KTX daemon ingest ports', () => {
});
});
- it('routes SQL batch analysis through the KTX daemon runner', async () => {
+ it('routes SQL batch analysis through the ktx daemon runner', async () => {
const requestJson = vi.fn(async () => ({
results: {
orders: {
diff --git a/packages/cli/test/mcp-http-server.test.ts b/packages/cli/test/mcp-http-server.test.ts
index ddd0bf0f..86c82326 100644
--- a/packages/cli/test/mcp-http-server.test.ts
+++ b/packages/cli/test/mcp-http-server.test.ts
@@ -41,7 +41,7 @@ describe('buildMcpSecurityConfig', () => {
allowedHosts: [],
allowedOrigins: [],
}),
- ).toThrow('Binding KTX MCP to 0.0.0.0 requires --token or KTX_MCP_TOKEN');
+ ).toThrow('Binding ktx MCP to 0.0.0.0 requires --token or KTX_MCP_TOKEN');
});
it('validates allowed origins as full origins', () => {
@@ -88,7 +88,7 @@ describe('isMcpRequestAuthorized', () => {
{ path: '/health', headers: { host: 'evil.example.test' } },
config,
),
- ).toEqual({ ok: false, status: 403, message: 'Host header is not allowed for KTX MCP.' });
+ ).toEqual({ ok: false, status: 403, message: 'Host header is not allowed for ktx MCP.' });
});
it('rejects browser origins unless explicitly allowed', () => {
@@ -100,7 +100,7 @@ describe('isMcpRequestAuthorized', () => {
},
config,
),
- ).toEqual({ ok: false, status: 403, message: 'Origin header is not allowed for KTX MCP.' });
+ ).toEqual({ ok: false, status: 403, message: 'Origin header is not allowed for ktx MCP.' });
});
it('requires bearer auth on /mcp when token auth is enabled', () => {
@@ -109,7 +109,7 @@ describe('isMcpRequestAuthorized', () => {
{ path: '/mcp', headers: { host: 'mcp.example.test', authorization: 'Bearer wrong' } },
config,
),
- ).toEqual({ ok: false, status: 401, message: 'Missing or invalid KTX MCP bearer token.' });
+ ).toEqual({ ok: false, status: 401, message: 'Missing or invalid ktx MCP bearer token.' });
});
it('does not require bearer auth on /health', () => {
diff --git a/packages/cli/test/mcp-server-factory.test.ts b/packages/cli/test/mcp-server-factory.test.ts
index 05ac5aac..e43fcb49 100644
--- a/packages/cli/test/mcp-server-factory.test.ts
+++ b/packages/cli/test/mcp-server-factory.test.ts
@@ -186,7 +186,7 @@ describe('createKtxMcpServerFactory', () => {
factory();
expect(io.stderr.write).toHaveBeenCalledWith(
- 'KTX MCP memory_ingest disabled: missing local memory prerequisites\n',
+ 'ktx MCP memory_ingest disabled: missing local memory prerequisites\n',
);
expect(createDefaultKtxMcpServer).toHaveBeenCalledWith(
expect.objectContaining({
diff --git a/packages/cli/test/memory-flow-tui.test.tsx b/packages/cli/test/memory-flow-tui.test.tsx
index 87a5a96f..85db125f 100644
--- a/packages/cli/test/memory-flow-tui.test.tsx
+++ b/packages/cli/test/memory-flow-tui.test.tsx
@@ -102,7 +102,7 @@ describe('sanitizeMemoryFlowTuiError', () => {
});
describe('MemoryFlowTuiApp', () => {
- it('always shows the KTX logo', () => {
+ it('always shows the ktx logo', () => {
const { lastFrame } = renderInkTest();
expect(lastFrame()).toContain('╚███╔╝');
});
@@ -197,7 +197,7 @@ describe('MemoryFlowTuiApp', () => {
expect(frame).toContain('Created so far:');
expect(frame).toContain('order lifecycle');
expect(frame).toContain('customer metrics');
- expect(frame).toContain('KTX finished ingesting your data');
+ expect(frame).toContain('ktx finished ingesting your data');
expect(frame).toContain('ktx sl');
expect(frame).toContain('ktx wiki');
expect(frame).not.toContain('ktx serve --mcp stdio --user-id local');
@@ -253,7 +253,7 @@ describe('MemoryFlowTuiApp', () => {
it('hides completion while running', () => {
const { lastFrame } = renderInkTest();
- expect(lastFrame()).not.toContain('KTX finished ingesting');
+ expect(lastFrame()).not.toContain('ktx finished ingesting');
});
});
diff --git a/packages/cli/test/next-steps.test.ts b/packages/cli/test/next-steps.test.ts
index eed0f3bf..3c433ddb 100644
--- a/packages/cli/test/next-steps.test.ts
+++ b/packages/cli/test/next-steps.test.ts
@@ -6,7 +6,7 @@ import {
formatSetupNextStepLines,
} from '../src/next-steps.js';
-describe('KTX demo next steps', () => {
+describe('ktx demo next steps', () => {
it('uses supported context-build commands before agent usage', () => {
expect(KTX_CONTEXT_BUILD_COMMANDS).toEqual([
{
@@ -48,8 +48,8 @@ describe('KTX demo next steps', () => {
it('explains what the next-step commands are for', () => {
const rendered = formatNextStepLines().join('\n');
- expect(rendered).toContain('KTX context is ready for agents.');
- expect(rendered).toContain('KTX project directory');
+ expect(rendered).toContain('ktx context is ready for agents.');
+ expect(rendered).toContain('ktx project directory');
expect(rendered).toContain('ask a data question');
expect(rendered).toContain('Verify with:');
expect(rendered).not.toContain('this directory');
@@ -82,7 +82,7 @@ describe('KTX demo next steps', () => {
agentIntegrationReady: true,
}).join('\n');
- expect(rendered).toContain('KTX context is ready for agents.');
+ expect(rendered).toContain('ktx context is ready for agents.');
expect(rendered).toContain('ktx status --json');
expect(rendered).not.toContain('ktx agent');
expect(rendered).not.toContain('ktx serve --mcp stdio --user-id local');
diff --git a/packages/cli/test/print-command-tree.test.ts b/packages/cli/test/print-command-tree.test.ts
index 387874b3..cbb7c573 100644
--- a/packages/cli/test/print-command-tree.test.ts
+++ b/packages/cli/test/print-command-tree.test.ts
@@ -21,7 +21,7 @@ describe('renderKtxCommandTree', () => {
expect(output).not.toContain('__complete');
expect(output).toContain('│ └── test [connectionId]');
- expect(output).toContain('│ ├── status Show KTX MCP daemon status');
+ expect(output).toContain('│ ├── status Show ktx MCP daemon status');
expect(output).not.toContain('│ ├── add');
expect(output).not.toContain('│ ├── remove');
expect(output).not.toContain('│ ├── map');
diff --git a/packages/cli/test/prompt-navigation.test.ts b/packages/cli/test/prompt-navigation.test.ts
index e0b4cf8b..9bbd34e9 100644
--- a/packages/cli/test/prompt-navigation.test.ts
+++ b/packages/cli/test/prompt-navigation.test.ts
@@ -7,8 +7,8 @@ describe('prompt navigation helpers', () => {
});
it('adds a blank separator between multiline menu copy and the option list', () => {
- expect(withMenuOptionSpacing('Which embedding option should KTX use?\n\nKTX uses embeddings for search.')).toBe(
- 'Which embedding option should KTX use?\n\nKTX uses embeddings for search.\n',
+ expect(withMenuOptionSpacing('Which embedding option should ktx use?\n\nktx uses embeddings for search.')).toBe(
+ 'Which embedding option should ktx use?\n\nktx uses embeddings for search.\n',
);
});
@@ -25,10 +25,10 @@ describe('prompt navigation helpers', () => {
it('adds a blank separator between text input helper copy and the editable value', () => {
expect(
withTextInputNavigation(
- 'Name this PostgreSQL connection\nKTX will use this short name in commands and config. You can rename it now.',
+ 'Name this PostgreSQL connection\nktx will use this short name in commands and config. You can rename it now.',
),
).toBe(
- 'Name this PostgreSQL connection\n│\n│ KTX will use this short name in commands and config. You can rename it now.\n│ Press Escape to go back.\n│',
+ 'Name this PostgreSQL connection\n│\n│ ktx will use this short name in commands and config. You can rename it now.\n│ Press Escape to go back.\n│',
);
});
@@ -39,10 +39,10 @@ describe('prompt navigation helpers', () => {
it('normalizes already hinted text input prompts without duplicating the hint', () => {
expect(
withTextInputNavigation(
- 'Name this PostgreSQL connection\nKTX will use this short name in commands and config. You can rename it now.\nPress Escape to go back.',
+ 'Name this PostgreSQL connection\nktx will use this short name in commands and config. You can rename it now.\nPress Escape to go back.',
),
).toBe(
- 'Name this PostgreSQL connection\n│\n│ KTX will use this short name in commands and config. You can rename it now.\n│ Press Escape to go back.\n│',
+ 'Name this PostgreSQL connection\n│\n│ ktx will use this short name in commands and config. You can rename it now.\n│ Press Escape to go back.\n│',
);
});
@@ -53,7 +53,7 @@ describe('prompt navigation helpers', () => {
it('is idempotent when text input navigation with body is applied twice', () => {
const once = withTextInputNavigation(
- 'Name this PostgreSQL connection\nKTX will use this short name in commands and config.',
+ 'Name this PostgreSQL connection\nktx will use this short name in commands and config.',
);
expect(withTextInputNavigation(once)).toBe(once);
});
diff --git a/packages/cli/test/public-ingest-copy.test.ts b/packages/cli/test/public-ingest-copy.test.ts
index 539d76ce..1554fc21 100644
--- a/packages/cli/test/public-ingest-copy.test.ts
+++ b/packages/cli/test/public-ingest-copy.test.ts
@@ -16,7 +16,7 @@ describe('public ingest copy sanitizers', () => {
it('maps database scan failure text into public database ingest wording', () => {
expect(
publicDatabaseIngestMessage(
- 'KTX scan enrichment failed after structural scan completed: embedding service timed out',
+ 'ktx scan enrichment failed after structural scan completed: embedding service timed out',
),
).toBe('Database enrichment failed after schema context completed: embedding service timed out');
expect(publicDatabaseIngestMessage('structural scan wrote partial artifacts')).toBe(
@@ -42,7 +42,7 @@ describe('public ingest copy sanitizers', () => {
it('sanitizes captured public output lines across database and query-history internals', () => {
expect(
publicIngestOutputLine(
- 'KTX scan enrichment failed after structural scan completed in raw-sources/warehouse/live-database/sync-1',
+ 'ktx scan enrichment failed after structural scan completed in raw-sources/warehouse/live-database/sync-1',
),
).toBe('Database enrichment failed after schema context completed in raw-sources/warehouse/database schema/sync-1');
expect(publicIngestOutputLine('Historic SQL local ingest requires a configured reader')).toBe(
diff --git a/packages/cli/test/public-ingest.test.ts b/packages/cli/test/public-ingest.test.ts
index 6dea8834..5e7fffdf 100644
--- a/packages/cli/test/public-ingest.test.ts
+++ b/packages/cli/test/public-ingest.test.ts
@@ -837,7 +837,7 @@ describe('runKtxPublicIngest', () => {
const io = makeIo();
const project = deepReadyProject({ warehouse: { driver: 'postgres' } });
const runScan = vi.fn(async (_args, scanIo) => {
- scanIo.stdout.write('KTX scan completed\n');
+ scanIo.stdout.write('ktx scan completed\n');
scanIo.stdout.write('Mode: structural\n');
scanIo.stdout.write('Report: raw-sources/warehouse/live-database/sync-1/scan-report.json\n');
scanIo.stdout.write('Raw sources: raw-sources/warehouse/live-database/sync-1\n');
@@ -861,7 +861,7 @@ describe('runKtxPublicIngest', () => {
expect(io.stdout()).toContain('Ingest finished\n');
expect(io.stdout()).toContain('warehouse');
- expect(io.stdout()).not.toContain('KTX scan completed');
+ expect(io.stdout()).not.toContain('ktx scan completed');
expect(io.stdout()).not.toContain('Mode: structural');
expect(io.stdout()).not.toContain('Report: raw-sources');
expect(io.stdout()).not.toContain('live-database');
@@ -871,7 +871,7 @@ describe('runKtxPublicIngest', () => {
const io = makeIo();
const project = deepReadyProject({ warehouse: { driver: 'postgres' } });
const runScan = vi.fn(async (_args, scanIo) => {
- scanIo.stdout.write('KTX scan enrichment failed after structural scan completed: embedding service timed out\n');
+ scanIo.stdout.write('ktx scan enrichment failed after structural scan completed: embedding service timed out\n');
return 1;
});
@@ -894,7 +894,7 @@ describe('runKtxPublicIngest', () => {
'warehouse failed: Database enrichment failed after schema context completed: embedding service timed out.',
);
expect(io.stdout()).toContain('Retry: ktx ingest warehouse --project-dir /tmp/project');
- expect(io.stdout()).not.toContain('KTX scan enrichment failed');
+ expect(io.stdout()).not.toContain('ktx scan enrichment failed');
expect(io.stdout()).not.toContain('structural scan');
});
@@ -988,7 +988,7 @@ describe('runKtxPublicIngest', () => {
docs: { driver: 'notion' },
});
const runScan = vi.fn>(async (_args, scanIo, deps) => {
- scanIo.stdout.write('KTX scan completed\n');
+ scanIo.stdout.write('ktx scan completed\n');
scanIo.stdout.write('Report: raw-sources/warehouse/live-database/sync-1/scan-report.json\n');
await deps?.progress?.update(0.12, 'Inspecting database schema');
const enrichmentProgress = deps?.progress?.startPhase(0.5);
@@ -1030,7 +1030,7 @@ describe('runKtxPublicIngest', () => {
expect(io.stdout()).toContain('Ingest finished');
expect(io.stdout()).toContain('warehouse');
expect(io.stdout()).toContain('docs');
- expect(io.stdout()).not.toContain('KTX scan completed');
+ expect(io.stdout()).not.toContain('ktx scan completed');
expect(io.stdout()).not.toContain('Report:');
expect(io.stdout()).not.toContain('Adapter:');
expect(io.stderr()).toContain('[1/2] warehouse · database schema\n');
@@ -1080,7 +1080,7 @@ describe('runKtxPublicIngest', () => {
const project = deepReadyProject({ warehouse: { driver: 'postgres' } });
const runScan = vi.fn>(async (_args, scanIo, deps) => {
await deps?.progress?.update(0.42, 'Enriching schema metadata');
- scanIo.stdout.write('KTX scan enrichment failed after structural scan completed: embedding service timed out\n');
+ scanIo.stdout.write('ktx scan enrichment failed after structural scan completed: embedding service timed out\n');
return 1;
});
@@ -1105,7 +1105,7 @@ describe('runKtxPublicIngest', () => {
expect(io.stdout()).toContain(
'warehouse failed: Database enrichment failed after schema context completed: embedding service timed out.',
);
- expect(io.stdout()).not.toContain('KTX scan enrichment failed');
+ expect(io.stdout()).not.toContain('ktx scan enrichment failed');
expect(io.stdout()).not.toContain('structural scan');
});
@@ -1477,7 +1477,7 @@ describe('runKtxPublicIngest', () => {
scanIo.stdout.write('Run: scan-run-1\n');
scanIo.stdout.write('Mode: enriched\n');
scanIo.stdout.write('Dry run: no\n');
- scanIo.stdout.write('KTX scan completed\n');
+ scanIo.stdout.write('ktx scan completed\n');
return 0;
});
const runIngest = vi.fn(async (_args, ingestIo) => {
@@ -1516,7 +1516,7 @@ describe('runKtxPublicIngest', () => {
const runIngest = vi.fn(async (_args, ingestIo) => {
ingestIo.stderr.write('Missing bundled Python runtime manifest: /repo/packages/cli/assets/python/manifest.json\n');
ingestIo.stderr.write('In a source checkout, build the local runtime assets with: pnpm run artifacts:build\n');
- ingestIo.stderr.write('Then retry the runtime-backed KTX command.\n');
+ ingestIo.stderr.write('Then retry the runtime-backed ktx command.\n');
return 1;
});
@@ -1542,7 +1542,7 @@ describe('runKtxPublicIngest', () => {
'In a source checkout, build the local runtime assets with: pnpm run artifacts:build',
);
expect(io.stdout()).toContain('Retry: ktx ingest warehouse --project-dir /tmp/project --query-history');
- expect(io.stdout()).not.toContain('Then retry the runtime-backed KTX command');
+ expect(io.stdout()).not.toContain('Then retry the runtime-backed ktx command');
});
it('fails enrichment-readiness targets before work starts while continuing independent --all targets', async () => {
diff --git a/packages/cli/test/runtime.test.ts b/packages/cli/test/runtime.test.ts
index 4525bf83..b730f36c 100644
--- a/packages/cli/test/runtime.test.ts
+++ b/packages/cli/test/runtime.test.ts
@@ -103,13 +103,13 @@ describe('runKtxRuntime', () => {
features: ['local-embeddings'],
force: true,
});
- expect(io.stdout()).toContain('Installed KTX Python runtime');
+ expect(io.stdout()).toContain('Installed ktx Python runtime');
expect(io.stdout()).toContain('features: core, local-embeddings');
expect(io.stdout()).toContain('manifest: /runtime/0.2.0/manifest.json');
expect(io.stderr()).toBe('');
});
- it('starts the KTX daemon and prints the base URL', async () => {
+ it('starts the ktx daemon and prints the base URL', async () => {
const io = makeIo();
const deps: KtxRuntimeDeps = {
startDaemon: vi.fn(async (): Promise => ({
@@ -160,14 +160,14 @@ describe('runKtxRuntime', () => {
features: ['local-embeddings'],
force: true,
});
- expect(io.stdout()).toContain('Started KTX daemon');
+ expect(io.stdout()).toContain('Started ktx daemon');
expect(io.stdout()).toContain('url: http://127.0.0.1:61234');
expect(io.stdout()).toContain('pid: 4242');
expect(io.stdout()).toContain('features: core, local-embeddings');
expect(io.stdout()).toContain('stderr: /work/proj/.ktx/runtime/daemon.stderr.log');
});
- it('stops the KTX daemon', async () => {
+ it('stops the ktx daemon', async () => {
const io = makeIo();
const deps: KtxRuntimeDeps = {
stopDaemon: vi.fn(async (): Promise => ({
@@ -208,11 +208,11 @@ describe('runKtxRuntime', () => {
).resolves.toBe(0);
expect(deps.stopDaemon).toHaveBeenCalledWith({ cliVersion: '0.2.0', projectDir: '/work/proj' });
- expect(io.stdout()).toContain('Stopped KTX daemon');
+ expect(io.stdout()).toContain('Stopped ktx daemon');
expect(io.stdout()).toContain('pid: 4242');
});
- it('stops all discovered KTX daemons and reports the summary', async () => {
+ it('stops all discovered ktx daemons and reports the summary', async () => {
const io = makeIo();
const deps: KtxRuntimeDeps = {
stopAllDaemons: vi.fn(async (): Promise => ({
@@ -231,7 +231,7 @@ describe('runKtxRuntime', () => {
).resolves.toBe(0);
expect(deps.stopAllDaemons).toHaveBeenCalledWith({ cliVersion: '0.2.0', projectDir: '/work/proj' });
- expect(io.stdout()).toContain('Stopped 2 KTX daemons');
+ expect(io.stdout()).toContain('Stopped 2 ktx daemons');
expect(io.stdout()).toContain('pid: 4242 source: state url: http://127.0.0.1:61234');
expect(io.stdout()).toContain('pid: 5252 source: process url: http://127.0.0.1:8765');
});
@@ -259,7 +259,7 @@ describe('runKtxRuntime', () => {
runKtxRuntime({ command: 'stop', cliVersion: '0.2.0', projectDir: '/work/proj', all: true }, io.io, deps),
).resolves.toBe(1);
- expect(io.stderr()).toContain('Stopped 0 KTX daemons; failed 1');
+ expect(io.stderr()).toContain('Stopped 0 ktx daemons; failed 1');
expect(io.stderr()).toContain('pid: 4242 source: state url: http://127.0.0.1:61234');
expect(io.stderr()).toContain('process scan: ps failed');
});
@@ -362,9 +362,9 @@ describe('runKtxRuntime', () => {
await expect(runKtxRuntime({ command: 'status', cliVersion: '0.2.0', json: false }, io.io, deps)).resolves.toBe(0);
- expect(io.stdout()).toContain('KTX Python runtime');
+ expect(io.stdout()).toContain('ktx Python runtime');
expect(io.stdout()).toContain('status: ready');
- expect(io.stdout()).toContain('KTX Python runtime checks');
+ expect(io.stdout()).toContain('ktx Python runtime checks');
expect(io.stdout()).toContain('PASS uv: uv 0.9.5');
expect(io.stdout()).toContain('PASS Managed Python runtime: Runtime ready at /runtime/0.2.0');
expect(io.stderr()).toBe('');
diff --git a/packages/cli/test/scan.test.ts b/packages/cli/test/scan.test.ts
index 51c55498..e1e8a29c 100644
--- a/packages/cli/test/scan.test.ts
+++ b/packages/cli/test/scan.test.ts
@@ -293,7 +293,7 @@ const reportWithAttention: KtxScanReport = {
warnings: [
{
code: 'connector_capability_missing',
- message: 'KTX scan connector is missing optional capability: columnStats',
+ message: 'ktx scan connector is missing optional capability: columnStats',
recoverable: true,
metadata: { capability: 'columnStats' },
},
@@ -372,7 +372,7 @@ describe('runKtxScan', () => {
connector: undefined,
}),
);
- expect(io.stdout()).toContain('KTX scan completed\n');
+ expect(io.stdout()).toContain('ktx scan completed\n');
expect(io.stdout()).toContain('Run: scan-run-1');
expect(io.stdout()).toContain('Mode: structural');
expect(io.stdout()).toContain('What changed\n');
@@ -494,7 +494,7 @@ describe('runKtxScan', () => {
);
});
- it('passes KTX daemon options to local ingest adapters when no explicit daemon URL is set', async () => {
+ it('passes ktx daemon options to local ingest adapters when no explicit daemon URL is set', async () => {
await initKtxProject({ projectDir: tempDir });
const createLocalIngestAdapters = vi.fn(() => []);
const runLocalScan = vi.fn(
@@ -649,7 +649,7 @@ describe('runKtxScan', () => {
warnings: [
{
code: 'connector_capability_missing',
- message: 'KTX scan connector cannot run read-only SQL relationship validation',
+ message: 'ktx scan connector cannot run read-only SQL relationship validation',
recoverable: true,
metadata: { capability: 'readOnlySql' },
},
@@ -690,7 +690,7 @@ describe('runKtxScan', () => {
expect(io.stdout()).toContain('Review: 12');
expect(io.stdout()).toContain('Rejected: 44');
expect(io.stdout()).toContain(
- 'connector_capability_missing: KTX scan connector cannot run read-only SQL relationship validation',
+ 'connector_capability_missing: ktx scan connector cannot run read-only SQL relationship validation',
);
});
@@ -972,7 +972,7 @@ describe('runKtxScan', () => {
}
expect(io.stdout()).toContain('✓');
- expect(io.stdout()).toContain('KTX scan completed');
+ expect(io.stdout()).toContain('ktx scan completed');
expect(io.stdout()).toContain('\u001b[');
});
@@ -1017,7 +1017,7 @@ describe('runKtxScan', () => {
}
}
- expect(io.stdout()).toContain('KTX scan completed');
+ expect(io.stdout()).toContain('ktx scan completed');
expect(io.stdout()).not.toContain('\u001b[');
});
diff --git a/packages/cli/test/setup-agents.test.ts b/packages/cli/test/setup-agents.test.ts
index c6c2d7c4..d08355e5 100644
--- a/packages/cli/test/setup-agents.test.ts
+++ b/packages/cli/test/setup-agents.test.ts
@@ -406,16 +406,16 @@ describe('setup agents', () => {
});
expect(prompts.select).toHaveBeenCalledWith({
- message: 'What should agents be allowed to do with this KTX project?',
+ message: 'What should agents be allowed to do with this ktx project?',
options: [
{
value: 'mcp',
- label: 'Ask data questions with KTX MCP',
+ label: 'Ask data questions with ktx MCP',
hint: 'Installs the MCP connection and analytics workflow skill. Best for normal use.',
},
{
value: 'mcp-cli',
- label: 'Ask data questions + manage KTX with CLI commands',
+ label: 'Ask data questions + manage ktx with CLI commands',
hint: 'Adds an admin CLI skill so agents can run ktx status, sl, wiki, and setup commands.',
},
{
@@ -459,16 +459,16 @@ describe('setup agents', () => {
).resolves.toMatchObject({ status: 'skipped', projectDir: tempDir });
expect(prompts.select).toHaveBeenCalledWith({
- message: 'What should agents be allowed to do with this KTX project?',
+ message: 'What should agents be allowed to do with this ktx project?',
options: [
{
value: 'mcp',
- label: 'Ask data questions with KTX MCP',
+ label: 'Ask data questions with ktx MCP',
hint: 'Installs the MCP connection and analytics workflow skill. Best for normal use.',
},
{
value: 'mcp-cli',
- label: 'Ask data questions + manage KTX with CLI commands',
+ label: 'Ask data questions + manage ktx with CLI commands',
hint: 'Adds an admin CLI skill so agents can run ktx status, sl, wiki, and setup commands.',
},
{
@@ -518,17 +518,17 @@ describe('setup agents', () => {
});
expect(prompts.select).toHaveBeenCalledWith({
- message: `Where should KTX install supported agent config?\n\nKTX project: ${tempDir}`,
+ message: `Where should ktx install supported agent config?\n\nktx project: ${tempDir}`,
options: [
{
value: 'project',
- label: 'Project scope (KTX project directory)',
- hint: 'Only agents opened from this KTX project path load the project-scoped config.',
+ label: 'Project scope (ktx project directory)',
+ hint: 'Only agents opened from this ktx project path load the project-scoped config.',
},
{
value: 'global',
label: 'Global scope (user config)',
- hint: 'Agents can load this KTX project from any working directory.',
+ hint: 'Agents can load this ktx project from any working directory.',
},
],
});
@@ -584,7 +584,7 @@ describe('setup agents', () => {
args: [expect.stringContaining('bin.js'), '--project-dir', tempDir, 'mcp', 'stdio'],
});
- expect(await readZipText(analyticsSkillPath, 'ktx-analytics/SKILL.md')).toContain('KTX Analytics Workflow');
+ expect(await readZipText(analyticsSkillPath, 'ktx-analytics/SKILL.md')).toContain('ktx Analytics Workflow');
await expect(readZipText(analyticsSkillPath, 'ktx/SKILL.md')).rejects.toThrow('Missing zip entry');
await expect(readZipText(analyticsSkillPath, '.claude-plugin/plugin.json')).rejects.toThrow('Missing zip entry');
await expect(readZipText(analyticsSkillPath, 'skills/ktx-analytics/SKILL.md')).rejects.toThrow(
@@ -597,11 +597,11 @@ describe('setup agents', () => {
expect(io.stdout()).toContain('claude_desktop_config.json');
expect(io.stdout()).toContain('Required before using agents');
expect(io.stdout()).toContain('1. Restart Claude Desktop');
- expect(io.stdout()).toContain('Claude Desktop loads KTX MCP after restart.');
+ expect(io.stdout()).toContain('Claude Desktop loads ktx MCP after restart.');
expect(io.stdout()).toContain('2. Upload Claude Desktop skills');
expect(io.stdout()).toContain('Customize > Skills > + > Create skill > Upload a skill');
expect(io.stdout()).toContain('Upload this file:');
- expect(io.stdout()).toContain('Toggle the uploaded KTX skills on.');
+ expect(io.stdout()).toContain('Toggle the uploaded ktx skills on.');
expect(io.stdout()).not.toContain('Run `ktx mcp start`');
} finally {
process.env.HOME = previousHome;
@@ -686,7 +686,7 @@ describe('setup agents', () => {
const analyticsSkillPath = join(tempDir, '.ktx/agents/claude/ktx-analytics.zip');
const adminSkillPath = join(tempDir, '.ktx/agents/claude/ktx.zip');
- expect(await readZipText(analyticsSkillPath, 'ktx-analytics/SKILL.md')).toContain('KTX Analytics Workflow');
+ expect(await readZipText(analyticsSkillPath, 'ktx-analytics/SKILL.md')).toContain('ktx Analytics Workflow');
await expect(readZipText(analyticsSkillPath, 'ktx/SKILL.md')).rejects.toThrow('Missing zip entry');
const adminSkill = await readZipText(adminSkillPath, 'ktx/SKILL.md');
expect(adminSkill).toContain(`--project-dir ${tempDir}`);
@@ -1026,7 +1026,7 @@ describe('setup agents', () => {
expect(io.stdout().match(/Space to select/g)).toHaveLength(1);
expect(prompts.multiselect).toHaveBeenCalledWith(
expect.objectContaining({
- message: 'Which agent targets should KTX install?',
+ message: 'Which agent targets should ktx install?',
}),
);
});
@@ -1055,7 +1055,7 @@ describe('setup agents', () => {
expect(output).toContain('Analytics skill installed.');
expect(output).toContain('Admin CLI skill installed.');
expect(output).not.toContain('Agent integration complete');
- expect(output).not.toContain(`KTX project\n ${tempDir}`);
+ expect(output).not.toContain(`ktx project\n ${tempDir}`);
expect(output).not.toContain('Installed agents');
expect(output).not.toContain('.claude/skills/ktx-analytics/SKILL.md');
expect(output).not.toContain('.claude/skills/ktx/SKILL.md');
@@ -1167,11 +1167,11 @@ describe('setup agents', () => {
expect(output).toContain('Run this command before using Claude Code:');
expect(output).toContain(`ktx mcp start --project-dir ${tempDir}`);
expect(output).toContain(`ktx mcp stop --project-dir ${tempDir}\n\n2. Open Claude Code`);
- expect(output).toContain('Open Claude Code from the KTX project directory');
+ expect(output).toContain('Open Claude Code from the ktx project directory');
expect(output).toContain('RUN:');
expect(output).toContain(`cd '${tempDir}'`);
expect(output).toContain('3. Restart Claude Desktop');
- expect(output).toContain('Claude Desktop loads KTX MCP after restart.');
+ expect(output).toContain('Claude Desktop loads ktx MCP after restart.');
expect(output).toContain('4. Upload Claude Desktop skills');
expect(output).toContain('Customize > Skills > + > Create skill > Upload a skill');
expect(output).toContain(join(tempDir, '.ktx/agents/claude/ktx-analytics.zip'));
@@ -1179,7 +1179,7 @@ describe('setup agents', () => {
expect(output).toContain('Upload this file:');
expect(output).toContain('All set.');
expect(output).not.toContain('Finish Claude Desktop setup');
- expect(output).not.toContain('Run `ktx mcp start` to enable the configured KTX MCP server.');
+ expect(output).not.toContain('Run `ktx mcp start` to enable the configured ktx MCP server.');
} finally {
process.env.HOME = previousHome;
await rm(home, { recursive: true, force: true });
@@ -1216,7 +1216,7 @@ describe('setup agents', () => {
expect(output).toContain('2. Open Claude Code');
expect(output).toContain('RUN:');
expect(output).toContain('claude');
- expect(output).not.toContain('Open Claude Code from the KTX project directory');
+ expect(output).not.toContain('Open Claude Code from the ktx project directory');
expect(output).not.toContain(`cd '${tempDir}'`);
} finally {
process.env.HOME = previousHome;
@@ -1263,7 +1263,7 @@ describe('setup agents', () => {
expect(output).toContain('3. Configure unsupported MCP clients');
expect(output).toContain('4. Start MCP');
expect(output).toContain('Run this command before using Codex, Cursor, OpenCode, and Universal .agents:');
- expect(output).toContain('Open Cursor from the KTX project directory');
+ expect(output).toContain('Open Cursor from the ktx project directory');
expect(output).toContain('Open ~/.codex/config.toml, then paste this block:\n\n PASTE:\n [mcp_servers.ktx]');
expect(output).toContain('Open opencode.json, then paste this block:');
expect(output).toContain('Use this endpoint when setting up unsupported MCP clients:');
@@ -1298,9 +1298,9 @@ describe('setup agents', () => {
expect(heading).toContain('Upload Claude Desktop skills');
expect(heading).not.toMatch(/^2\. /);
- const sub = format(' Toggle the uploaded KTX skills on.');
+ const sub = format(' Toggle the uploaded ktx skills on.');
expect(sub).toMatch(/^ {3}/);
- expect(sub).toContain('Toggle the uploaded KTX skills on.');
+ expect(sub).toContain('Toggle the uploaded ktx skills on.');
});
it('renders skill bundle .zip paths as bullets and shortens HOME to ~', () => {
diff --git a/packages/cli/test/setup-context.test.ts b/packages/cli/test/setup-context.test.ts
index 743cfee9..92606166 100644
--- a/packages/cli/test/setup-context.test.ts
+++ b/packages/cli/test/setup-context.test.ts
@@ -288,7 +288,7 @@ describe('setup context build state', () => {
reportIds: ['report-docs-1'],
artifactPaths: ['raw-sources/warehouse/live-database/sync-1/scan-report.json'],
});
- expect(io.stdout()).toContain('KTX context is ready for agents.');
+ expect(io.stdout()).toContain('ktx context is ready for agents.');
expect(io.stdout()).toContain('Databases:');
expect(io.stdout()).not.toContain(['Primary sources', ':'].join(''));
});
@@ -398,7 +398,7 @@ describe('setup context build state', () => {
completedAt: '2026-05-09T10:00:00.000Z',
contextSourceConnectionIds: ['docs'],
});
- expect(io.stdout()).toContain('KTX context is ready for agents.');
+ expect(io.stdout()).toContain('ktx context is ready for agents.');
expect(io.stdout()).not.toContain(['Primary sources', ':'].join(''));
});
@@ -523,7 +523,7 @@ describe('setup context build state', () => {
),
).resolves.toEqual({ status: 'failed', projectDir: tempDir });
- expect(io.stderr()).toContain('No databases or context sources are configured for a KTX context build.');
+ expect(io.stderr()).toContain('No databases or context sources are configured for a ktx context build.');
});
it('starts a fresh foreground build when stale state is found', async () => {
diff --git a/packages/cli/test/setup-databases.test.ts b/packages/cli/test/setup-databases.test.ts
index 16626e34..5c25b266 100644
--- a/packages/cli/test/setup-databases.test.ts
+++ b/packages/cli/test/setup-databases.test.ts
@@ -111,7 +111,7 @@ function makePromptAdapter(options: {
if (message.startsWith('Enable all tables in ') && message.includes(', or refine tables?')) {
return 'save';
}
- if (message.includes('How much database context should KTX build?')) {
+ if (message.includes('How much database context should ktx build?')) {
const nextValue = selectValues[0];
return nextValue === 'fast' || nextValue === 'deep' || nextValue === 'back'
? (selectValues.shift() ?? 'fast')
@@ -126,7 +126,7 @@ function makePromptAdapter(options: {
}
function connectionNamePrompt(label: string): string {
- return `Name this ${label} connection\nKTX will use this short name in commands and config. You can rename it now.`;
+ return `Name this ${label} connection\nktx will use this short name in commands and config. You can rename it now.`;
}
function textInputPrompt(message: string): string {
@@ -234,7 +234,7 @@ describe('setup databases step', () => {
expect(result.status).toBe('back');
expect(prompts.multiselect).toHaveBeenCalledWith({
message:
- 'Which databases should KTX connect to?\n' +
+ 'Which databases should ktx connect to?\n' +
'Use Up/Down to move, Space to select or unselect, Enter to confirm, Escape to go back, or Ctrl+C to exit.',
options: [
{ value: 'postgres', label: 'PostgreSQL' },
@@ -272,7 +272,7 @@ describe('setup databases step', () => {
});
expect(prompts.multiselect).toHaveBeenCalledTimes(2);
expect(vi.mocked(prompts.multiselect).mock.calls[1]?.[0].message).toBe(
- 'Which databases should KTX connect to?\n' +
+ 'Which databases should ktx connect to?\n' +
'Use Up/Down to move, Space to select or unselect, Enter to confirm, Escape to go back, or Ctrl+C to exit.',
);
});
@@ -926,7 +926,7 @@ describe('setup databases step', () => {
initialValues: ['postgres'],
required: true,
}));
- expect(io.stdout()).not.toContain('KTX cannot work without at least one database');
+ expect(io.stdout()).not.toContain('ktx cannot work without at least one database');
expect(prompts.select).toHaveBeenNthCalledWith(3, {
message: 'Databases configured: postgres-warehouse\nWhat would you like to do?',
options: [
@@ -971,7 +971,7 @@ describe('setup databases step', () => {
initialValues: ['postgres'],
required: true,
}));
- expect(io.stdout()).not.toContain('KTX cannot work without at least one database');
+ expect(io.stdout()).not.toContain('ktx cannot work without at least one database');
expect(prompts.select).toHaveBeenNthCalledWith(2, {
message: 'Databases configured: warehouse\nWhat would you like to do?',
options: [
@@ -1813,7 +1813,7 @@ describe('setup databases step', () => {
commandIo.stdout.write('[55%] Semantic layer comparison found 2 changes across 2 tables\n');
commandIo.stdout.write('[70%] Writing schema artifacts\n');
commandIo.stdout.write('[100%] Scan completed\n');
- commandIo.stdout.write('✓ KTX scan completed\n');
+ commandIo.stdout.write('✓ ktx scan completed\n');
commandIo.stdout.write('Status: done\n');
commandIo.stdout.write('Run: local-moywh3ky\n');
commandIo.stdout.write('Connection: postgres-warehouse\n');
@@ -3176,7 +3176,7 @@ describe('setup databases step', () => {
});
vi.mocked(prompts.select).mockImplementation(async ({ message, options }) => {
if (message.startsWith('Enable query-history ingest')) return 'yes';
- if (message.includes('How much database context should KTX build?')) return 'fast';
+ if (message.includes('How much database context should ktx build?')) return 'fast';
if (message.startsWith('Connection setup failed for analytics')) {
failurePromptCount += 1;
failurePromptOptions.push(options);
@@ -3300,89 +3300,6 @@ describe('setup databases step', () => {
expect(config.connections.warehouse.historicSql).toBeUndefined();
});
- it('migrates legacy historicSql to context.queryHistory during database setup', async () => {
- await writeFile(
- join(tempDir, 'ktx.yaml'),
- [
- 'connections:',
- ' warehouse:',
- ' driver: postgres',
- ' readonly: true',
- ' schemas:',
- " - 'public'",
- ' historicSql:',
- ' enabled: true',
- ' dialect: postgres',
- ' windowDays: 45',
- ' minExecutions: 9',
- ' concurrency: 3',
- ' staleArchiveAfterDays: 120',
- ' filters:',
- ' dropTrivialProbes: true',
- ' serviceAccounts:',
- ' mode: exclude',
- ' patterns:',
- " - '^svc_'",
- ' orchestrators:',
- ' mode: exclude',
- ' patterns:',
- ' - airflow',
- ' dropFailedBelow: 2',
- ' redactionPatterns:',
- " - '(?i)secret'",
- '',
- ].join('\n'),
- 'utf-8',
- );
-
- const io = makeIo();
-
- await expect(
- runKtxSetupDatabasesStep(
- {
- projectDir: tempDir,
- inputMode: 'disabled',
- databaseConnectionIds: ['warehouse'],
- databaseSchemas: [],
- skipDatabases: false,
- },
- io.io,
- {
- testConnection: vi.fn(async () => 0),
- scanConnection: vi.fn(async () => 0),
- historicSqlReadinessProbe: vi.fn(async () => {
- const runner = fakeHistoricSqlRunner('postgres', 'pg_stat_statements');
- return {
- ok: true as const,
- dialect: 'postgres' as const,
- runner,
- result: { pgServerVersion: 'PostgreSQL 16.4', warnings: [], info: [] },
- };
- }),
- },
- ),
- ).resolves.toMatchObject({ status: 'ready' });
-
- const config = parseKtxProjectConfig(await readFile(join(tempDir, 'ktx.yaml'), 'utf-8'));
- expect(config.connections.warehouse.historicSql).toBeUndefined();
- expect(config.connections.warehouse.context).toMatchObject({
- queryHistory: {
- enabled: true,
- windowDays: 45,
- minExecutions: 9,
- concurrency: 3,
- staleArchiveAfterDays: 120,
- filters: {
- dropTrivialProbes: true,
- serviceAccounts: { mode: 'exclude', patterns: ['^svc_'] },
- orchestrators: { mode: 'exclude', patterns: ['airflow'] },
- dropFailedBelow: 2,
- },
- redactionPatterns: ['(?i)secret'],
- },
- });
- });
-
it('prints a non-blocking Postgres query history probe failure after connection test succeeds', async () => {
const io = makeIo();
const runner = {
@@ -3594,7 +3511,7 @@ describe('setup databases step', () => {
);
expect(result.status).toBe('skipped');
- expect(io.stdout()).toContain('KTX cannot work until you add a database.');
+ expect(io.stdout()).toContain('ktx cannot work until you add a database.');
expect(await readFile(join(tempDir, 'ktx.yaml'), 'utf-8')).not.toContain('completed_steps:');
});
});
diff --git a/packages/cli/test/setup-demo-tour.test.ts b/packages/cli/test/setup-demo-tour.test.ts
index 3916076c..e3efeea9 100644
--- a/packages/cli/test/setup-demo-tour.test.ts
+++ b/packages/cli/test/setup-demo-tour.test.ts
@@ -99,7 +99,7 @@ describe('renderDemoCompletionSummary', () => {
it('includes star headline', () => {
const plain = stripAnsi(renderDemoCompletionSummary(projectDir, true));
- expect(plain).toContain('★ KTX demo is ready');
+ expect(plain).toContain('★ ktx demo is ready');
});
it('shows manual instructions when agent not installed', () => {
diff --git a/packages/cli/test/setup-embeddings.test.ts b/packages/cli/test/setup-embeddings.test.ts
index 9af9f913..5754913c 100644
--- a/packages/cli/test/setup-embeddings.test.ts
+++ b/packages/cli/test/setup-embeddings.test.ts
@@ -9,9 +9,9 @@ import { ManagedPythonDaemonStartError } from '../src/managed-python-daemon.js';
import { type KtxSetupEmbeddingsPromptAdapter, runKtxSetupEmbeddingsStep } from '../src/setup-embeddings.js';
const EMBEDDING_OPTION_PROMPT_MESSAGE = [
- 'Which embedding option should KTX use?',
+ 'Which embedding option should ktx use?',
'',
- 'KTX uses embeddings for semantic search over semantic-layer sources, wiki context, schema metadata, ' +
+ 'ktx uses embeddings for semantic search over semantic-layer sources, wiki context, schema metadata, ' +
'and relationship evidence.',
].join('\n');
@@ -128,7 +128,7 @@ describe('setup embeddings step', () => {
});
expect(vi.mocked(prompts.select).mock.calls.map((call) => call[0].message)).toEqual([
EMBEDDING_OPTION_PROMPT_MESSAGE,
- 'How should KTX find your OpenAI embedding API key?',
+ 'How should ktx find your OpenAI embedding API key?',
EMBEDDING_OPTION_PROMPT_MESSAGE,
]);
});
@@ -286,7 +286,7 @@ describe('setup embeddings step', () => {
const io = makeIo();
const ensureLocalEmbeddings = vi.fn(async () => {
throw new Error(
- 'KTX Python runtime is required for this command. Run: ktx admin runtime install --feature local-embeddings --yes',
+ 'ktx Python runtime is required for this command. Run: ktx admin runtime install --feature local-embeddings --yes',
);
});
@@ -304,7 +304,7 @@ describe('setup embeddings step', () => {
expect(result.status).toBe('failed');
expect(io.stderr()).toContain(
- 'KTX Python runtime is required for this command. Run: ktx admin runtime install --feature local-embeddings --yes',
+ 'ktx Python runtime is required for this command. Run: ktx admin runtime install --feature local-embeddings --yes',
);
});
@@ -361,7 +361,7 @@ describe('setup embeddings step', () => {
);
expect(result.status).toBe('failed');
- expect(io.stderr()).toContain('Recent KTX daemon stderr:');
+ expect(io.stderr()).toContain('Recent ktx daemon stderr:');
expect(io.stderr()).toContain('daemon traceback line 6');
expect(io.stderr()).toContain('daemon traceback line 45');
expect(io.stderr()).not.toContain('daemon traceback line 5');
@@ -395,7 +395,7 @@ describe('setup embeddings step', () => {
expect(result.status).toBe('failed');
expect(io.stderr()).toContain('Local embedding health check failed: fetch failed: connect ECONNREFUSED');
- expect(io.stderr()).toContain('Recent KTX daemon stderr:');
+ expect(io.stderr()).toContain('Recent ktx daemon stderr:');
expect(io.stderr()).toContain('daemon startup traceback 6');
expect(io.stderr()).toContain('daemon startup traceback 45');
expect(io.stderr()).not.toContain('daemon startup traceback 5');
@@ -425,7 +425,7 @@ describe('setup embeddings step', () => {
);
expect(result.status).toBe('failed');
- expect(io.stderr()).not.toContain('Recent KTX daemon stderr:');
+ expect(io.stderr()).not.toContain('Recent ktx daemon stderr:');
});
it('uses fixed OpenAI defaults and only asks for credentials when OpenAI is selected', async () => {
@@ -506,7 +506,7 @@ describe('setup embeddings step', () => {
});
expect(prompts.select).toHaveBeenCalledWith(
expect.objectContaining({
- message: 'Local embeddings are not reachable. Start the local KTX daemon, then retry.',
+ message: 'Local embeddings are not reachable. Start the local ktx daemon, then retry.',
options: expect.arrayContaining([expect.objectContaining({ value: 'openai' })]),
}),
);
diff --git a/packages/cli/test/setup-models.test.ts b/packages/cli/test/setup-models.test.ts
index ba5ce21f..e6ec9001 100644
--- a/packages/cli/test/setup-models.test.ts
+++ b/packages/cli/test/setup-models.test.ts
@@ -146,7 +146,7 @@ describe('setup Anthropic model step', () => {
expect(result.status).toBe('back');
expect(prompts.select).toHaveBeenCalledWith(
expect.objectContaining({
- message: expect.stringContaining('Which LLM provider should KTX use?'),
+ message: expect.stringContaining('Which LLM provider should ktx use?'),
options: [
{ value: 'claude-code', label: 'Claude subscription (Pro/Max)' },
{ value: 'codex', label: 'Codex subscription' },
@@ -199,12 +199,12 @@ describe('setup Anthropic model step', () => {
expect(result.status).toBe('ready');
expect(prompts.select).toHaveBeenCalledWith(
expect.objectContaining({
- message: expect.stringContaining('Which LLM provider should KTX use?'),
+ message: expect.stringContaining('Which LLM provider should ktx use?'),
}),
);
expect(prompts.select).not.toHaveBeenCalledWith(
expect.objectContaining({
- message: expect.stringContaining('Which Claude Code model should KTX use?'),
+ message: expect.stringContaining('Which Claude Code model should ktx use?'),
}),
);
const config = parseKtxProjectConfig(await readFile(join(tempDir, 'ktx.yaml'), 'utf-8'));
@@ -299,7 +299,7 @@ describe('setup Anthropic model step', () => {
expect(result.status).toBe('ready');
expect(io.stderr()).toContain('claude-code ignores llm.promptCaching.systemTtl');
- expect(io.stderr()).toContain('Claude Agent SDK does not expose KTX prompt-cache TTL, tool, or history markers');
+ expect(io.stderr()).toContain('Claude Agent SDK does not expose ktx prompt-cache TTL, tool, or history markers');
});
it('returns from Anthropic credential Back to provider selection', async () => {
@@ -315,7 +315,7 @@ describe('setup Anthropic model step', () => {
expect(prompts.select).toHaveBeenNthCalledWith(
3,
expect.objectContaining({
- message: expect.stringContaining('Which LLM provider should KTX use?'),
+ message: expect.stringContaining('Which LLM provider should ktx use?'),
}),
);
});
@@ -495,7 +495,7 @@ describe('setup Anthropic model step', () => {
expect(result.status).toBe('ready');
expect(prompts.select).not.toHaveBeenCalledWith(
expect.objectContaining({
- message: expect.stringContaining('How should KTX authenticate with Google Vertex AI?'),
+ message: expect.stringContaining('How should ktx authenticate with Google Vertex AI?'),
}),
);
expect(readGcloudProject).toHaveBeenCalled();
@@ -503,7 +503,7 @@ describe('setup Anthropic model step', () => {
expect(prompts.text).not.toHaveBeenCalled();
expect(prompts.autocomplete).toHaveBeenCalledWith(
expect.objectContaining({
- message: expect.stringContaining('Which Google Cloud project should KTX use for Vertex AI?'),
+ message: expect.stringContaining('Which Google Cloud project should ktx use for Vertex AI?'),
options: [
{ value: 'local-gcp-project', label: 'local-gcp-project - Local project (current gcloud project)' },
{ value: 'other-gcp-project', label: 'other-gcp-project - Other project' },
@@ -545,12 +545,12 @@ describe('setup Anthropic model step', () => {
expect(result.status).toBe('ready');
expect(prompts.select).not.toHaveBeenCalledWith(
expect.objectContaining({
- message: expect.stringContaining('How should KTX authenticate with Google Vertex AI?'),
+ message: expect.stringContaining('How should ktx authenticate with Google Vertex AI?'),
}),
);
expect(prompts.autocomplete).toHaveBeenCalledWith(
expect.objectContaining({
- message: expect.stringContaining('Which Google Cloud project should KTX use for Vertex AI?'),
+ message: expect.stringContaining('Which Google Cloud project should ktx use for Vertex AI?'),
}),
);
expect(healthCheck).toHaveBeenCalledWith(
@@ -615,7 +615,7 @@ describe('setup Anthropic model step', () => {
expect(result.status).toBe('ready');
expect(prompts.autocomplete).toHaveBeenCalledWith(
expect.objectContaining({
- message: expect.stringContaining('Which Google Cloud project should KTX use for Vertex AI?'),
+ message: expect.stringContaining('Which Google Cloud project should ktx use for Vertex AI?'),
options: [
{ value: 'manual', label: 'Enter a project ID manually' },
{ value: 'back', label: 'Back' },
@@ -710,7 +710,7 @@ describe('setup Anthropic model step', () => {
expect(prompts.select).toHaveBeenNthCalledWith(
2,
expect.objectContaining({
- message: expect.stringContaining('Which LLM provider should KTX use?'),
+ message: expect.stringContaining('Which LLM provider should ktx use?'),
}),
);
});
@@ -899,20 +899,20 @@ describe('setup Anthropic model step', () => {
expect(result.status).toBe('back');
expect(prompts.select).toHaveBeenCalledWith(
expect.objectContaining({
- message: expect.stringContaining('How should KTX find your Anthropic API key?'),
+ message: expect.stringContaining('How should ktx find your Anthropic API key?'),
options: expect.not.arrayContaining([expect.objectContaining({ value: 'skip' })]),
}),
);
});
- it('explains why KTX asks for an Anthropic API key', async () => {
+ it('explains why ktx asks for an Anthropic API key', async () => {
const io = makeIo();
const prompts = makePromptAdapter({ credentialChoice: 'back' });
const expectedPromptMessage = [
- 'How should KTX find your Anthropic API key?',
+ 'How should ktx find your Anthropic API key?',
'',
[
- 'KTX uses the key to verify Anthropic model access now and to run ingest agents that turn schemas, SQL,',
+ 'ktx uses the key to verify Anthropic model access now and to run ingest agents that turn schemas, SQL,',
'BI metadata, and docs into semantic-layer sources and wiki context. ktx.yaml stores an env: or file:',
'reference, not the raw key.',
].join(' '),
@@ -930,7 +930,7 @@ describe('setup Anthropic model step', () => {
message: expectedPromptMessage,
}),
);
- expect(io.stdout()).not.toContain('KTX uses the key');
+ expect(io.stdout()).not.toContain('ktx uses the key');
});
it('does not persist llm completion when the health check fails', async () => {
@@ -980,7 +980,7 @@ describe('setup Anthropic model step', () => {
expect(prompts.select).toHaveBeenCalledTimes(3);
expect(prompts.autocomplete).not.toHaveBeenCalledWith(
expect.objectContaining({
- message: expect.stringContaining('Which Anthropic model should KTX use?'),
+ message: expect.stringContaining('Which Anthropic model should ktx use?'),
}),
);
expect(io.stderr()).toContain('Anthropic model health check failed: model not found');
diff --git a/packages/cli/test/setup-project.test.ts b/packages/cli/test/setup-project.test.ts
index 1f0eae4d..63fd6c07 100644
--- a/packages/cli/test/setup-project.test.ts
+++ b/packages/cli/test/setup-project.test.ts
@@ -131,7 +131,7 @@ describe('setup project step', () => {
expect(result.projectDir).toBe(projectDir);
expect(prompts.select).toHaveBeenCalledWith(
expect.objectContaining({
- message: 'Where should KTX create the project?',
+ message: 'Where should ktx create the project?',
options: [
expect.objectContaining({ value: 'current', label: `Current directory (${projectDir})` }),
expect.objectContaining({
@@ -165,7 +165,7 @@ describe('setup project step', () => {
expect(prompts.select).toHaveBeenNthCalledWith(
1,
expect.objectContaining({
- message: 'Where should KTX create the project?',
+ message: 'Where should ktx create the project?',
options: expect.arrayContaining([
expect.objectContaining({
value: 'new-default',
@@ -176,11 +176,11 @@ describe('setup project step', () => {
);
expect(prompts.select).toHaveBeenNthCalledWith(
2,
- expect.objectContaining({ message: `Create KTX project at ${projectDir}?` }),
+ expect.objectContaining({ message: `Create ktx project at ${projectDir}?` }),
);
expect(prompts.text).not.toHaveBeenCalled();
expect(result.status === 'ready' ? result.project.configPath : '').toBe(join(projectDir, 'ktx.yaml'));
- expect(testIo.stdout()).toContain(`│ KTX will create:\n│ ${projectDir}`);
+ expect(testIo.stdout()).toContain(`│ ktx will create:\n│ ${projectDir}`);
await expect(stat(join(projectDir, 'ktx.yaml'))).resolves.toBeDefined();
});
@@ -243,7 +243,7 @@ describe('setup project step', () => {
expect(prompts.select).toHaveBeenNthCalledWith(
2,
expect.objectContaining({
- message: `Create KTX project at ${customProjectDir}?`,
+ message: `Create ktx project at ${customProjectDir}?`,
options: [
expect.objectContaining({ value: 'create', label: 'Create project' }),
expect.objectContaining({ value: 'choose-another', label: 'Choose another folder' }),
@@ -253,7 +253,7 @@ describe('setup project step', () => {
);
expect(prompts.select).toHaveBeenNthCalledWith(
3,
- expect.objectContaining({ message: 'Where should KTX create the project?' }),
+ expect.objectContaining({ message: 'Where should ktx create the project?' }),
);
await expect(stat(join(customProjectDir, 'ktx.yaml'))).rejects.toThrow();
});
@@ -280,7 +280,7 @@ describe('setup project step', () => {
);
});
- it('confirms before creating KTX files inside an existing non-empty folder', async () => {
+ it('confirms before creating ktx files inside an existing non-empty folder', async () => {
const startDir = join(tempDir, 'start');
const projectDir = join(startDir, 'analytics-ktx');
await mkdir(projectDir, { recursive: true });
@@ -300,7 +300,7 @@ describe('setup project step', () => {
expect.objectContaining({
message: `That folder already exists and is not empty: ${projectDir}`,
options: expect.arrayContaining([
- expect.objectContaining({ value: 'use-existing', label: 'Yes, create KTX files there' }),
+ expect.objectContaining({ value: 'use-existing', label: 'Yes, create ktx files there' }),
expect.objectContaining({ value: 'choose-another', label: 'Choose another folder' }),
]),
}),
diff --git a/packages/cli/test/setup-prompts.test.ts b/packages/cli/test/setup-prompts.test.ts
index f3c2109b..8833849d 100644
--- a/packages/cli/test/setup-prompts.test.ts
+++ b/packages/cli/test/setup-prompts.test.ts
@@ -73,14 +73,14 @@ describe('setup prompt adapter', () => {
await expect(
adapter.select({
- message: 'Which embedding option should KTX use?\n\nKTX uses embeddings for search.',
+ message: 'Which embedding option should ktx use?\n\nktx uses embeddings for search.',
options,
}),
).resolves.toBe('openai');
expect(mocks.withSetupInterruptConfirmation).toHaveBeenCalledTimes(1);
expect(mocks.select).toHaveBeenCalledWith({
- message: 'Which embedding option should KTX use?\n\nKTX uses embeddings for search.\n',
+ message: 'Which embedding option should ktx use?\n\nktx uses embeddings for search.\n',
options,
});
});
@@ -229,10 +229,10 @@ describe('setup prompt adapter', () => {
};
const ui = createKtxSetupUiAdapter();
- ui.intro('KTX setup', io);
+ ui.intro('ktx setup', io);
ui.note(' $ ktx status', 'What you can do next', io);
- expect(chunks.join('')).toBe('KTX setup\n\nWhat you can do next:\n $ ktx status\n');
+ expect(chunks.join('')).toBe('ktx setup\n\nWhat you can do next:\n $ ktx status\n');
expect(mocks.intro).not.toHaveBeenCalled();
expect(mocks.note).not.toHaveBeenCalled();
});
@@ -251,13 +251,13 @@ describe('setup prompt adapter', () => {
};
const ui = createKtxSetupUiAdapter();
- ui.intro('KTX setup', io);
+ ui.intro('ktx setup', io);
ui.note(' $ ktx status', 'What you can do next', io);
const bannerWrite = output.write.mock.calls.map((call) => String(call[0])).join('');
expect(bannerWrite).toContain('██');
expect(bannerWrite).toContain('context layer for data agents');
- expect(mocks.intro).toHaveBeenCalledWith('KTX setup', { output });
+ expect(mocks.intro).toHaveBeenCalledWith('ktx setup', { output });
expect(mocks.note).toHaveBeenCalledWith(' $ ktx status', 'What you can do next', { output });
});
});
diff --git a/packages/cli/test/setup-ready-menu.test.ts b/packages/cli/test/setup-ready-menu.test.ts
index 39c62a32..6e172422 100644
--- a/packages/cli/test/setup-ready-menu.test.ts
+++ b/packages/cli/test/setup-ready-menu.test.ts
@@ -74,7 +74,7 @@ describe('runKtxSetupReadyMenu', () => {
{ value: 'embeddings', label: 'Embeddings' },
{ value: 'databases', label: 'Databases' },
{ value: 'sources', label: 'Context sources' },
- { value: 'context', label: 'Rebuild KTX context' },
+ { value: 'context', label: 'Rebuild ktx context' },
{ value: 'agents', label: 'Agent integration' },
{ value: 'exit', label: 'Exit' },
],
@@ -95,7 +95,7 @@ describe('runKtxSetupReadyChangeMenu', () => {
{ value: 'embeddings', label: 'Embeddings' },
{ value: 'databases', label: 'Databases' },
{ value: 'sources', label: 'Context sources' },
- { value: 'context', label: 'Rebuild KTX context' },
+ { value: 'context', label: 'Rebuild ktx context' },
{ value: 'agents', label: 'Agent integration' },
{ value: 'exit', label: 'Exit' },
],
diff --git a/packages/cli/test/setup-runtime.test.ts b/packages/cli/test/setup-runtime.test.ts
index ab5777e4..24490e3b 100644
--- a/packages/cli/test/setup-runtime.test.ts
+++ b/packages/cli/test/setup-runtime.test.ts
@@ -71,7 +71,7 @@ describe('runKtxSetupRuntimeStep', () => {
it('fails fast when required runtime features cannot be installed in no-input mode', async () => {
const io = makeIo();
const ensureRuntime = vi.fn(async () => {
- throw new Error('KTX Python runtime is required for this command. Run: ktx admin runtime install --yes');
+ throw new Error('ktx Python runtime is required for this command. Run: ktx admin runtime install --yes');
});
await expect(
@@ -97,7 +97,7 @@ describe('runKtxSetupRuntimeStep', () => {
expect(io.stderr()).toContain('ktx admin runtime install --yes');
});
- it('starts the KTX daemon for configured sentence-transformers embeddings', async () => {
+ it('starts the ktx daemon for configured sentence-transformers embeddings', async () => {
const io = makeIo();
const ensureLocalEmbeddings = vi.fn(async () => ({
baseUrl: 'http://127.0.0.1:61234',
diff --git a/packages/cli/test/setup-sources.test.ts b/packages/cli/test/setup-sources.test.ts
index ef18a1b6..a6a91805 100644
--- a/packages/cli/test/setup-sources.test.ts
+++ b/packages/cli/test/setup-sources.test.ts
@@ -57,7 +57,7 @@ function prompts(values: {
}
function connectionNamePrompt(label: string): string {
- return `Name this ${label} connection\nKTX will use this short name in commands and config. You can rename it now.`;
+ return `Name this ${label} connection\nktx will use this short name in commands and config. You can rename it now.`;
}
function textInputPrompt(message: string): string {
@@ -445,7 +445,7 @@ describe('setup sources step', () => {
expect(pickNotionRootPages).toHaveBeenCalledOnce();
expect(testPrompts.select).toHaveBeenCalledWith({
- message: 'Which Notion pages should KTX ingest?',
+ message: 'Which Notion pages should ktx ingest?',
options: [
{ value: 'all_accessible', label: 'All pages the integration can access' },
{ value: 'selected_roots', label: 'Specific pages and their subpages (choose them in a picker)' },
@@ -673,7 +673,7 @@ describe('setup sources step', () => {
it('lets visible Metabase mapping surface refresh and validation failures', async () => {
await addPrimarySource();
const runMapping = vi.fn(async (_projectDir: string, _connectionId: string, io: KtxCliIo) => {
- io.stderr.write('1: Metabase database does not match KTX connection database\n');
+ io.stderr.write('1: Metabase database does not match ktx connection database\n');
return 1;
});
const io = makeIo();
@@ -704,7 +704,7 @@ describe('setup sources step', () => {
stderr: expect.objectContaining({ write: expect.any(Function) }),
}),
);
- expect(io.stderr()).toContain('1: Metabase database does not match KTX connection database');
+ expect(io.stderr()).toContain('1: Metabase database does not match ktx connection database');
expect(io.stderr()).not.toContain('Metabase mapping validation failed');
expect(testPrompts.log).toHaveBeenCalledWith('Validating Metabase mapping...');
expect(testPrompts.select).toHaveBeenCalledWith(
@@ -761,7 +761,7 @@ describe('setup sources step', () => {
expect(testPrompts.multiselect).toHaveBeenCalledWith(
expect.objectContaining({
message:
- 'Which context sources should KTX ingest?\nUse Up/Down to move, Space to select or unselect, Enter to confirm, Escape to go back, or Ctrl+C to exit.',
+ 'Which context sources should ktx ingest?\nUse Up/Down to move, Space to select or unselect, Enter to confirm, Escape to go back, or Ctrl+C to exit.',
}),
);
const options = vi.mocked(testPrompts.multiselect).mock.calls[0]?.[0].options ?? [];
@@ -1404,7 +1404,7 @@ describe('setup sources step', () => {
).resolves.toEqual({ status: 'ready', projectDir, connectionIds: ['notion-main'] });
expect(testPrompts.select).toHaveBeenCalledWith({
- message: 'How should KTX find your Notion integration token?',
+ message: 'How should ktx find your Notion integration token?',
options: [
{ value: 'keep', label: 'Keep existing credential' },
{ value: 'paste', label: 'Paste a key and save it as a local secret file' },
@@ -1473,7 +1473,7 @@ describe('setup sources step', () => {
initialValue: 'https://metabase-old.example.com',
});
expect(testPrompts.select).toHaveBeenCalledWith({
- message: 'How should KTX find your Metabase API key?',
+ message: 'How should ktx find your Metabase API key?',
options: [
{ value: 'keep', label: 'Keep existing credential' },
{ value: 'paste', label: 'Paste a key and save it as a local secret file' },
@@ -1817,7 +1817,7 @@ describe('setup sources step', () => {
select: ['env', 'back', 'env', 'all_accessible'],
text: ['notion-main'],
deps: { validateNotion: vi.fn(async () => ({ ok: true as const, detail: 'roots=0' })) },
- repeatedSelectMessage: 'How should KTX find your Notion integration token?',
+ repeatedSelectMessage: 'How should ktx find your Notion integration token?',
},
];
@@ -1961,7 +1961,7 @@ describe('setup sources step', () => {
expect(testPrompts.select).toHaveBeenCalledWith(
expect.objectContaining({
- message: 'Multiple dbt projects found — which one should KTX use?',
+ message: 'Multiple dbt projects found — which one should ktx use?',
}),
);
expect(testPrompts.text).toHaveBeenCalledTimes(2);
diff --git a/packages/cli/test/setup.test.ts b/packages/cli/test/setup.test.ts
index 546136fa..f24e744f 100644
--- a/packages/cli/test/setup.test.ts
+++ b/packages/cli/test/setup.test.ts
@@ -402,7 +402,7 @@ describe('setup status', () => {
expect(status.llm).toMatchObject({ backend: 'vertex', ready: true, model: 'claude-sonnet-4-6' });
expect(status.context).toMatchObject({ ready: true, status: 'completed' });
expect(rendered).toContain('LLM ready: yes (claude-sonnet-4-6)');
- expect(rendered).toContain('KTX context built: yes');
+ expect(rendered).toContain('ktx context built: yes');
});
it('reports context ready after a partial ingest report saved memory', async () => {
@@ -462,10 +462,10 @@ describe('setup status', () => {
const status = await readKtxSetupStatus(tempDir);
const rendered = formatKtxSetupStatus(status);
- expect(rendered).toContain(`No KTX project found at ${tempDir}.`);
+ expect(rendered).toContain(`No ktx project found at ${tempDir}.`);
expect(rendered).toContain('Check another project: ktx --project-dir status');
expect(rendered).toContain('Or from that folder: ktx status');
- expect(rendered).toContain('Create a new KTX project here: ktx setup');
+ expect(rendered).toContain('Create a new ktx project here: ktx setup');
expect(rendered).not.toContain('Project ready: no');
expect(JSON.parse(JSON.stringify(status))).toMatchObject({ project: { path: tempDir, ready: false } });
});
@@ -475,13 +475,13 @@ describe('setup status', () => {
const rendered = formatKtxSetupStatus(await readKtxSetupStatus(tempDir));
- expect(rendered).toContain(`KTX project: ${tempDir}`);
+ expect(rendered).toContain(`ktx project: ${tempDir}`);
expect(rendered).toContain('Project ready: yes');
expect(rendered).toContain('LLM ready: no');
expect(rendered).toContain('Databases configured: no');
expect(rendered).not.toContain(['Primary sources', 'configured'].join(' '));
- expect(rendered).toContain('KTX context built: no');
- expect(rendered).not.toContain('No KTX project found.');
+ expect(rendered).toContain('ktx context built: no');
+ expect(rendered).not.toContain('No ktx project found.');
});
it('formats a concise ready summary for completed agent setup', () => {
@@ -511,7 +511,7 @@ describe('setup status', () => {
` ktx mcp stop --project-dir ${tempDir}`,
'',
'2. Open Claude Code',
- ' Open Claude Code from the KTX project directory:',
+ ' Open Claude Code from the ktx project directory:',
'',
' RUN:',
` cd '${tempDir}'`,
@@ -528,7 +528,7 @@ describe('setup status', () => {
expect(rendered).toContain(' RUN:');
expect(rendered).toContain(' If you need to stop MCP later:');
expect(rendered).toContain(`ktx mcp stop --project-dir ${tempDir}`);
- expect(rendered).toContain('After that, try\n Ask your agent: "Use KTX to show me the available tables."');
+ expect(rendered).toContain('After that, try\n Ask your agent: "Use ktx to show me the available tables."');
expect(rendered).not.toContain('Verify');
expect(rendered).not.toContain('Project ready: yes');
expect(rendered).not.toContain('What you can do next');
@@ -582,8 +582,8 @@ describe('setup status', () => {
expect(output).toContain('Requires MCP to be started.');
expect(output).toContain('Analytics skill installed.');
expect(output).not.toContain('Agent integration complete');
- expect(output).toContain('Finish KTX agent setup');
- expect(output).not.toContain('KTX project ready');
+ expect(output).toContain('Finish ktx agent setup');
+ expect(output).not.toContain('ktx project ready');
expect(output).toContain('REQUIRED BEFORE USING AGENTS');
expect(output).toContain('Run this command before using Claude Code:');
expect(output).toContain(`ktx mcp start --project-dir ${tempDir}`);
@@ -651,7 +651,7 @@ describe('setup status', () => {
),
).resolves.toBe(0);
- expect(testIo.stdout()).toContain('KTX setup');
+ expect(testIo.stdout()).toContain('ktx setup');
expect(testIo.stdout()).toContain(`Project: ${tempDir}`);
expect(testIo.stdout()).toContain('Project ready: yes');
expect(testIo.stdout()).toContain('What you can do next:');
@@ -733,7 +733,7 @@ describe('setup status', () => {
await expect(stat(join(projectDir, '.ktx'))).resolves.toBeDefined();
});
- it('preserves KTX scaffold files in an initially empty project directory when setup fails', async () => {
+ it('preserves ktx scaffold files in an initially empty project directory when setup fails', async () => {
const testIo = makeIo();
await expect(
@@ -860,12 +860,12 @@ describe('setup status', () => {
const select = vi.fn(async (options: { options: Array<{ value: string; label: string }> }) => {
const labels = options.options.map((option) => option.label);
expect(labels).toEqual([
- 'Set up KTX for my data',
+ 'Set up ktx for my data',
'Check setup status',
- 'Explore a pre-built KTX project',
+ 'Explore a pre-built ktx project',
'Exit',
]);
- expect(labels.indexOf('Explore a pre-built KTX project')).toBe(labels.length - 2);
+ expect(labels.indexOf('Explore a pre-built ktx project')).toBe(labels.length - 2);
return 'exit';
});
const cancel = vi.fn();
@@ -901,17 +901,17 @@ describe('setup status', () => {
const missingIo = makeIo();
const existingIo = makeIo();
const missingSelect = vi.fn(async (options: { options: Array<{ value: string; label: string }> }) => {
- expect(options.options.map((option) => option.label)).not.toContain('Connect a coding agent to KTX');
+ expect(options.options.map((option) => option.label)).not.toContain('Connect a coding agent to ktx');
return 'exit';
});
const existingSelect = vi.fn(async (options: { options: Array<{ value: string; label: string }> }) => {
const labels = options.options.map((option) => option.label);
expect(labels).toEqual([
'Resume or change an existing setup',
- 'Create a new KTX project',
- 'Connect a coding agent to KTX',
+ 'Create a new ktx project',
+ 'Connect a coding agent to ktx',
'Check setup status',
- 'Explore a pre-built KTX project',
+ 'Explore a pre-built ktx project',
'Exit',
]);
return 'exit';
@@ -1009,13 +1009,13 @@ describe('setup status', () => {
expect(projectPrompts.select).toHaveBeenCalledWith(
expect.objectContaining({
- message: 'Where should KTX create the project?',
+ message: 'Where should ktx create the project?',
options: expect.arrayContaining([expect.objectContaining({ value: 'back', label: 'Back' })]),
}),
);
expect(projectPrompts.select).toHaveBeenCalledWith(
expect.objectContaining({
- message: 'Where should KTX create the project?',
+ message: 'Where should ktx create the project?',
options: expect.not.arrayContaining([expect.objectContaining({ value: 'exit', label: 'Exit' })]),
}),
);
@@ -1068,7 +1068,7 @@ describe('setup status', () => {
expect(projectPrompts.select).toHaveBeenCalledWith(
expect.objectContaining({
- message: 'Where should KTX create the project?',
+ message: 'Where should ktx create the project?',
options: expect.arrayContaining([expect.objectContaining({ value: 'back', label: 'Back' })]),
}),
);
@@ -1145,7 +1145,7 @@ describe('setup status', () => {
}),
);
expect(projectPrompts.select).toHaveBeenCalledWith(
- expect.objectContaining({ message: 'Where should KTX create the project?' }),
+ expect.objectContaining({ message: 'Where should ktx create the project?' }),
);
await expect(stat(join(newProjectDir, 'ktx.yaml'))).resolves.toBeDefined();
await expect(readFile(join(existingProjectDir, 'ktx.yaml'), 'utf-8')).resolves.toBe(existingConfig);
@@ -1268,7 +1268,7 @@ describe('setup status', () => {
await expect(readFile(join(tempDir, '.ktx', 'setup', 'state.json'), 'utf-8')).resolves.toBe(
`${JSON.stringify({ completed_steps: ['project', 'sources'] }, null, 2)}\n`,
);
- expect(testIo.stdout()).toContain('KTX setup');
+ expect(testIo.stdout()).toContain('ktx setup');
expect(testIo.stdout()).toContain(`Project: ${tempDir}`);
expect(testIo.stdout()).toContain('Project ready: yes');
expect(testIo.stderr()).toBe('');
@@ -1969,7 +1969,7 @@ describe('setup status', () => {
).resolves.toBe(0);
expect(calls).toEqual(['model', 'embeddings', 'databases', 'sources']);
- expect(io.stderr()).not.toContain('KTX cannot build agent-ready context yet.');
+ expect(io.stderr()).not.toContain('ktx cannot build agent-ready context yet.');
});
it('runs context after sources and before agents in full setup', async () => {
@@ -2185,7 +2185,7 @@ describe('setup status', () => {
expect(runtime).not.toHaveBeenCalled();
expect(context).not.toHaveBeenCalled();
expect(agents).toHaveBeenCalledTimes(1);
- expect(io.stderr()).not.toContain('KTX context is not ready for agents.');
+ expect(io.stderr()).not.toContain('ktx context is not ready for agents.');
});
it('runs non-TTY --agents with a target without requiring --no-input or --yes', async () => {
diff --git a/packages/cli/test/standalone-smoke.test.ts b/packages/cli/test/standalone-smoke.test.ts
index 7dde8979..24afecd3 100644
--- a/packages/cli/test/standalone-smoke.test.ts
+++ b/packages/cli/test/standalone-smoke.test.ts
@@ -172,7 +172,7 @@ describe('standalone built ktx CLI smoke', () => {
it('runs status setup checks through the built binary', async () => {
const result = await runBuiltCli(['status', '--verbose', '--no-input'], { cwd: tempDir });
- expect(result.stdout).toMatch(/KTX status/);
+ expect(result.stdout).toMatch(/ktx status/);
if (result.stdout.includes('No project here yet.')) {
expect(result.stdout).toContain('ktx setup');
} else {
@@ -203,7 +203,7 @@ describe('standalone built ktx CLI smoke', () => {
const ingest = await runBuiltCli(['ingest', 'warehouse', '--project-dir', projectDir, '--no-input']);
expect(ingest.code).toBe(1);
expect(ingest.stdout).toContain('warehouse cannot be ingested: enrichment is not configured');
- expect(ingest.stdout).not.toContain('KTX scan completed');
+ expect(ingest.stdout).not.toContain('ktx scan completed');
}, 30_000);
it('parses gateway LLM config and OpenAI enrichment embeddings used by standalone scans without network calls', async () => {
diff --git a/packages/cli/test/text-ingest.test.ts b/packages/cli/test/text-ingest.test.ts
index 5122208e..5e599814 100644
--- a/packages/cli/test/text-ingest.test.ts
+++ b/packages/cli/test/text-ingest.test.ts
@@ -111,7 +111,7 @@ describe('runKtxTextIngest', () => {
expect.objectContaining({
userId: 'local-cli',
chatId: 'cli-text-ingest-1700000000000-1',
- userMessage: 'Ingest external text artifact "Revenue means gross receipts." into KTX memory.',
+ userMessage: 'Ingest external text artifact "Revenue means gross receipts." into ktx memory.',
assistantMessage: 'Revenue means gross receipts.',
sourceType: 'external_ingest',
}),
@@ -120,7 +120,7 @@ describe('runKtxTextIngest', () => {
2,
expect.objectContaining({
chatId: 'cli-text-ingest-1700000000000-2',
- userMessage: 'Ingest external text artifact "Orders are completed purchases." into KTX memory.',
+ userMessage: 'Ingest external text artifact "Orders are completed purchases." into ktx memory.',
assistantMessage: 'Orders are completed purchases.',
}),
);
@@ -176,7 +176,7 @@ describe('runKtxTextIngest', () => {
expect.objectContaining({
connectionId: 'warehouse',
userId: 'agent',
- userMessage: 'Ingest external text artifact "revenue.md" into KTX memory.',
+ userMessage: 'Ingest external text artifact "revenue.md" into ktx memory.',
assistantMessage: 'file:/tmp/docs/revenue.md',
}),
);
@@ -184,7 +184,7 @@ describe('runKtxTextIngest', () => {
2,
expect.objectContaining({
connectionId: 'warehouse',
- userMessage: 'Ingest external text artifact "stdin" into KTX memory.',
+ userMessage: 'Ingest external text artifact "stdin" into ktx memory.',
assistantMessage: 'stdin content',
}),
);
@@ -228,19 +228,19 @@ describe('runKtxTextIngest', () => {
expect(ingest.ingest).toHaveBeenNthCalledWith(
1,
expect.objectContaining({
- userMessage: 'Ingest external text artifact "remember to call me Andrey" into KTX memory.',
+ userMessage: 'Ingest external text artifact "remember to call me Andrey" into ktx memory.',
}),
);
expect(ingest.ingest).toHaveBeenNthCalledWith(
2,
expect.objectContaining({
- userMessage: 'Ingest external text artifact "first line second line" into KTX memory.',
+ userMessage: 'Ingest external text artifact "first line second line" into ktx memory.',
}),
);
expect(ingest.ingest).toHaveBeenNthCalledWith(
3,
expect.objectContaining({
- userMessage: 'Ingest external text artifact "This inline note is intentionally long xxxxxxxx..." into KTX memory.',
+ userMessage: 'Ingest external text artifact "This inline note is intentionally long xxxxxxxx..." into ktx memory.',
}),
);
});
diff --git a/python/ktx-daemon/README.md b/python/ktx-daemon/README.md
index 95a3ffbf..d5ff17f2 100644
--- a/python/ktx-daemon/README.md
+++ b/python/ktx-daemon/README.md
@@ -1,6 +1,6 @@
# ktx-daemon
-`ktx-daemon` is the portable Python compute package for KTX.
+`ktx-daemon` is the portable Python compute package for **ktx**.
It supports portable compute in two modes:
@@ -99,6 +99,6 @@ Code execution is off by default. When enabled, it runs Python `exec` in the
daemon process with the same in-process boundary as the one-shot
`code-execute` command and does not provide OS-level sandboxing.
-HTTP code execution uses the standalone KTX boundary. It does not forward
+HTTP code execution uses the standalone **ktx** boundary. It does not forward
caller authorization headers to a host app and does not connect scratchpad or
visualization helpers to host application APIs.
diff --git a/python/ktx-daemon/pyproject.toml b/python/ktx-daemon/pyproject.toml
index 3bbb3f60..5364e883 100644
--- a/python/ktx-daemon/pyproject.toml
+++ b/python/ktx-daemon/pyproject.toml
@@ -1,7 +1,7 @@
[project]
name = "ktx-daemon"
version = "0.11.0"
-description = "Portable compute package for KTX semantic-layer operations"
+description = "Portable compute package for ktx semantic-layer operations"
readme = "README.md"
requires-python = ">=3.13"
license = "Apache-2.0"
diff --git a/python/ktx-daemon/src/ktx_daemon/__init__.py b/python/ktx-daemon/src/ktx_daemon/__init__.py
index d228ac79..6bfd9795 100644
--- a/python/ktx-daemon/src/ktx_daemon/__init__.py
+++ b/python/ktx-daemon/src/ktx_daemon/__init__.py
@@ -1,4 +1,4 @@
-"""Portable compute package for KTX."""
+"""Portable compute package for ktx."""
from collections.abc import Callable
from importlib.metadata import PackageNotFoundError, version
diff --git a/python/ktx-daemon/src/ktx_daemon/__main__.py b/python/ktx-daemon/src/ktx_daemon/__main__.py
index cbc2e228..83fe0367 100644
--- a/python/ktx-daemon/src/ktx_daemon/__main__.py
+++ b/python/ktx-daemon/src/ktx_daemon/__main__.py
@@ -1,4 +1,4 @@
-"""Command entry point for one-shot KTX daemon compute operations."""
+"""Command entry point for one-shot ktx daemon compute operations."""
from __future__ import annotations
@@ -67,7 +67,7 @@ def build_parser() -> argparse.ArgumentParser:
)
serve_http = subcommands.add_parser(
"serve-http",
- help="Run the KTX daemon portable compute HTTP server",
+ help="Run the ktx daemon portable compute HTTP server",
)
serve_http.add_argument("--host", default="127.0.0.1")
serve_http.add_argument("--port", type=int, default=8765)
diff --git a/python/ktx-daemon/src/ktx_daemon/app.py b/python/ktx-daemon/src/ktx_daemon/app.py
index 5860c4e4..63487439 100644
--- a/python/ktx-daemon/src/ktx_daemon/app.py
+++ b/python/ktx-daemon/src/ktx_daemon/app.py
@@ -1,4 +1,4 @@
-"""FastAPI app factory for the KTX daemon semantic compute server."""
+"""FastAPI app factory for the ktx daemon semantic compute server."""
from __future__ import annotations
@@ -142,8 +142,8 @@ def create_app(
)
app = FastAPI(
- title="KTX Daemon",
- description="Stateless portable compute server for KTX.",
+ title="ktx Daemon",
+ description="Stateless portable compute server for ktx.",
version=VERSION,
lifespan=lifespan,
)
diff --git a/python/ktx-daemon/src/ktx_daemon/code_execution.py b/python/ktx-daemon/src/ktx_daemon/code_execution.py
index 7c793f4f..041925d7 100644
--- a/python/ktx-daemon/src/ktx_daemon/code_execution.py
+++ b/python/ktx-daemon/src/ktx_daemon/code_execution.py
@@ -1,4 +1,4 @@
-"""Portable in-process code execution helpers for KTX daemon.
+"""Portable in-process code execution helpers for ktx daemon.
This module preserves the host application's current Python execution behavior.
It runs code with Python ``exec`` in the current process and does not provide
diff --git a/python/ktx-daemon/src/ktx_daemon/database_introspection.py b/python/ktx-daemon/src/ktx_daemon/database_introspection.py
index 6ba84265..69be4209 100644
--- a/python/ktx-daemon/src/ktx_daemon/database_introspection.py
+++ b/python/ktx-daemon/src/ktx_daemon/database_introspection.py
@@ -1,4 +1,4 @@
-"""Portable database introspection helpers for KTX daemon."""
+"""Portable database introspection helpers for ktx daemon."""
from __future__ import annotations
diff --git a/python/ktx-daemon/src/ktx_daemon/embeddings.py b/python/ktx-daemon/src/ktx_daemon/embeddings.py
index edf398e4..2c4ac7b2 100644
--- a/python/ktx-daemon/src/ktx_daemon/embeddings.py
+++ b/python/ktx-daemon/src/ktx_daemon/embeddings.py
@@ -1,4 +1,4 @@
-"""Portable embedding compute helpers for KTX daemon."""
+"""Portable embedding compute helpers for ktx daemon."""
from __future__ import annotations
diff --git a/python/ktx-daemon/src/ktx_daemon/semantic_layer.py b/python/ktx-daemon/src/ktx_daemon/semantic_layer.py
index f58c6e39..b7e7f133 100644
--- a/python/ktx-daemon/src/ktx_daemon/semantic_layer.py
+++ b/python/ktx-daemon/src/ktx_daemon/semantic_layer.py
@@ -1,4 +1,4 @@
-"""Semantic-layer compute helpers for the KTX daemon package."""
+"""Semantic-layer compute helpers for the ktx daemon package."""
from __future__ import annotations
diff --git a/scripts/build-python-runtime-wheel.mjs b/scripts/build-python-runtime-wheel.mjs
index 46e30ce5..2d591e52 100644
--- a/scripts/build-python-runtime-wheel.mjs
+++ b/scripts/build-python-runtime-wheel.mjs
@@ -32,7 +32,7 @@ export function runtimeWheelPyproject() {
return `[project]
name = "${RUNTIME_WHEEL_DISTRIBUTION_NAME}"
version = "${RUNTIME_WHEEL_PACKAGE_VERSION}"
-description = "Bundled Python runtime payload for the KTX npm package"
+description = "Bundled Python runtime payload for the ktx npm package"
readme = "README.md"
requires-python = ">=3.13"
license = "Apache-2.0"
@@ -76,7 +76,7 @@ packages = ["semantic_layer", "ktx_daemon"]
export function runtimeWheelReadme() {
return `# kaelio-ktx Python runtime
-Bundled Python runtime wheel for KTX.
+Bundled Python runtime wheel for ktx.
This wheel is built from the repository's \`semantic_layer\` and
\`ktx_daemon\` source trees for inclusion in the npm package. It is not a
diff --git a/scripts/build-python-runtime-wheel.test.mjs b/scripts/build-python-runtime-wheel.test.mjs
index 67b85175..7d4acb9c 100644
--- a/scripts/build-python-runtime-wheel.test.mjs
+++ b/scripts/build-python-runtime-wheel.test.mjs
@@ -70,7 +70,7 @@ describe('runtimeWheelPyproject', () => {
});
describe('createRuntimeWheelBuildTree', () => {
- it('copies KTX-owned Python packages into the build tree', async () => {
+ it('copies ktx-owned Python packages into the build tree', async () => {
const root = await mkdtemp(join(tmpdir(), 'ktx-runtime-wheel-test-'));
try {
await writeRuntimeSourceFixture(root);
@@ -90,7 +90,7 @@ describe('createRuntimeWheelBuildTree', () => {
assert.match(pyproject, /name = "kaelio-ktx"/);
assert.match(pyproject, /local-embeddings = \[/);
const readme = await readFile(join(layout.buildRoot, 'README.md'), 'utf8');
- assert.match(readme, /Bundled Python runtime wheel for KTX/);
+ assert.match(readme, /Bundled Python runtime wheel for ktx/);
} finally {
await rm(root, { recursive: true, force: true });
}
diff --git a/scripts/check-boundaries.test.mjs b/scripts/check-boundaries.test.mjs
index e6dd4bb8..bff32c78 100644
--- a/scripts/check-boundaries.test.mjs
+++ b/scripts/check-boundaries.test.mjs
@@ -25,7 +25,7 @@ describe('scanFileContent', () => {
[],
);
assert.deepEqual(
- scanFileContent('packages/cli/src/prompts/memory_agent_bundle_ingest_work_unit.md', 'Write output for KTX.'),
+ scanFileContent('packages/cli/src/prompts/memory_agent_bundle_ingest_work_unit.md', 'Write output for ktx.'),
[],
);
});
@@ -83,7 +83,7 @@ describe('scanFileContent', () => {
);
});
- it('rejects old KTX LLM port declarations in context', () => {
+ it('rejects old ktx LLM port declarations in context', () => {
const violations = [
...scanFileContent('packages/cli/src/context/agent/agent-runner.service.ts', 'export interface LlmProviderPort {}'),
...scanFileContent('packages/cli/src/context/scan/types.ts', 'export interface KtxScanLlmPort {}'),
diff --git a/scripts/ci-artifact-upload.test.mjs b/scripts/ci-artifact-upload.test.mjs
index 2c931cd0..21b907ed 100644
--- a/scripts/ci-artifact-upload.test.mjs
+++ b/scripts/ci-artifact-upload.test.mjs
@@ -20,8 +20,8 @@ async function readCiWorkflowOrSkip(testContext) {
return readFile(ciWorkflowPath, 'utf-8');
}
-describe('KTX CI artifact upload contract', () => {
- it('uploads verified KTX package artifacts from the standalone check job', async (testContext) => {
+describe('ktx CI artifact upload contract', () => {
+ it('uploads verified ktx package artifacts from the standalone check job', async (testContext) => {
const workflow = await readCiWorkflowOrSkip(testContext);
if (workflow === null) {
return;
diff --git a/scripts/conductor-run.sh b/scripts/conductor-run.sh
index 33b40b20..4518d99c 100755
--- a/scripts/conductor-run.sh
+++ b/scripts/conductor-run.sh
@@ -1,5 +1,5 @@
#!/bin/bash
-# conductor-run.sh - Starts the long-lived local KTX daemon for Conductor.
+# conductor-run.sh - Starts the long-lived local ktx daemon for Conductor.
#
# Uses a fixed port because Conductor runs this workspace in nonconcurrent mode.
@@ -82,9 +82,9 @@ resolve_uv_for_project() {
printf '%s\n' "$workspace_uv"
}
-echo "=== Starting KTX for Conductor ==="
+echo "=== Starting ktx for Conductor ==="
-echo "Building KTX packages..."
+echo "Building ktx packages..."
pnpm run build
KTX_UV_BIN="$(resolve_uv_for_project "pyproject.toml")"
@@ -94,5 +94,5 @@ if [ -f ".venv/bin/activate" ]; then
source .venv/bin/activate
fi
-echo "KTX daemon: http://127.0.0.1:8765"
+echo "ktx daemon: http://127.0.0.1:8765"
exec uv run ktx-daemon serve-http --host 127.0.0.1 --port 8765
diff --git a/scripts/conductor-scripts.test.mjs b/scripts/conductor-scripts.test.mjs
index 3284efae..c8885be1 100644
--- a/scripts/conductor-scripts.test.mjs
+++ b/scripts/conductor-scripts.test.mjs
@@ -42,7 +42,7 @@ describe('Conductor workspace scripts', () => {
assert.doesNotMatch(workspaceScript, /link_agent_skills_for_claude/);
});
- it('runs the KTX daemon on the documented fixed local port', async () => {
+ it('runs the ktx daemon on the documented fixed local port', async () => {
const runScript = await readText('scripts/conductor-run.sh');
assert.match(runScript, /pnpm run build/);
diff --git a/scripts/conductor-setup.sh b/scripts/conductor-setup.sh
index 81049e81..7adf4b1f 100755
--- a/scripts/conductor-setup.sh
+++ b/scripts/conductor-setup.sh
@@ -1,5 +1,5 @@
#!/bin/bash
-# conductor-setup.sh - Runs once when Conductor creates a KTX workspace.
+# conductor-setup.sh - Runs once when Conductor creates a ktx workspace.
#
# Prepares the standalone pnpm + uv workspace and builds the local CLI.
@@ -114,7 +114,7 @@ link_agent_overlays() {
fi
}
-echo "=== Conductor KTX workspace setup ==="
+echo "=== Conductor ktx workspace setup ==="
link_agent_overlays
@@ -126,21 +126,21 @@ fi
KTX_UV_BIN="$(resolve_uv_for_project "pyproject.toml")"
export PATH="$(dirname "$KTX_UV_BIN"):$PATH"
-echo "Installing KTX Python dependencies..."
+echo "Installing ktx Python dependencies..."
uv sync --all-packages --all-groups
-echo "Installing KTX JS dependencies..."
+echo "Installing ktx JS dependencies..."
pnpm install --frozen-lockfile --prefer-offline
echo "Rebuilding native JS dependencies..."
pnpm run native:rebuild
-echo "Building KTX runtime artifacts..."
+echo "Building ktx runtime artifacts..."
# Builds every internal package (llm/context/connectors/cli) before producing
# the wheel + npm tarball, so a separate `pnpm run build` would be redundant.
pnpm run artifacts:build
-echo "Running KTX setup doctor..."
+echo "Running ktx setup doctor..."
# Run from a temp dir so `ktx status` doesn't walk up into a parent ktx.yaml
# (e.g. ~/ktx.yaml) and report on an unrelated project.
KTX_CLI_BIN="$PWD/packages/cli/dist/bin.js"
diff --git a/scripts/installed-live-database-smoke.test.mjs b/scripts/installed-live-database-smoke.test.mjs
index 2ddeed5d..6b53cff2 100644
--- a/scripts/installed-live-database-smoke.test.mjs
+++ b/scripts/installed-live-database-smoke.test.mjs
@@ -49,7 +49,7 @@ describe('installed live-database artifact smoke helpers', () => {
);
});
- it('writes a public database ingest KTX project config with SQLite local state', () => {
+ it('writes a public database ingest ktx project config with SQLite local state', () => {
assert.equal(
buildKtxYaml('postgresql://ktx:postgres@127.0.0.1:15432/warehouse'), // pragma: allowlist secret
[
diff --git a/scripts/link-dev-cli.mjs b/scripts/link-dev-cli.mjs
index 20893bd8..17166db2 100644
--- a/scripts/link-dev-cli.mjs
+++ b/scripts/link-dev-cli.mjs
@@ -73,7 +73,7 @@ async function writePinnedPosixLauncher(globalBin, binPath, binaryName, writeFil
const launcherPath = join(globalBin, binaryName);
const script = [
'#!/bin/sh',
- '# Generated by `pnpm run link:dev` in the KTX workspace.',
+ '# Generated by `pnpm run link:dev` in the ktx workspace.',
'# Keep this launcher pinned to the Node binary that built native dependencies.',
`exec ${shellDoubleQuote(process.execPath)} ${shellDoubleQuote(binPath)} "$@"`,
'',
@@ -88,7 +88,7 @@ async function writePinnedWindowsLauncher(globalBin, binPath, binaryName, writeF
const launcherPath = join(globalBin, `${binaryName}.cmd`);
const script = [
'@echo off',
- 'REM Generated by `pnpm run link:dev` in the KTX workspace.',
+ 'REM Generated by `pnpm run link:dev` in the ktx workspace.',
`"${process.execPath}" "${binPath}" %*`,
'',
].join('\r\n');
@@ -179,7 +179,7 @@ if (import.meta.url === pathToFileURL(process.argv[1]).href) {
checkOnly: hasFlag('--check-only'),
binaryName: optionValue('--name', 'ktx-dev'),
});
- process.stdout.write(`KTX CLI bin: ${result.binPath}\n`);
+ process.stdout.write(`ktx CLI bin: ${result.binPath}\n`);
if (result.linked) {
process.stdout.write(`Linked binary: ${result.binaryName}\n`);
process.stdout.write(`Verified: ${result.verification.output}\n`);
diff --git a/scripts/local-embeddings-runtime-smoke.mjs b/scripts/local-embeddings-runtime-smoke.mjs
index 539eaa60..e0e69768 100644
--- a/scripts/local-embeddings-runtime-smoke.mjs
+++ b/scripts/local-embeddings-runtime-smoke.mjs
@@ -312,7 +312,7 @@ export async function runLocalEmbeddingsRuntimeSmoke(options = {}) {
timeoutMs: commands[2].timeoutMs,
});
requireSuccess(commands[2].label, install);
- requireOutput(commands[2].label, install, /Installed KTX Python runtime/);
+ requireOutput(commands[2].label, install, /Installed ktx Python runtime/);
requireOutput(commands[2].label, install, /features: core, local-embeddings/);
const readyStatus = parseJsonStdout(
@@ -342,11 +342,11 @@ export async function runLocalEmbeddingsRuntimeSmoke(options = {}) {
const embeddingResponse = await postJson(
baseUrl,
'/embeddings/compute',
- { text: 'KTX local embeddings release smoke' },
+ { text: 'ktx local embeddings release smoke' },
900_000,
);
validateEmbeddingResponse(embeddingResponse, 384);
- process.stdout.write('KTX daemon computed a 384-dimensional embedding\n');
+ process.stdout.write('ktx daemon computed a 384-dimensional embedding\n');
const setup = await run(commands[5].command, commands[5].args, {
cwd: installDir,
@@ -363,7 +363,7 @@ export async function runLocalEmbeddingsRuntimeSmoke(options = {}) {
if (/base_url:/.test(config)) {
throw new Error(`ktx.yaml should omit base_url for managed local embeddings:\n${config}`);
}
- process.stdout.write('KTX setup persisted managed local embeddings (no base_url)\n');
+ process.stdout.write('ktx setup persisted managed local embeddings (no base_url)\n');
const stop = await run(commands[6].command, commands[6].args, {
cwd: installDir,
@@ -372,9 +372,9 @@ export async function runLocalEmbeddingsRuntimeSmoke(options = {}) {
});
requireSuccess(commands[6].label, stop);
daemonStarted = false;
- requireOutput(commands[6].label, stop, /Stopped KTX daemon/);
+ requireOutput(commands[6].label, stop, /Stopped ktx daemon/);
- process.stdout.write('KTX local embeddings runtime smoke verified\n');
+ process.stdout.write('ktx local embeddings runtime smoke verified\n');
} finally {
if (daemonStarted) {
await run('pnpm', ['exec', 'ktx', 'admin', 'runtime', 'stop'], {
@@ -395,7 +395,7 @@ async function main() {
const args = process.argv.slice(2);
const optIn = localEmbeddingsSmokeOptIn(process.env, args);
if (!optIn.run) {
- process.stdout.write(`Skipping KTX local embeddings runtime smoke. ${optIn.message}\n`);
+ process.stdout.write(`Skipping ktx local embeddings runtime smoke. ${optIn.message}\n`);
if (args.includes('--require-opt-in')) {
process.exitCode = 1;
}
diff --git a/scripts/local-embeddings-runtime-smoke.test.mjs b/scripts/local-embeddings-runtime-smoke.test.mjs
index 92df9dae..2e171474 100644
--- a/scripts/local-embeddings-runtime-smoke.test.mjs
+++ b/scripts/local-embeddings-runtime-smoke.test.mjs
@@ -129,13 +129,13 @@ describe('localEmbeddingsSmokeCommands', () => {
describe('parseDaemonBaseUrl', () => {
it('extracts the daemon URL from runtime start output', () => {
assert.equal(
- parseDaemonBaseUrl('Started KTX daemon\nurl: http://127.0.0.1:61234\nfeatures: local-embeddings\n'),
+ parseDaemonBaseUrl('Started ktx daemon\nurl: http://127.0.0.1:61234\nfeatures: local-embeddings\n'),
'http://127.0.0.1:61234',
);
});
it('rejects output without a daemon URL', () => {
- assert.throws(() => parseDaemonBaseUrl('Started KTX daemon\n'), /Daemon URL was not printed/);
+ assert.throws(() => parseDaemonBaseUrl('Started ktx daemon\n'), /Daemon URL was not printed/);
});
});
diff --git a/scripts/package-artifacts.mjs b/scripts/package-artifacts.mjs
index e9ab5e9a..14567c31 100644
--- a/scripts/package-artifacts.mjs
+++ b/scripts/package-artifacts.mjs
@@ -791,7 +791,7 @@ try {
requireSuccessWithStderr(
'ktx sl query first managed runtime install',
slQuery,
- /Installing KTX Python runtime \\(core\\) with uv[\\s\\S]*KTX Python runtime ready:/,
+ /Installing ktx Python runtime \\(core\\) with uv[\\s\\S]*ktx Python runtime ready:/,
);
requireOutput('ktx sl query first managed runtime install', slQuery, /"mode": "compile_only"/);
requireOutput('ktx sl query first managed runtime install', slQuery, /orders/);
@@ -836,26 +836,26 @@ try {
const runtimeDoctor = await run(...Object.values(pnpmCommand(['exec', 'ktx', 'admin', 'runtime', 'status'])));
requireSuccess('ktx admin runtime status', runtimeDoctor);
- requireOutput('ktx admin runtime status', runtimeDoctor, /KTX Python runtime/);
+ requireOutput('ktx admin runtime status', runtimeDoctor, /ktx Python runtime/);
requireOutput('ktx admin runtime status', runtimeDoctor, /status: ready/);
process.stdout.write('ktx admin runtime status verified\\n');
const runtimeStart = await run(...Object.values(pnpmCommand(['exec', 'ktx', 'admin', 'runtime', 'start'])));
requireSuccess('ktx admin runtime start', runtimeStart);
daemonStarted = true;
- requireOutput('ktx admin runtime start', runtimeStart, /Started KTX daemon/);
+ requireOutput('ktx admin runtime start', runtimeStart, /Started ktx daemon/);
requireOutput('ktx admin runtime start', runtimeStart, /url: http:\\/\\/127\\.0\\.0\\.1:\\d+/);
requireOutput('ktx admin runtime start', runtimeStart, /features: core/);
const runtimeStartReuse = await run(...Object.values(pnpmCommand(['exec', 'ktx', 'admin', 'runtime', 'start'])));
requireSuccess('ktx admin runtime start reuse', runtimeStartReuse);
- requireOutput('ktx admin runtime start reuse', runtimeStartReuse, /Using existing KTX daemon/);
+ requireOutput('ktx admin runtime start reuse', runtimeStartReuse, /Using existing ktx daemon/);
requireOutput('ktx admin runtime start reuse', runtimeStartReuse, /features: core/);
const runtimeStop = await run(...Object.values(pnpmCommand(['exec', 'ktx', 'admin', 'runtime', 'stop'])));
requireSuccess('ktx admin runtime stop', runtimeStop);
daemonStarted = false;
- requireOutput('ktx admin runtime stop', runtimeStop, /Stopped KTX daemon/);
+ requireOutput('ktx admin runtime stop', runtimeStop, /Stopped ktx daemon/);
process.stdout.write('ktx admin runtime daemon lifecycle verified\\n');
const databaseIngest = await run(
@@ -952,7 +952,7 @@ try {
const doctor = await run(...Object.values(pnpmCommand(['exec', 'ktx', 'status', '--verbose', '--no-input'])));
assert.ok([0, 1].includes(doctor.code), 'ktx status setup exit code must be 0 or 1');
- requireStdout('ktx status setup', doctor, /KTX status/);
+ requireStdout('ktx status setup', doctor, /ktx status/);
requireStdout('ktx status setup', doctor, /No project here yet\\./);
requireStdout('ktx status setup', doctor, /ktx setup/);
requireStdout('ktx status setup', doctor, /Node 22\\+/);
diff --git a/scripts/package-artifacts.test.mjs b/scripts/package-artifacts.test.mjs
index 29e7fb1e..f307dcec 100644
--- a/scripts/package-artifacts.test.mjs
+++ b/scripts/package-artifacts.test.mjs
@@ -516,8 +516,8 @@ describe('verification snippets', () => {
assert.match(source, /managed-runtime/);
assert.match(source, /ktx admin runtime status missing/);
assert.match(source, /runtimeStatusBefore\.kind, 'missing'/);
- assert.ok(source.includes(String.raw`Installing KTX Python runtime \(core\) with uv`));
- assert.match(source, /KTX Python runtime ready:/);
+ assert.ok(source.includes(String.raw`Installing ktx Python runtime \(core\) with uv`));
+ assert.match(source, /ktx Python runtime ready:/);
assert.match(source, /ktx admin runtime status ready/);
assert.match(source, /runtimeStatusAfter\.kind, 'ready'/);
assert.match(source, /runtimeStatusAfter\.manifest\.features/);
@@ -525,7 +525,7 @@ describe('verification snippets', () => {
assert.match(source, /status: ready/);
assert.match(source, /ktx admin runtime start/);
assert.match(source, /ktx admin runtime start reuse/);
- assert.match(source, /Using existing KTX daemon/);
+ assert.match(source, /Using existing ktx daemon/);
assert.match(source, /ktx admin runtime stop/);
assert.doesNotMatch(source, /ktx admin runtime prune/);
assert.doesNotMatch(source, /staleRuntimeDir/);
@@ -557,7 +557,7 @@ describe('verification snippets', () => {
assert.match(source, /Usage: ktx setup/);
assert.doesNotMatch(source, new RegExp(["'demo'", "'--mode'", "'deterministic'"].join(', ')));
assert.match(source, /'status', '--verbose', '--no-input'/);
- assert.match(source, /KTX status/);
+ assert.match(source, /ktx status/);
assert.match(source, /No project here yet/);
assert.doesNotMatch(source, /function requireProjectStderr/);
assert.match(source, /Object\.keys\(packageJson\.dependencies\)/);
diff --git a/scripts/prepare-cli-bin.mjs b/scripts/prepare-cli-bin.mjs
index e9b106b0..04e55823 100644
--- a/scripts/prepare-cli-bin.mjs
+++ b/scripts/prepare-cli-bin.mjs
@@ -36,7 +36,7 @@ export async function ensureCliBinExecutable(rootDir = ktxRootDir()) {
if (import.meta.url === pathToFileURL(process.argv[1]).href) {
try {
const binPath = await ensureCliBinExecutable();
- process.stdout.write(`Prepared KTX CLI bin: ${binPath}\n`);
+ process.stdout.write(`Prepared ktx CLI bin: ${binPath}\n`);
} catch (error) {
process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
process.exitCode = 1;
diff --git a/scripts/published-package-smoke.mjs b/scripts/published-package-smoke.mjs
index 88902c42..53e8d565 100644
--- a/scripts/published-package-smoke.mjs
+++ b/scripts/published-package-smoke.mjs
@@ -143,7 +143,7 @@ async function main() {
if (config.requireConfig) {
throw new Error(config.reason);
}
- process.stdout.write(`Published KTX package smoke skipped: ${config.reason}\n`);
+ process.stdout.write(`Published ktx package smoke skipped: ${config.reason}\n`);
return;
}
diff --git a/scripts/relationship-orbit-verification.mjs b/scripts/relationship-orbit-verification.mjs
index 5f9ada62..fb402308 100644
--- a/scripts/relationship-orbit-verification.mjs
+++ b/scripts/relationship-orbit-verification.mjs
@@ -197,7 +197,7 @@ function formatBlocked(result) {
export function formatOrbitVerificationMarkdown(result) {
const lines = [
- '# KTX Relationship Discovery Orbit Verification',
+ '# ktx Relationship Discovery Orbit Verification',
'',
`Date: ${result.date}`,
'',
@@ -323,7 +323,7 @@ export async function runOrbitVerification(options = {}) {
projectDir,
scanCommand,
scanExitCode: scan.exitCode,
- blocker: 'KTX scan completed without printing a Run id',
+ blocker: 'ktx scan completed without printing a Run id',
scanStdout: scan.stdout,
scanStderr: scan.stderr,
};
@@ -337,7 +337,7 @@ export async function runOrbitVerification(options = {}) {
projectDir,
scanCommand,
scanExitCode: scan.exitCode,
- blocker: 'KTX scan completed without printing a report artifact path',
+ blocker: 'ktx scan completed without printing a report artifact path',
scanStdout: scan.stdout,
scanStderr: scan.stderr,
};
diff --git a/scripts/relationship-orbit-verification.test.mjs b/scripts/relationship-orbit-verification.test.mjs
index 65a200c4..7f947b91 100644
--- a/scripts/relationship-orbit-verification.test.mjs
+++ b/scripts/relationship-orbit-verification.test.mjs
@@ -51,13 +51,13 @@ function successReportJson() {
function successfulRunKtxScan(calls = []) {
return async (args, io) => {
calls.push(args);
- io.stdout.write('KTX scan completed\nRun: scan-orbit-1\nConnection: orbit\n Report: reports/scan-report.json\n');
+ io.stdout.write('ktx scan completed\nRun: scan-orbit-1\nConnection: orbit\n Report: reports/scan-report.json\n');
return 0;
};
}
describe('relationship Orbit verification helper', () => {
- it('exposes the Orbit verification command from the KTX workspace package', async () => {
+ it('exposes the Orbit verification command from the ktx workspace package', async () => {
const packageJson = JSON.parse(await readFile(new URL('../package.json', import.meta.url), 'utf8'));
assert.equal(
@@ -145,8 +145,8 @@ describe('relationship Orbit verification helper', () => {
});
it('extracts the run id from human scan output', () => {
- assert.equal(extractRunId(`KTX scan completed\nStatus: done\nRun: scan-orbit-1\nConnection: orbit\n`), 'scan-orbit-1');
- assert.equal(extractRunId('KTX scan completed without a run line\n'), null);
+ assert.equal(extractRunId(`ktx scan completed\nStatus: done\nRun: scan-orbit-1\nConnection: orbit\n`), 'scan-orbit-1');
+ assert.equal(extractRunId('ktx scan completed without a run line\n'), null);
assert.equal(extractReportPath('Artifacts\n Report: reports/scan-report.json\n'), 'reports/scan-report.json');
});
@@ -159,12 +159,12 @@ describe('relationship Orbit verification helper', () => {
scanCommand: 'internal runKtxScan connection=orbit mode=relationships projectDir=/tmp/orbit-project',
reportPath: '/tmp/orbit-project/reports/scan-report.json',
scanExitCode: 0,
- scanStdout: 'KTX scan completed\nRun: scan-orbit-1\n',
+ scanStdout: 'ktx scan completed\nRun: scan-orbit-1\n',
scanStderr: '',
report: JSON.parse(successReportJson()),
});
- assert.match(markdown, /# KTX Relationship Discovery Orbit Verification/);
+ assert.match(markdown, /# ktx Relationship Discovery Orbit Verification/);
assert.match(markdown, /Outcome/);
assert.match(markdown, /Exit code: 0/);
assert.match(markdown, /Accepted: 14/);
diff --git a/scripts/release-readiness.mjs b/scripts/release-readiness.mjs
index ae3aa825..f4281382 100644
--- a/scripts/release-readiness.mjs
+++ b/scripts/release-readiness.mjs
@@ -319,9 +319,9 @@ async function main() {
return;
}
- process.stdout.write(`KTX release mode: ${report.releaseMode}\n`);
- process.stdout.write(`KTX source revision: ${report.sourceRevision ?? 'local'}\n`);
- process.stdout.write(`KTX packages: ${report.packageNames.join(', ')}\n`);
+ process.stdout.write(`ktx release mode: ${report.releaseMode}\n`);
+ process.stdout.write(`ktx source revision: ${report.sourceRevision ?? 'local'}\n`);
+ process.stdout.write(`ktx packages: ${report.packageNames.join(', ')}\n`);
process.stdout.write(`Published package smoke: ${report.publishedPackageSmokeGate.status}\n`);
process.stdout.write(`Published package smoke script: ${report.publishedPackageSmokeGate.script}\n`);
process.stdout.write(`Published package smoke reason: ${report.publishedPackageSmokeGate.reason}\n`);
diff --git a/scripts/release-readiness.test.mjs b/scripts/release-readiness.test.mjs
index e01337b9..a889537d 100644
--- a/scripts/release-readiness.test.mjs
+++ b/scripts/release-readiness.test.mjs
@@ -102,7 +102,7 @@ async function writeReadyFixture(root, options = {}) {
}
describe('release readiness policy', () => {
- it('reads the checked release policy path from the KTX root', async () => {
+ it('reads the checked release policy path from the ktx root', async () => {
const root = await mkdtemp(join(tmpdir(), 'ktx-release-policy-test-'));
try {
const policy = releasePolicy();
diff --git a/scripts/run-ktx.mjs b/scripts/run-ktx.mjs
index 1a6ba735..d963e725 100644
--- a/scripts/run-ktx.mjs
+++ b/scripts/run-ktx.mjs
@@ -161,13 +161,13 @@ export async function runWorkspaceKtx(argv, options = {}) {
if (needsBuild) {
stderr.write(
binExists
- ? 'KTX CLI build output is stale. Rebuilding it now with `pnpm run build`...\n'
- : 'KTX CLI build output is missing. Building it now with `pnpm run build`...\n',
+ ? 'ktx CLI build output is stale. Rebuilding it now with `pnpm run build`...\n'
+ : 'ktx CLI build output is missing. Building it now with `pnpm run build`...\n',
);
const buildExitCode = await runCommand('pnpm', ['run', 'build'], { cwd: rootDir, env: commandEnv });
if (buildExitCode !== 0) {
stderr.write(
- '\nKTX CLI build failed. Run `pnpm run setup:dev` from the KTX directory, then retry this command.\n',
+ '\nktx CLI build failed. Run `pnpm run setup:dev` from the ktx directory, then retry this command.\n',
);
return buildExitCode;
}
diff --git a/scripts/run-ktx.test.mjs b/scripts/run-ktx.test.mjs
index 65ca4797..3cc36406 100644
--- a/scripts/run-ktx.test.mjs
+++ b/scripts/run-ktx.test.mjs
@@ -153,7 +153,7 @@ test('runWorkspaceKtx builds the workspace CLI before running it when dist is mi
],
);
assert.deepEqual(logs, [
- ['stderr', 'KTX CLI build output is missing. Building it now with `pnpm run build`...\n'],
+ ['stderr', 'ktx CLI build output is missing. Building it now with `pnpm run build`...\n'],
['stdout', 'build ok\n'],
['stdout', 'Replay complete\n'],
]);
@@ -216,7 +216,7 @@ test('runWorkspaceKtx rebuilds before running when workspace sources are newer t
],
);
assert.deepEqual(logs, [
- ['stderr', 'KTX CLI build output is stale. Rebuilding it now with `pnpm run build`...\n'],
+ ['stderr', 'ktx CLI build output is stale. Rebuilding it now with `pnpm run build`...\n'],
['stdout', 'build ok\n'],
['stdout', '{"status":"ready"}\n'],
]);
@@ -256,7 +256,7 @@ test('runWorkspaceKtx skips rebuild when only bin.js is older than sources but s
},
execFile: async (command, args, options) => {
calls.push({ command, args, cwd: options.cwd });
- return { stdout: 'KTX status\n', stderr: '' };
+ return { stdout: 'ktx status\n', stderr: '' };
},
writeFile: async (path, contents) => {
writes.push({ path, contents });
@@ -271,7 +271,7 @@ test('runWorkspaceKtx skips rebuild when only bin.js is older than sources but s
[[process.execPath, ['/workspace/ktx/packages/cli/dist/bin.js', 'status']]],
);
assert.deepEqual(writes, []);
- assert.deepEqual(logs, [['stdout', 'KTX status\n']]);
+ assert.deepEqual(logs, [['stdout', 'ktx status\n']]);
});
test('runWorkspaceKtx rebuilds when stamp is missing even if bin.js exists', async () => {
@@ -308,7 +308,7 @@ test('runWorkspaceKtx rebuilds when stamp is missing even if bin.js exists', asy
if (command === 'pnpm') {
return { stdout: 'build ok\n', stderr: '' };
}
- return { stdout: 'KTX status\n', stderr: '' };
+ return { stdout: 'ktx status\n', stderr: '' };
},
writeFile: async (path, contents) => {
writes.push({ path, contents });
@@ -327,7 +327,7 @@ test('runWorkspaceKtx rebuilds when stamp is missing even if bin.js exists', asy
);
assert.deepEqual(logs[0], [
'stderr',
- 'KTX CLI build output is stale. Rebuilding it now with `pnpm run build`...\n',
+ 'ktx CLI build output is stale. Rebuilding it now with `pnpm run build`...\n',
]);
assert.deepEqual(writes, [
{ path: '/workspace/ktx/packages/cli/dist/.ktx-build-stamp', contents: '' },
diff --git a/scripts/standalone-ci-workflow.test.mjs b/scripts/standalone-ci-workflow.test.mjs
index 103d61d7..9c807ef5 100644
--- a/scripts/standalone-ci-workflow.test.mjs
+++ b/scripts/standalone-ci-workflow.test.mjs
@@ -12,7 +12,7 @@ function assertIncludesAll(text, values) {
}
}
-describe('standalone KTX CI workflow', () => {
+describe('standalone ktx CI workflow', () => {
it('runs package checks in parallel jobs from the repository root', async () => {
const workflow = await readText('.github/workflows/ci.yml');
diff --git a/scripts/update-public-release-version.test.mjs b/scripts/update-public-release-version.test.mjs
index 63391819..fa063d60 100644
--- a/scripts/update-public-release-version.test.mjs
+++ b/scripts/update-public-release-version.test.mjs
@@ -27,7 +27,7 @@ async function readText(path) {
const DAEMON_PYPROJECT = `[project]
name = "ktx-daemon"
version = "0.4.0"
-description = "Portable compute package for KTX semantic-layer operations"
+description = "Portable compute package for ktx semantic-layer operations"
[build-system]
requires = ["hatchling"]
diff --git a/skills/ktx/SKILL.md b/skills/ktx/SKILL.md
index 746b2a5d..5560abaa 100644
--- a/skills/ktx/SKILL.md
+++ b/skills/ktx/SKILL.md
@@ -244,7 +244,7 @@ as "ready, LLM optional" and judge the data layer by the connection and
For known failure signatures (`invalid ELF header`,
`Native CLI binary for not found`, `Missing Anthropic API key`,
-`claude-code` probe failure, `KTX cannot work without a database` on resume,
+`claude-code` probe failure, `ktx cannot work without a database` on resume,
`Run in a TTY, or pass --target .` with a misleading exit 1, and a
secret that resolves empty only during `ktx ingest`/`ktx mcp`), see
[troubleshooting.md](troubleshooting.md).
diff --git a/skills/ktx/troubleshooting.md b/skills/ktx/troubleshooting.md
index 20f72d23..09d30212 100644
--- a/skills/ktx/troubleshooting.md
+++ b/skills/ktx/troubleshooting.md
@@ -63,7 +63,7 @@ If `claude-code` cannot be made to work, fall back to `--skip-llm` and let
the rest of setup complete; the project is still a usable context layer
without an LLM.
-## `KTX cannot work without a database` when resuming setup
+## `ktx cannot work without a database` when resuming setup
`ktx setup` validates the **current invocation's flags**, not the persisted
`ktx.yaml`. Resuming setup with only `--llm-backend …` fails even when the