feat: automated completion setup in postinstall and onboarding

This commit is contained in:
Shakker
2026-01-31 04:45:11 +00:00
committed by Shakker
parent 48aaf6ce4e
commit b1d25ed0dd
2 changed files with 38 additions and 0 deletions

View File

@@ -248,12 +248,37 @@ function applyPatchFile({ patchPath, targetDir }) {
applyPatchSet({ patchText, targetDir });
}
function trySetupCompletion(repoRoot) {
// Skip in CI or if explicitly disabled
if (process.env.CI || process.env.OPENCLAW_SKIP_COMPLETION_SETUP) return;
const binPath = path.join(repoRoot, "openclaw.mjs");
if (!fs.existsSync(binPath)) return;
// In development, dist might not exist yet during postinstall
const distEntry = path.join(repoRoot, "dist", "index.js");
if (!fs.existsSync(distEntry)) return;
try {
// Run with OPENCLAW_SKIP_POSTINSTALL to avoid any weird recursion,
// though distinct from this script.
spawnSync(process.execPath, [binPath, "completion", "--install", "--yes"], {
cwd: repoRoot,
stdio: "inherit",
env: { ...process.env, OPENCLAW_SKIP_POSTINSTALL: "1" },
});
} catch (err) {
// Ignore errors to not break install
}
}
function main() {
const repoRoot = getRepoRoot();
process.chdir(repoRoot);
ensureExecutable(path.join(repoRoot, "dist", "entry.js"));
setupGitHooks({ repoRoot });
trySetupCompletion(repoRoot);
if (!shouldApplyPnpmPatchedDependenciesFallback()) {
return;

View File

@@ -42,6 +42,7 @@ import { finalizeOnboardingWizard } from "./onboarding.finalize.js";
import { configureGatewayForOnboarding } from "./onboarding.gateway-config.js";
import type { QuickstartGatewayDefaults, WizardFlow } from "./onboarding.types.js";
import { WizardCancelledError, type WizardPrompter } from "./prompts.js";
import { installCompletion } from "../cli/completion-cli.js";
async function requireRiskAcknowledgement(params: {
opts: OnboardOptions;
@@ -448,4 +449,16 @@ export async function runOnboardingWizard(
prompter,
runtime,
});
const installShell = await prompter.confirm({
message: "Install shell completion script?",
initialValue: true,
});
if (installShell) {
const shell = process.env.SHELL?.split("/").pop() || "zsh";
// We pass 'yes=true' to skip any double-confirmation inside the helper,
// as the wizard prompt above serves as confirmation.
await installCompletion(shell, true);
}
}