The Search API provides fast, ranked full-text search over learnings using SQLite’s FTS5 engine with BM25 scoring. Search by keywords, categories, or projects with sub-millisecond performance.
SearchResult Interface
export interface SearchResult extends Learning {
rank : number ; // BM25 relevance score (lower is better)
snippet ?: string ; // Highlighted match excerpt
}
BM25 is a probabilistic ranking function. Lower scores indicate higher relevance.
SearchOptions Interface
export interface SearchOptions {
limit ?: number ; // Max results (default: 10)
project ?: string ; // Filter by project
category ?: string ; // Filter by category
}
Search Functions
searchLearnings
db
Database.Database
required
SQLite database instance from store.db or initializeDatabase().
Search query. Supports prefix matching, phrases, and boolean operators.
options
SearchOptions
default: "{}"
Optional filters for limit, project, and category.
Array of learnings ranked by BM25 relevance with highlighted snippets.
Basic Search
Filtered Search
Phrase Search
import { createStore , searchLearnings } from 'pro-workflow' ;
const store = createStore ();
const results = searchLearnings ( store . db , 'testing' , { limit: 5 });
for ( const result of results ) {
console . log ( `# ${ result . id } [ ${ result . category } ] ${ result . rule } ` );
console . log ( ` Rank: ${ result . rank } ` );
if ( result . snippet ) {
console . log ( ` Match: ${ result . snippet } ` );
}
}
store . close ();
Query Syntax
Prefix Matching
All terms are automatically prefix-matched:
searchLearnings ( store . db , 'test' );
// Matches: "testing", "tests", "test-driven", etc.
Phrase Search
Use quotes for exact phrases:
searchLearnings ( store . db , '"git commit"' );
// Matches only exact phrase "git commit"
Multiple Terms (OR)
Space-separated terms are OR’d:
searchLearnings ( store . db , 'git commit push' );
// Matches learnings containing ANY of: git, commit, push
Wildcards
Use * for explicit wildcards:
searchLearnings ( store . db , 'test*' );
// Matches: test, testing, tests, etc.
Prefix matching is applied automatically, so wildcards are rarely needed.
BM25 Tuning
The search query uses custom BM25 weights:
bm25 ( learnings_fts , 1.0 , 2.0 , 1.0 , 1.0 )
// ^ ^ ^ ^
// | | | └─ correction weight
// | | └────── mistake weight
// | └─────────── rule weight (2x)
// └──────────────── category weight
The rule field has 2x weight because it’s the primary searchable field.
Specialized Search Functions
searchByCategory
db
Database.Database
required
SQLite database instance.
Category name (e.g., "Testing", "Git").
options
SearchOptions
default: "{}"
Optional filters for limit and project.
Learnings in the category, sorted by times_applied DESC, created_at DESC.
import { createStore , searchByCategory } from 'pro-workflow' ;
const store = createStore ();
const testingLearnings = searchByCategory ( store . db , 'Testing' , { limit: 10 });
store . close ();
This bypasses FTS and uses a direct category lookup. Faster for category-only queries.
db
Database.Database
required
SQLite database instance.
Learning ID to find related learnings for.
Maximum number of related learnings to return.
Learnings related to the specified learning, excluding the learning itself.
Related Learnings
Algorithm
import { createStore , getRelatedLearnings } from 'pro-workflow' ;
const store = createStore ();
const related = getRelatedLearnings ( store . db , 42 , 5 );
for ( const learning of related ) {
console . log ( `Related: ${ learning . rule } ` );
}
store . close ();
getMostAppliedLearnings
db
Database.Database
required
SQLite database instance.
Maximum number of learnings to return.
Learnings with times_applied > 0, sorted by times_applied DESC, created_at DESC.
import { createStore , getMostAppliedLearnings } from 'pro-workflow' ;
const store = createStore ();
const topLearnings = getMostAppliedLearnings ( store . db , 10 );
console . log ( 'Most applied learnings:' );
for ( const learning of topLearnings ) {
console . log ( ` ${ learning . rule } ( ${ learning . times_applied } x)` );
}
store . close ();
Use this to surface frequently-applied patterns. Great for onboarding or session handoffs.
getRecentLearnings
db
Database.Database
required
SQLite database instance.
Maximum number of learnings to return.
Filter by project. Omit for all learnings.
Learnings sorted by created_at DESC.
import { createStore , getRecentLearnings } from 'pro-workflow' ;
const store = createStore ();
const recent = getRecentLearnings ( store . db , 5 , 'my-app' );
store . close ();
Snippet Highlighting
Snippets show 32 tokens of context with matches highlighted:
const results = searchLearnings ( store . db , 'test' );
for ( const result of results ) {
console . log ( result . snippet );
// Example: "Always run <mark>tests</mark> before committing..."
}
Snippets use <mark> tags. Strip or convert to ANSI codes for CLI display.
FTS5 Index
The learnings_fts virtual table indexes:
category
rule
mistake
correction
Updates are automatic via triggers (no manual sync required).
Operation Time Simple query (1 term) <1ms Complex query (3+ terms) <5ms Filtered query (project + category) <10ms Full table scan (no FTS) 10-100ms
For best performance, use FTS queries (searchLearnings) instead of SELECT * WHERE rule LIKE '%term%'.
CLI Examples
Search from CLI
Raw SQL
Most Applied
# Search learnings
node -e "
const { createStore, searchLearnings } = require('pro-workflow');
const store = createStore();
const results = searchLearnings(store.db, 'testing', { limit: 5 });
for (const r of results) {
console.log('#' + r.id + ': ' + r.rule);
}
store.close();
"
Integration Examples
---
description : Search learnings by keyword
argument-hint : <query>
---
# Search Learnings
Query: $ARGUMENTS
Run this:
\`\`\` bash
node -e "
const { createStore, searchLearnings } = require('pro-workflow');
const store = createStore();
const results = searchLearnings(store.db, '$ARGUMENTS', { limit: 10 });
if (results.length === 0) {
console.log('No learnings found.');
} else {
console.log('Found ' + results.length + ' learnings: \\ n');
for (const r of results) {
console.log('#' + r.id + ' [' + r.category + '] ' + r.rule);
if (r.mistake) console.log(' Mistake: ' + r.mistake);
console.log(' Applied: ' + r.times_applied + 'x \\ n');
}
}
store.close();
"
\`\`\`
skills/replay-learnings/SKILL.md
---
name : replay-learnings
description : Surface relevant past learnings for the current task
---
# Replay Learnings
Ask the user what they're working on, then search for relevant learnings:
\`\`\` typescript
import { createStore, searchLearnings } from 'pro-workflow';
const store = createStore();
const task = ' < user input > ';
const results = searchLearnings(store.db, task, { limit: 5 });
if (results.length > 0) {
console.log('Relevant learnings:');
for (const r of results) {
console.log( `- ${r.rule}` );
}
}
store.close();
\`\`\`
Next Steps
Learnings API CRUD operations for learnings
Commands Build search commands
Skills Create searchable skills
Agents Preload search results into agents