ktx/scripts/published-package-smoke-config.mjs
Andrey Avtomonov 9dad936ac7
feat: npm-managed Python runtime for @kaelio/ktx (#7)
* docs: add npm managed python runtime design

* build: add bundled python runtime wheel builder

* build: make local embedding dependencies optional

* build: bundle python runtime wheel in cli artifacts

* build: track bundled python runtime release artifact

* test: verify bundled python runtime wheel

* docs: add plan for bundled python runtime wheel

* test: cover managed python runtime lifecycle

* feat: add managed python runtime installer

* feat: add runtime command runner

* feat: expose runtime management commands

* test: verify managed python runtime commands

* docs: add plan for managed python runtime installer

* feat: add managed python command helper

* feat: use managed runtime for sl query compute

* feat: route sl query managed runtime policy

* docs: add plan for managed runtime sl query integration

* feat: add managed runtime daemon metadata

* feat: manage python daemon lifecycle

* feat: add runtime daemon start stop commands

* fix: verify managed runtime daemon lifecycle

* docs: add plan for managed runtime daemon lifecycle

* feat: add managed local embeddings config marker

* feat: add managed local embeddings daemon helper

* feat: use managed runtime for local embedding setup

* feat: pass managed runtime policy through setup

* docs: add plan for managed local embeddings runtime

* feat: read CLI package metadata dynamically

* feat: assemble public kaelio ktx npm package

* feat: release one public kaelio ktx npm artifact

* test: cover public kaelio ktx package invocations

* chore: verify public kaelio ktx package artifacts

* docs: add plan for public kaelio ktx npm package

* test: verify managed runtime in public package smoke

* test: finalize managed runtime release smoke

* docs: add plan for managed runtime release smoke

* test: specify local embeddings release smoke

* feat: add local embeddings runtime smoke

* chore: register local embeddings smoke

* fix: verify local embeddings smoke

* fix: restore artifact smoke python env helper

* docs: add plan for managed local embeddings release smoke

* refactor: share managed runtime install policy parsing

* feat: use managed runtime for agent semantic queries

* feat: use managed runtime for MCP semantic compute

* docs: add plan for managed agent and MCP semantic runtime

* feat(cli): add managed daemon HTTP helpers

* feat(cli): route local adapters through managed daemon

* feat(cli): use managed daemon for ingest helpers

* feat(cli): pass managed daemon options to scan

* feat(context): pass MCP ingest pull config options

* feat(cli): pass managed daemon options to serve ingest

* test: verify managed local ingest daemon runtime

* docs: add plan for managed local ingest daemon runtime

* docs: align managed runtime examples

* docs: add plan for managed runtime docs cleanup

* test: cover published package runtime smoke commands

* test: validate published package smoke outputs

* docs: add plan for published package runtime smoke

* build: stamp public npm package version

* release: add npm public release policy

* release: add guarded npm publish script

* release: document public npm release handoff

* docs: add plan for public npm release handoff

* test: cover managed runtime prune in package smoke

* docs: document managed runtime prune

* docs: add plan for managed runtime prune smoke and docs

* chore: encode uv runtime prerequisite policy

* fix: clarify missing uv runtime error

* docs: document uv runtime prerequisite

* docs: add plan for uv runtime prerequisite contract

* refactor: limit release artifacts to public package runtime

* chore: align release policy with bundled runtime wheel

* docs: describe single public runtime artifact surface

* test: verify single public runtime artifact contract

* docs: add plan for single public runtime artifact cleanup

* fix: align local embeddings smoke with public version

* docs: add plan for local embeddings smoke public version

* release: soft-launch as @kaelio/ktx@0.1.0-rc.0 on next tag

Publish target moves to the pre-release version 0.1.0-rc.0 under the next
dist-tag so npm install @kaelio/ktx (which resolves to latest) does not
pick up the soft-launch build. Users opt in via @kaelio/ktx@next.

* Fix release script boundary checks

* Remove PostHog from public package bundle
2026-05-11 15:50:34 +02:00

208 lines
6.2 KiB
JavaScript

import { dirname, join } from 'node:path';
import assert from 'node:assert/strict';
import { readFile } from 'node:fs/promises';
export const DEFAULT_VERSION_TAG = 'latest';
export const NO_PACKAGE_REASON =
'Set KTX_PUBLISHED_KTX_PACKAGE or release-policy.json publishedPackageSmoke.packageName to the published npm package name after the release decision.';
function optionalTrimmedString(value) {
return typeof value === 'string' && value.trim().length > 0 ? value.trim() : null;
}
function assertSafePackageName(packageName, label) {
if (!/^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/.test(packageName)) {
throw new Error(`Invalid ${label}: ${packageName}`);
}
}
function assertSafeVersionTag(version, label) {
if (!/^[a-zA-Z0-9][a-zA-Z0-9._+-]*$/.test(version)) {
throw new Error(`Invalid ${label}: ${version}`);
}
}
function assertHttpRegistry(registry, label) {
const parsed = new URL(registry);
if (parsed.protocol !== 'https:' && parsed.protocol !== 'http:') {
throw new Error(`${label} must be an http(s) URL`);
}
}
function registryEnv(config) {
return config.registry ? { npm_config_registry: config.registry } : {};
}
function runtimeCommandEnv(config, runtimeRoot) {
return { ...registryEnv(config), KTX_RUNTIME_ROOT: runtimeRoot };
}
function semanticQueryArgs(projectDir) {
return [
'sl',
'query',
'--project-dir',
projectDir,
'--connection-id',
'orbit_demo',
'--measure',
'contracts.contract_count',
'--format',
'sql',
'--yes',
];
}
function normalizePolicyConfig(policyConfig = {}) {
if (policyConfig === null || policyConfig === undefined) {
return { packageName: null, version: DEFAULT_VERSION_TAG, registry: null };
}
if (typeof policyConfig !== 'object' || Array.isArray(policyConfig)) {
throw new Error('release-policy.json publishedPackageSmoke must be a JSON object');
}
const normalized = {
packageName: optionalTrimmedString(policyConfig.packageName),
version: optionalTrimmedString(policyConfig.version) ?? DEFAULT_VERSION_TAG,
registry: optionalTrimmedString(policyConfig.registry),
};
assertSafeVersionTag(normalized.version, 'release-policy.json publishedPackageSmoke.version');
if (normalized.registry) {
assertHttpRegistry(normalized.registry, 'release-policy.json publishedPackageSmoke.registry');
}
return normalized;
}
export function readPublishedPackageSmokeConfig(env = process.env, args = process.argv.slice(2), policyConfig = {}) {
const requireConfig = args.includes('--require-config');
const policy = normalizePolicyConfig(policyConfig);
const envPackageName = optionalTrimmedString(env.KTX_PUBLISHED_KTX_PACKAGE);
const packageName = envPackageName ?? policy.packageName;
if (!packageName) {
return {
enabled: false,
requireConfig,
reason: NO_PACKAGE_REASON,
};
}
const configSource = envPackageName ? 'environment' : 'release-policy';
assertSafePackageName(
packageName,
configSource === 'environment'
? 'KTX_PUBLISHED_KTX_PACKAGE'
: 'release-policy.json publishedPackageSmoke.packageName',
);
const packageVersion = optionalTrimmedString(env.KTX_PUBLISHED_KTX_VERSION) ?? policy.version;
assertSafeVersionTag(
packageVersion,
optionalTrimmedString(env.KTX_PUBLISHED_KTX_VERSION)
? 'KTX_PUBLISHED_KTX_VERSION'
: 'release-policy.json publishedPackageSmoke.version',
);
const registry = optionalTrimmedString(env.KTX_PUBLISHED_KTX_REGISTRY) ?? policy.registry;
if (registry) {
assertHttpRegistry(
registry,
optionalTrimmedString(env.KTX_PUBLISHED_KTX_REGISTRY)
? 'KTX_PUBLISHED_KTX_REGISTRY'
: 'release-policy.json publishedPackageSmoke.registry',
);
}
return {
enabled: true,
requireConfig,
configSource,
packageName,
packageVersion,
registry,
};
}
export async function readPublishedPackageSmokeConfigFromPolicyFile(
policyPath,
env = process.env,
args = process.argv.slice(2),
) {
const policy = JSON.parse(await readFile(policyPath, 'utf8'));
return readPublishedPackageSmokeConfig(env, args, policy.publishedPackageSmoke ?? {});
}
export function publishedPackageSpec(config) {
assert.equal(config.enabled, true, 'publishedPackageSpec requires an enabled smoke config');
return `${config.packageName}@${config.packageVersion}`;
}
export function buildPublishedPackageNpxCommand(config, args, label = 'published package command', extraEnv = {}) {
return {
label,
command: 'npx',
args: ['--yes', publishedPackageSpec(config), ...args],
env: { ...registryEnv(config), ...extraEnv },
};
}
export function buildPublishedPackageSmokeCommands(
config,
projectDir,
runtimeRoot = join(dirname(projectDir), 'managed-runtime'),
) {
const runtimeEnv = runtimeCommandEnv(config, runtimeRoot);
const packageEnv = registryEnv(config);
const queryArgs = semanticQueryArgs(projectDir);
return [
buildPublishedPackageNpxCommand(config, ['--version'], 'published package npx version'),
buildPublishedPackageNpxCommand(
config,
['setup', 'demo', '--project-dir', projectDir, '--no-input', '--plain'],
'published package setup demo',
{ KTX_RUNTIME_ROOT: runtimeRoot },
),
buildPublishedPackageNpxCommand(config, queryArgs, 'published package npx sl query', {
KTX_RUNTIME_ROOT: runtimeRoot,
}),
{
label: 'published package local install',
command: 'pnpm',
args: ['add', publishedPackageSpec(config)],
env: packageEnv,
},
{
label: 'published package local version',
command: 'npx',
args: ['ktx', '--version'],
env: packageEnv,
},
{
label: 'published package local sl query',
command: 'npx',
args: ['ktx', ...queryArgs],
env: runtimeEnv,
},
{
label: 'published package global install',
command: 'pnpm',
args: ['add', '--global', publishedPackageSpec(config)],
env: packageEnv,
},
{
label: 'published package global version',
command: 'ktx',
args: ['--version'],
env: packageEnv,
},
{
label: 'published package global sl query',
command: 'ktx',
args: queryArgs,
env: runtimeEnv,
},
];
}