Skip to content

Commit d261d95

Browse files
committed
fix: npm exec
1 parent 7178288 commit d261d95

File tree

1 file changed

+43
-29
lines changed

1 file changed

+43
-29
lines changed

bin/package-manager-completion.ts

Lines changed: 43 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,22 @@ async function checkCliHasCompletions(
1212
packageManager: string
1313
): Promise<boolean> {
1414
try {
15-
debugLog(`Checking if ${cliName} has completions via ${packageManager}`);
16-
const command = `${packageManager} ${cliName} complete --`;
17-
const result = execSync(command, {
15+
const result = execSync(`${cliName} complete --`, {
1816
encoding: 'utf8',
1917
stdio: ['pipe', 'pipe', 'ignore'],
2018
timeout: 1000,
2119
});
22-
const hasCompletions = !!result.trim();
23-
debugLog(`${cliName} supports completions: ${hasCompletions}`);
24-
return hasCompletions;
25-
} catch (error) {
26-
debugLog(`Error checking completions for ${cliName}:`, error);
20+
if (result.trim()) return true;
21+
} catch { }
22+
23+
try {
24+
const result = execSync(`${packageManager} ${cliName} complete --`, {
25+
encoding: 'utf8',
26+
stdio: ['pipe', 'pipe', 'ignore'],
27+
timeout: 1000,
28+
});
29+
return !!result.trim();
30+
} catch {
2731
return false;
2832
}
2933
}
@@ -33,24 +37,29 @@ async function getCliCompletions(
3337
packageManager: string,
3438
args: string[]
3539
): Promise<string[]> {
36-
try {
37-
const completeArgs = args.map((arg) =>
38-
arg.includes(' ') ? `"${arg}"` : arg
39-
);
40-
const completeCommand = `${packageManager} ${cliName} complete -- ${completeArgs.join(' ')}`;
41-
debugLog(`Getting completions with command: ${completeCommand}`);
40+
const completeArgs = args.map((arg) =>
41+
arg.includes(' ') ? `"${arg}"` : arg
42+
);
4243

43-
const result = execSync(completeCommand, {
44+
try {
45+
const result = execSync(`${cliName} complete -- ${completeArgs.join(' ')}`, {
4446
encoding: 'utf8',
4547
stdio: ['pipe', 'pipe', 'ignore'],
4648
timeout: 1000,
4749
});
50+
if (result.trim()) {
51+
return result.trim().split('\n').filter(Boolean);
52+
}
53+
} catch { }
4854

49-
const completions = result.trim().split('\n').filter(Boolean);
50-
debugLog(`Got ${completions.length} completions from ${cliName}`);
51-
return completions;
52-
} catch (error) {
53-
debugLog(`Error getting completions from ${cliName}:`, error);
55+
try {
56+
const result = execSync(`${packageManager} ${cliName} complete -- ${completeArgs.join(' ')}`, {
57+
encoding: 'utf8',
58+
stdio: ['pipe', 'pipe', 'ignore'],
59+
timeout: 1000,
60+
});
61+
return result.trim().split('\n').filter(Boolean);
62+
} catch {
5463
return [];
5564
}
5665
}
@@ -69,11 +78,18 @@ export class PackageManagerCompletion extends RootCommand {
6978
this.packageManager = packageManager;
7079
}
7180

72-
// Enhanced parse method with package manager logic
81+
private stripPackageManagerCommands(args: string[]): string[] {
82+
if (args.length === 0) return args;
83+
const execCommands = ['exec', 'x', 'run', 'dlx'];
84+
if (execCommands.includes(args[0])) return args.slice(1);
85+
return args;
86+
}
87+
7388
async parse(args: string[]) {
74-
// Handle package manager completions first
75-
if (args.length >= 1 && args[0].trim() !== '') {
76-
const potentialCliName = args[0];
89+
const normalizedArgs = this.stripPackageManagerCommands(args);
90+
91+
if (normalizedArgs.length >= 1 && normalizedArgs[0].trim() !== '') {
92+
const potentialCliName = normalizedArgs[0];
7793
const knownCommands = [...this.commands.keys()];
7894

7995
if (!knownCommands.includes(potentialCliName)) {
@@ -83,33 +99,31 @@ export class PackageManagerCompletion extends RootCommand {
8399
);
84100

85101
if (hasCompletions) {
86-
const cliArgs = args.slice(1);
102+
const cliArgs = normalizedArgs.slice(1);
87103
const suggestions = await getCliCompletions(
88104
potentialCliName,
89105
this.packageManager,
90106
cliArgs
91107
);
92108

93109
if (suggestions.length > 0) {
94-
// Print completions directly in the same format as the core library
110+
debugLog(`Returning ${suggestions.length} completions for ${potentialCliName}`);
95111
for (const suggestion of suggestions) {
96112
if (suggestion.startsWith(':')) continue;
97-
98113
if (suggestion.includes('\t')) {
99114
const [value, description] = suggestion.split('\t');
100115
console.log(`${value}\t${description}`);
101116
} else {
102117
console.log(suggestion);
103118
}
104119
}
105-
console.log(':4'); // Shell completion directive (NoFileComp)
120+
console.log(':4');
106121
return;
107122
}
108123
}
109124
}
110125
}
111126

112-
// Fall back to regular completion logic (shows basic package manager commands)
113127
return super.parse(args);
114128
}
115129
}

0 commit comments

Comments
 (0)