Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "firecrawl-cli",
"version": "1.23.4-alexandria-beta.19",
"version": "1.23.4-alexandria-beta.20",
"publishConfig": {
"tag": "alexandria"
},
Expand Down
21 changes: 21 additions & 0 deletions src/__tests__/alexandria-beta.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,27 @@ it('preserves mixed search results, tools and billing metadata', async () => {
);
});

it('searches Alexandria semantically with the positional shortcut', async () => {
response = { success: true, data: { tools: [] } };
const result = await cli(['search', 'alexandria', 'hello world', '--json']);
expect(result.code).toBe(0);
expect(requests).toHaveLength(1);
expect(requests[0].body).toMatchObject({
query: 'hello world',
sources: [{ type: 'alexandria' }],
domainTools: false,
});
const invalid = await cli([
'search',
'alexandria',
'hello world',
'--sources',
'web',
]);
expect(invalid.code).not.toBe(0);
expect(requests).toHaveLength(1);
});

it('sends provider calls to Scrape with a stable retry ID and preserves the receipt', async () => {
const args = [
'scrape',
Expand Down
36 changes: 32 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -920,7 +920,8 @@ Max upload size: 50 MB
function createSearchCommand(): Command {
const searchCmd = new Command('search')
.description('Search the web and discover relevant Alexandria tools')
.argument('<query>', 'Search query')
.argument('<query>', 'Search query, or alexandria for semantic tool search')
.argument('[tool-query]', 'Query for search alexandria')
.option(
'--limit <number>',
'Maximum number of results (default: 5, max: 100)',
Expand Down Expand Up @@ -986,9 +987,30 @@ function createSearchCommand(): Command {
// false
// )
.option('--json', 'Output as compact JSON', false)
.action(async (query, options) => {
.action(async (query, toolQuery, options) => {
const alexandriaOnly = toolQuery !== undefined;
if (alexandriaOnly && query !== 'alexandria') {
throw new Error(
'Quote your search query, or use search alexandria "query".'
);
}
if (alexandriaOnly && !toolQuery.trim()) {
throw new Error('Provide a non-empty Alexandria search query.');
}
if (
alexandriaOnly &&
options.sources &&
options.sources.trim().toLowerCase() !== 'alexandria'
) {
throw new Error(
'search alexandria requires --sources alexandria; omit --sources or use regular search.'
);
}
if (alexandriaOnly) query = toolQuery;
// Parse sources
let sources: SearchSource[] = ['web', 'alexandria'];
let sources: SearchSource[] = alexandriaOnly
? ['alexandria']
: ['web', 'alexandria'];
if (options.sources) {
sources = options.sources
.split(',')
Expand Down Expand Up @@ -1035,7 +1057,9 @@ function createSearchCommand(): Command {

const searchOptions = {
query,
domainTools: options.domainTools ?? sources.includes('alexandria'),
domainTools:
options.domainTools ??
(!alexandriaOnly && sources.includes('alexandria')),
limit: options.limit,
sources,
categories,
Expand Down Expand Up @@ -1066,6 +1090,10 @@ function createSearchCommand(): Command {
'--no-domain-tools',
'Disable domain matching; source selection still controls semantic tools'
);
searchCmd.addHelpText(
'after',
'\nSemantic tool search: firecrawl search alexandria "find company contacts"\n'
);
return searchCmd;
}

Expand Down
Loading