
























@@ -63,17 +63,31 @@ export async function completionCacheExists(
6363return pathExists(cachePath);
6464}
656566-function formatCompletionSourceLine(
66+function escapePowerShellSingleQuotedString(value: string): string {
67+return value.replace(/'/g, "''");
68+}
69+70+export function formatCompletionSourceLine(
6771shell: CompletionShell,
6872_binName: string,
6973cachePath: string,
7074): string {
75+if (shell === "powershell") {
76+return `. '${escapePowerShellSingleQuotedString(cachePath)}'`;
77+}
7178if (shell === "fish") {
7279return `test -f "${cachePath}"; and source "${cachePath}"`;
7380}
7481return `[ -f "${cachePath}" ] && source "${cachePath}"`;
7582}
768384+export function formatCompletionReloadCommand(shell: CompletionShell, profilePath: string): string {
85+if (shell === "powershell") {
86+return `. '${escapePowerShellSingleQuotedString(profilePath)}'`;
87+}
88+return `source ${profilePath}`;
89+}
90+7791function isCompletionProfileHeader(line: string): boolean {
7892return line.trim() === "# OpenClaw Completion";
7993}
@@ -126,8 +140,18 @@ function updateCompletionProfile(
126140return { next, changed: next !== content, hadExisting };
127141}
128142129-function getShellProfilePath(shell: CompletionShell): string {
130-const home = process.env.HOME || os.homedir();
143+export function resolveCompletionProfilePath(
144+shell: CompletionShell,
145+options: {
146+env?: NodeJS.ProcessEnv;
147+homeDir?: () => string;
148+platform?: NodeJS.Platform;
149+} = {},
150+): string {
151+const env = options.env ?? process.env;
152+const homeDir = options.homeDir ?? os.homedir;
153+const platform = options.platform ?? process.platform;
154+const home = env.HOME || homeDir();
131155if (shell === "zsh") {
132156return path.join(home, ".zshrc");
133157}
@@ -137,9 +161,9 @@ function getShellProfilePath(shell: CompletionShell): string {
137161if (shell === "fish") {
138162return path.join(home, ".config", "fish", "config.fish");
139163}
140-if (process.platform === "win32") {
141-return path.join(
142-process.env.USERPROFILE || home,
164+if (platform === "win32") {
165+return path.win32.join(
166+env.USERPROFILE || home,
143167"Documents",
144168"PowerShell",
145169"Microsoft.PowerShell_profile.ps1",
@@ -152,7 +176,7 @@ export async function isCompletionInstalled(
152176shell: CompletionShell,
153177binName = "openclaw",
154178): Promise<boolean> {
155-const profilePath = getShellProfilePath(shell);
179+const profilePath = resolveCompletionProfilePath(shell);
156180157181if (!(await pathExists(profilePath))) {
158182return false;
@@ -174,7 +198,7 @@ export async function usesSlowDynamicCompletion(
174198shell: CompletionShell,
175199binName = "openclaw",
176200): Promise<boolean> {
177-const profilePath = getShellProfilePath(shell);
201+const profilePath = resolveCompletionProfilePath(shell);
178202179203if (!(await pathExists(profilePath))) {
180204return false;
@@ -193,7 +217,6 @@ export async function usesSlowDynamicCompletion(
193217}
194218195219export async function installCompletion(shell: string, yes: boolean, binName = "openclaw") {
196-const home = process.env.HOME || os.homedir();
197220let profilePath = "";
198221let sourceLine = "";
199222@@ -213,19 +236,23 @@ export async function installCompletion(shell: string, yes: boolean, binName = "
213236}
214237215238if (shell === "zsh") {
216-profilePath = path.join(home, ".zshrc");
239+profilePath = resolveCompletionProfilePath("zsh");
217240sourceLine = formatCompletionSourceLine("zsh", binName, cachePath);
218241} else if (shell === "bash") {
219-profilePath = path.join(home, ".bashrc");
242+profilePath = resolveCompletionProfilePath("bash");
220243try {
221244await fs.access(profilePath);
222245} catch {
246+const home = process.env.HOME || os.homedir();
223247profilePath = path.join(home, ".bash_profile");
224248}
225249sourceLine = formatCompletionSourceLine("bash", binName, cachePath);
226250} else if (shell === "fish") {
227-profilePath = path.join(home, ".config", "fish", "config.fish");
251+profilePath = resolveCompletionProfilePath("fish");
228252sourceLine = formatCompletionSourceLine("fish", binName, cachePath);
253+} else if (shell === "powershell") {
254+profilePath = resolveCompletionProfilePath("powershell");
255+sourceLine = formatCompletionSourceLine("powershell", binName, cachePath);
229256} else {
230257console.error(`Automated installation not supported for ${shell} yet.`);
231258return;
@@ -258,7 +285,9 @@ export async function installCompletion(shell: string, yes: boolean, binName = "
258285259286await fs.writeFile(profilePath, update.next, "utf-8");
260287if (!yes) {
261-console.log(`Completion installed. Restart your shell or run: source ${profilePath}`);
288+console.log(
289+`Completion installed. Restart your shell or run: ${formatCompletionReloadCommand(shell, profilePath)}`,
290+);
262291}
263292} catch (err) {
264293console.error(`Failed to install completion: ${err as string}`);
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。