@botpress/adk-cli
Version:
Command-line interface for the Botpress Agent Development Kit (ADK)
227 lines (223 loc) • 8.3 kB
JavaScript
// @bun
import {
detectPackageManagers,
getPreferredPackageManager
} from "./chunk-nbasj5jm.js";
import {
EXPECTED_RUNTIME_VERSION
} from "./chunk-nxy2ya5r.js";
import {
require_semver
} from "./chunk-2a5b6azq.js";
import {
__toESM
} from "./chunk-dhs2bg35.js";
// src/utils/runtime-version-check.ts
var semver2 = __toESM(require_semver(), 1);
import { readFileSync, existsSync } from "fs";
import { join } from "path";
// src/utils/is-runtime-compatible.ts
var semver = __toESM(require_semver(), 1);
function getRuntimeCompatibilityStatus(installed, expected) {
if (installed.major !== expected.major) {
return "major_mismatch";
}
if (semver.lt(installed, expected)) {
return "outdated";
}
if (semver.gt(installed, expected)) {
return "newer";
}
return "current";
}
// src/utils/runtime-version-check.ts
class RuntimeVersionMismatchError extends Error {
installedVersion;
expectedVersion;
installCommand;
report;
status;
resolution;
constructor(installedVersion, expectedVersion, installCommand, report) {
super(formatRuntimeVersionMismatchMessage({ installedVersion, expectedVersion, installCommand, status: report?.status }));
this.installedVersion = installedVersion;
this.expectedVersion = expectedVersion;
this.installCommand = installCommand;
this.report = report;
this.name = "RuntimeVersionMismatchError";
this.status = report?.status;
this.resolution = report?.resolution;
}
}
function formatRuntimeVersionMismatchMessage(props) {
const expected = semver2.parse(props.expectedVersion);
const supportedMajor = expected ? `${expected.major}.x` : `v${props.expectedVersion}`;
const majorRelation = getRuntimeMajorRelation(props.installedVersion, props.expectedVersion);
const runtimeLine = props.status === "not_installed" || props.installedVersion === "<not installed>" ? "@botpress/runtime is not installed in this project." : props.status === "invalid" ? "@botpress/runtime has an invalid version in this project." : props.status === "major_mismatch" && majorRelation === "newer" ? `@botpress/runtime v${props.installedVersion} is newer than this CLI supports.` : `@botpress/runtime v${props.installedVersion} is not supported by this CLI.`;
const resolutionLines = props.status === "major_mismatch" && majorRelation === "newer" ? [
"Run `adk self-upgrade` to update this CLI.",
`If you intentionally need this older CLI line, pin the project runtime back to supported major ${supportedMajor}.`
] : [
"Run `adk project upgrade --dry-run` to review required project updates.",
"Run `adk project upgrade` to apply them."
];
return [
runtimeLine,
`Supported runtime major: ${supportedMajor}.`,
`Recommended runtime: v${props.expectedVersion}.`,
"",
...resolutionLines
].join(`
`);
}
function getInstalledRuntimeVersion(agentRoot) {
try {
const runtimePackagePath = join(agentRoot, "node_modules", "@botpress", "runtime", "package.json");
if (!existsSync(runtimePackagePath)) {
return null;
}
const packageJson = JSON.parse(readFileSync(runtimePackagePath, "utf-8"));
return packageJson.version;
} catch {
return null;
}
}
function getRuntimeVersionStatus(installedVersion, expectedVersion) {
if (!installedVersion) {
return "not_installed";
}
const expected = semver2.parse(expectedVersion);
const installed = semver2.parse(installedVersion);
if (!expected || !installed) {
return "invalid";
}
return getRuntimeCompatibilityStatus(installed, expected);
}
function getRuntimeMajor(version) {
return semver2.parse(version)?.major ?? null;
}
function getRuntimeMajorRelation(installedVersion, expectedVersion) {
const expected = semver2.parse(expectedVersion);
const installed = installedVersion ? semver2.parse(installedVersion) : null;
if (!expected || !installed) {
return "unknown";
}
if (installed.major < expected.major) {
return "older";
}
if (installed.major > expected.major) {
return "newer";
}
return "same";
}
function isRuntimeVersionCompatible(status) {
return status === "current" || status === "outdated" || status === "newer";
}
function getInstallCommand(agentRoot) {
const managers = detectPackageManagers();
const pm = getPreferredPackageManager(agentRoot, managers);
return pm?.installCommand ?? null;
}
function buildResolution(props) {
const reviewProjectUpgrade = "Run `adk project upgrade --dry-run` to review required project updates.";
const runProjectUpgrade = "Run `adk project upgrade` to apply them.";
const projectUpgradeCommands = ["adk project upgrade --dry-run", "adk project upgrade"];
const runSelfUpgrade = "Run `adk self-upgrade` to update this CLI.";
if (props.status === "current") {
return {
summary: "@botpress/runtime is compatible with this CLI.",
commands: [],
manualSteps: [],
canAutoFix: false
};
}
if (props.status === "outdated") {
return {
summary: "@botpress/runtime is on the expected semver major, but an upgrade is recommended.",
commands: projectUpgradeCommands,
manualSteps: [reviewProjectUpgrade, runProjectUpgrade],
canAutoFix: true
};
}
if (props.status === "newer") {
return {
summary: "@botpress/runtime is on the expected semver major.",
commands: [],
manualSteps: [],
canAutoFix: false
};
}
if (props.status === "not_installed") {
return {
summary: "@botpress/runtime is not installed in this project.",
commands: projectUpgradeCommands,
manualSteps: [reviewProjectUpgrade, runProjectUpgrade],
canAutoFix: true
};
}
if (props.status === "invalid") {
return {
summary: "@botpress/runtime has an invalid version in node_modules.",
commands: projectUpgradeCommands,
manualSteps: [reviewProjectUpgrade, runProjectUpgrade],
canAutoFix: true
};
}
if (props.status === "major_mismatch") {
const majorRelation = getRuntimeMajorRelation(props.installedVersion, props.expectedVersion);
if (majorRelation === "newer") {
const expectedMajor = getRuntimeMajor(props.expectedVersion);
const supportedMajor = expectedMajor !== null ? `${expectedMajor}.x` : `v${props.expectedVersion}`;
return {
summary: `This project's runtime (v${props.installedVersion}) is newer than this CLI supports.`,
commands: ["adk self-upgrade"],
manualSteps: [
runSelfUpgrade,
`If you intentionally need this older CLI line, pin the project runtime back to supported major ${supportedMajor}.`
],
canAutoFix: false
};
}
return {
summary: "The project runtime is on a different semver major than this CLI.",
commands: projectUpgradeCommands,
manualSteps: [reviewProjectUpgrade, runProjectUpgrade],
canAutoFix: true
};
}
return {
summary: "@botpress/runtime compatibility could not be determined.",
commands: projectUpgradeCommands,
manualSteps: [reviewProjectUpgrade, runProjectUpgrade],
canAutoFix: true
};
}
function getRuntimeVersionReport(agentRoot) {
const expectedVersion = EXPECTED_RUNTIME_VERSION;
const installedVersion = getInstalledRuntimeVersion(agentRoot);
const installCommand = getInstallCommand(agentRoot) || "npm install";
const expectedMajor = getRuntimeMajor(expectedVersion);
const status = getRuntimeVersionStatus(installedVersion, expectedVersion);
return {
installedVersion,
expectedVersion,
expectedMajor,
status,
compatible: isRuntimeVersionCompatible(status),
installCommand,
resolution: buildResolution({
status,
installedVersion,
expectedVersion,
installCommand
})
};
}
function preflightRuntimeVersionCheck(agentRoot) {
const report = getRuntimeVersionReport(agentRoot);
if (report.compatible) {
return report;
}
throw new RuntimeVersionMismatchError(report.installedVersion ?? "<not installed>", report.expectedVersion, report.installCommand, report);
}
export { RuntimeVersionMismatchError, formatRuntimeVersionMismatchMessage, getInstalledRuntimeVersion, getRuntimeVersionStatus, getRuntimeMajor, getRuntimeMajorRelation, getRuntimeVersionReport, preflightRuntimeVersionCheck };