@botpress/adk-cli
Version:
Command-line interface for the Botpress Agent Development Kit (ADK)
193 lines (186 loc) • 5.64 kB
JavaScript
// @bun
import {
getAdkVersion
} from "./chunk-26vqkz52.js";
import {
detectPackageManagers,
getPreferredPackageManager
} from "./chunk-nbasj5jm.js";
import {
ne
} from "./chunk-6w0knnta.js";
// src/utils/external-harness-capabilities.ts
import { exec } from "child_process";
import { promisify } from "util";
// src/utils/fetch-commands.ts
import { existsSync, mkdirSync, writeFileSync } from "fs";
import { basename, join } from "path";
// src/utils/skills-ref.ts
function getSkillsGitRef() {
const version = getAdkVersion();
if (version === "0.0.0") {
return "dev";
}
return `v${version}`;
}
function getSkillsRepoRef() {
const version = getAdkVersion();
if (version === "0.0.0") {
return "botpress/skills#dev";
}
return `botpress/skills@v${version}`;
}
// src/utils/fetch-commands.ts
var REPO = "botpress/skills";
var COMMANDS_DIR = "commands";
var REQUEST_TIMEOUT_MS = 15000;
function getGithubRawBase() {
return `https://raw.githubusercontent.com/${REPO}/${getSkillsGitRef()}/${COMMANDS_DIR}`;
}
var TARGET_DIRS = {
"claude-code": ".claude/commands",
opencode: ".opencode/commands",
cursor: ".cursor/commands"
};
var ALL_TARGETS = Object.keys(TARGET_DIRS);
var ManifestEntrySchema = ne.object({
name: ne.string(),
path: ne.string(),
description: ne.string()
});
var ManifestSchema = ne.object({
commands: ne.array(ManifestEntrySchema)
});
function isManifest(value) {
return ManifestSchema.safeParse(value).success;
}
async function fetchWithTimeout(url, timeoutMs) {
const controller = new AbortController;
const timer = setTimeout(() => controller.abort(), timeoutMs);
try {
return await fetch(url, { signal: controller.signal });
} finally {
clearTimeout(timer);
}
}
async function fetchManifest() {
try {
const res = await fetchWithTimeout(`${getGithubRawBase()}/manifest.json`, REQUEST_TIMEOUT_MS);
if (!res.ok) {
return null;
}
const data = await res.json();
if (!isManifest(data)) {
return null;
}
return data;
} catch {
return null;
}
}
function listCommandFiles(manifest) {
if (manifest && manifest.commands.length > 0) {
return manifest.commands.map((entry) => entry.path);
}
return [];
}
async function downloadCommand(filePath) {
try {
const res = await fetchWithTimeout(`${getGithubRawBase()}/${filePath}`, REQUEST_TIMEOUT_MS);
if (!res.ok) {
return null;
}
return await res.text();
} catch {
return null;
}
}
async function installCommands(projectPath, targets) {
const result = { attempted: true, success: true, installedCommands: 0, failed: 0 };
const targetPaths = targets.map((t) => join(projectPath, TARGET_DIRS[t]));
for (const dir of targetPaths) {
if (!existsSync(dir)) {
mkdirSync(dir, { recursive: true });
}
}
const manifest = await fetchManifest();
const filenames = listCommandFiles(manifest);
const downloads = await Promise.all(filenames.map(async (filePath) => {
const content = await downloadCommand(filePath);
return { filePath, content };
}));
for (const { filePath, content } of downloads) {
if (content === null) {
result.failed += 1;
continue;
}
const outputName = basename(filePath);
for (const dir of targetPaths) {
writeFileSync(join(dir, outputName), content);
}
result.installedCommands += 1;
}
if (result.installedCommands === 0) {
result.success = false;
result.error = "Could not download any command files from GitHub";
}
return result;
}
// src/utils/external-harness-capabilities.ts
var execAsync = promisify(exec);
async function installExternalHarnessCapabilities(options) {
const commandTargets = options.commandTargets ?? ALL_TARGETS;
const skillsCommand = buildExternalHarnessSkillsCommand(options.projectPath, options.packageManagerCommand);
const skills = {
attempted: true,
success: true,
command: skillsCommand
};
try {
if (options.runCommand) {
await options.runCommand(skillsCommand, options.projectPath);
} else {
await execAsync(skillsCommand, {
cwd: options.projectPath,
env: { ...process.env },
timeout: 120000
});
}
} catch (error) {
skills.success = false;
const stderr = error instanceof Error && "stderr" in error && error.stderr ? String(error.stderr).trim() : undefined;
skills.error = stderr || (error instanceof Error ? error.message : String(error));
}
let commands = { attempted: false, success: true, installedCommands: 0, failed: 0 };
if (commandTargets.length > 0) {
try {
commands = await installCommands(options.projectPath, commandTargets);
} catch (error) {
commands = {
attempted: true,
success: false,
installedCommands: 0,
failed: 0,
error: error instanceof Error ? error.message : String(error)
};
}
}
return {
success: skills.success && commands.success,
skills,
commands
};
}
function buildExternalHarnessSkillsCommand(projectPath, packageManagerCommand) {
const skillsRunner = getSkillsRunner(projectPath, packageManagerCommand);
return `${skillsRunner} skills add ${getSkillsRepoRef()} -s '*' -a codex claude-code -y`;
}
function getSkillsRunner(projectPath, packageManagerCommand) {
if (packageManagerCommand) {
return packageManagerCommand === "bun" ? "bunx" : "npx";
}
const managers = detectPackageManagers();
const preferred = getPreferredPackageManager(projectPath, managers);
return preferred?.command === "bun" ? "bunx" : "npx";
}
export { installExternalHarnessCapabilities };