@heretek-ai/openclaw 2026.3.27 → 2026.3.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/.buildstamp CHANGED
@@ -1 +1 @@
1
- {"builtAt":1774362789993,"head":"8c105a767e34dbbc950e52858cad6e5623429498"}
1
+ {"builtAt":1774369832018,"head":"11cc5e788a005e7630206b618fa8b88ecce3f492"}
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2026.3.27",
3
- "commit": "8c105a767e34dbbc950e52858cad6e5623429498",
4
- "builtAt": "2026-03-24T14:33:21.569Z"
2
+ "version": "2026.3.29",
3
+ "commit": "11cc5e788a005e7630206b618fa8b88ecce3f492",
4
+ "builtAt": "2026-03-24T16:31:01.165Z"
5
5
  }
@@ -1 +1 @@
1
- b47b4db97ef184c2e90e6ad571812c36b72ba9f7830ef171e852a14d67e3ab53
1
+ aefce4b5c9c1dc074a16e39a314f70b2bf435c912926142a174cbb3f7ec5e665
@@ -0,0 +1,214 @@
1
+ import { E as getPrimaryCommand, k as hasHelpOrVersion } from "./logger-vRSRu9wD.mjs";
2
+ import { a as removeCommandByName, i as registerSubCliCommands, o as reparseProgramFromActionArgs } from "./register.subclis-CVkk-8A3.mjs";
3
+ import { t as getCoreCliCommandDescriptors } from "./core-command-descriptors-TFRcY_t7.mjs";
4
+
5
+ //#region src/cli/program/command-registry.ts
6
+ const shouldRegisterCorePrimaryOnly = (argv) => {
7
+ if (hasHelpOrVersion(argv)) return false;
8
+ return true;
9
+ };
10
+ const coreEntries = [
11
+ {
12
+ commands: [{
13
+ name: "setup",
14
+ description: "Initialize local config and agent workspace",
15
+ hasSubcommands: false
16
+ }],
17
+ register: async ({ program }) => {
18
+ (await import("./register.setup-BqV-_yA8.mjs")).registerSetupCommand(program);
19
+ }
20
+ },
21
+ {
22
+ commands: [{
23
+ name: "onboard",
24
+ description: "Interactive onboarding for gateway, workspace, and skills",
25
+ hasSubcommands: false
26
+ }],
27
+ register: async ({ program }) => {
28
+ (await import("./register.onboard-D128_sx4.mjs")).registerOnboardCommand(program);
29
+ }
30
+ },
31
+ {
32
+ commands: [{
33
+ name: "configure",
34
+ description: "Interactive configuration for credentials, channels, gateway, and agent defaults",
35
+ hasSubcommands: false
36
+ }],
37
+ register: async ({ program }) => {
38
+ (await import("./register.configure-zvnV2PSt.mjs")).registerConfigureCommand(program);
39
+ }
40
+ },
41
+ {
42
+ commands: [{
43
+ name: "config",
44
+ description: "Non-interactive config helpers (get/set/unset/file/validate). Default: starts guided setup.",
45
+ hasSubcommands: true
46
+ }],
47
+ register: async ({ program }) => {
48
+ (await import("./config-cli-BOBQYttC.mjs")).registerConfigCli(program);
49
+ }
50
+ },
51
+ {
52
+ commands: [{
53
+ name: "backup",
54
+ description: "Create and verify local backup archives for OpenClaw state",
55
+ hasSubcommands: true
56
+ }],
57
+ register: async ({ program }) => {
58
+ (await import("./register.backup-xkhaqqi_.mjs")).registerBackupCommand(program);
59
+ }
60
+ },
61
+ {
62
+ commands: [
63
+ {
64
+ name: "doctor",
65
+ description: "Health checks + quick fixes for the gateway and channels",
66
+ hasSubcommands: false
67
+ },
68
+ {
69
+ name: "dashboard",
70
+ description: "Open the Control UI with your current token",
71
+ hasSubcommands: false
72
+ },
73
+ {
74
+ name: "reset",
75
+ description: "Reset local config/state (keeps the CLI installed)",
76
+ hasSubcommands: false
77
+ },
78
+ {
79
+ name: "uninstall",
80
+ description: "Uninstall the gateway service + local data (CLI remains)",
81
+ hasSubcommands: false
82
+ }
83
+ ],
84
+ register: async ({ program }) => {
85
+ (await import("./register.maintenance-BdaRRBo0.mjs")).registerMaintenanceCommands(program);
86
+ }
87
+ },
88
+ {
89
+ commands: [{
90
+ name: "message",
91
+ description: "Send, read, and manage messages",
92
+ hasSubcommands: true
93
+ }],
94
+ register: async ({ program, ctx }) => {
95
+ (await import("./register.message-xPNqGndv.mjs")).registerMessageCommands(program, ctx);
96
+ }
97
+ },
98
+ {
99
+ commands: [{
100
+ name: "memory",
101
+ description: "Search and reindex memory files",
102
+ hasSubcommands: true
103
+ }],
104
+ register: async ({ program }) => {
105
+ (await import("../cli/memory-cli.mjs")).registerMemoryCli(program);
106
+ }
107
+ },
108
+ {
109
+ commands: [{
110
+ name: "mcp",
111
+ description: "Manage embedded Pi MCP servers",
112
+ hasSubcommands: true
113
+ }],
114
+ register: async ({ program }) => {
115
+ (await import("./mcp-cli-C-78eMUr.mjs")).registerMcpCli(program);
116
+ }
117
+ },
118
+ {
119
+ commands: [{
120
+ name: "agent",
121
+ description: "Run one agent turn via the Gateway",
122
+ hasSubcommands: false
123
+ }, {
124
+ name: "agents",
125
+ description: "Manage isolated agents (workspaces, auth, routing)",
126
+ hasSubcommands: true
127
+ }],
128
+ register: async ({ program, ctx }) => {
129
+ (await import("./register.agent-CfJLdlXL.mjs")).registerAgentCommands(program, { agentChannelOptions: ctx.agentChannelOptions });
130
+ }
131
+ },
132
+ {
133
+ commands: [
134
+ {
135
+ name: "status",
136
+ description: "Show channel health and recent session recipients",
137
+ hasSubcommands: false
138
+ },
139
+ {
140
+ name: "health",
141
+ description: "Fetch health from the running gateway",
142
+ hasSubcommands: false
143
+ },
144
+ {
145
+ name: "sessions",
146
+ description: "List stored conversation sessions",
147
+ hasSubcommands: true
148
+ }
149
+ ],
150
+ register: async ({ program }) => {
151
+ (await import("./register.status-health-sessions-BzfZ47A5.mjs")).registerStatusHealthSessionsCommands(program);
152
+ }
153
+ },
154
+ {
155
+ commands: [{
156
+ name: "browser",
157
+ description: "Manage OpenClaw's dedicated browser (Chrome/Chromium)",
158
+ hasSubcommands: true
159
+ }],
160
+ register: async ({ program }) => {
161
+ (await import("./browser-cli-Dh3oTAem.mjs")).registerBrowserCli(program);
162
+ }
163
+ }
164
+ ];
165
+ function getCoreCliCommandNames() {
166
+ return getCoreCliCommandDescriptors().map((command) => command.name);
167
+ }
168
+ function removeEntryCommands(program, entry) {
169
+ for (const cmd of entry.commands) removeCommandByName(program, cmd.name);
170
+ }
171
+ function registerLazyCoreCommand(program, ctx, entry, command) {
172
+ const placeholder = program.command(command.name).description(command.description);
173
+ placeholder.allowUnknownOption(true);
174
+ placeholder.allowExcessArguments(true);
175
+ placeholder.action(async (...actionArgs) => {
176
+ removeEntryCommands(program, entry);
177
+ await entry.register({
178
+ program,
179
+ ctx,
180
+ argv: process.argv
181
+ });
182
+ await reparseProgramFromActionArgs(program, actionArgs);
183
+ });
184
+ }
185
+ async function registerCoreCliByName(program, ctx, name, argv = process.argv) {
186
+ const entry = coreEntries.find((candidate) => candidate.commands.some((cmd) => cmd.name === name));
187
+ if (!entry) return false;
188
+ removeEntryCommands(program, entry);
189
+ await entry.register({
190
+ program,
191
+ ctx,
192
+ argv
193
+ });
194
+ return true;
195
+ }
196
+ function registerCoreCliCommands(program, ctx, argv) {
197
+ const primary = getPrimaryCommand(argv);
198
+ if (primary && shouldRegisterCorePrimaryOnly(argv)) {
199
+ const entry = coreEntries.find((candidate) => candidate.commands.some((cmd) => cmd.name === primary));
200
+ if (entry) {
201
+ const cmd = entry.commands.find((c) => c.name === primary);
202
+ if (cmd) registerLazyCoreCommand(program, ctx, entry, cmd);
203
+ return;
204
+ }
205
+ }
206
+ for (const entry of coreEntries) for (const cmd of entry.commands) registerLazyCoreCommand(program, ctx, entry, cmd);
207
+ }
208
+ function registerProgramCommands(program, ctx, argv = process.argv) {
209
+ registerCoreCliCommands(program, ctx, argv);
210
+ registerSubCliCommands(program, argv);
211
+ }
212
+
213
+ //#endregion
214
+ export { registerProgramCommands as i, registerCoreCliByName as n, registerCoreCliCommands as r, getCoreCliCommandNames as t };
@@ -0,0 +1,14 @@
1
+ import "./logger-vRSRu9wD.mjs";
2
+ import "./paths-CNST7z3O.mjs";
3
+ import "./tmp-openclaw-dir-BeWwpCKM.mjs";
4
+ import "./theme-w86ra_7m.mjs";
5
+ import "./globals-DZFR3wyP.mjs";
6
+ import "./subsystem-yLe4Gjha.mjs";
7
+ import "./ansi-BJ9IOlIp.mjs";
8
+ import "./boolean-Bwxxidw8.mjs";
9
+ import "./env-9fhyzTaG.mjs";
10
+ import "./register.subclis-CVkk-8A3.mjs";
11
+ import { n as getCoreCliCommandsWithSubcommands, t as getCoreCliCommandDescriptors } from "./core-command-descriptors-TFRcY_t7.mjs";
12
+ import { i as registerProgramCommands, n as registerCoreCliByName, r as registerCoreCliCommands, t as getCoreCliCommandNames } from "./command-registry-B9Orjysx.mjs";
13
+
14
+ export { registerCoreCliByName };
@@ -0,0 +1,448 @@
1
+ import { _ as resolveStateDir } from "./paths-CNST7z3O.mjs";
2
+ import { r as theme } from "./theme-w86ra_7m.mjs";
3
+ import { c as routeLogsToStderr } from "./subsystem-yLe4Gjha.mjs";
4
+ import { h as pathExists } from "./utils-Dc9DiBqf.mjs";
5
+ import { t as formatDocsLink } from "./links-BNNF54ea.mjs";
6
+ import { r as registerSubCliByName, t as getSubCliEntries } from "./register.subclis-CVkk-8A3.mjs";
7
+ import { n as registerCoreCliByName, t as getCoreCliCommandNames } from "./command-registry-B9Orjysx.mjs";
8
+ import { t as getProgramContext } from "./program-context-9v4H9od4.mjs";
9
+ import path from "node:path";
10
+ import os from "node:os";
11
+ import fs from "node:fs/promises";
12
+ import { Option } from "commander";
13
+
14
+ //#region src/cli/completion-fish.ts
15
+ function escapeFishDescription(value) {
16
+ return value.replace(/'/g, "'\\''");
17
+ }
18
+ function parseOptionFlags(flags) {
19
+ const parts = flags.split(/[ ,|]+/);
20
+ return {
21
+ long: parts.find((flag) => flag.startsWith("--"))?.replace(/^--/, ""),
22
+ short: parts.find((flag) => flag.startsWith("-") && !flag.startsWith("--"))?.replace(/^-/, "")
23
+ };
24
+ }
25
+ function buildFishSubcommandCompletionLine(params) {
26
+ const desc = escapeFishDescription(params.description);
27
+ return `complete -c ${params.rootCmd} -n "${params.condition}" -a "${params.name}" -d '${desc}'\n`;
28
+ }
29
+ function buildFishOptionCompletionLine(params) {
30
+ const { short, long } = parseOptionFlags(params.flags);
31
+ const desc = escapeFishDescription(params.description);
32
+ let line = `complete -c ${params.rootCmd} -n "${params.condition}"`;
33
+ if (short) line += ` -s ${short}`;
34
+ if (long) line += ` -l ${long}`;
35
+ line += ` -d '${desc}'\n`;
36
+ return line;
37
+ }
38
+
39
+ //#endregion
40
+ //#region src/cli/completion-cli.ts
41
+ const COMPLETION_SHELLS = [
42
+ "zsh",
43
+ "bash",
44
+ "powershell",
45
+ "fish"
46
+ ];
47
+ function isCompletionShell(value) {
48
+ return COMPLETION_SHELLS.includes(value);
49
+ }
50
+ function resolveShellFromEnv(env = process.env) {
51
+ const shellPath = env.SHELL?.trim() ?? "";
52
+ const shellName = shellPath ? path.basename(shellPath).toLowerCase() : "";
53
+ if (shellName === "zsh") return "zsh";
54
+ if (shellName === "bash") return "bash";
55
+ if (shellName === "fish") return "fish";
56
+ if (shellName === "pwsh" || shellName === "powershell") return "powershell";
57
+ return "zsh";
58
+ }
59
+ function sanitizeCompletionBasename(value) {
60
+ const trimmed = value.trim();
61
+ if (!trimmed) return "openclaw";
62
+ return trimmed.replace(/[^a-zA-Z0-9._-]/g, "-");
63
+ }
64
+ function resolveCompletionCacheDir(env = process.env) {
65
+ const stateDir = resolveStateDir(env, os.homedir);
66
+ return path.join(stateDir, "completions");
67
+ }
68
+ function resolveCompletionCachePath(shell, binName) {
69
+ const basename$1 = sanitizeCompletionBasename(binName);
70
+ const extension = shell === "powershell" ? "ps1" : shell === "fish" ? "fish" : shell === "bash" ? "bash" : "zsh";
71
+ return path.join(resolveCompletionCacheDir(), `${basename$1}.${extension}`);
72
+ }
73
+ /** Check if the completion cache file exists for the given shell. */
74
+ async function completionCacheExists(shell, binName = "openclaw") {
75
+ return pathExists(resolveCompletionCachePath(shell, binName));
76
+ }
77
+ function getCompletionScript(shell, program) {
78
+ if (shell === "zsh") return generateZshCompletion(program);
79
+ if (shell === "bash") return generateBashCompletion(program);
80
+ if (shell === "powershell") return generatePowerShellCompletion(program);
81
+ return generateFishCompletion(program);
82
+ }
83
+ async function writeCompletionCache(params) {
84
+ const cacheDir = resolveCompletionCacheDir();
85
+ await fs.mkdir(cacheDir, { recursive: true });
86
+ for (const shell of params.shells) {
87
+ const script = getCompletionScript(shell, params.program);
88
+ const targetPath = resolveCompletionCachePath(shell, params.binName);
89
+ await fs.writeFile(targetPath, script, "utf-8");
90
+ }
91
+ }
92
+ function formatCompletionSourceLine(shell, binName, cachePath) {
93
+ if (shell === "fish") return `source "${cachePath}"`;
94
+ return `source "${cachePath}"`;
95
+ }
96
+ function isCompletionProfileHeader(line) {
97
+ return line.trim() === "# OpenClaw Completion";
98
+ }
99
+ function isCompletionProfileLine(line, binName, cachePath) {
100
+ if (line.includes(`${binName} completion`)) return true;
101
+ if (cachePath && line.includes(cachePath)) return true;
102
+ return false;
103
+ }
104
+ /** Check if a line uses the slow dynamic completion pattern (source <(...)) */
105
+ function isSlowDynamicCompletionLine(line, binName) {
106
+ return line.includes(`<(${binName} completion`) || line.includes(`${binName} completion`) && line.includes("| source");
107
+ }
108
+ function updateCompletionProfile(content, binName, cachePath, sourceLine) {
109
+ const lines = content.split("\n");
110
+ const filtered = [];
111
+ let hadExisting = false;
112
+ for (let i = 0; i < lines.length; i += 1) {
113
+ const line = lines[i] ?? "";
114
+ if (isCompletionProfileHeader(line)) {
115
+ hadExisting = true;
116
+ i += 1;
117
+ continue;
118
+ }
119
+ if (isCompletionProfileLine(line, binName, cachePath)) {
120
+ hadExisting = true;
121
+ continue;
122
+ }
123
+ filtered.push(line);
124
+ }
125
+ const trimmed = filtered.join("\n").trimEnd();
126
+ const block = `# OpenClaw Completion\n${sourceLine}`;
127
+ const next = trimmed ? `${trimmed}\n\n${block}\n` : `${block}\n`;
128
+ return {
129
+ next,
130
+ changed: next !== content,
131
+ hadExisting
132
+ };
133
+ }
134
+ function getShellProfilePath(shell) {
135
+ const home = process.env.HOME || os.homedir();
136
+ if (shell === "zsh") return path.join(home, ".zshrc");
137
+ if (shell === "bash") return path.join(home, ".bashrc");
138
+ if (shell === "fish") return path.join(home, ".config", "fish", "config.fish");
139
+ if (process.platform === "win32") return path.join(process.env.USERPROFILE || home, "Documents", "PowerShell", "Microsoft.PowerShell_profile.ps1");
140
+ return path.join(home, ".config", "powershell", "Microsoft.PowerShell_profile.ps1");
141
+ }
142
+ async function isCompletionInstalled(shell, binName = "openclaw") {
143
+ const profilePath = getShellProfilePath(shell);
144
+ if (!await pathExists(profilePath)) return false;
145
+ const cachePathCandidate = resolveCompletionCachePath(shell, binName);
146
+ const cachedPath = await pathExists(cachePathCandidate) ? cachePathCandidate : null;
147
+ return (await fs.readFile(profilePath, "utf-8")).split("\n").some((line) => isCompletionProfileHeader(line) || isCompletionProfileLine(line, binName, cachedPath));
148
+ }
149
+ /**
150
+ * Check if the profile uses the slow dynamic completion pattern.
151
+ * Returns true if profile has `source <(openclaw completion ...)` instead of cached file.
152
+ */
153
+ async function usesSlowDynamicCompletion(shell, binName = "openclaw") {
154
+ const profilePath = getShellProfilePath(shell);
155
+ if (!await pathExists(profilePath)) return false;
156
+ const cachePath = resolveCompletionCachePath(shell, binName);
157
+ const lines = (await fs.readFile(profilePath, "utf-8")).split("\n");
158
+ for (const line of lines) if (isSlowDynamicCompletionLine(line, binName) && !line.includes(cachePath)) return true;
159
+ return false;
160
+ }
161
+ function registerCompletionCli(program) {
162
+ program.command("completion").description("Generate shell completion script").addHelpText("after", () => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/completion", "docs.openclaw.ai/cli/completion")}\n`).addOption(new Option("-s, --shell <shell>", "Shell to generate completion for (default: zsh)").choices(COMPLETION_SHELLS)).option("-i, --install", "Install completion script to shell profile").option("--write-state", "Write completion scripts to $OPENCLAW_STATE_DIR/completions (no stdout)").option("-y, --yes", "Skip confirmation (non-interactive)", false).action(async (options) => {
163
+ routeLogsToStderr();
164
+ const shell = options.shell ?? "zsh";
165
+ const ctx = getProgramContext(program);
166
+ if (ctx) for (const name of getCoreCliCommandNames()) await registerCoreCliByName(program, ctx, name);
167
+ const entries = getSubCliEntries();
168
+ for (const entry of entries) {
169
+ if (entry.name === "completion") continue;
170
+ await registerSubCliByName(program, entry.name);
171
+ }
172
+ if (options.writeState) await writeCompletionCache({
173
+ program,
174
+ shells: options.shell ? [shell] : [...COMPLETION_SHELLS],
175
+ binName: program.name()
176
+ });
177
+ if (options.install) {
178
+ await installCompletion(options.shell ?? resolveShellFromEnv(), Boolean(options.yes), program.name());
179
+ return;
180
+ }
181
+ if (options.writeState) return;
182
+ if (!isCompletionShell(shell)) throw new Error(`Unsupported shell: ${shell}`);
183
+ const script = getCompletionScript(shell, program);
184
+ process.stdout.write(script + "\n");
185
+ });
186
+ }
187
+ async function installCompletion(shell, yes, binName = "openclaw") {
188
+ const home = process.env.HOME || os.homedir();
189
+ let profilePath = "";
190
+ let sourceLine = "";
191
+ if (!isCompletionShell(shell)) {
192
+ console.error(`Automated installation not supported for ${shell} yet.`);
193
+ return;
194
+ }
195
+ const cachePath = resolveCompletionCachePath(shell, binName);
196
+ if (!await pathExists(cachePath)) {
197
+ console.error(`Completion cache not found at ${cachePath}. Run \`${binName} completion --write-state\` first.`);
198
+ return;
199
+ }
200
+ if (shell === "zsh") {
201
+ profilePath = path.join(home, ".zshrc");
202
+ sourceLine = formatCompletionSourceLine("zsh", binName, cachePath);
203
+ } else if (shell === "bash") {
204
+ profilePath = path.join(home, ".bashrc");
205
+ try {
206
+ await fs.access(profilePath);
207
+ } catch {
208
+ profilePath = path.join(home, ".bash_profile");
209
+ }
210
+ sourceLine = formatCompletionSourceLine("bash", binName, cachePath);
211
+ } else if (shell === "fish") {
212
+ profilePath = path.join(home, ".config", "fish", "config.fish");
213
+ sourceLine = formatCompletionSourceLine("fish", binName, cachePath);
214
+ } else {
215
+ console.error(`Automated installation not supported for ${shell} yet.`);
216
+ return;
217
+ }
218
+ try {
219
+ try {
220
+ await fs.access(profilePath);
221
+ } catch {
222
+ if (!yes) console.warn(`Profile not found at ${profilePath}. Created a new one.`);
223
+ await fs.mkdir(path.dirname(profilePath), { recursive: true });
224
+ await fs.writeFile(profilePath, "", "utf-8");
225
+ }
226
+ const update = updateCompletionProfile(await fs.readFile(profilePath, "utf-8"), binName, cachePath, sourceLine);
227
+ if (!update.changed) {
228
+ if (!yes) console.log(`Completion already installed in ${profilePath}`);
229
+ return;
230
+ }
231
+ if (!yes) {
232
+ const action = update.hadExisting ? "Updating" : "Installing";
233
+ console.log(`${action} completion in ${profilePath}...`);
234
+ }
235
+ await fs.writeFile(profilePath, update.next, "utf-8");
236
+ if (!yes) console.log(`Completion installed. Restart your shell or run: source ${profilePath}`);
237
+ } catch (err) {
238
+ console.error(`Failed to install completion: ${err}`);
239
+ }
240
+ }
241
+ function generateZshCompletion(program) {
242
+ const rootCmd = program.name();
243
+ return `
244
+ #compdef ${rootCmd}
245
+
246
+ _${rootCmd}_root_completion() {
247
+ local -a commands
248
+ local -a options
249
+
250
+ _arguments -C \\
251
+ ${generateZshArgs(program)} \\
252
+ ${generateZshSubcmdList(program)} \\
253
+ "*::arg:->args"
254
+
255
+ case $state in
256
+ (args)
257
+ case $line[1] in
258
+ ${program.commands.map((cmd) => `(${cmd.name()}) _${rootCmd}_${cmd.name().replace(/-/g, "_")} ;;`).join("\n ")}
259
+ esac
260
+ ;;
261
+ esac
262
+ }
263
+
264
+ ${generateZshSubcommands(program, rootCmd)}
265
+
266
+ compdef _${rootCmd}_root_completion ${rootCmd}
267
+ `;
268
+ }
269
+ function generateZshArgs(cmd) {
270
+ return (cmd.options || []).map((opt) => {
271
+ const flags = opt.flags.split(/[ ,|]+/);
272
+ const name = flags.find((f) => f.startsWith("--")) || flags[0];
273
+ const short = flags.find((f) => f.startsWith("-") && !f.startsWith("--"));
274
+ const desc = opt.description.replace(/\\/g, "\\\\").replace(/"/g, "\\\"").replace(/'/g, "'\\''").replace(/\[/g, "\\[").replace(/\]/g, "\\]");
275
+ if (short) return `"(${name} ${short})"{${name},${short}}"[${desc}]"`;
276
+ return `"${name}[${desc}]"`;
277
+ }).join(" \\\n ");
278
+ }
279
+ function generateZshSubcmdList(cmd) {
280
+ return `"1: :_values 'command' ${cmd.commands.map((c) => {
281
+ const desc = c.description().replace(/\\/g, "\\\\").replace(/'/g, "'\\''").replace(/\[/g, "\\[").replace(/\]/g, "\\]");
282
+ return `'${c.name()}[${desc}]'`;
283
+ }).join(" ")}"`;
284
+ }
285
+ function generateZshSubcommands(program, prefix) {
286
+ const segments = [];
287
+ const visit = (current, currentPrefix) => {
288
+ for (const cmd of current.commands) {
289
+ const nextPrefix = `${currentPrefix}_${cmd.name().replace(/-/g, "_")}`;
290
+ const funcName = `_${nextPrefix}`;
291
+ visit(cmd, nextPrefix);
292
+ const subCommands = cmd.commands;
293
+ if (subCommands.length > 0) {
294
+ segments.push(`
295
+ ${funcName}() {
296
+ local -a commands
297
+ local -a options
298
+
299
+ _arguments -C \\
300
+ ${generateZshArgs(cmd)} \\
301
+ ${generateZshSubcmdList(cmd)} \\
302
+ "*::arg:->args"
303
+
304
+ case $state in
305
+ (args)
306
+ case $line[1] in
307
+ ${subCommands.map((sub) => `(${sub.name()}) ${funcName}_${sub.name().replace(/-/g, "_")} ;;`).join("\n ")}
308
+ esac
309
+ ;;
310
+ esac
311
+ }
312
+ `);
313
+ continue;
314
+ }
315
+ segments.push(`
316
+ ${funcName}() {
317
+ _arguments -C \\
318
+ ${generateZshArgs(cmd)}
319
+ }
320
+ `);
321
+ }
322
+ };
323
+ visit(program, prefix);
324
+ return segments.join("");
325
+ }
326
+ function generateBashCompletion(program) {
327
+ const rootCmd = program.name();
328
+ return `
329
+ _${rootCmd}_completion() {
330
+ local cur prev opts
331
+ COMPREPLY=()
332
+ cur="\${COMP_WORDS[COMP_CWORD]}"
333
+ prev="\${COMP_WORDS[COMP_CWORD-1]}"
334
+
335
+ # Simple top-level completion for now
336
+ opts="${program.commands.map((c) => c.name()).join(" ")} ${program.options.map((o) => o.flags.split(" ")[0]).join(" ")}"
337
+
338
+ case "\${prev}" in
339
+ ${program.commands.map((cmd) => generateBashSubcommand(cmd)).join("\n ")}
340
+ esac
341
+
342
+ if [[ \${cur} == -* ]] ; then
343
+ COMPREPLY=( $(compgen -W "\${opts}" -- \${cur}) )
344
+ return 0
345
+ fi
346
+
347
+ COMPREPLY=( $(compgen -W "\${opts}" -- \${cur}) )
348
+ }
349
+
350
+ complete -F _${rootCmd}_completion ${rootCmd}
351
+ `;
352
+ }
353
+ function generateBashSubcommand(cmd) {
354
+ return `${cmd.name()})
355
+ opts="${cmd.commands.map((c) => c.name()).join(" ")} ${cmd.options.map((o) => o.flags.split(" ")[0]).join(" ")}"
356
+ COMPREPLY=( $(compgen -W "\${opts}" -- \${cur}) )
357
+ return 0
358
+ ;;`;
359
+ }
360
+ function generatePowerShellCompletion(program) {
361
+ const rootCmd = program.name();
362
+ const segments = [];
363
+ const visit = (cmd, pathSegments) => {
364
+ const fullPath = pathSegments.join(" ");
365
+ const subCommands = cmd.commands.map((c) => c.name());
366
+ const options = cmd.options.map((o) => o.flags.split(/[ ,|]+/)[0]);
367
+ const allCompletions = [...subCommands, ...options].map((s) => `'${s}'`).join(",");
368
+ if (fullPath.length > 0 && allCompletions.length > 0) segments.push(`
369
+ if ($commandPath -eq '${fullPath}') {
370
+ $completions = @(${allCompletions})
371
+ $completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
372
+ [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
373
+ }
374
+ }
375
+ `);
376
+ for (const sub of cmd.commands) visit(sub, [...pathSegments, sub.name()]);
377
+ };
378
+ visit(program, []);
379
+ const rootBody = segments.join("");
380
+ return `
381
+ Register-ArgumentCompleter -Native -CommandName ${rootCmd} -ScriptBlock {
382
+ param($wordToComplete, $commandAst, $cursorPosition)
383
+
384
+ $commandElements = $commandAst.CommandElements
385
+ $commandPath = ""
386
+
387
+ # Reconstruct command path (simple approximation)
388
+ # Skip the executable name
389
+ for ($i = 1; $i -lt $commandElements.Count; $i++) {
390
+ $element = $commandElements[$i].Extent.Text
391
+ if ($element -like "-*") { break }
392
+ if ($i -eq $commandElements.Count - 1 -and $wordToComplete -ne "") { break } # Don't include current word being typed
393
+ $commandPath += "$element "
394
+ }
395
+ $commandPath = $commandPath.Trim()
396
+
397
+ # Root command
398
+ if ($commandPath -eq "") {
399
+ $completions = @(${program.commands.map((c) => `'${c.name()}'`).join(",")}, ${program.options.map((o) => `'${o.flags.split(" ")[0]}'`).join(",")})
400
+ $completions | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
401
+ [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterName', $_)
402
+ }
403
+ }
404
+
405
+ ${rootBody}
406
+ }
407
+ `;
408
+ }
409
+ function generateFishCompletion(program) {
410
+ const rootCmd = program.name();
411
+ const segments = [];
412
+ const visit = (cmd, parents) => {
413
+ const cmdName = cmd.name();
414
+ if (parents.length === 0) {
415
+ for (const sub of cmd.commands) segments.push(buildFishSubcommandCompletionLine({
416
+ rootCmd,
417
+ condition: "__fish_use_subcommand",
418
+ name: sub.name(),
419
+ description: sub.description()
420
+ }));
421
+ for (const opt of cmd.options) segments.push(buildFishOptionCompletionLine({
422
+ rootCmd,
423
+ condition: "__fish_use_subcommand",
424
+ flags: opt.flags,
425
+ description: opt.description
426
+ }));
427
+ } else {
428
+ for (const sub of cmd.commands) segments.push(buildFishSubcommandCompletionLine({
429
+ rootCmd,
430
+ condition: `__fish_seen_subcommand_from ${cmdName}`,
431
+ name: sub.name(),
432
+ description: sub.description()
433
+ }));
434
+ for (const opt of cmd.options) segments.push(buildFishOptionCompletionLine({
435
+ rootCmd,
436
+ condition: `__fish_seen_subcommand_from ${cmdName}`,
437
+ flags: opt.flags,
438
+ description: opt.description
439
+ }));
440
+ }
441
+ for (const sub of cmd.commands) visit(sub, [...parents, cmdName]);
442
+ };
443
+ visit(program, []);
444
+ return segments.join("");
445
+ }
446
+
447
+ //#endregion
448
+ export { registerCompletionCli as a, usesSlowDynamicCompletion as c, isCompletionInstalled as i, getCompletionScript as n, resolveCompletionCachePath as o, installCompletion as r, resolveShellFromEnv as s, completionCacheExists as t };