From d261d95f205c302e06cc803ce59b104b75981e80 Mon Sep 17 00:00:00 2001 From: AmirSa12 Date: Sun, 19 Oct 2025 13:43:21 +0330 Subject: [PATCH 1/3] fix: npm exec --- bin/package-manager-completion.ts | 72 ++++++++++++++++++------------- 1 file changed, 43 insertions(+), 29 deletions(-) diff --git a/bin/package-manager-completion.ts b/bin/package-manager-completion.ts index 964d252..df34825 100644 --- a/bin/package-manager-completion.ts +++ b/bin/package-manager-completion.ts @@ -12,18 +12,22 @@ async function checkCliHasCompletions( packageManager: string ): Promise { try { - debugLog(`Checking if ${cliName} has completions via ${packageManager}`); - const command = `${packageManager} ${cliName} complete --`; - const result = execSync(command, { + const result = execSync(`${cliName} complete --`, { encoding: 'utf8', stdio: ['pipe', 'pipe', 'ignore'], timeout: 1000, }); - const hasCompletions = !!result.trim(); - debugLog(`${cliName} supports completions: ${hasCompletions}`); - return hasCompletions; - } catch (error) { - debugLog(`Error checking completions for ${cliName}:`, error); + if (result.trim()) return true; + } catch { } + + try { + const result = execSync(`${packageManager} ${cliName} complete --`, { + encoding: 'utf8', + stdio: ['pipe', 'pipe', 'ignore'], + timeout: 1000, + }); + return !!result.trim(); + } catch { return false; } } @@ -33,24 +37,29 @@ async function getCliCompletions( packageManager: string, args: string[] ): Promise { - try { - const completeArgs = args.map((arg) => - arg.includes(' ') ? `"${arg}"` : arg - ); - const completeCommand = `${packageManager} ${cliName} complete -- ${completeArgs.join(' ')}`; - debugLog(`Getting completions with command: ${completeCommand}`); + const completeArgs = args.map((arg) => + arg.includes(' ') ? `"${arg}"` : arg + ); - const result = execSync(completeCommand, { + try { + const result = execSync(`${cliName} complete -- ${completeArgs.join(' ')}`, { encoding: 'utf8', stdio: ['pipe', 'pipe', 'ignore'], timeout: 1000, }); + if (result.trim()) { + return result.trim().split('\n').filter(Boolean); + } + } catch { } - const completions = result.trim().split('\n').filter(Boolean); - debugLog(`Got ${completions.length} completions from ${cliName}`); - return completions; - } catch (error) { - debugLog(`Error getting completions from ${cliName}:`, error); + try { + const result = execSync(`${packageManager} ${cliName} complete -- ${completeArgs.join(' ')}`, { + encoding: 'utf8', + stdio: ['pipe', 'pipe', 'ignore'], + timeout: 1000, + }); + return result.trim().split('\n').filter(Boolean); + } catch { return []; } } @@ -69,11 +78,18 @@ export class PackageManagerCompletion extends RootCommand { this.packageManager = packageManager; } - // Enhanced parse method with package manager logic + private stripPackageManagerCommands(args: string[]): string[] { + if (args.length === 0) return args; + const execCommands = ['exec', 'x', 'run', 'dlx']; + if (execCommands.includes(args[0])) return args.slice(1); + return args; + } + async parse(args: string[]) { - // Handle package manager completions first - if (args.length >= 1 && args[0].trim() !== '') { - const potentialCliName = args[0]; + const normalizedArgs = this.stripPackageManagerCommands(args); + + if (normalizedArgs.length >= 1 && normalizedArgs[0].trim() !== '') { + const potentialCliName = normalizedArgs[0]; const knownCommands = [...this.commands.keys()]; if (!knownCommands.includes(potentialCliName)) { @@ -83,7 +99,7 @@ export class PackageManagerCompletion extends RootCommand { ); if (hasCompletions) { - const cliArgs = args.slice(1); + const cliArgs = normalizedArgs.slice(1); const suggestions = await getCliCompletions( potentialCliName, this.packageManager, @@ -91,10 +107,9 @@ export class PackageManagerCompletion extends RootCommand { ); if (suggestions.length > 0) { - // Print completions directly in the same format as the core library + debugLog(`Returning ${suggestions.length} completions for ${potentialCliName}`); for (const suggestion of suggestions) { if (suggestion.startsWith(':')) continue; - if (suggestion.includes('\t')) { const [value, description] = suggestion.split('\t'); console.log(`${value}\t${description}`); @@ -102,14 +117,13 @@ export class PackageManagerCompletion extends RootCommand { console.log(suggestion); } } - console.log(':4'); // Shell completion directive (NoFileComp) + console.log(':4'); return; } } } } - // Fall back to regular completion logic (shows basic package manager commands) return super.parse(args); } } From e16eaf352b0ed46b7a4c8b587847981e9a0647c2 Mon Sep 17 00:00:00 2001 From: AmirSa12 Date: Sun, 19 Oct 2025 13:44:47 +0330 Subject: [PATCH 2/3] prettier --- bin/package-manager-completion.ts | 34 +++++++++++++++++++------------ 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/bin/package-manager-completion.ts b/bin/package-manager-completion.ts index df34825..91e683c 100644 --- a/bin/package-manager-completion.ts +++ b/bin/package-manager-completion.ts @@ -18,7 +18,7 @@ async function checkCliHasCompletions( timeout: 1000, }); if (result.trim()) return true; - } catch { } + } catch {} try { const result = execSync(`${packageManager} ${cliName} complete --`, { @@ -42,22 +42,28 @@ async function getCliCompletions( ); try { - const result = execSync(`${cliName} complete -- ${completeArgs.join(' ')}`, { - encoding: 'utf8', - stdio: ['pipe', 'pipe', 'ignore'], - timeout: 1000, - }); + const result = execSync( + `${cliName} complete -- ${completeArgs.join(' ')}`, + { + encoding: 'utf8', + stdio: ['pipe', 'pipe', 'ignore'], + timeout: 1000, + } + ); if (result.trim()) { return result.trim().split('\n').filter(Boolean); } - } catch { } + } catch {} try { - const result = execSync(`${packageManager} ${cliName} complete -- ${completeArgs.join(' ')}`, { - encoding: 'utf8', - stdio: ['pipe', 'pipe', 'ignore'], - timeout: 1000, - }); + const result = execSync( + `${packageManager} ${cliName} complete -- ${completeArgs.join(' ')}`, + { + encoding: 'utf8', + stdio: ['pipe', 'pipe', 'ignore'], + timeout: 1000, + } + ); return result.trim().split('\n').filter(Boolean); } catch { return []; @@ -107,7 +113,9 @@ export class PackageManagerCompletion extends RootCommand { ); if (suggestions.length > 0) { - debugLog(`Returning ${suggestions.length} completions for ${potentialCliName}`); + debugLog( + `Returning ${suggestions.length} completions for ${potentialCliName}` + ); for (const suggestion of suggestions) { if (suggestion.startsWith(':')) continue; if (suggestion.includes('\t')) { From ad5a2dc0122bf05286a7fdf46c2ee2590361b097 Mon Sep 17 00:00:00 2001 From: AmirSa12 Date: Sun, 19 Oct 2025 13:50:38 +0330 Subject: [PATCH 3/3] changeset --- .changeset/cuddly-clubs-count.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/cuddly-clubs-count.md diff --git a/.changeset/cuddly-clubs-count.md b/.changeset/cuddly-clubs-count.md new file mode 100644 index 0000000..d72e0af --- /dev/null +++ b/.changeset/cuddly-clubs-count.md @@ -0,0 +1,5 @@ +--- +'@bomb.sh/tab': patch +--- + +npm exec support