Commit setup config updates

This commit is contained in:
Luca Martial 2026-05-11 20:39:01 -07:00
parent 6d00cbbc2e
commit 2c70e506f1
2 changed files with 65 additions and 0 deletions

View file

@ -1,11 +1,15 @@
import { execFile } from 'node:child_process';
import { mkdir, mkdtemp, readFile, rm, stat, writeFile } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { promisify } from 'node:util';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { contextBuildCommands, writeKtxSetupContextState } from './setup-context.js';
import { readKtxSetupStatus, runKtxSetup } from './setup.js';
const execFileAsync = promisify(execFile);
function makeIo() {
let stdout = '';
let stderr = '';
@ -1293,6 +1297,60 @@ describe('setup status', () => {
expect(calls).toEqual(['model', 'embeddings', 'databases', 'sources', 'context', 'agents']);
});
it('commits setup config changes written by later setup steps', async () => {
const io = makeIo();
await expect(
runKtxSetup(
{
command: 'run',
projectDir: tempDir,
mode: 'new',
agents: false,
inputMode: 'disabled',
yes: true,
cliVersion: '0.2.0',
skipLlm: true,
skipEmbeddings: true,
skipDatabases: true,
skipSources: true,
skipAgents: false,
databaseSchemas: [],
},
io.io,
{
model: async () => ({ status: 'skipped', projectDir: tempDir }),
embeddings: async () => ({ status: 'skipped', projectDir: tempDir }),
databases: async () => {
const configPath = join(tempDir, 'ktx.yaml');
const current = await readFile(configPath, 'utf-8');
await writeFile(
configPath,
current.replace(
'connections: {}',
['connections:', ' warehouse:', ' driver: postgres', ' url: env:DATABASE_URL'].join('\n'),
),
'utf-8',
);
return { status: 'skipped', projectDir: tempDir };
},
sources: async () => ({ status: 'skipped', projectDir: tempDir }),
context: async () => ({ status: 'ready', projectDir: tempDir, runId: 'setup-context-local-test' }),
agents: async () => ({
status: 'ready',
projectDir: tempDir,
installs: [{ target: 'codex', scope: 'project', mode: 'cli' }],
}),
},
),
).resolves.toBe(0);
const { stdout } = await execFileAsync('git', ['-C', tempDir, 'status', '--short', '--', 'ktx.yaml']);
expect(stdout).toBe('');
const committedConfig = await execFileAsync('git', ['-C', tempDir, 'show', 'HEAD:ktx.yaml']);
expect(committedConfig.stdout).toContain('warehouse:');
});
it('runs agent setup after context succeeds in --agents mode', async () => {
const calls: string[] = [];
const io = makeIo();

View file

@ -415,6 +415,11 @@ function setupRuntimeInstallPolicy(args: Extract<KtxSetupArgs, { command: 'run'
return args.inputMode === 'disabled' ? 'never' : 'prompt';
}
async function commitSetupConfigChanges(projectDir: string): Promise<void> {
const project = await loadKtxProject({ projectDir });
await project.git.commitFile('ktx.yaml', 'setup: update KTX project config', 'ktx setup', 'setup@ktx.local');
}
export async function runKtxSetup(args: KtxSetupArgs, io: KtxCliIo, deps: KtxSetupDeps = {}): Promise<number> {
try {
return await runKtxSetupInner(args, io, deps);
@ -755,6 +760,8 @@ async function runKtxSetupInner(args: KtxSetupArgs, io: KtxCliIo, deps: KtxSetup
break;
}
await commitSetupConfigChanges(projectResult.projectDir);
const status = await readKtxSetupStatus(projectResult.projectDir);
io.stdout.write(formatKtxSetupStatus(status));
io.stdout.write('\nWhat you can do next:\n');