refactor(release): single source of truth for package version

Make packages/cli/package.json the single source of truth for the
@kaelio/ktx version. publicNpmPackageVersion() now reads it directly,
so artifact filenames, release-readiness checks, and the Python wheel
version all derive from one field. The duplicate
release-policy.json.publicNpmPackageVersion is removed.

Previously the two fields could drift: tarballs were named
kaelio-ktx-0.4.1.tgz while internally containing
@kaelio/ktx@0.0.0-private.

- update-public-release-version.mjs rewrites both Python pyproject.toml
  files (ktx-daemon, ktx-sl) alongside the npm package.jsons,
  normalizing the version for PEP 440 (e.g. 0.1.0-rc.2 -> 0.1.0rc2).
- semantic-release-config.cjs adds the two pyproject.toml files to
  @semantic-release/git assets so the release commit back to main
  carries every version source in lockstep.
- The six "?? '0.0.0-private'" fallback literals across the CLI are
  replaced with "?? getKtxCliPackageInfo().version", and
  createDefaultKtxMcpServer makes its version arg required.
- docs/release.md describes the actual commit-back model: the dev tree
  always reflects the most recent release; no sentinel pin to
  maintain.

Verified: pnpm run artifacts:build now produces
kaelio-ktx-0.4.1.tgz and kaelio_ktx-0.4.1-py3-none-any.whl with
@kaelio/ktx@0.4.1 inside. Full type-check, dead-code, and
2287 vitests + 173 script tests pass.
This commit is contained in:
Andrey Avtomonov 2026-05-21 14:23:28 +02:00
parent 36805c4533
commit 99f7a31919
22 changed files with 168 additions and 54 deletions

View file

@ -16,11 +16,11 @@ export function createKtxMcpServer(deps: KtxMcpServerDeps): KtxMcpServerDeps['se
}
export function createDefaultKtxMcpServer(
deps: Omit<KtxMcpServerDeps, 'server'> & { name?: string; version?: string },
deps: Omit<KtxMcpServerDeps, 'server'> & { name?: string; version: string },
): McpServer {
const server = new McpServer({
name: deps.name ?? 'ktx',
version: deps.version ?? '0.0.0-private',
version: deps.version,
});
createKtxMcpServer({
server: server as KtxMcpServerLike,

View file

@ -8,6 +8,7 @@ import type { MemoryFlowEvent, MemoryFlowReplayInput } from './context/ingest/me
import { renderMemoryFlowReplay } from './context/ingest/memory-flow/render.js';
import type { KtxSqlQueryExecutorPort } from './context/connections/query-executor.js';
import { loadKtxProject, type KtxLocalProject } from './context/project/project.js';
import { getKtxCliPackageInfo } from './cli-runtime.js';
import { resolveProjectEmbeddingProvider } from './embedding-resolution.js';
import { createKtxCliIngestQueryExecutor } from './ingest-query-executor.js';
import { readIngestReportSnapshotFile } from './ingest-report-file.js';
@ -677,7 +678,7 @@ export async function runKtxIngest(
const resolution = await resolveProjectEmbeddingProvider(project, {
mode: 'ensure',
installPolicy: args.runtimeInstallPolicy ?? 'never',
cliVersion: args.cliVersion ?? '0.0.0-private',
cliVersion: args.cliVersion ?? getKtxCliPackageInfo().version,
io,
});
const embeddingProvider =

View file

@ -4,7 +4,7 @@ import { loadKtxProject } from './context/project/project.js';
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
import { isInitializeRequest } from '@modelcontextprotocol/sdk/types.js';
import type { KtxCliIo } from './cli-runtime.js';
import { getKtxCliPackageInfo, type KtxCliIo } from './cli-runtime.js';
import { createKtxMcpServerFactory } from './mcp-server-factory.js';
const DEFAULT_ALLOWED_HOSTS = ['localhost', '127.0.0.1', '::1'] as const;
@ -178,7 +178,7 @@ export async function runKtxMcpHttpServer(options: RunKtxMcpHttpServerOptions):
(await createKtxMcpServerFactory({
project: project!,
projectDir: options.projectDir,
cliVersion: options.cliVersion ?? '0.0.0-private',
cliVersion: options.cliVersion ?? getKtxCliPackageInfo().version,
io: options.io,
}));
const sessions = new Map<string, StreamableHTTPServerTransport>();

View file

@ -3,7 +3,7 @@ import type { Readable, Writable } from 'node:stream';
import { loadKtxProject } from './context/project/project.js';
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import type { KtxCliIo } from './cli-runtime.js';
import { getKtxCliPackageInfo, type KtxCliIo } from './cli-runtime.js';
import { createKtxMcpServerFactory } from './mcp-server-factory.js';
export interface RunKtxMcpStdioServerOptions {
@ -30,7 +30,7 @@ export async function runKtxMcpStdioServer(options: RunKtxMcpStdioServerOptions)
(await createKtxMcpServerFactory({
project: project!,
projectDir: options.projectDir,
cliVersion: options.cliVersion ?? '0.0.0-private',
cliVersion: options.cliVersion ?? getKtxCliPackageInfo().version,
io: protocolIo,
}));
const stdin = options.stdin ?? process.stdin;

View file

@ -1,3 +1,4 @@
import { getKtxCliPackageInfo } from './cli-runtime.js';
import { loadKtxProject, type KtxLocalProject } from './context/project/project.js';
import type { KtxProjectConnectionConfig } from './context/project/config.js';
import type { KtxProgressPort } from './context/scan/types.js';
@ -878,7 +879,7 @@ export async function runKtxPublicIngest(
for (const feature of requirements.features) {
try {
await ensureRuntime({
cliVersion: args.cliVersion ?? '0.0.0-private',
cliVersion: args.cliVersion ?? getKtxCliPackageInfo().version,
installPolicy: args.runtimeInstallPolicy ?? 'prompt',
io,
feature,

View file

@ -1,6 +1,7 @@
import type { KtxProgressPort, KtxScanMode, KtxScanReport, KtxScanWarning } from './context/scan/types.js';
import { runLocalScan } from './context/scan/local-scan.js';
import { loadKtxProject } from './context/project/project.js';
import { getKtxCliPackageInfo } from './cli-runtime.js';
import { resolveProjectEmbeddingProvider } from './embedding-resolution.js';
import type { KtxCliIo } from './index.js';
import { createKtxCliLocalIngestAdapters } from './local-adapters.js';
@ -314,7 +315,7 @@ export async function runKtxScan(args: KtxScanArgs, io: KtxCliIo = process, deps
const resolution = await resolveProjectEmbeddingProvider(project, {
mode: 'ensure',
installPolicy: args.runtimeInstallPolicy ?? 'never',
cliVersion: args.cliVersion ?? '0.0.0-private',
cliVersion: args.cliVersion ?? getKtxCliPackageInfo().version,
io,
});
const embeddingProvider =