UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

140 lines (139 loc) 6.16 kB
import { t as resolveOpenClawPackageRoot } from "./openclaw-root-CNp1Ofdk.js"; import { n as resolveCliName } from "./cli-name-CAJoj2J5.js"; import { t as note } from "./note-BRSJp0UF.js"; import { a as installCompletion, c as resolveCompletionCachePath, d as usesSlowDynamicCompletion, i as formatCompletionReloadCommand, l as resolveCompletionProfilePath, o as isCompletionInstalled, r as completionCacheExists, u as resolveShellFromEnv } from "./completion-runtime-CTM38KC1.js"; import path from "node:path"; import { spawnSync } from "node:child_process"; //#region src/commands/doctor-completion.ts /** Doctor checks and repair effects for cached shell completion setup. */ const COMPLETION_CACHE_WRITE_TIMEOUT_MS = 3e4; function resolveCompletionReloadPath(shell) { if (shell === "powershell") return resolveCompletionProfilePath("powershell"); return `~/.${shell === "zsh" ? "zshrc" : shell === "bash" ? "bashrc" : "config/fish/config.fish"}`; } function formatCompletionReloadNote(shell, action) { return `Shell completion ${action}. Restart your shell or run: ${formatCompletionReloadCommand(shell, resolveCompletionReloadPath(shell))}`; } /** Generate the completion cache by spawning the CLI. */ async function generateCompletionCache() { const root = await resolveOpenClawPackageRoot({ moduleUrl: import.meta.url, argv1: process.argv[1], cwd: process.cwd() }); if (!root) return false; const binPath = path.join(root, "openclaw.mjs"); return spawnSync(process.execPath, [ binPath, "completion", "--write-state" ], { cwd: root, env: process.env, encoding: "utf-8", timeout: COMPLETION_CACHE_WRITE_TIMEOUT_MS }).status === 0; } /** Check the status of shell completion for the current shell. */ async function checkShellCompletionStatus(binName = "openclaw") { const shell = resolveShellFromEnv(); return { shell, profileInstalled: await isCompletionInstalled(shell, binName), cacheExists: await completionCacheExists(shell, binName), cachePath: resolveCompletionCachePath(shell, binName), usesSlowPattern: await usesSlowDynamicCompletion(shell, binName) }; } /** Converts shell completion status into health findings shown by check flows. */ function shellCompletionStatusToHealthFindings(status) { const checkId = "core/doctor/shell-completion"; const pathLocal = `shellCompletion.${status.shell}`; if (status.usesSlowPattern) return [{ checkId, severity: "info", message: `Your ${status.shell} profile uses slow dynamic completion (source <(...)).`, path: pathLocal, fixHint: "Run `openclaw doctor --fix` to upgrade to cached completion." }]; if (status.profileInstalled && !status.cacheExists) return [{ checkId, severity: "info", message: `Shell completion is configured in your ${status.shell} profile but the cache is missing.`, path: pathLocal, fixHint: `Run \`openclaw completion --write-state\` or \`openclaw doctor --fix\` to regenerate ${status.cachePath}.` }]; return []; } /** Converts shell completion status into dry-run repair effects for health check reporting. */ function shellCompletionStatusToRepairEffects(status) { const effects = []; if (status.usesSlowPattern && !status.cacheExists) effects.push({ kind: "state", action: "would-generate-completion-cache", target: status.cachePath, dryRunSafe: true }); if (status.usesSlowPattern) effects.push({ kind: "file", action: "would-upgrade-shell-profile-completion", target: status.shell, dryRunSafe: false }); else if (status.profileInstalled && !status.cacheExists) effects.push({ kind: "state", action: "would-regenerate-completion-cache", target: status.cachePath, dryRunSafe: true }); return effects; } /** * Repairs shell completion setup when doctor runs interactively. * * Slow dynamic profiles are upgraded to cached completion; configured profiles with a missing * cache regenerate it; missing completion prompts unless non-interactive mode is active. */ async function doctorShellCompletion(_runtime, prompter, options = {}) { const cliName = resolveCliName(); const status = await checkShellCompletionStatus(cliName); if (status.usesSlowPattern) { note(`Your ${status.shell} profile uses slow dynamic completion (source <(...)).\nUpgrading to cached completion for faster shell startup...`, "Shell completion"); if (!status.cacheExists) { if (!await generateCompletionCache()) { note(`Failed to generate completion cache. Run \`${cliName} completion --write-state\` manually.`, "Shell completion"); return; } } await installCompletion(status.shell, true, cliName); note(formatCompletionReloadNote(status.shell, "upgraded"), "Shell completion"); return; } if (status.profileInstalled && !status.cacheExists) { note(`Shell completion is configured in your ${status.shell} profile but the cache is missing.\nRegenerating cache...`, "Shell completion"); if (await generateCompletionCache()) note(`Completion cache regenerated at ${status.cachePath}`, "Shell completion"); else note(`Failed to regenerate completion cache. Run \`${cliName} completion --write-state\` manually.`, "Shell completion"); return; } if (!status.profileInstalled) { if (options.nonInteractive) return; if (await prompter.confirm({ message: `Enable ${status.shell} shell completion for ${cliName}?`, initialValue: true })) { if (!await generateCompletionCache()) { note(`Failed to generate completion cache. Run \`${cliName} completion --write-state\` manually.`, "Shell completion"); return; } await installCompletion(status.shell, true, cliName); note(formatCompletionReloadNote(status.shell, "installed"), "Shell completion"); } } } /** Ensures the shell completion cache exists without prompting during setup/update flows. */ async function ensureCompletionCacheExists(binName = "openclaw") { if (await completionCacheExists(resolveShellFromEnv(), binName)) return true; return generateCompletionCache(); } //#endregion export { shellCompletionStatusToRepairEffects as a, shellCompletionStatusToHealthFindings as i, doctorShellCompletion as n, ensureCompletionCacheExists as r, checkShellCompletionStatus as t };