import type { RuneConfig } from "../types.ts"; export const DEFAULT_PREFIX = "bunx @lanyuanxiaoyao/rune"; export function inferFromEnvironment( execPath: string, userAgent: string | undefined, ): string | null { if (execPath.includes("bun")) return "bunx @lanyuanxiaoyao/rune"; if (userAgent?.includes("pnpm")) return "pnpx @lanyuanxiaoyao/rune"; if (userAgent?.includes("npm")) return "npx @lanyuanxiaoyao/rune"; return null; } export async function checkCommandAvailable(command: string): Promise { const which = process.platform === "win32" ? "where" : "which"; try { const proc = Bun.spawn([which, command], { stdout: "ignore", stderr: "ignore", }); const exitCode = await proc.exited; return exitCode === 0; } catch { return false; } } export async function detectCommandPrefix(): Promise { if (await checkCommandAvailable("rune")) return "rune"; const inferred = inferFromEnvironment(process.execPath, process.env.npm_config_user_agent); if (inferred) return inferred; for (const pm of ["bunx", "pnpx", "npx"]) { if (await checkCommandAvailable(pm)) return `${pm} @lanyuanxiaoyao/rune`; } return null; } export function getPmPrefix(config?: RuneConfig): string { return config?.metadata?.command ?? DEFAULT_PREFIX; } export function getFallbackNote(): string { return `如果没有安装 bun,可使用 \`pnpx @lanyuanxiaoyao/rune\` 或 \`npx @lanyuanxiaoyao/rune\` 替代`; } export function applyCommandPrefix(text: string, config?: RuneConfig): string { const prefix = getPmPrefix(config); const hasCommand = /\brune(?=\s)/.test(text); const result = text.replace(/\brune(?=\s)/g, prefix); if (!config?.metadata?.command && hasCommand) { return result + "\n\n" + getFallbackNote(); } return result; }