diff --git a/docs-site/content/docs/cli-reference/ktx-dev.mdx b/docs-site/content/docs/cli-reference/ktx-dev.mdx index 16a36393..333b6f35 100644 --- a/docs-site/content/docs/cli-reference/ktx-dev.mdx +++ b/docs-site/content/docs/cli-reference/ktx-dev.mdx @@ -22,7 +22,6 @@ ktx dev [options] | Flag | Description | Default | |------|-------------|---------| -| `--name ` | Project name written to `ktx.yaml` | — | | `--force` | Rewrite `ktx.yaml` and scaffold files in an existing project | `false` | ## `dev runtime` @@ -40,7 +39,7 @@ ktx dev [options] ```bash ktx dev init -ktx dev init ./my-project --name "Analytics Context" +ktx dev init ./my-project ktx dev init --force ktx dev runtime install --yes diff --git a/examples/local-warehouse/ktx.yaml b/examples/local-warehouse/ktx.yaml index a967e31c..fb8ae027 100644 --- a/examples/local-warehouse/ktx.yaml +++ b/examples/local-warehouse/ktx.yaml @@ -1,4 +1,3 @@ -project: local-warehouse connections: warehouse: driver: postgres diff --git a/examples/orbit-relationship-verification/ktx.yaml b/examples/orbit-relationship-verification/ktx.yaml index 1251d5a1..b1d30961 100644 --- a/examples/orbit-relationship-verification/ktx.yaml +++ b/examples/orbit-relationship-verification/ktx.yaml @@ -1,4 +1,3 @@ -project: orbit-relationship-verification connections: orbit: driver: sqlite diff --git a/packages/cli/src/cli-program.ts b/packages/cli/src/cli-program.ts index cfbc86b0..01f66332 100644 --- a/packages/cli/src/cli-program.ts +++ b/packages/cli/src/cli-program.ts @@ -20,7 +20,7 @@ export interface KtxCliCommandContext { deps: KtxCliDeps; packageInfo: KtxCliPackageInfo; setExitCode: (code: number) => void; - runInit: (args: { projectDir: string; projectName?: string; force: boolean }, io: KtxCliIo) => Promise; + runInit: (args: { projectDir: string; force: boolean }, io: KtxCliIo) => Promise; writeDebug?: (command: string, commandContext: CommandWithGlobalOptions) => void; } @@ -32,14 +32,14 @@ export interface OutputModeOptions { } interface KtxCommanderProgramOptions { - runInit: (args: { projectDir: string; projectName?: string; force: boolean }, io: KtxCliIo) => Promise; + runInit: (args: { projectDir: string; force: boolean }, io: KtxCliIo) => Promise; } export interface BuildKtxProgramOptions { io: KtxCliIo; deps: KtxCliDeps; packageInfo: KtxCliPackageInfo; - runInit: (args: { projectDir: string; projectName?: string; force: boolean }, io: KtxCliIo) => Promise; + runInit: (args: { projectDir: string; force: boolean }, io: KtxCliIo) => Promise; setExitCode?: (code: number) => void; } diff --git a/packages/cli/src/cli-runtime.ts b/packages/cli/src/cli-runtime.ts index a2147904..cc1a2b98 100644 --- a/packages/cli/src/cli-runtime.ts +++ b/packages/cli/src/cli-runtime.ts @@ -59,14 +59,10 @@ export function packageInfoFromJson(packageJson: unknown): KtxCliPackageInfo { }; } -async function runInit( - args: { projectDir: string; projectName?: string; force: boolean }, - io: KtxCliIo, -): Promise { +async function runInit(args: { projectDir: string; force: boolean }, io: KtxCliIo): Promise { const { initKtxProject } = await import('@ktx/context/project'); const result = await initKtxProject({ projectDir: args.projectDir, - projectName: args.projectName, force: args.force, }); @@ -77,7 +73,7 @@ async function runInit( } export async function runInitForCommander( - args: { projectDir: string; projectName?: string; force: boolean }, + args: { projectDir: string; force: boolean }, io: KtxCliIo, ): Promise { return await runInit(args, io); diff --git a/packages/cli/src/connection.test.ts b/packages/cli/src/connection.test.ts index 5a41dbe4..88f4b921 100644 --- a/packages/cli/src/connection.test.ts +++ b/packages/cli/src/connection.test.ts @@ -82,7 +82,7 @@ describe('runKtxConnection', () => { it('lists configured connections without resolving secrets', async () => { const projectDir = join(tempDir, 'project'); - await initKtxProject({ projectDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir }); await writeConnections(projectDir, { warehouse: { driver: 'postgres', url: 'env:DATABASE_URL' }, docs: { driver: 'notion', auth_token_ref: 'env:NOTION_TOKEN', crawl_mode: 'all_accessible' }, @@ -100,7 +100,7 @@ describe('runKtxConnection', () => { it('prints an empty-state message that points at setup instead of removed connection add', async () => { const projectDir = join(tempDir, 'project'); - await initKtxProject({ projectDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir }); const io = makeIo(); await expect(runKtxConnection({ command: 'list', projectDir }, io.io)).resolves.toBe(0); @@ -111,7 +111,7 @@ describe('runKtxConnection', () => { it('tests a native connection by calling connector.testConnection (not introspect)', async () => { const projectDir = join(tempDir, 'project'); - await initKtxProject({ projectDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir }); await writeConnections(projectDir, { warehouse: { driver: 'sqlite' }, }); @@ -136,7 +136,7 @@ describe('runKtxConnection', () => { it('reports the connector error and still cleans up when native testConnection fails', async () => { const projectDir = join(tempDir, 'project'); - await initKtxProject({ projectDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir }); await writeConnections(projectDir, { warehouse: { driver: 'sqlite' }, }); @@ -155,7 +155,7 @@ describe('runKtxConnection', () => { it('tests a configured Metabase connection through the Metabase runtime client', async () => { const projectDir = join(tempDir, 'project'); - await initKtxProject({ projectDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir }); await writeConnections(projectDir, { prod_metabase: { driver: 'metabase', @@ -201,7 +201,7 @@ describe('runKtxConnection', () => { it('tests a Looker connection through the Looker client', async () => { const projectDir = join(tempDir, 'project'); - await initKtxProject({ projectDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir }); await writeConnections(projectDir, { bi_looker: { driver: 'looker', @@ -230,7 +230,7 @@ describe('runKtxConnection', () => { it('falls back to userId when Looker metadata has no display name', async () => { const projectDir = join(tempDir, 'project'); - await initKtxProject({ projectDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir }); await writeConnections(projectDir, { bi_looker: { driver: 'looker', @@ -255,7 +255,7 @@ describe('runKtxConnection', () => { it('reports the Looker error when testConnection fails', async () => { const projectDir = join(tempDir, 'project'); - await initKtxProject({ projectDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir }); await writeConnections(projectDir, { bi_looker: { driver: 'looker', @@ -277,7 +277,7 @@ describe('runKtxConnection', () => { it('tests a Notion connection by retrieving the bot user', async () => { const projectDir = join(tempDir, 'project'); - await initKtxProject({ projectDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir }); await writeConnections(projectDir, { docs: { driver: 'notion', @@ -302,7 +302,7 @@ describe('runKtxConnection', () => { it('falls back to bot id when Notion bot has no name', async () => { const projectDir = join(tempDir, 'project'); - await initKtxProject({ projectDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir }); await writeConnections(projectDir, { docs: { driver: 'notion', @@ -323,7 +323,7 @@ describe('runKtxConnection', () => { it('tests a dbt connection via testRepoConnection (success)', async () => { const projectDir = join(tempDir, 'project'); - await initKtxProject({ projectDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir }); process.env.DBT_TOKEN = 'gh_token_abc'; // pragma: allowlist secret await writeConnections(projectDir, { 'dbt-main': { @@ -354,7 +354,7 @@ describe('runKtxConnection', () => { it('reports the git error when testRepoConnection fails for dbt', async () => { const projectDir = join(tempDir, 'project'); - await initKtxProject({ projectDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir }); await writeConnections(projectDir, { 'dbt-main': { driver: 'dbt', @@ -377,7 +377,7 @@ describe('runKtxConnection', () => { it('tests a LookML connection via testRepoConnection with camelCase repoUrl', async () => { const projectDir = join(tempDir, 'project'); - await initKtxProject({ projectDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir }); await writeConnections(projectDir, { lookml_main: { driver: 'lookml', @@ -400,7 +400,7 @@ describe('runKtxConnection', () => { it('tests a MetricFlow connection via the nested metricflow block', async () => { const projectDir = join(tempDir, 'project'); - await initKtxProject({ projectDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir }); await writeConnections(projectDir, { mf_main: { driver: 'metricflow', @@ -422,7 +422,7 @@ describe('runKtxConnection', () => { it('--all: prints a single coherent list with one row per connection', async () => { const projectDir = join(tempDir, 'project'); - await initKtxProject({ projectDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir }); await writeConnections(projectDir, { warehouse: { driver: 'sqlite' }, docs: { driver: 'notion', auth_token: 'secret_token', crawl_mode: 'all_accessible' }, // pragma: allowlist secret @@ -450,7 +450,7 @@ describe('runKtxConnection', () => { it('--all: marks failing connections, keeps passing ones, and returns non-zero', async () => { const projectDir = join(tempDir, 'project'); - await initKtxProject({ projectDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir }); await writeConnections(projectDir, { warehouse: { driver: 'sqlite' }, broken: { driver: 'sqlite' }, @@ -476,7 +476,7 @@ describe('runKtxConnection', () => { it('--all: shows an empty-state message when no connections are configured', async () => { const projectDir = join(tempDir, 'project'); - await initKtxProject({ projectDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir }); const io = makeIo(); await expect(runKtxConnection({ command: 'test-all', projectDir }, io.io)).resolves.toBe(0); @@ -488,14 +488,18 @@ describe('runKtxConnection', () => { it('rejects unknown drivers with a helpful error', async () => { const projectDir = join(tempDir, 'project'); - await initKtxProject({ projectDir, projectName: 'warehouse' }); - await writeFile(join(projectDir, 'ktx.yaml'), 'project: warehouse\nconnections:\n mystery:\n driver: duckdb\n', 'utf-8'); + await initKtxProject({ projectDir }); + await writeFile( + join(projectDir, 'ktx.yaml'), + 'connections:\n mystery:\n driver: duckdb\n', + 'utf-8', + ); const io = makeIo(); await expect( runKtxConnection({ command: 'test', projectDir, connectionId: 'mystery' }, io.io), ).resolves.toBe(1); - expect(io.stderr()).toContain('uses driver "duckdb"'); - expect(io.stderr()).toContain('Supported:'); + expect(io.stderr()).toContain('connections.mystery.driver'); + expect(io.stderr()).toContain('postgres'); }); }); diff --git a/packages/cli/src/context-build-view.test.ts b/packages/cli/src/context-build-view.test.ts index 487e5468..8d6b48ad 100644 --- a/packages/cli/src/context-build-view.test.ts +++ b/packages/cli/src/context-build-view.test.ts @@ -40,7 +40,7 @@ function projectWithConnections(connections: KtxProjectConfig['connections']): K return { projectDir: '/tmp/project', config: { - ...buildDefaultKtxProjectConfig('warehouse'), + ...buildDefaultKtxProjectConfig(), connections, }, }; diff --git a/packages/cli/src/demo-assets.ts b/packages/cli/src/demo-assets.ts index aae9f1a2..674af8cf 100644 --- a/packages/cli/src/demo-assets.ts +++ b/packages/cli/src/demo-assets.ts @@ -52,7 +52,6 @@ export function defaultDemoProjectDir(): string { function demoConfig(databasePath: string): string { return [ - 'project: ktx-demo-orbit', 'connections:', ` ${DEMO_CONNECTION_ID}:`, ' driver: sqlite', diff --git a/packages/cli/src/dev.test.ts b/packages/cli/src/dev.test.ts index e2c72012..bda96692 100644 --- a/packages/cli/src/dev.test.ts +++ b/packages/cli/src/dev.test.ts @@ -72,10 +72,10 @@ describe('dev Commander tree', () => { const testIo = makeIo(); try { - await expect(runKtxCli(['dev', 'init', projectDir, '--name', 'warehouse'], testIo.io)).resolves.toBe(0); + await expect(runKtxCli(['dev', 'init', projectDir], testIo.io)).resolves.toBe(0); expect(testIo.stdout()).toContain(`Initialized KTX project at ${projectDir}`); - await expect(readFile(join(projectDir, 'ktx.yaml'), 'utf-8')).resolves.toContain('project: warehouse'); + await expect(readFile(join(projectDir, 'ktx.yaml'), 'utf-8')).resolves.not.toContain('project:'); expect(testIo.stderr()).toBe(''); } finally { await rm(tempDir, { recursive: true, force: true }); @@ -92,7 +92,7 @@ describe('dev Commander tree', () => { try { await expect( - runKtxCli(['--project-dir', projectDir, 'dev', 'init', '--name', 'global-init'], testIo.io), + runKtxCli(['--project-dir', projectDir, 'dev', 'init'], testIo.io), ).resolves.toBe(0); expect(testIo.stdout()).toContain(`Initialized KTX project at ${projectDir}`); diff --git a/packages/cli/src/dev.ts b/packages/cli/src/dev.ts index 80a86ec4..12ad6f46 100644 --- a/packages/cli/src/dev.ts +++ b/packages/cli/src/dev.ts @@ -25,19 +25,17 @@ export function registerDevCommands(program: Command, context: KtxCliCommandCont .command('init') .description('Initialize a Git-backed KTX project directory for maintenance scripts') .argument('[directory]', 'Project directory') - .option('--name ', 'Project name written to ktx.yaml') .option('--force', 'Rewrite ktx.yaml and scaffold files in an existing project', false) .action( async ( projectDir: string | undefined, - commandOptions: { name?: string; force?: boolean }, + commandOptions: { force?: boolean }, command: CommandWithGlobalOptions, ) => { context.setExitCode( await context.runInit( { projectDir: projectDir ? resolve(projectDir) : resolveCommandProjectDir(command), - ...(commandOptions.name ? { projectName: commandOptions.name } : {}), force: commandOptions.force === true, }, context.io, diff --git a/packages/cli/src/doctor.test.ts b/packages/cli/src/doctor.test.ts index 5a9a3fdd..fddb4c68 100644 --- a/packages/cli/src/doctor.test.ts +++ b/packages/cli/src/doctor.test.ts @@ -1,6 +1,6 @@ import { mkdtemp, rm, writeFile } from 'node:fs/promises'; import { tmpdir } from 'node:os'; -import { join } from 'node:path'; +import { basename, join } from 'node:path'; import { afterEach, beforeEach, describe, expect, it } from 'vitest'; import { formatDoctorReport, @@ -328,7 +328,6 @@ describe('runKtxDoctor', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: warehouse', 'storrage:', ' state: sqlite', 'ingest:', @@ -359,7 +358,7 @@ describe('runKtxDoctor', () => { it('emits structured JSON when ktx.yaml fails Zod validation', async () => { await writeFile( join(tempDir, 'ktx.yaml'), - ['project: warehouse', 'storrage: {}', ''].join('\n'), + ['storrage: {}', ''].join('\n'), 'utf-8', ); const testIo = makeIo(); @@ -387,7 +386,6 @@ describe('runKtxDoctor', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: sqlite', @@ -418,7 +416,6 @@ describe('runKtxDoctor', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: sqlite', @@ -452,7 +449,7 @@ describe('runKtxDoctor', () => { const out = testIo.stdout(); expect(out).toContain('KTX status'); - expect(out).toContain('· warehouse'); + expect(out).toContain(`· ${basename(tempDir)}`); expect(out).toContain('Connections (1)'); expect(out).toContain('LLM'); expect(out).toContain('anthropic'); @@ -468,7 +465,6 @@ describe('runKtxDoctor', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: postgres', @@ -528,7 +524,6 @@ describe('runKtxDoctor', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: sqlite', @@ -558,7 +553,6 @@ describe('runKtxDoctor', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: postgres', @@ -620,7 +614,6 @@ describe('runKtxDoctor', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: sqlite', @@ -660,7 +653,6 @@ describe('runKtxDoctor', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: sqlite', @@ -695,7 +687,6 @@ describe('runKtxDoctor', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: sqlite', @@ -724,7 +715,6 @@ describe('runKtxDoctor', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: warehouse', 'storrage:', ' state: sqlite', 'ingest:', @@ -752,7 +742,7 @@ describe('runKtxDoctor', () => { it('emits structured JSON issues when validation fails', async () => { await writeFile( join(tempDir, 'ktx.yaml'), - ['project: warehouse', 'storrage: {}', ''].join('\n'), + ['storrage: {}', ''].join('\n'), 'utf-8', ); const testIo = makeIo(); @@ -788,7 +778,6 @@ describe('runKtxDoctor', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: postgres', diff --git a/packages/cli/src/index.test.ts b/packages/cli/src/index.test.ts index 1e2da422..86a7468c 100644 --- a/packages/cli/src/index.test.ts +++ b/packages/cli/src/index.test.ts @@ -102,7 +102,7 @@ describe('runKtxCli', () => { beforeEach(async () => { tempDir = await mkdtemp(join(tmpdir(), 'ktx-cli-')); - await writeFile(join(tempDir, 'ktx.yaml'), 'project: cli-dispatch-fixture\n', 'utf-8'); + await writeFile(join(tempDir, 'ktx.yaml'), '{}\n', 'utf-8'); }); afterEach(async () => { @@ -502,7 +502,7 @@ describe('runKtxCli', () => { it('keeps representative JSON command stdout parseable', async () => { const projectDir = join(tempDir, 'project'); - await initKtxProject({ projectDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir }); const commands = [ ['--project-dir', projectDir, 'status', '--json'], ['--project-dir', projectDir, 'sl', 'list', '--json'], @@ -580,7 +580,7 @@ describe('runKtxCli', () => { try { delete process.env.KTX_PROJECT_DIR; - await writeFile(join(tempDir, 'ktx.yaml'), 'project: revenue\nconnections: {}\n', 'utf-8'); + await writeFile(join(tempDir, 'ktx.yaml'), 'connections: {}\n', 'utf-8'); process.chdir(tempDir); await expect(runKtxCli([], testIo.io, { setup })).resolves.toBe(0); @@ -1482,7 +1482,7 @@ describe('runKtxCli', () => { it('dispatches public connection subcommands through the existing connection implementation', async () => { const tempDir = await mkdtemp(join(tmpdir(), 'ktx-connection-dispatch-')); - await writeFile(join(tempDir, 'ktx.yaml'), 'project: connection-dispatch\n', 'utf-8'); + await writeFile(join(tempDir, 'ktx.yaml'), '{}\n', 'utf-8'); const connection = vi.fn(async () => 0); await expect( diff --git a/packages/cli/src/ingest.test-utils.ts b/packages/cli/src/ingest.test-utils.ts index 7b65e33a..048e7411 100644 --- a/packages/cli/src/ingest.test-utils.ts +++ b/packages/cli/src/ingest.test-utils.ts @@ -106,7 +106,6 @@ export async function writeWarehouseConfig(projectDir: string): Promise { await writeFile( join(projectDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' prod-metabase:', ' driver: metabase', @@ -126,7 +125,6 @@ export async function writeMetabaseConfig(projectDir: string): Promise { await writeFile( join(projectDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: postgres', @@ -488,7 +486,6 @@ export async function runPublicMetabaseSyncModeCase(tempDir: string, input: Sync await writeFile( join(projectDir, 'ktx.yaml'), [ - `project: metabase-sync-mode-${input.name}`, 'connections:', ' prod-metabase:', ' driver: metabase', diff --git a/packages/cli/src/ingest.test.ts b/packages/cli/src/ingest.test.ts index 7626918c..52dcbc38 100644 --- a/packages/cli/src/ingest.test.ts +++ b/packages/cli/src/ingest.test.ts @@ -633,7 +633,6 @@ describe('runKtxIngest', () => { await writeFile( join(projectDir, 'ktx.yaml'), [ - 'project: metabase-cli', 'connections:', ' prod-metabase:', ' driver: metabase', @@ -1099,7 +1098,7 @@ describe('runKtxIngest', () => { it('passes managed 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, projectName: 'managed-daemon-ingest-project' }); + await initKtxProject({ projectDir }); await writeWarehouseConfig(projectDir); const createdAdapters: SourceAdapter[] = [ { source: 'fake', skillNames: [], detect: async () => true, chunk: async () => ({ workUnits: [] }) }, @@ -1159,7 +1158,6 @@ describe('runKtxIngest', () => { await writeFile( join(projectDir, 'ktx.yaml'), [ - 'project: historic-sql-project', 'connections:', ' warehouse:', ' driver: postgres', @@ -1224,7 +1222,6 @@ describe('runKtxIngest', () => { await writeFile( join(projectDir, 'ktx.yaml'), [ - 'project: historic-sql-progress-project', 'connections:', ' warehouse:', ' driver: postgres', @@ -1353,7 +1350,6 @@ describe('runKtxIngest', () => { await writeFile( join(projectDir, 'ktx.yaml'), [ - 'project: historic-sql-step-progress-project', 'connections:', ' warehouse:', ' driver: postgres', @@ -1446,7 +1442,6 @@ describe('runKtxIngest', () => { await writeFile( join(projectDir, 'ktx.yaml'), [ - 'project: historic-sql-concurrent-progress-project', 'connections:', ' warehouse:', ' driver: postgres', @@ -1596,7 +1591,6 @@ describe('runKtxIngest', () => { await writeFile( join(projectDir, 'ktx.yaml'), [ - 'project: looker-cli', 'connections:', ' prod-looker:', ' driver: looker', diff --git a/packages/cli/src/knowledge.test.ts b/packages/cli/src/knowledge.test.ts index 2486d621..04f367c0 100644 --- a/packages/cli/src/knowledge.test.ts +++ b/packages/cli/src/knowledge.test.ts @@ -53,7 +53,7 @@ describe('runKtxKnowledge', () => { it('writes, reads, lists, and searches wiki pages', async () => { const projectDir = join(tempDir, 'project'); - await initKtxProject({ projectDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir }); const writeIo = makeIo(); await expect( @@ -95,7 +95,7 @@ describe('runKtxKnowledge', () => { it('prints wiki list, search, and read as public JSON envelopes', async () => { const projectDir = join(tempDir, 'project'); - await initKtxProject({ projectDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir }); await expect( runKtxKnowledge( @@ -154,7 +154,7 @@ describe('runKtxKnowledge', () => { it('rejects slash-delimited write keys with a flat-key suggestion', async () => { const projectDir = join(tempDir, 'project'); - await initKtxProject({ projectDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir }); const writeIo = makeIo(); await expect( @@ -183,7 +183,7 @@ describe('runKtxKnowledge', () => { it('explains empty search results for a project without wiki pages', async () => { const projectDir = join(tempDir, 'empty-project'); - await initKtxProject({ projectDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir }); const searchIo = makeIo(); await expect( @@ -197,7 +197,7 @@ describe('runKtxKnowledge', () => { it('uses configured embeddings for semantic wiki search', async () => { const projectDir = join(tempDir, 'semantic-project'); - await initKtxProject({ projectDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir }); await expect( runKtxKnowledge( diff --git a/packages/cli/src/local-adapters.test.ts b/packages/cli/src/local-adapters.test.ts index 12f8d652..dbb03f2b 100644 --- a/packages/cli/src/local-adapters.test.ts +++ b/packages/cli/src/local-adapters.test.ts @@ -40,7 +40,6 @@ describe('CLI local ingest adapters', () => { await writeProject( tempDir, [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: postgres', @@ -71,7 +70,6 @@ describe('CLI local ingest adapters', () => { await writeProject( tempDir, [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: postgres', @@ -103,7 +101,6 @@ describe('CLI local ingest adapters', () => { await writeProject( tempDir, [ - 'project: warehouse', 'connections:', ' bq:', ' driver: bigquery', @@ -136,7 +133,6 @@ describe('CLI local ingest adapters', () => { await writeProject( tempDir, [ - 'project: warehouse', 'connections:', ' sf:', ' driver: snowflake', @@ -172,7 +168,6 @@ describe('CLI local ingest adapters', () => { await writeProject( tempDir, [ - 'project: warehouse', 'connections:', ' bq:', ' driver: bigquery', diff --git a/packages/cli/src/local-scan-connectors.test.ts b/packages/cli/src/local-scan-connectors.test.ts index d287b563..a0f9e714 100644 --- a/packages/cli/src/local-scan-connectors.test.ts +++ b/packages/cli/src/local-scan-connectors.test.ts @@ -39,11 +39,10 @@ describe('createKtxCliScanConnector', () => { }); it('creates a native sqlite connector from standalone config', async () => { - await initKtxProject({ projectDir: tempDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir: tempDir }); await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: sqlite', @@ -61,11 +60,10 @@ describe('createKtxCliScanConnector', () => { }); it('passes canonical BigQuery YAML scan limits through to the connector', async () => { - await initKtxProject({ projectDir: tempDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir: tempDir }); await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: bigquery', @@ -95,11 +93,10 @@ describe('createKtxCliScanConnector', () => { }); it('throws for structural daemon-only fallback configs', async () => { - await initKtxProject({ projectDir: tempDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir: tempDir }); await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: duckdb', @@ -116,11 +113,10 @@ describe('createKtxCliScanConnector', () => { }); it('throws a clear error when the connection block has no driver field', async () => { - await initKtxProject({ projectDir: tempDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir: tempDir }); await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' type: postgres', diff --git a/packages/cli/src/project-dir.test.ts b/packages/cli/src/project-dir.test.ts index b5006bcc..25a9b585 100644 --- a/packages/cli/src/project-dir.test.ts +++ b/packages/cli/src/project-dir.test.ts @@ -6,7 +6,7 @@ import { runKtxCli, type KtxCliDeps } from './index.js'; async function makeFixtureProject(prefix: string): Promise { const dir = await mkdtemp(join(tmpdir(), prefix)); - await writeFile(join(dir, 'ktx.yaml'), 'project: project-dir-fixture\n', 'utf-8'); + await writeFile(join(dir, 'ktx.yaml'), '{}\n', 'utf-8'); return dir; } @@ -138,7 +138,7 @@ describe('project directory defaults', () => { const projectDir = join(root, 'warehouse'); const nestedDir = join(projectDir, 'nested', 'deeper'); await mkdir(nestedDir, { recursive: true }); - await writeFile(join(projectDir, 'ktx.yaml'), 'project: warehouse\n', 'utf-8'); + await writeFile(join(projectDir, 'ktx.yaml'), '{}\n', 'utf-8'); const expectedProjectDir = await realpath(projectDir); const publicIngest = vi.fn(async () => 0); diff --git a/packages/cli/src/project-resolver.test.ts b/packages/cli/src/project-resolver.test.ts index 74ef02bc..39dab27b 100644 --- a/packages/cli/src/project-resolver.test.ts +++ b/packages/cli/src/project-resolver.test.ts @@ -48,7 +48,7 @@ describe('resolveKtxProjectDir', () => { const project = join(tempDir, 'warehouse'); const nested = join(project, 'nested', 'deeper'); await mkdir(nested, { recursive: true }); - await writeFile(join(project, 'ktx.yaml'), 'project: warehouse\n', 'utf-8'); + await writeFile(join(project, 'ktx.yaml'), '{}\n', 'utf-8'); expect(resolveKtxProjectDir({ env: {}, cwd: nested })).toBe(resolve(project)); expect(findNearestKtxProjectDir(nested)).toBe(resolve(project)); diff --git a/packages/cli/src/public-ingest.test.ts b/packages/cli/src/public-ingest.test.ts index 05981ded..d34a5785 100644 --- a/packages/cli/src/public-ingest.test.ts +++ b/packages/cli/src/public-ingest.test.ts @@ -41,7 +41,7 @@ function projectWithConnections(connections: KtxProjectConfig['connections']): K return { projectDir: '/tmp/project', config: { - ...buildDefaultKtxProjectConfig('warehouse'), + ...buildDefaultKtxProjectConfig(), connections, }, }; @@ -51,7 +51,7 @@ function deepReadyProject( connections: KtxProjectConfig['connections'], relationshipsEnabled = true, ): KtxPublicIngestProject { - const config = buildDefaultKtxProjectConfig('warehouse'); + const config = buildDefaultKtxProjectConfig(); return { projectDir: '/tmp/project', config: { diff --git a/packages/cli/src/scan.test.ts b/packages/cli/src/scan.test.ts index 487bd935..5fe4a342 100644 --- a/packages/cli/src/scan.test.ts +++ b/packages/cli/src/scan.test.ts @@ -316,7 +316,7 @@ describe('runKtxScan', () => { }); it('runs structural scans and prints a dev-friendly plain summary', async () => { - await initKtxProject({ projectDir: tempDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir: tempDir }); const runLocalScan = vi.fn( async (_input: RunLocalScanOptions): Promise => ({ runId: 'scan-run-1', @@ -377,7 +377,7 @@ describe('runKtxScan', () => { }); it('passes managed daemon options to local ingest adapters when no explicit daemon URL is set', async () => { - await initKtxProject({ projectDir: tempDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir: tempDir }); const createLocalIngestAdapters = vi.fn(() => []); const runLocalScan = vi.fn( async (_input: RunLocalScanOptions): Promise => ({ @@ -421,7 +421,7 @@ describe('runKtxScan', () => { }); it('explains warnings, capability gaps, and relationships in human scan summaries', async () => { - await initKtxProject({ projectDir: tempDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir: tempDir }); const runLocalScan = vi.fn( async (_input: RunLocalScanOptions): Promise => ({ runId: 'scan-run-1', @@ -472,7 +472,7 @@ describe('runKtxScan', () => { }); it('prints review-only relationship summaries and validation capability warnings', async () => { - await initKtxProject({ projectDir: tempDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir: tempDir }); const reviewOnlyReport: KtxScanReport = { ...reportWithAttention, capabilityGaps: [], @@ -525,7 +525,7 @@ describe('runKtxScan', () => { }); it('passes a scan progress port and prints TTY progress messages', async () => { - await initKtxProject({ projectDir: tempDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir: tempDir }); const runLocalScan = vi.fn(async (input: RunLocalScanOptions): Promise => { await input.progress?.update(0.15, 'Inspecting database schema'); await input.progress?.update(0.55, 'Semantic layer comparison found 5 changes across 18 tables'); @@ -572,7 +572,7 @@ describe('runKtxScan', () => { }); it('uses injected structured progress without requiring TTY progress output', async () => { - await initKtxProject({ projectDir: tempDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir: tempDir }); const progressEvents: Array<{ progress: number; message?: string; transient?: boolean }> = []; const structuredProgress = { async update(progress: number, message?: string, options?: { transient?: boolean }) { @@ -674,7 +674,7 @@ describe('runKtxScan', () => { }); it('flushes transient TTY progress messages before printing scan failures', async () => { - await initKtxProject({ projectDir: tempDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir: tempDir }); const runLocalScan = vi.fn(async (input: RunLocalScanOptions): Promise => { await input.progress?.update(0.42, 'Generating descriptions 3/35 tables', { transient: true }); throw new Error('scan failed'); @@ -711,7 +711,7 @@ describe('runKtxScan', () => { }); it('does not print live progress messages for non-TTY output', async () => { - await initKtxProject({ projectDir: tempDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir: tempDir }); const runLocalScan = vi.fn(async (input: RunLocalScanOptions): Promise => { await input.progress?.update(0.15, 'Inspecting database schema'); return { @@ -747,7 +747,7 @@ describe('runKtxScan', () => { }); it('uses terminal-aware visual styling only for TTY output', async () => { - await initKtxProject({ projectDir: tempDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir: tempDir }); const runLocalScan = vi.fn( async (_input: RunLocalScanOptions): Promise => ({ runId: 'scan-run-1', @@ -807,7 +807,7 @@ describe('runKtxScan', () => { }); it('honors NO_COLOR for TTY scan summaries', async () => { - await initKtxProject({ projectDir: tempDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir: tempDir }); const runLocalScan = vi.fn( async (_input: RunLocalScanOptions): Promise => ({ runId: 'scan-run-1', @@ -853,11 +853,10 @@ describe('runKtxScan', () => { it('passes native CLI adapters into local scan runs for mysql configs', async () => { const tempProject = await mkdtemp(join(tmpdir(), 'ktx-scan-cli-native-')); - await initKtxProject({ projectDir: tempProject, projectName: 'warehouse' }); + await initKtxProject({ projectDir: tempProject }); await writeFile( join(tempProject, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: mysql', @@ -901,11 +900,10 @@ describe('runKtxScan', () => { it('creates a native connector for standalone relationship scans', async () => { const tempProject = await mkdtemp(join(tmpdir(), 'ktx-scan-cli-relationships-')); - await initKtxProject({ projectDir: tempProject, projectName: 'warehouse' }); + await initKtxProject({ projectDir: tempProject }); await writeFile( join(tempProject, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: sqlite', @@ -955,11 +953,10 @@ describe('runKtxScan', () => { it('routes standalone postgres scans through the native connector before daemon fallback', async () => { const tempProject = await mkdtemp(join(tmpdir(), 'ktx-scan-cli-native-postgres-')); - await initKtxProject({ projectDir: tempProject, projectName: 'warehouse' }); + await initKtxProject({ projectDir: tempProject }); await writeFile( join(tempProject, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: postgres', @@ -1021,11 +1018,10 @@ describe('runKtxScan', () => { it('passes native CLI adapters into local scan runs for clickhouse configs', async () => { const tempProject = await mkdtemp(join(tmpdir(), 'ktx-scan-cli-native-clickhouse-')); - await initKtxProject({ projectDir: tempProject, projectName: 'warehouse' }); + await initKtxProject({ projectDir: tempProject }); await writeFile( join(tempProject, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: clickhouse', @@ -1072,11 +1068,10 @@ describe('runKtxScan', () => { it('passes native CLI adapters into local scan runs for sqlserver configs', async () => { const tempProject = await mkdtemp(join(tmpdir(), 'ktx-scan-cli-native-sqlserver-')); - await initKtxProject({ projectDir: tempProject, projectName: 'warehouse' }); + await initKtxProject({ projectDir: tempProject }); await writeFile( join(tempProject, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: sqlserver', @@ -1138,11 +1133,10 @@ describe('runKtxScan', () => { it('passes native CLI adapters into local scan runs for bigquery configs', async () => { const tempProject = await mkdtemp(join(tmpdir(), 'ktx-scan-cli-native-bigquery-')); - await initKtxProject({ projectDir: tempProject, projectName: 'warehouse' }); + await initKtxProject({ projectDir: tempProject }); await writeFile( join(tempProject, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: bigquery', @@ -1203,11 +1197,10 @@ describe('runKtxScan', () => { it('passes native CLI adapters into local scan runs for snowflake configs', async () => { const tempProject = await mkdtemp(join(tmpdir(), 'ktx-scan-cli-native-snowflake-')); - await initKtxProject({ projectDir: tempProject, projectName: 'warehouse' }); + await initKtxProject({ projectDir: tempProject }); await writeFile( join(tempProject, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: snowflake', diff --git a/packages/cli/src/setup-agents.test.ts b/packages/cli/src/setup-agents.test.ts index 19647a3f..ee5c7718 100644 --- a/packages/cli/src/setup-agents.test.ts +++ b/packages/cli/src/setup-agents.test.ts @@ -30,7 +30,7 @@ describe('setup agents', () => { beforeEach(async () => { tempDir = await mkdtemp(join(tmpdir(), 'ktx-setup-agents-')); await mkdir(join(tempDir, '.ktx', 'agents'), { recursive: true }); - await writeFile(join(tempDir, 'ktx.yaml'), 'project: revenue\nconnections: {}\n', 'utf-8'); + await writeFile(join(tempDir, 'ktx.yaml'), 'connections: {}\n', 'utf-8'); }); afterEach(async () => { diff --git a/packages/cli/src/setup-context.test.ts b/packages/cli/src/setup-context.test.ts index 66c8f6fe..61a9019a 100644 --- a/packages/cli/src/setup-context.test.ts +++ b/packages/cli/src/setup-context.test.ts @@ -50,7 +50,7 @@ type ReadyProjectOverrides = Omit, 'ingest' | 'llm' | }; async function writeReadyProject(projectDir: string, overrides: ReadyProjectOverrides = {}) { - const defaults = buildDefaultKtxProjectConfig('revenue'); + const defaults = buildDefaultKtxProjectConfig(); const readyConfig: KtxProjectConfig = { ...defaults, setup: { database_connection_ids: ['warehouse'] }, @@ -595,7 +595,6 @@ describe('setup context build state', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: revenue', 'connections: {}', 'llm:', ' provider:', diff --git a/packages/cli/src/setup-databases.test.ts b/packages/cli/src/setup-databases.test.ts index cc69e6cc..86a73fa3 100644 --- a/packages/cli/src/setup-databases.test.ts +++ b/packages/cli/src/setup-databases.test.ts @@ -119,7 +119,7 @@ describe('setup databases step', () => { beforeEach(async () => { tempDir = await mkdtemp(join(tmpdir(), 'ktx-setup-databases-')); - await initKtxProject({ projectDir: tempDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir: tempDir }); }); afterEach(async () => { @@ -242,7 +242,6 @@ describe('setup databases step', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: postgres', @@ -575,7 +574,6 @@ describe('setup databases step', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: postgres', @@ -622,7 +620,6 @@ describe('setup databases step', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: postgres', @@ -770,7 +767,6 @@ describe('setup databases step', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: postgres', @@ -815,7 +811,6 @@ describe('setup databases step', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: postgres', @@ -864,7 +859,6 @@ describe('setup databases step', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: postgres', @@ -936,7 +930,6 @@ describe('setup databases step', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: postgres', @@ -1010,7 +1003,6 @@ describe('setup databases step', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: postgres', @@ -1079,7 +1071,6 @@ describe('setup databases step', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: postgres', @@ -1146,7 +1137,6 @@ describe('setup databases step', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: postgres', @@ -1646,7 +1636,6 @@ describe('setup databases step', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: postgres', @@ -1939,7 +1928,6 @@ describe('setup databases step', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: postgres', @@ -2019,7 +2007,6 @@ describe('setup databases step', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' analytics:', ' driver: bigquery', @@ -2074,7 +2061,6 @@ describe('setup databases step', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: postgres', @@ -2123,7 +2109,6 @@ describe('setup databases step', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: postgres', diff --git a/packages/cli/src/setup-embeddings.test.ts b/packages/cli/src/setup-embeddings.test.ts index c251b45c..aadb8a9f 100644 --- a/packages/cli/src/setup-embeddings.test.ts +++ b/packages/cli/src/setup-embeddings.test.ts @@ -60,7 +60,7 @@ describe('setup embeddings step', () => { beforeEach(async () => { tempDir = await mkdtemp(join(tmpdir(), 'ktx-setup-embeddings-')); - await initKtxProject({ projectDir: tempDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir: tempDir }); }); afterEach(async () => { @@ -446,11 +446,10 @@ describe('setup embeddings step', () => { it('preserves already completed embeddings setup when no embedding args request changes', async () => { await mkdir(join(tempDir, '.ktx'), { recursive: true }); - await initKtxProject({ projectDir: tempDir, projectName: 'warehouse', force: true }); + await initKtxProject({ projectDir: tempDir, force: true }); await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: warehouse', 'setup:', ' database_connection_ids: []', 'connections: {}', diff --git a/packages/cli/src/setup-models.test.ts b/packages/cli/src/setup-models.test.ts index d9fef97d..fc41cf1d 100644 --- a/packages/cli/src/setup-models.test.ts +++ b/packages/cli/src/setup-models.test.ts @@ -92,7 +92,7 @@ describe('setup Anthropic model step', () => { beforeEach(async () => { tempDir = await mkdtemp(join(tmpdir(), 'ktx-setup-models-')); - await initKtxProject({ projectDir: tempDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir: tempDir }); }); afterEach(async () => { @@ -1049,11 +1049,10 @@ describe('setup Anthropic model step', () => { it('preserves already completed llm setup when no model args request changes', async () => { await mkdir(join(tempDir, '.ktx'), { recursive: true }); - await initKtxProject({ projectDir: tempDir, projectName: 'warehouse', force: true }); + await initKtxProject({ projectDir: tempDir, force: true }); await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: warehouse', 'setup:', ' database_connection_ids: []', 'connections: {}', @@ -1099,7 +1098,6 @@ describe('setup Anthropic model step', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: warehouse', 'setup:', ' database_connection_ids: []', 'connections: {}', diff --git a/packages/cli/src/setup-project.test.ts b/packages/cli/src/setup-project.test.ts index e20b9544..578beb8b 100644 --- a/packages/cli/src/setup-project.test.ts +++ b/packages/cli/src/setup-project.test.ts @@ -76,11 +76,10 @@ describe('setup project step', () => { it('loads an existing project with --existing and drops config setup progress', async () => { const projectDir = join(tempDir, 'warehouse'); - await initKtxProject({ projectDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir }); await writeFile( join(projectDir, 'ktx.yaml'), [ - 'project: warehouse', 'setup:', ' database_connection_ids:', ' - warehouse', @@ -196,7 +195,7 @@ describe('setup project step', () => { expect.objectContaining({ message: `Create KTX project at ${projectDir}?` }), ); expect(prompts.text).not.toHaveBeenCalled(); - expect(result.status === 'ready' ? result.project.config.project : '').toBe('ktx-project'); + expect(result.status === 'ready' ? result.project.configPath : '').toBe(join(projectDir, 'ktx.yaml')); expect(testIo.stdout()).toContain(`│ KTX will create:\n│ ${projectDir}`); await expect(stat(join(projectDir, 'ktx.yaml'))).resolves.toBeDefined(); }); diff --git a/packages/cli/src/setup-project.ts b/packages/cli/src/setup-project.ts index fa2dd3ed..23884b0c 100644 --- a/packages/cli/src/setup-project.ts +++ b/packages/cli/src/setup-project.ts @@ -1,7 +1,7 @@ import { existsSync } from 'node:fs'; import { mkdir, readdir, readFile, stat, writeFile } from 'node:fs/promises'; import { homedir } from 'node:os'; -import { basename, join, resolve } from 'node:path'; +import { join, resolve } from 'node:path'; import { initKtxProject, type KtxLocalProject, @@ -156,7 +156,7 @@ async function persistProjectStep(project: KtxLocalProject): Promise { const initProject = deps.initProject ?? initKtxProject; - const initialized = await initProject({ projectDir, projectName: basename(projectDir) || 'ktx-project' }); + const initialized = await initProject({ projectDir }); return await persistProjectStep(initialized); } diff --git a/packages/cli/src/setup-sources.test.ts b/packages/cli/src/setup-sources.test.ts index d7d337f1..bfcb54bc 100644 --- a/packages/cli/src/setup-sources.test.ts +++ b/packages/cli/src/setup-sources.test.ts @@ -79,7 +79,7 @@ describe('setup sources step', () => { beforeEach(async () => { tempDir = await mkdtemp(join(tmpdir(), 'ktx-setup-sources-')); projectDir = join(tempDir, 'project'); - await initKtxProject({ projectDir, projectName: 'sources' }); + await initKtxProject({ projectDir }); }); afterEach(async () => { diff --git a/packages/cli/src/setup.test.ts b/packages/cli/src/setup.test.ts index 7e479c0e..84b9e1a2 100644 --- a/packages/cli/src/setup.test.ts +++ b/packages/cli/src/setup.test.ts @@ -68,7 +68,6 @@ describe('setup status', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: revenue', 'llm:', ' provider:', ' backend: anthropic', @@ -109,7 +108,6 @@ describe('setup status', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: revenue', 'llm:', ' provider:', ...fixture.providerLines, @@ -129,7 +127,6 @@ describe('setup status', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: revenue', 'setup:', ' database_connection_ids:', ' - warehouse', @@ -162,7 +159,6 @@ describe('setup status', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: revenue', 'setup:', ' database_connection_ids:', ' - warehouse', @@ -183,7 +179,6 @@ describe('setup status', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: revenue', 'setup:', ' database_connection_ids:', ' - warehouse', @@ -206,7 +201,6 @@ describe('setup status', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: revenue', 'setup:', ' database_connection_ids: []', 'connections:', @@ -230,7 +224,7 @@ describe('setup status', () => { it('reports agent status from the install manifest', async () => { await mkdir(join(tempDir, '.ktx', 'agents'), { recursive: true }); - await writeFile(join(tempDir, 'ktx.yaml'), 'project: revenue\nconnections: {}\n', 'utf-8'); + await writeFile(join(tempDir, 'ktx.yaml'), 'connections: {}\n', 'utf-8'); await writeFile( join(tempDir, '.ktx/agents/install-manifest.json'), JSON.stringify( @@ -256,7 +250,6 @@ describe('setup status', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: revenue', 'setup:', ' database_connection_ids:', ' - warehouse', @@ -309,7 +302,6 @@ describe('setup status', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: revenue', 'setup:', ' database_connection_ids:', ' - warehouse', @@ -370,7 +362,7 @@ describe('setup status', () => { }); it('prints the readiness checklist for an existing project', async () => { - await writeFile(join(tempDir, 'ktx.yaml'), 'project: revenue\nconnections: {}\n', 'utf-8'); + await writeFile(join(tempDir, 'ktx.yaml'), 'connections: {}\n', 'utf-8'); const rendered = formatKtxSetupStatus(await readKtxSetupStatus(tempDir)); @@ -503,7 +495,7 @@ describe('setup status', () => { ), ).resolves.toBe(0); - await writeFile(join(tempDir, 'ktx.yaml'), 'project: revenue\nconnections: {}\n', 'utf-8'); + await writeFile(join(tempDir, 'ktx.yaml'), 'connections: {}\n', 'utf-8'); await expect( runKtxSetup( @@ -589,7 +581,7 @@ describe('setup status', () => { }); it('lets Back from new project creation return to the first setup intent menu', async () => { - const existingConfig = 'project: revenue\nconnections: {}\n'; + const existingConfig = 'connections: {}\n'; await writeFile(join(tempDir, 'ktx.yaml'), existingConfig, 'utf-8'); const entryChoices = ['new-project', 'exit']; @@ -645,7 +637,7 @@ describe('setup status', () => { const existingProjectDir = join(tempDir, 'existing'); const newProjectDir = join(tempDir, 'fresh'); await mkdir(existingProjectDir, { recursive: true }); - const existingConfig = 'project: revenue\nconnections: {}\n'; + const existingConfig = 'connections: {}\n'; await writeFile(join(existingProjectDir, 'ktx.yaml'), existingConfig, 'utf-8'); const projectChoices = ['custom', 'create']; @@ -722,7 +714,7 @@ describe('setup status', () => { const existingProjectDir = join(tempDir, 'existing'); const newProjectDir = join(tempDir, 'fresh'); await mkdir(existingProjectDir, { recursive: true }); - await writeFile(join(existingProjectDir, 'ktx.yaml'), 'project: revenue\nconnections: {}\n', 'utf-8'); + await writeFile(join(existingProjectDir, 'ktx.yaml'), 'connections: {}\n', 'utf-8'); const projectChoices = ['custom', 'create']; const projectPrompts = { @@ -1147,7 +1139,7 @@ describe('setup status', () => { }); it('lets Back from the first setup step return to the entry menu instead of exiting', async () => { - await writeFile(join(tempDir, 'ktx.yaml'), 'project: test\nconnections: {}\n', 'utf-8'); + await writeFile(join(tempDir, 'ktx.yaml'), 'connections: {}\n', 'utf-8'); const testIo = makeIo(); const entryChoices = ['setup', 'exit']; @@ -1254,7 +1246,7 @@ describe('setup status', () => { it('runs sources after database setup', async () => { const calls: string[] = []; const io = makeIo(); - await writeFile(join(tempDir, 'ktx.yaml'), ['project: revenue', 'connections: {}', ''].join('\n'), 'utf-8'); + await writeFile(join(tempDir, 'ktx.yaml'), ['connections: {}', ''].join('\n'), 'utf-8'); await expect( runKtxSetup( @@ -1315,7 +1307,6 @@ describe('setup status', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: revenue', 'setup:', ' database_connection_ids:', ' - warehouse', @@ -1374,7 +1365,6 @@ describe('setup status', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: revenue', 'connections:', ' warehouse:', ' driver: postgres', @@ -1430,7 +1420,7 @@ describe('setup status', () => { it('runs context after sources and before agents in full setup', async () => { const calls: string[] = []; const io = makeIo(); - await writeFile(join(tempDir, 'ktx.yaml'), ['project: revenue', 'connections: {}', ''].join('\n'), 'utf-8'); + await writeFile(join(tempDir, 'ktx.yaml'), ['connections: {}', ''].join('\n'), 'utf-8'); await expect( runKtxSetup( @@ -1543,7 +1533,7 @@ describe('setup status', () => { it('runs agent setup after context succeeds in --agents mode', async () => { const calls: string[] = []; const io = makeIo(); - await writeFile(join(tempDir, 'ktx.yaml'), ['project: revenue', 'connections: {}', ''].join('\n'), 'utf-8'); + await writeFile(join(tempDir, 'ktx.yaml'), ['connections: {}', ''].join('\n'), 'utf-8'); await expect( runKtxSetup( @@ -1596,7 +1586,7 @@ describe('setup status', () => { projectDir: tempDir, installs: [{ target: 'codex' as const, scope: 'project' as const, mode: 'cli' as const }], })); - await writeFile(join(tempDir, 'ktx.yaml'), ['project: revenue', 'connections: {}', ''].join('\n'), 'utf-8'); + await writeFile(join(tempDir, 'ktx.yaml'), ['connections: {}', ''].join('\n'), 'utf-8'); await expect( runKtxSetup( @@ -1633,7 +1623,6 @@ describe('setup status', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: revenue', 'setup:', ' database_connection_ids:', ' - warehouse', @@ -1671,7 +1660,6 @@ describe('setup status', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: revenue', 'setup:', ' database_connection_ids: []', 'connections: {}', @@ -1778,7 +1766,6 @@ describe('setup status', () => { await writeFile( join(tempDir, 'ktx.yaml'), [ - 'project: revenue', 'setup:', ' database_connection_ids: []', 'connections: {}', diff --git a/packages/cli/src/setup.ts b/packages/cli/src/setup.ts index d89a4eec..cf458f1d 100644 --- a/packages/cli/src/setup.ts +++ b/packages/cli/src/setup.ts @@ -1,5 +1,5 @@ import { existsSync } from 'node:fs'; -import { join, resolve } from 'node:path'; +import { basename, join, resolve } from 'node:path'; import { getLatestLocalIngestStatus, savedMemoryCountsForReport } from '@ktx/context/ingest'; import { ktxLocalStateDbPath, @@ -317,7 +317,7 @@ export async function readKtxSetupStatus(projectDir: string): Promise ({ diff --git a/packages/cli/src/sl.test.ts b/packages/cli/src/sl.test.ts index 14f18337..16041a31 100644 --- a/packages/cli/src/sl.test.ts +++ b/packages/cli/src/sl.test.ts @@ -44,7 +44,7 @@ async function seedSlSource(input: { sourceName?: string; yaml?: string; }): Promise { - const project = await initKtxProject({ projectDir: input.projectDir, projectName: 'warehouse' }); + const project = await initKtxProject({ projectDir: input.projectDir }); await project.fileStore.writeFile( `semantic-layer/${input.connectionId ?? 'warehouse'}/${input.sourceName ?? 'orders'}.yaml`, input.yaml ?? ORDERS_YAML, @@ -139,7 +139,7 @@ describe('runKtxSl', () => { it('fails validation when a table-backed source declares columns absent from a matching warehouse manifest', async () => { const projectDir = join(tempDir, 'project'); - const project = await initKtxProject({ projectDir, projectName: 'warehouse' }); + const project = await initKtxProject({ projectDir }); await project.fileStore.writeFile( 'semantic-layer/postgres-warehouse/_schema/orbit_analytics.yaml', `tables: @@ -189,7 +189,7 @@ joins: [] it('runs sl query and prints SQL output', async () => { const projectDir = join(tempDir, 'project'); - const project = await initKtxProject({ projectDir, projectName: 'warehouse' }); + const project = await initKtxProject({ projectDir }); project.config.connections.warehouse = { driver: 'postgres' }; await project.fileStore.writeFile( 'semantic-layer/warehouse/orders.yaml', @@ -246,7 +246,7 @@ joins: [] it('runs sl query from a JSON query file', async () => { const projectDir = join(tempDir, 'project'); - const project = await initKtxProject({ projectDir, projectName: 'warehouse' }); + const project = await initKtxProject({ projectDir }); project.config.connections.warehouse = { driver: 'postgres' }; await project.fileStore.writeFile( 'semantic-layer/warehouse/orders.yaml', @@ -313,7 +313,7 @@ joins: [] it('creates default sl query compute through the managed runtime helper', async () => { const projectDir = join(tempDir, 'project'); - const project = await initKtxProject({ projectDir, projectName: 'warehouse' }); + const project = await initKtxProject({ projectDir }); project.config.connections.warehouse = { driver: 'postgres' }; await project.fileStore.writeFile( 'semantic-layer/warehouse/orders.yaml', @@ -374,7 +374,7 @@ joins: [] it('executes sl query through the injected query executor', async () => { const projectDir = join(tempDir, 'project'); - const project = await initKtxProject({ projectDir, projectName: 'warehouse' }); + const project = await initKtxProject({ projectDir }); project.config.connections.warehouse = { driver: 'postgres', url: 'postgres://example/db' }; await project.fileStore.writeFile( 'semantic-layer/warehouse/orders.yaml', @@ -459,7 +459,7 @@ joins: [] it('executes sl query against a local SQLite connection through the default executor', async () => { const projectDir = join(tempDir, 'project'); - const project = await initKtxProject({ projectDir, projectName: 'warehouse' }); + const project = await initKtxProject({ projectDir }); const dbPath = join(projectDir, 'warehouse.db'); const db = new Database(dbPath); db.exec(` @@ -475,7 +475,6 @@ joins: [] await writeFile( join(projectDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: sqlite', diff --git a/packages/cli/src/standalone-smoke.test.ts b/packages/cli/src/standalone-smoke.test.ts index 3b657780..d63be434 100644 --- a/packages/cli/src/standalone-smoke.test.ts +++ b/packages/cli/src/standalone-smoke.test.ts @@ -80,7 +80,6 @@ async function writeSqliteScanConfig(projectDir: string, dbPath: string, enrich await writeFile( join(projectDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: sqlite', @@ -218,7 +217,6 @@ describe('standalone built ktx CLI smoke', () => { await writeFile( join(projectDir, 'ktx.yaml'), [ - 'project: gateway-smoke', 'llm:', ' provider:', ' backend: gateway', diff --git a/packages/cli/src/status-project.ts b/packages/cli/src/status-project.ts index 7a272183..6e953dc8 100644 --- a/packages/cli/src/status-project.ts +++ b/packages/cli/src/status-project.ts @@ -1,3 +1,4 @@ +import { basename } from 'node:path'; import type { KtxConfigIssue, KtxLocalProject, @@ -650,7 +651,7 @@ export async function buildProjectStatus(project: KtxLocalProject, options: Buil const { verdict, reason, nextActions } = buildVerdict(llm, embeddings, connections, queryHistory, warnings); return { - projectName: config.project, + projectName: basename(project.projectDir) || project.projectDir, projectDir: project.projectDir, config: configStatus, llm, diff --git a/packages/context/src/ingest/adapters/historic-sql/local-ingest-acceptance.test.ts b/packages/context/src/ingest/adapters/historic-sql/local-ingest-acceptance.test.ts index 8f583d9c..5540c991 100644 --- a/packages/context/src/ingest/adapters/historic-sql/local-ingest-acceptance.test.ts +++ b/packages/context/src/ingest/adapters/historic-sql/local-ingest-acceptance.test.ts @@ -166,7 +166,6 @@ async function writeHistoricSqlProject(project: KtxLocalProject): Promise { }); it('projects table and pattern evidence into semantic-layer and wiki retrieval surfaces', async () => { - const initialized = await initKtxProject({ projectDir: join(tempDir, 'project'), projectName: 'warehouse' }); + const initialized = await initKtxProject({ projectDir: join(tempDir, 'project') }); const project = await writeHistoricSqlProject(initialized); const sqlAnalysis = acceptanceSqlAnalysis(); const agentRunner = new HistoricSqlAcceptanceAgentRunner(); diff --git a/packages/context/src/ingest/adapters/metabase/local-source-state-store.test.ts b/packages/context/src/ingest/adapters/metabase/local-source-state-store.test.ts index b337fc66..4fdafba5 100644 --- a/packages/context/src/ingest/adapters/metabase/local-source-state-store.test.ts +++ b/packages/context/src/ingest/adapters/metabase/local-source-state-store.test.ts @@ -22,7 +22,7 @@ describe('Metabase YAML source state and discovery cache', () => { function projectWithMetabaseMappings(mappings: Record) { return { config: { - ...buildDefaultKtxProjectConfig('metabase-cache-test'), + ...buildDefaultKtxProjectConfig(), connections: { 'prod-metabase': connectionConfigSchema.parse({ driver: 'metabase', diff --git a/packages/context/src/ingest/local-adapters.test.ts b/packages/context/src/ingest/local-adapters.test.ts index e8cbf5a5..17269698 100644 --- a/packages/context/src/ingest/local-adapters.test.ts +++ b/packages/context/src/ingest/local-adapters.test.ts @@ -16,7 +16,7 @@ describe('local ingest adapters', () => { beforeEach(async () => { tempDir = await mkdtemp(join(tmpdir(), 'ktx-local-adapters-')); const projectDir = join(tempDir, 'project'); - await initKtxProject({ projectDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir }); project = await loadKtxProject({ projectDir }); }); diff --git a/packages/context/src/ingest/local-bundle-ingest.test.ts b/packages/context/src/ingest/local-bundle-ingest.test.ts index fe781b33..79071134 100644 --- a/packages/context/src/ingest/local-bundle-ingest.test.ts +++ b/packages/context/src/ingest/local-bundle-ingest.test.ts @@ -314,11 +314,10 @@ describe('canonical local ingest', () => { beforeEach(async () => { tempDir = await mkdtemp(join(tmpdir(), 'ktx-local-full-ingest-')); const projectDir = join(tempDir, 'project'); - await initKtxProject({ projectDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir }); await writeFile( join(projectDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: postgres', @@ -443,7 +442,6 @@ describe('canonical local ingest', () => { await writeFile( join(project.projectDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: postgres', @@ -521,11 +519,10 @@ describe('canonical local ingest', () => { it('runs historic-SQL evidence projection through the local bundle post-processor', async () => { const projectDir = join(tempDir, 'historic-sql-project'); - await initKtxProject({ projectDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir }); await writeFile( join(projectDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: postgres', @@ -605,11 +602,10 @@ describe('canonical local ingest', () => { it('rejects direct Metabase scheduled pulls before requiring a local ingest LLM provider', async () => { const projectDir = join(tempDir, 'metabase-project'); - await initKtxProject({ projectDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir }); await writeFile( join(projectDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: postgres', @@ -637,7 +633,7 @@ describe('canonical local ingest', () => { it('runs full MetricFlow local ingest from a dbt repo fixture through the canonical runner', async () => { const projectDir = join(tempDir, 'metricflow-run-project'); - await initKtxProject({ projectDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir }); const fixtureDir = join(tempDir, 'metricflow-fixture'); await mkdir(join(fixtureDir, 'models'), { recursive: true }); @@ -685,7 +681,6 @@ describe('canonical local ingest', () => { await writeFile( join(projectDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: postgres', @@ -767,7 +762,6 @@ describe('canonical local ingest', () => { await writeFile( join(projectDir, 'ktx.yaml'), [ - 'project: local-mf', 'connections:', ' warehouse:', ' driver: postgres', @@ -801,11 +795,10 @@ describe('canonical local ingest', () => { it('runs scheduled Looker ingest through the canonical local runner and records SL target evidence', async () => { const projectDir = join(tempDir, 'looker-project'); - await initKtxProject({ projectDir, projectName: 'looker-runtime' }); + await initKtxProject({ projectDir }); await writeFile( join(projectDir, 'ktx.yaml'), [ - 'project: looker-runtime', 'connections:', ' prod-looker:', ' driver: looker', diff --git a/packages/context/src/ingest/local-bundle-runtime.test.ts b/packages/context/src/ingest/local-bundle-runtime.test.ts index c6bd0539..bee28653 100644 --- a/packages/context/src/ingest/local-bundle-runtime.test.ts +++ b/packages/context/src/ingest/local-bundle-runtime.test.ts @@ -24,11 +24,10 @@ describe('createLocalBundleIngestRuntime', () => { beforeEach(async () => { tempDir = await mkdtemp(join(tmpdir(), 'ktx-local-bundle-runtime-')); const projectDir = join(tempDir, 'project'); - await initKtxProject({ projectDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir }); await writeFile( join(projectDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: postgres', @@ -149,7 +148,6 @@ describe('createLocalBundleIngestRuntime', () => { await writeFile( join(project.projectDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: postgres', diff --git a/packages/context/src/ingest/local-stage-ingest.test.ts b/packages/context/src/ingest/local-stage-ingest.test.ts index 3a0beaa5..d12ce167 100644 --- a/packages/context/src/ingest/local-stage-ingest.test.ts +++ b/packages/context/src/ingest/local-stage-ingest.test.ts @@ -17,7 +17,6 @@ async function writeWarehouseConfig(projectDir: string): Promise { await writeFile( join(projectDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: postgres', @@ -34,7 +33,6 @@ async function writeLiveDatabaseConfig(projectDir: string): Promise { await writeFile( join(projectDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: postgres', @@ -88,7 +86,7 @@ describe('local ingest', () => { beforeEach(async () => { tempDir = await mkdtemp(join(tmpdir(), 'ktx-local-ingest-')); const projectDir = join(tempDir, 'project'); - await initKtxProject({ projectDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir }); await writeWarehouseConfig(projectDir); project = await loadKtxProject({ projectDir }); }); @@ -574,7 +572,6 @@ describe('local ingest', () => { await writeFile( join(project.projectDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' notion-main:', ' driver: notion', diff --git a/packages/context/src/ingest/tools/warehouse-verification/entity-details.tool.test.ts b/packages/context/src/ingest/tools/warehouse-verification/entity-details.tool.test.ts index 9188bc68..24a14863 100644 --- a/packages/context/src/ingest/tools/warehouse-verification/entity-details.tool.test.ts +++ b/packages/context/src/ingest/tools/warehouse-verification/entity-details.tool.test.ts @@ -15,7 +15,7 @@ describe('EntityDetailsTool', () => { beforeEach(async () => { tempDir = await mkdtemp(join(tmpdir(), 'ktx-entity-details-')); - project = await initKtxProject({ projectDir: join(tempDir, 'project'), projectName: 'warehouse' }); + project = await initKtxProject({ projectDir: join(tempDir, 'project') }); await seedLiveDatabaseScan(); tool = new EntityDetailsTool(() => new WarehouseCatalogService({ fileStore: project.fileStore })); context = { diff --git a/packages/context/src/ingest/tools/warehouse-verification/warehouse-catalog.service.test.ts b/packages/context/src/ingest/tools/warehouse-verification/warehouse-catalog.service.test.ts index c2ab1f36..03340ace 100644 --- a/packages/context/src/ingest/tools/warehouse-verification/warehouse-catalog.service.test.ts +++ b/packages/context/src/ingest/tools/warehouse-verification/warehouse-catalog.service.test.ts @@ -11,7 +11,7 @@ describe('WarehouseCatalogService', () => { beforeEach(async () => { tempDir = await mkdtemp(join(tmpdir(), 'ktx-warehouse-catalog-')); - project = await initKtxProject({ projectDir: join(tempDir, 'project'), projectName: 'warehouse' }); + project = await initKtxProject({ projectDir: join(tempDir, 'project') }); }); afterEach(async () => { diff --git a/packages/context/src/llm/local-config.test.ts b/packages/context/src/llm/local-config.test.ts index 5d114e12..59ad34b7 100644 --- a/packages/context/src/llm/local-config.test.ts +++ b/packages/context/src/llm/local-config.test.ts @@ -194,7 +194,7 @@ describe('local KTX embedding config', () => { it('constructs deterministic embeddings from the default project config', () => { const createKtxEmbeddingProvider = vi.fn(() => ({}) as never); const provider = createLocalKtxEmbeddingProviderFromConfig( - buildDefaultKtxProjectConfig('warehouse').ingest.embeddings, + buildDefaultKtxProjectConfig().ingest.embeddings, { createKtxEmbeddingProvider }, ); diff --git a/packages/context/src/mcp/local-project-ports.test.ts b/packages/context/src/mcp/local-project-ports.test.ts index fab2f076..4d01b846 100644 --- a/packages/context/src/mcp/local-project-ports.test.ts +++ b/packages/context/src/mcp/local-project-ports.test.ts @@ -71,7 +71,7 @@ describe('createLocalProjectMcpContextPorts', () => { } it('lists local project connections from ktx.yaml', async () => { - const project = await initKtxProject({ projectDir: tempDir, projectName: 'warehouse' }); + const project = await initKtxProject({ projectDir: tempDir }); project.config.connections.warehouse = { driver: 'postgres', url: 'env:DATABASE_URL', @@ -84,7 +84,7 @@ describe('createLocalProjectMcpContextPorts', () => { }); it('tests a local project connection through the native scan connector factory', async () => { - const project = await initKtxProject({ projectDir: tempDir, projectName: 'warehouse' }); + const project = await initKtxProject({ projectDir: tempDir }); project.config.connections.warehouse = { driver: 'postgres', url: 'env:DATABASE_URL', @@ -120,7 +120,7 @@ describe('createLocalProjectMcpContextPorts', () => { }); it('triggers canonical bundle ingest and reads status, report, and replay through MCP ports', async () => { - const project = await initKtxProject({ projectDir: tempDir, projectName: 'warehouse' }); + const project = await initKtxProject({ projectDir: tempDir }); project.config.connections.warehouse = { driver: 'postgres', }; @@ -216,7 +216,7 @@ describe('createLocalProjectMcpContextPorts', () => { }); it('returns child run metadata for local Metabase fan-out triggers', async () => { - const project = await initKtxProject({ projectDir: tempDir, projectName: 'warehouse' }); + const project = await initKtxProject({ projectDir: tempDir }); project.config.connections = { 'prod-metabase': { driver: 'metabase', @@ -339,7 +339,7 @@ describe('createLocalProjectMcpContextPorts', () => { }); it('writes, reads, and searches global wiki pages', async () => { - const project = await initKtxProject({ projectDir: tempDir, projectName: 'warehouse' }); + const project = await initKtxProject({ projectDir: tempDir }); const ports = createLocalProjectMcpContextPorts(project); await expect( @@ -383,7 +383,7 @@ describe('createLocalProjectMcpContextPorts', () => { }); it('writes, lists, reads, and validates semantic-layer sources', async () => { - const project = await initKtxProject({ projectDir: tempDir, projectName: 'warehouse' }); + const project = await initKtxProject({ projectDir: tempDir }); const ports = createLocalProjectMcpContextPorts(project); await expect( @@ -449,7 +449,7 @@ describe('createLocalProjectMcpContextPorts', () => { }); it('returns semantic-layer hybrid search metadata through local project ports', async () => { - const project = await initKtxProject({ projectDir: tempDir, projectName: 'warehouse' }); + const project = await initKtxProject({ projectDir: tempDir }); await writeLocalSlSource(project, { connectionId: 'warehouse', sourceName: 'orders', @@ -518,7 +518,7 @@ describe('createLocalProjectMcpContextPorts', () => { }); it('returns historic SQL usage frequency and snippet through semantic-layer list search', async () => { - const project = await initKtxProject({ projectDir: tempDir, projectName: 'warehouse' }); + const project = await initKtxProject({ projectDir: tempDir }); await project.fileStore.writeFile( 'semantic-layer/warehouse/_schema/public.yaml', `tables: @@ -566,7 +566,7 @@ describe('createLocalProjectMcpContextPorts', () => { }); it('uses configured local embeddings for semantic-layer search when available', async () => { - const project = await initKtxProject({ projectDir: tempDir, projectName: 'warehouse' }); + const project = await initKtxProject({ projectDir: tempDir }); project.config.ingest.embeddings = { backend: 'none', dimensions: 2 }; await writeLocalSlSource(project, { connectionId: 'warehouse', @@ -607,7 +607,7 @@ describe('createLocalProjectMcpContextPorts', () => { }); it('rejects path traversal keys before touching the project directory', async () => { - const project = await initKtxProject({ projectDir: tempDir, projectName: 'warehouse' }); + const project = await initKtxProject({ projectDir: tempDir }); const ports = createLocalProjectMcpContextPorts(project); await expect( @@ -626,7 +626,7 @@ describe('createLocalProjectMcpContextPorts', () => { }); it('uses semantic compute for validation and compile-only sl_query when supplied', async () => { - const project = await initKtxProject({ projectDir: tempDir, projectName: 'warehouse' }); + const project = await initKtxProject({ projectDir: tempDir }); project.config.connections.warehouse = { driver: 'postgres', url: 'env:DATABASE_URL', @@ -712,7 +712,7 @@ describe('createLocalProjectMcpContextPorts', () => { }); it('executes local MCP sl_query when a query executor is configured', async () => { - const project = await initKtxProject({ projectDir: tempDir, projectName: 'warehouse' }); + const project = await initKtxProject({ projectDir: tempDir }); project.config.connections.warehouse = { driver: 'postgres', url: 'env:DATABASE_URL', @@ -770,7 +770,7 @@ describe('createLocalProjectMcpContextPorts', () => { }); it('exposes detailed local ingest trigger and status ports when local ingest is enabled', async () => { - const project = await initKtxProject({ projectDir: tempDir, projectName: 'warehouse' }); + const project = await initKtxProject({ projectDir: tempDir }); project.config.connections.warehouse = { driver: 'postgres' }; project.config.ingest.adapters = ['fake']; project.config.ingest.embeddings = { @@ -890,7 +890,7 @@ describe('createLocalProjectMcpContextPorts', () => { }); it('passes local ingest pull-config options into runLocalIngest', async () => { - const project = await initKtxProject({ projectDir: tempDir, projectName: 'warehouse' }); + const project = await initKtxProject({ projectDir: tempDir }); project.config.connections.warehouse = { driver: 'postgres' }; project.config.ingest.adapters = ['looker']; const runLocalIngest = vi.fn(async () => ({ @@ -949,7 +949,7 @@ describe('createLocalProjectMcpContextPorts', () => { }); it('triggers fetch-capable local ingest without sourceDir config', async () => { - const project = await initKtxProject({ projectDir: tempDir, projectName: 'warehouse' }); + const project = await initKtxProject({ projectDir: tempDir }); project.config.connections.warehouse = { driver: 'postgres', url: 'postgres://localhost:5432/warehouse', @@ -1024,7 +1024,7 @@ describe('createLocalProjectMcpContextPorts', () => { }); it('lists and reads only artifacts that belong to a local scan report', async () => { - const project = await initKtxProject({ projectDir: tempDir, projectName: 'warehouse' }); + const project = await initKtxProject({ projectDir: tempDir }); project.config.connections.warehouse = { driver: 'postgres', url: 'env:DATABASE_URL', @@ -1140,6 +1140,6 @@ describe('createLocalProjectMcpContextPorts', () => { }), ).resolves.toBeNull(); await expect(ports.scan?.listArtifacts?.({ runId: 'missing' })).resolves.toBeNull(); - await expect(readFile(join(project.projectDir, 'ktx.yaml'), 'utf-8')).resolves.toContain('project: warehouse'); + await expect(readFile(join(project.projectDir, 'ktx.yaml'), 'utf-8')).resolves.not.toContain('project:'); }); }); diff --git a/packages/context/src/mcp/server.test.ts b/packages/context/src/mcp/server.test.ts index 193d8f67..e02f2574 100644 --- a/packages/context/src/mcp/server.test.ts +++ b/packages/context/src/mcp/server.test.ts @@ -168,7 +168,7 @@ describe('createKtxMcpServer', () => { it('runs MCP memory_capture against a local project memory port', async () => { const tempDir = await mkdtemp(join(tmpdir(), 'ktx-mcp-local-memory-')); try { - const project = await initKtxProject({ projectDir: tempDir, projectName: 'warehouse' }); + const project = await initKtxProject({ projectDir: tempDir }); const agentRunner = { runLoop: async ({ toolSet, diff --git a/packages/context/src/memory/local-memory.test.ts b/packages/context/src/memory/local-memory.test.ts index 83b22146..f0b870eb 100644 --- a/packages/context/src/memory/local-memory.test.ts +++ b/packages/context/src/memory/local-memory.test.ts @@ -89,7 +89,7 @@ describe('createLocalProjectMemoryCapture', () => { }); it('captures a wiki page through the local memory agent and persists pollable status', async () => { - const project = await initKtxProject({ projectDir: tempDir, projectName: 'warehouse' }); + const project = await initKtxProject({ projectDir: tempDir }); const agentRunner = { runLoop: async ({ toolSet, @@ -144,7 +144,7 @@ describe('createLocalProjectMemoryCapture', () => { }); it('captures a semantic-layer source for a named local connection id', async () => { - const project = await initKtxProject({ projectDir: tempDir, projectName: 'warehouse' }); + const project = await initKtxProject({ projectDir: tempDir }); project.config.connections.warehouse = { driver: 'postgres' }; const agentRunner = { runLoop: async ({ diff --git a/packages/context/src/project/config.test.ts b/packages/context/src/project/config.test.ts index 9ecbcb3e..164282eb 100644 --- a/packages/context/src/project/config.test.ts +++ b/packages/context/src/project/config.test.ts @@ -11,7 +11,6 @@ describe('KTX project config', () => { it.each(['status', 'replay', 'run', 'watch'])('accepts former ingest subcommand name "%s" as a connection id', (connectionId) => { expect( parseKtxProjectConfig(` -project: reserved-test connections: ${connectionId}: driver: postgres @@ -24,8 +23,7 @@ connections: }); it('builds the default standalone project config', () => { - expect(buildDefaultKtxProjectConfig('warehouse')).toEqual({ - project: 'warehouse', + expect(buildDefaultKtxProjectConfig()).toEqual({ connections: {}, storage: { state: 'sqlite', @@ -84,15 +82,14 @@ connections: }); it('round-trips through YAML with stable defaults', () => { - const serialized = serializeKtxProjectConfig(buildDefaultKtxProjectConfig('warehouse')); + const serialized = serializeKtxProjectConfig(buildDefaultKtxProjectConfig()); const parsed = parseKtxProjectConfig(serialized); - expect(serialized).toContain('project: warehouse'); + expect(serialized).not.toContain('project:'); expect(serialized).not.toContain('live-database'); expect(serialized).toContain( ' embeddings:\n backend: deterministic\n model: deterministic\n dimensions: 8', ); - expect(parsed.project).toBe('warehouse'); expect(parsed.ingest.adapters).toEqual([]); expect(parsed.ingest.embeddings).toEqual({ backend: 'deterministic', @@ -103,7 +100,6 @@ connections: it('parses and serializes setup warehouse metadata without setup progress', () => { const config = parseKtxProjectConfig(` -project: revenue setup: database_connection_ids: - warehouse @@ -126,7 +122,6 @@ connections: it('parses global direct Anthropic LLM config', () => { const config = parseKtxProjectConfig(` -project: demo llm: provider: backend: anthropic @@ -166,7 +161,6 @@ ingest: it('parses global Vertex LLM config', () => { const config = parseKtxProjectConfig(` -project: demo llm: provider: backend: vertex @@ -188,7 +182,6 @@ llm: it('parses gateway LLM, OpenAI scan embeddings, and sentence-transformers ingest embeddings', () => { const config = parseKtxProjectConfig(` -project: demo llm: provider: backend: gateway @@ -232,7 +225,6 @@ scan: it('parses scan relationship settings', () => { const config = parseKtxProjectConfig(` -project: demo scan: relationships: enabled: false @@ -273,7 +265,6 @@ scan: it('parses the scan relationship validation budget sentinel', () => { const config = parseKtxProjectConfig(` -project: demo scan: relationships: validationBudget: all @@ -285,7 +276,6 @@ scan: it('rejects out-of-range scan relationship numeric settings', () => { const yaml = ` -project: demo scan: relationships: acceptThreshold: 2 @@ -316,7 +306,6 @@ scan: it('rejects invalid scan relationship validation budget strings', () => { const yaml = ` -project: demo scan: relationships: validationBudget: infinite @@ -327,7 +316,6 @@ scan: it('rejects unsupported local LLM and embedding fields', () => { expect(() => parseKtxProjectConfig(` -project: demo ingest: llm: backend: anthropic @@ -336,7 +324,6 @@ ingest: expect(() => parseKtxProjectConfig(` -project: demo scan: enrichment: backend: gateway @@ -345,7 +332,6 @@ scan: expect(() => parseKtxProjectConfig(` -project: demo scan: enrichment: mode: llm @@ -356,7 +342,6 @@ scan: expect(() => parseKtxProjectConfig(` -project: demo ingest: embeddings: provider: gateway @@ -368,7 +353,6 @@ ingest: it('rejects gateway embedding configs', () => { expect(() => parseKtxProjectConfig(` -project: demo ingest: embeddings: backend: gateway @@ -379,7 +363,6 @@ ingest: expect(() => parseKtxProjectConfig(` -project: demo scan: enrichment: mode: llm @@ -392,9 +375,9 @@ scan: }); it('fills optional sections when a minimal config is loaded', () => { - const config = parseKtxProjectConfig('project: local\n'); + const config = parseKtxProjectConfig('{}\n'); - expect(config).toEqual(buildDefaultKtxProjectConfig('local')); + expect(config).toEqual(buildDefaultKtxProjectConfig()); expect(config.ingest.embeddings).toEqual({ backend: 'deterministic', model: 'deterministic', @@ -406,14 +389,15 @@ scan: expect(() => parseKtxProjectConfig('- nope\n')).toThrow('ktx.yaml must contain a YAML object'); }); - it('rejects configs with a missing project name', () => { - expect(() => parseKtxProjectConfig('connections: {}\n')).toThrow('ktx.yaml field "project" is required'); + it('accepts configs without a project name', () => { + expect(parseKtxProjectConfig('connections: {}\n')).toMatchObject({ + connections: {}, + }); }); it('rejects unknown top-level fields under strict mode', () => { expect(() => parseKtxProjectConfig(` -project: demo storrage: state: sqlite `), @@ -423,13 +407,12 @@ storrage: describe('validateKtxProjectConfig', () => { it('returns ok: true with no issues for a valid config', () => { - const result = validateKtxProjectConfig('project: warehouse\n'); + const result = validateKtxProjectConfig('connections: {}\n'); expect(result).toEqual({ ok: true, issues: [] }); }); it('collects every schema issue without throwing', () => { const result = validateKtxProjectConfig(` -project: "" storage: search: not-a-real-backend scan: @@ -441,7 +424,6 @@ scan: const paths = result.issues.map((issue) => issue.path); expect(paths).toEqual( expect.arrayContaining([ - 'project', 'storage.search', 'scan.relationships.acceptThreshold', ]), @@ -450,7 +432,6 @@ scan: it('attaches migration hints for known deprecated keys', () => { const result = validateKtxProjectConfig(` -project: demo ingest: llm: backend: anthropic @@ -499,18 +480,15 @@ describe('generateKtxProjectConfigJsonSchema', () => { it('exposes every top-level ktx.yaml section under properties', () => { const properties = schema.properties as Record; - expect(Object.keys(properties).sort()).toEqual( - ['agent', 'connections', 'ingest', 'llm', 'memory', 'project', 'scan', 'setup', 'storage'].sort(), - ); + expect(Object.keys(properties).sort()).toEqual(['agent', 'connections', 'ingest', 'llm', 'memory', 'scan', 'setup', 'storage'].sort()); }); - it('marks "project" as required', () => { - expect(schema.required).toEqual(expect.arrayContaining(['project'])); + it('does not require any top-level fields', () => { + expect(schema.required).toBeUndefined(); }); it('carries .describe() text on top-level fields', () => { const properties = schema.properties as Record; - expect(properties.project?.description).toMatch(/Project identifier/); expect(properties.llm?.description).toMatch(/LLM/); expect(properties.scan?.description).toMatch(/Schema-scan/); }); diff --git a/packages/context/src/project/config.ts b/packages/context/src/project/config.ts index 07c30891..178721c4 100644 --- a/packages/context/src/project/config.ts +++ b/packages/context/src/project/config.ts @@ -238,11 +238,6 @@ const memorySchema = z const ktxProjectConfigSchema = z .strictObject({ - project: z - .string({ error: 'ktx.yaml field "project" is required' }) - .trim() - .min(1, 'ktx.yaml field "project" is required') - .describe('Project identifier; used in logs, ktx state files, and as the default workspace name.'), setup: setupSchema.optional().describe('Setup-wizard state. Written by `ktx setup`; may be omitted.'), connections: z .record(z.string(), connectionSchema) @@ -332,8 +327,8 @@ function formatZodError(error: z.ZodError, input: unknown): string { .join('\n'); } -export function buildDefaultKtxProjectConfig(projectName = 'ktx-project'): KtxProjectConfig { - return ktxProjectConfigSchema.parse({ project: projectName }); +export function buildDefaultKtxProjectConfig(): KtxProjectConfig { + return ktxProjectConfigSchema.parse({}); } export function parseKtxProjectConfig(raw: string): KtxProjectConfig { diff --git a/packages/context/src/project/project.test.ts b/packages/context/src/project/project.test.ts index caf36220..21e27d6a 100644 --- a/packages/context/src/project/project.test.ts +++ b/packages/context/src/project/project.test.ts @@ -20,15 +20,13 @@ describe('KTX local project runtime', () => { const result = await initKtxProject({ projectDir, - projectName: 'warehouse', authorName: 'Agent', authorEmail: 'agent@example.com', }); expect(result.projectDir).toBe(projectDir); - expect(result.config.project).toBe('warehouse'); expect(result.commitHash).toMatch(/^[0-9a-f]{40}$/); - await expect(readFile(join(projectDir, 'ktx.yaml'), 'utf-8')).resolves.toContain('project: warehouse'); + await expect(readFile(join(projectDir, 'ktx.yaml'), 'utf-8')).resolves.not.toContain('project:'); const gitignore = await readFile(join(projectDir, '.ktx/.gitignore'), 'utf-8'); expect(gitignore).toContain('cache/'); expect(gitignore).toContain('db.sqlite'); @@ -46,7 +44,7 @@ describe('KTX local project runtime', () => { it('loads an initialized project with a working file store', async () => { const projectDir = join(tempDir, 'warehouse'); - await initKtxProject({ projectDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir }); const loaded = await loadKtxProject({ projectDir }); await loaded.fileStore.writeFile( @@ -57,7 +55,6 @@ describe('KTX local project runtime', () => { 'Add revenue page', ); - expect(loaded.config.project).toBe('warehouse'); await expect(loaded.fileStore.readFile('wiki/global/revenue.md')).resolves.toMatchObject({ content: '# Revenue\n', }); @@ -65,16 +62,12 @@ describe('KTX local project runtime', () => { it('rejects reinitializing an existing project unless force is set', async () => { const projectDir = join(tempDir, 'warehouse'); - await initKtxProject({ projectDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir }); - await expect(initKtxProject({ projectDir, projectName: 'warehouse' })).rejects.toThrow( - 'Project already contains ktx.yaml', - ); + await expect(initKtxProject({ projectDir })).rejects.toThrow('Project already contains ktx.yaml'); - await expect(initKtxProject({ projectDir, projectName: 'warehouse-v2', force: true })).resolves.toMatchObject({ - config: { - project: 'warehouse-v2', - }, + await expect(initKtxProject({ projectDir, force: true })).resolves.toMatchObject({ + configPath: join(projectDir, 'ktx.yaml'), }); }); }); diff --git a/packages/context/src/project/project.ts b/packages/context/src/project/project.ts index 50f89262..572ac325 100644 --- a/packages/context/src/project/project.ts +++ b/packages/context/src/project/project.ts @@ -7,7 +7,6 @@ import { LocalGitFileStore } from './local-git-file-store.js'; export interface InitKtxProjectOptions { projectDir: string; - projectName?: string; force?: boolean; authorName?: string; authorEmail?: string; @@ -101,7 +100,7 @@ async function createRuntime( export async function initKtxProject(options: InitKtxProjectOptions): Promise { const projectDir = resolve(options.projectDir); - const projectName = options.projectName?.trim() || basename(projectDir) || 'ktx-project'; + const projectName = basename(projectDir) || 'ktx-project'; const authorName = options.authorName ?? 'ktx'; const authorEmail = options.authorEmail ?? 'ktx@example.com'; const logger = options.logger ?? noopLogger; @@ -112,7 +111,7 @@ export async function initKtxProject(options: InitKtxProjectOptions): Promise { }); it('sets setup database connection ids without duplicates', () => { - const config = buildDefaultKtxProjectConfig('warehouse'); + const config = buildDefaultKtxProjectConfig(); const withDatabases = setKtxSetupDatabaseConnectionIds(config, ['warehouse', 'analytics', 'warehouse']); diff --git a/packages/context/src/scan/local-enrichment-artifacts.test.ts b/packages/context/src/scan/local-enrichment-artifacts.test.ts index 8e0c25fd..068e6cb1 100644 --- a/packages/context/src/scan/local-enrichment-artifacts.test.ts +++ b/packages/context/src/scan/local-enrichment-artifacts.test.ts @@ -231,7 +231,6 @@ describe('writeLocalScanEnrichmentArtifacts', () => { tempDir = await mkdtemp(join(tmpdir(), 'ktx-local-enrichment-artifacts-')); project = await initKtxProject({ projectDir: join(tempDir, 'project'), - projectName: 'warehouse', }); }); diff --git a/packages/context/src/scan/local-enrichment.test.ts b/packages/context/src/scan/local-enrichment.test.ts index cbed687d..86a595d4 100644 --- a/packages/context/src/scan/local-enrichment.test.ts +++ b/packages/context/src/scan/local-enrichment.test.ts @@ -371,7 +371,7 @@ describe('local scan enrichment', () => { }, }, relationshipSettings: { - ...buildDefaultKtxProjectConfig('warehouse').scan.relationships, + ...buildDefaultKtxProjectConfig().scan.relationships, llmProposals: false, maxLlmTablesPerBatch: 40, }, @@ -383,7 +383,7 @@ describe('local scan enrichment', () => { it('skips relationship detection when scan relationships are disabled', async () => { const settings = { - ...buildDefaultKtxProjectConfig('warehouse').scan.relationships, + ...buildDefaultKtxProjectConfig().scan.relationships, enabled: false, }; const result = await runLocalScanEnrichment({ @@ -474,7 +474,7 @@ describe('local scan enrichment', () => { })), }; const settings = { - ...buildDefaultKtxProjectConfig('test').scan.relationships, + ...buildDefaultKtxProjectConfig().scan.relationships, enabled: false, }; diff --git a/packages/context/src/scan/local-enrichment.ts b/packages/context/src/scan/local-enrichment.ts index 5d58e189..ffefd923 100644 --- a/packages/context/src/scan/local-enrichment.ts +++ b/packages/context/src/scan/local-enrichment.ts @@ -515,8 +515,7 @@ export async function runLocalScanEnrichment( const now = input.now ?? (() => new Date()); const state = completedKtxScanEnrichmentStateSummary(); const syncId = input.syncId ?? input.context.runId; - const relationshipSettings = - input.relationshipSettings ?? buildDefaultKtxProjectConfig(input.connectionId).scan.relationships; + const relationshipSettings = input.relationshipSettings ?? buildDefaultKtxProjectConfig().scan.relationships; const inputHash = computeKtxScanEnrichmentInputHash({ snapshot, mode: input.mode, diff --git a/packages/context/src/scan/local-scan.test.ts b/packages/context/src/scan/local-scan.test.ts index 6e9076c6..40c8e225 100644 --- a/packages/context/src/scan/local-scan.test.ts +++ b/packages/context/src/scan/local-scan.test.ts @@ -105,7 +105,6 @@ async function writeLiveDatabaseConfig(projectDir: string): Promise { await writeFile( join(projectDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: postgres', @@ -123,7 +122,6 @@ async function writeDatabaseConfigWithoutIngestAdapters(projectDir: string): Pro await writeFile( join(projectDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: postgres', @@ -184,7 +182,7 @@ describe('local scan', () => { beforeEach(async () => { tempDir = await mkdtemp(join(tmpdir(), 'ktx-local-scan-')); const projectDir = join(tempDir, 'project'); - await initKtxProject({ projectDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir }); await writeLiveDatabaseConfig(projectDir); project = await loadKtxProject({ projectDir }); }); @@ -1037,7 +1035,6 @@ describe('local scan', () => { await writeFile( join(project.projectDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: postgres', @@ -1393,7 +1390,6 @@ describe('local scan', () => { await writeFile( join(project.projectDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: sqlite', @@ -1425,7 +1421,6 @@ describe('local scan', () => { await writeFile( join(project.projectDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: mysql', @@ -1457,7 +1452,6 @@ describe('local scan', () => { await writeFile( join(project.projectDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: clickhouse', @@ -1492,7 +1486,6 @@ describe('local scan', () => { await writeFile( join(project.projectDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: sqlserver', diff --git a/packages/context/src/scan/local-structural-artifacts.test.ts b/packages/context/src/scan/local-structural-artifacts.test.ts index 653c3b53..e8089158 100644 --- a/packages/context/src/scan/local-structural-artifacts.test.ts +++ b/packages/context/src/scan/local-structural-artifacts.test.ts @@ -13,7 +13,6 @@ describe('readLocalScanStructuralSnapshot', () => { tempDir = await mkdtemp(join(tmpdir(), 'ktx-local-structural-artifacts-')); project = await initKtxProject({ projectDir: join(tempDir, 'project'), - projectName: 'warehouse', }); }); diff --git a/packages/context/src/scan/relationship-artifacts.test.ts b/packages/context/src/scan/relationship-artifacts.test.ts index c366f1b2..f66de0c2 100644 --- a/packages/context/src/scan/relationship-artifacts.test.ts +++ b/packages/context/src/scan/relationship-artifacts.test.ts @@ -19,7 +19,6 @@ async function writeWarehouseConfig(projectDir: string): Promise { await writeFile( join(projectDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: sqlite', @@ -67,7 +66,7 @@ function liveDatabaseAdapter(): SourceAdapter { } async function createLiveDatabaseRun(projectDir: string, runId: string) { - await initKtxProject({ projectDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir }); await writeWarehouseConfig(projectDir); const project = await loadKtxProject({ projectDir }); await runLocalStageOnlyIngest({ @@ -283,7 +282,7 @@ describe('local scan relationship artifact reader', () => { it('returns null when the scan run has no report', async () => { const projectDir = await mkdtemp(join(tmpdir(), 'ktx-relationship-artifacts-missing-run-')); try { - await initKtxProject({ projectDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir }); const project = await loadKtxProject({ projectDir }); await expect(readLocalScanRelationshipArtifacts(project, 'missing-run')).resolves.toBeNull(); diff --git a/packages/context/src/scan/relationship-discovery.test.ts b/packages/context/src/scan/relationship-discovery.test.ts index 5d958b2d..4e83227b 100644 --- a/packages/context/src/scan/relationship-discovery.test.ts +++ b/packages/context/src/scan/relationship-discovery.test.ts @@ -243,7 +243,7 @@ function llmProvider(): KtxLlmProvider { } function relationshipSettings() { - return buildDefaultKtxProjectConfig('warehouse').scan.relationships; + return buildDefaultKtxProjectConfig().scan.relationships; } function llmOnlyRelationshipSnapshot(): KtxSchemaSnapshot { @@ -557,7 +557,7 @@ describe('production relationship discovery', () => { `); const settings = { - ...buildDefaultKtxProjectConfig('warehouse').scan.relationships, + ...buildDefaultKtxProjectConfig().scan.relationships, acceptThreshold: 0.99, reviewThreshold: 0.55, }; @@ -633,7 +633,7 @@ describe('production relationship discovery', () => { schema: snapshotToKtxEnrichedSchema(richSnapshot), context: { runId: 'candidate-cap' }, settings: { - ...buildDefaultKtxProjectConfig('warehouse').scan.relationships, + ...buildDefaultKtxProjectConfig().scan.relationships, maxCandidatesPerColumn: 1, }, }); diff --git a/packages/context/src/scan/relationship-review-apply.test.ts b/packages/context/src/scan/relationship-review-apply.test.ts index 7a8e597f..268c9598 100644 --- a/packages/context/src/scan/relationship-review-apply.test.ts +++ b/packages/context/src/scan/relationship-review-apply.test.ts @@ -202,7 +202,6 @@ async function projectWithDecisions( const tempDir = await mkdtemp(join(tmpdir(), 'ktx-relationship-review-apply-')); const project = await initKtxProject({ projectDir: join(tempDir, 'project'), - projectName: 'warehouse', }); await project.fileStore.writeFile( 'raw-sources/warehouse/live-database/sync-a/enrichment/relationship-review-decisions.json', diff --git a/packages/context/src/scan/relationship-review-decisions.test.ts b/packages/context/src/scan/relationship-review-decisions.test.ts index 30277c57..979c863b 100644 --- a/packages/context/src/scan/relationship-review-decisions.test.ts +++ b/packages/context/src/scan/relationship-review-decisions.test.ts @@ -19,11 +19,10 @@ async function writeProjectFile(projectDir: string, relativePath: string, conten } async function createProject(projectDir: string): Promise { - await initKtxProject({ projectDir, projectName: 'warehouse' }); + await initKtxProject({ projectDir }); await writeFile( join(projectDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: sqlite', diff --git a/packages/context/src/search/backend-conformance.test.ts b/packages/context/src/search/backend-conformance.test.ts index 95858486..31519c8b 100644 --- a/packages/context/src/search/backend-conformance.test.ts +++ b/packages/context/src/search/backend-conformance.test.ts @@ -241,7 +241,7 @@ describe('SQLite hybrid search backend conformance', () => { beforeEach(async () => { tempDir = await mkdtemp(join(tmpdir(), 'ktx-search-conformance-')); - project = await initKtxProject({ projectDir: join(tempDir, 'project'), projectName: 'warehouse' }); + project = await initKtxProject({ projectDir: join(tempDir, 'project') }); dbPath = join(tempDir, '.ktx', 'db.sqlite'); }); diff --git a/packages/context/src/sl/local-query.test.ts b/packages/context/src/sl/local-query.test.ts index 4105c9f6..2852b35a 100644 --- a/packages/context/src/sl/local-query.test.ts +++ b/packages/context/src/sl/local-query.test.ts @@ -13,7 +13,7 @@ describe('compileLocalSlQuery', () => { beforeEach(async () => { tempDir = await mkdtemp(join(tmpdir(), 'ktx-local-query-')); - project = await initKtxProject({ projectDir: join(tempDir, 'project'), projectName: 'warehouse' }); + project = await initKtxProject({ projectDir: join(tempDir, 'project') }); project.config.connections.warehouse = { driver: 'postgres' }; await project.fileStore.writeFile( 'semantic-layer/warehouse/orders.yaml', diff --git a/packages/context/src/sl/local-sl.test.ts b/packages/context/src/sl/local-sl.test.ts index b7d56e22..5e5fb6c4 100644 --- a/packages/context/src/sl/local-sl.test.ts +++ b/packages/context/src/sl/local-sl.test.ts @@ -51,7 +51,7 @@ describe('local semantic-layer helpers', () => { beforeEach(async () => { tempDir = await mkdtemp(join(tmpdir(), 'ktx-local-sl-')); - project = await initKtxProject({ projectDir: join(tempDir, 'project'), projectName: 'warehouse' }); + project = await initKtxProject({ projectDir: join(tempDir, 'project') }); }); afterEach(async () => { diff --git a/packages/context/src/sl/pglite-sl-search-prototype.test.ts b/packages/context/src/sl/pglite-sl-search-prototype.test.ts index 0c599dca..29c81062 100644 --- a/packages/context/src/sl/pglite-sl-search-prototype.test.ts +++ b/packages/context/src/sl/pglite-sl-search-prototype.test.ts @@ -169,7 +169,7 @@ describe('PGlite semantic-layer search prototype', () => { beforeEach(async () => { tempDir = await mkdtemp(join(tmpdir(), 'ktx-pglite-sl-prototype-')); - project = await initKtxProject({ projectDir: join(tempDir, 'project'), projectName: 'warehouse' }); + project = await initKtxProject({ projectDir: join(tempDir, 'project') }); project.config.ingest.embeddings.dimensions = 3; pgliteDataDir = join(tempDir, 'pglite-search'); port = await allocatePort(); diff --git a/packages/context/src/sl/sl-dictionary-profile.test.ts b/packages/context/src/sl/sl-dictionary-profile.test.ts index 756cb81a..21400a71 100644 --- a/packages/context/src/sl/sl-dictionary-profile.test.ts +++ b/packages/context/src/sl/sl-dictionary-profile.test.ts @@ -11,7 +11,7 @@ describe('loadLatestSlDictionaryEntries', () => { beforeEach(async () => { tempDir = await mkdtemp(join(tmpdir(), 'ktx-sl-dictionary-profile-')); - project = await initKtxProject({ projectDir: join(tempDir, 'project'), projectName: 'warehouse' }); + project = await initKtxProject({ projectDir: join(tempDir, 'project') }); }); afterEach(async () => { diff --git a/packages/context/src/wiki/local-knowledge.test.ts b/packages/context/src/wiki/local-knowledge.test.ts index 09d61a3c..122e56b5 100644 --- a/packages/context/src/wiki/local-knowledge.test.ts +++ b/packages/context/src/wiki/local-knowledge.test.ts @@ -28,7 +28,7 @@ describe('local knowledge helpers', () => { beforeEach(async () => { tempDir = await mkdtemp(join(tmpdir(), 'ktx-local-knowledge-')); - project = await initKtxProject({ projectDir: join(tempDir, 'project'), projectName: 'warehouse' }); + project = await initKtxProject({ projectDir: join(tempDir, 'project') }); }); afterEach(async () => { diff --git a/scripts/examples-docs.test.mjs b/scripts/examples-docs.test.mjs index 0ae3371a..23553853 100644 --- a/scripts/examples-docs.test.mjs +++ b/scripts/examples-docs.test.mjs @@ -43,7 +43,7 @@ describe('standalone example docs', () => { assert.match(readme, /Accepted: 9/); assert.match(readme, /Review: 0/); assert.match(readme, /Rejected: 0/); - assert.match(config, /project: orbit-relationship-verification/); + assert.doesNotMatch(config, /^project:/m); assert.match(config, /orbit:/); assert.match(config, /driver: sqlite/); assert.match( diff --git a/scripts/installed-live-database-smoke.mjs b/scripts/installed-live-database-smoke.mjs index fae97850..6337a582 100644 --- a/scripts/installed-live-database-smoke.mjs +++ b/scripts/installed-live-database-smoke.mjs @@ -87,7 +87,6 @@ export function buildSeedSql() { export function buildKtxYaml(postgresUrl) { return [ - 'project: artifact-live-database', 'connections:', ' warehouse:', ' driver: postgres', diff --git a/scripts/installed-live-database-smoke.test.mjs b/scripts/installed-live-database-smoke.test.mjs index 3eda6cf0..ef618725 100644 --- a/scripts/installed-live-database-smoke.test.mjs +++ b/scripts/installed-live-database-smoke.test.mjs @@ -53,7 +53,6 @@ describe('installed live-database artifact smoke helpers', () => { assert.equal( buildKtxYaml('postgresql://ktx:postgres@127.0.0.1:15432/warehouse'), // pragma: allowlist secret [ - 'project: artifact-live-database', 'connections:', ' warehouse:', ' driver: postgres', diff --git a/scripts/package-artifacts.mjs b/scripts/package-artifacts.mjs index 219f3e3c..efe7f6f3 100644 --- a/scripts/package-artifacts.mjs +++ b/scripts/package-artifacts.mjs @@ -642,7 +642,6 @@ try { await writeFile( join(projectDir, 'ktx.yaml'), [ - 'project: warehouse', 'connections:', ' warehouse:', ' driver: sqlite',