Skip to content

Commit 8bb27a5

Browse files
Merge pull request #77 from firecrawl/install-sh
add native skill installer and post-install setup flow
2 parents 1328fd3 + 49c5484 commit 8bb27a5

4 files changed

Lines changed: 572 additions & 39 deletions

File tree

scripts/install.sh

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -204,9 +204,33 @@ main() {
204204
echo ""
205205
success "Firecrawl CLI v${version} installed successfully!"
206206
echo ""
207-
echo " Run 'firecrawl --help' to get started."
208-
echo " Run 'firecrawl login' to authenticate with your API key."
209-
echo ""
207+
208+
# Resolve the binary path (may need updated PATH)
209+
local firecrawl_bin="$install_dir/firecrawl"
210+
211+
# Offer to continue with setup (login, skills, integrations)
212+
if [ -t 0 ] && [ -t 1 ]; then
213+
# Interactive terminal — prompt
214+
echo " Next: authenticate and install AI coding skills."
215+
echo ""
216+
printf " Continue with setup? [Y/n] "
217+
read -r answer </dev/tty || answer=""
218+
echo ""
219+
220+
case "$answer" in
221+
[nN]*)
222+
echo " Run 'firecrawl init --skip-install' later to set up."
223+
echo ""
224+
;;
225+
*)
226+
"$firecrawl_bin" init --skip-install
227+
;;
228+
esac
229+
else
230+
# Non-interactive (piped) — print instructions
231+
echo " Run 'firecrawl init --skip-install' to authenticate and install skills."
232+
echo ""
233+
fi
210234
}
211235

212236
main "$@"

src/commands/init.ts

Lines changed: 50 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { isAuthenticated, browserLogin, interactiveLogin } from '../utils/auth';
99
import { saveCredentials } from '../utils/credentials';
1010
import { updateConfig, getApiKey } from '../utils/config';
1111
import { buildSkillsInstallArgs } from './skills-install';
12+
import { hasNpx, installSkillsNative } from './skills-native';
1213

1314
export interface InitOptions {
1415
global?: boolean;
@@ -215,19 +216,29 @@ async function stepIntegrations(options: InitOptions): Promise<void> {
215216
switch (integration) {
216217
case 'skills': {
217218
console.log(`\n Setting up skills...`);
218-
const args = buildSkillsInstallArgs({
219-
agent: options.agent,
220-
yes: options.yes || options.all,
221-
global: true,
222-
includeNpxYes: true,
223-
});
224-
try {
225-
execSync(args.join(' '), { stdio: 'inherit' });
226-
console.log(` ${green}${reset} Skills installed`);
227-
} catch {
228-
console.error(
229-
' Failed to install skills. Run "firecrawl setup skills" later.'
230-
);
219+
if (hasNpx()) {
220+
const args = buildSkillsInstallArgs({
221+
agent: options.agent,
222+
yes: options.yes || options.all,
223+
global: true,
224+
includeNpxYes: true,
225+
});
226+
try {
227+
execSync(args.join(' '), { stdio: 'inherit' });
228+
console.log(` ${green}${reset} Skills installed`);
229+
} catch {
230+
console.error(
231+
' Failed to install skills. Run "firecrawl setup skills" later.'
232+
);
233+
}
234+
} else {
235+
try {
236+
await installSkillsNative();
237+
} catch {
238+
console.error(
239+
' Failed to install skills. Run "firecrawl setup skills" later.'
240+
);
241+
}
231242
}
232243
break;
233244
}
@@ -616,20 +627,32 @@ async function runNonInteractive(options: InitOptions): Promise<void> {
616627
console.log(
617628
`${stepLabel()} Installing firecrawl skill for AI coding agents...`
618629
);
619-
const args = buildSkillsInstallArgs({
620-
agent: options.agent,
621-
yes: true,
622-
global: true,
623-
includeNpxYes: true,
624-
});
625-
try {
626-
execSync(args.join(' '), { stdio: 'inherit' });
627-
console.log(`${green}${reset} Skills installed\n`);
628-
} catch {
629-
console.error(
630-
'\nFailed to install skills. You can retry with: firecrawl setup skills'
631-
);
632-
process.exit(1);
630+
if (hasNpx()) {
631+
const args = buildSkillsInstallArgs({
632+
agent: options.agent,
633+
yes: true,
634+
global: true,
635+
includeNpxYes: true,
636+
});
637+
try {
638+
execSync(args.join(' '), { stdio: 'inherit' });
639+
console.log(`${green}${reset} Skills installed\n`);
640+
} catch {
641+
console.error(
642+
'\nFailed to install skills. You can retry with: firecrawl setup skills'
643+
);
644+
process.exit(1);
645+
}
646+
} else {
647+
try {
648+
await installSkillsNative();
649+
console.log('');
650+
} catch {
651+
console.error(
652+
'\nFailed to install skills. You can retry with: firecrawl setup skills'
653+
);
654+
process.exit(1);
655+
}
633656
}
634657
}
635658

src/commands/setup.ts

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import { execSync } from 'child_process';
77
import { getApiKey } from '../utils/config';
88
import { buildSkillsInstallArgs } from './skills-install';
9+
import { hasNpx, installSkillsNative } from './skills-native';
910

1011
export type SetupSubcommand = 'skills' | 'mcp';
1112

@@ -40,18 +41,32 @@ export async function handleSetupCommand(
4041
}
4142

4243
async function installSkills(options: SetupOptions): Promise<void> {
43-
const args = buildSkillsInstallArgs({
44-
agent: options.agent,
45-
global: true,
46-
includeNpxYes: true,
47-
});
44+
if (hasNpx()) {
45+
const args = buildSkillsInstallArgs({
46+
agent: options.agent,
47+
global: true,
48+
includeNpxYes: true,
49+
});
4850

49-
const cmd = args.join(' ');
50-
console.log(`Running: ${cmd}\n`);
51+
const cmd = args.join(' ');
52+
console.log(`Running: ${cmd}\n`);
5153

54+
try {
55+
execSync(cmd, { stdio: 'inherit' });
56+
return;
57+
} catch {
58+
process.exit(1);
59+
}
60+
}
61+
62+
// Fallback: native install (no npx/Node required)
5263
try {
53-
execSync(cmd, { stdio: 'inherit' });
54-
} catch {
64+
await installSkillsNative();
65+
} catch (error) {
66+
console.error(
67+
'Failed to install skills:',
68+
error instanceof Error ? error.message : 'Unknown error'
69+
);
5570
process.exit(1);
5671
}
5772
}

0 commit comments

Comments
 (0)