mirror of
https://github.com/Kaelio/ktx.git
synced 2026-07-04 10:52:13 +02:00
fix(cli): survive ktx.yaml version skew and derive repo ownership from disk (#293)
* fix(cli): survive ktx.yaml version skew and derive repo ownership from disk Loading ktx.yaml is now tolerant of keys this ktx version does not recognize: they are stripped from the in-memory config (the file on disk is never rewritten) and reported by ktx status as non-blocking warnings, while invalid values on recognized fields still fail hard. Repo ownership is derived from observed state (a .git directory plus a root ktx.yaml) instead of a ktx.managed git-config marker, so projects created by any past or future ktx classify identically. initKtxProject now runs an explicit foreign-repo pre-check and writes ktx.yaml before initializing git, so an interrupted init leaves only recoverable residue instead of a bare .git misread as foreign. * style(cli): trim comment blocks to constraint-only notes * docs(agents): require constraint-only code comments
This commit is contained in:
parent
a278d2f7d0
commit
0689d709d2
14 changed files with 502 additions and 146 deletions
|
|
@ -1,6 +1,6 @@
|
|||
import { promises as fs } from 'node:fs';
|
||||
import { basename, dirname, join, resolve } from 'node:path';
|
||||
import { GitService } from '../../context/core/git.service.js';
|
||||
import { classifyKtxRepoOwnership, GitService, KtxForeignGitRepositoryError } from '../../context/core/git.service.js';
|
||||
import { type KtxCoreConfig, type KtxLogger, noopLogger } from '../../context/core/config.js';
|
||||
import type { KtxProjectConfig } from './config.js';
|
||||
import { buildDefaultKtxProjectConfig, parseKtxProjectConfig, serializeKtxProjectConfig } from './config.js';
|
||||
|
|
@ -112,14 +112,24 @@ export async function initKtxProject(options: InitKtxProjectOptions): Promise<In
|
|||
throw new Error(`Project already contains ktx.yaml: ${configPath}`);
|
||||
}
|
||||
|
||||
const config = buildDefaultKtxProjectConfig();
|
||||
const runtime = await createRuntime(projectDir, config, authorName, authorEmail, logger);
|
||||
// Must run before ktx.yaml is written: once that file exists the directory
|
||||
// classifies as ktx-managed, so a foreign repo would be silently adopted.
|
||||
if ((await classifyKtxRepoOwnership(projectDir)) === 'foreign') {
|
||||
throw new KtxForeignGitRepositoryError(projectDir);
|
||||
}
|
||||
|
||||
await writeProjectFile(projectDir, 'ktx.yaml', serializeKtxProjectConfig(config));
|
||||
const config = buildDefaultKtxProjectConfig();
|
||||
|
||||
// ktx.yaml (the ownership signal) is written before git init, so an
|
||||
// interrupted init can never leave a bare `.git` without it — residue that
|
||||
// would classify as a foreign repo and be unrecoverable.
|
||||
await fs.mkdir(join(projectDir, '.ktx/cache'), { recursive: true });
|
||||
for (const file of TRACKED_SCAFFOLD_FILES) {
|
||||
await writeProjectFile(projectDir, file.path, file.content);
|
||||
}
|
||||
await writeProjectFile(projectDir, 'ktx.yaml', serializeKtxProjectConfig(config));
|
||||
|
||||
const runtime = await createRuntime(projectDir, config, authorName, authorEmail, logger);
|
||||
|
||||
const commit = await runtime.git.commitFiles(
|
||||
['ktx.yaml', ...TRACKED_SCAFFOLD_FILES.map((file) => file.path)],
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue