oaustegard/claude-skills/scripts

Claude Code and agent skill by oaustegard/claude-skills

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Query a portable, embedding-free lexical knowledgebase bundled as a `.skill`. Use when the user references this KB or asks a question whose answer is in its corpus ({{SOURCE}}). Retrieval is BM25 over a precomputed inverted index — there is no embedding model, so YOU expand the query into search terms before searching. Bundle holds index.json + chunks.jsonl + search.js + search.py; pure stdlib, no install, no network.

Install

npx vskill@latest install oaustegard/claude-skills/scripts

SKILL.md

lexical-kb — query an embedding-free knowledgebase

This KB has no semantic search and no embedding model. Retrieval is pure lexical BM25 over a precomputed inverted index. That design moves one job onto you: bridging the gap between how the user phrases a question and how the corpus phrases the answer. An embedding model would do this with a vector; here you are the semantic layer — you expand the query into terms before searching.

Corpus: {{SOURCE}} ({{CHUNK_COUNT}} chunks).

The retrieval protocol — follow every step

A raw user question fed straight to BM25 underperforms: it matches only the exact words the user happened to use. The expansion step is what makes lexical retrieval competitive with embeddings. Do not skip it.

  1. Read the question. Extract `core` terms — the essential nouns, proper

nouns, and identifiers the answer MUST contain. These carry full weight.

  1. Generate `expand` terms — synonyms, morphological variants (plural/verb

forms), acronym expansions and contractions, and adjacent concepts. These carry lower weight. This is the work the missing embedding model would have done. Be generous: 5–15 expansion terms is normal.

  1. Run the searcher. It ships in this bundle in two equivalent runtimes —

node search.js or python3 search.py, identical flags and identical results. Use whichever your environment has. Pass the user's original question via --query AND your term groups — expansion is additive, it never replaces the user's words:

``bash node search.js \ --query "how does centered simhash differ from random projection?" \ --core "simhash" --core "centered" \ --expand "random projection" --expand "hyperplane" --expand "LSH" \ --expand "binary quantization" --expand "hamming distance" \ --k 5 ``

--core/--expand are repeatable; pass phrases, the searcher tokenizes them. The --query terms contribute at a low floor weight so a curated synonym can lift a result but can never drop a doc the literal question would have matched. Defaults: core 1.0, expand 0.4, query-floor 0.25, top-k 5. Keep expansion targeted — terms too generic ("system", "process") leak into unrelated chunks and blur the ranking. A precise word can mislead too if it is polysemous: prefer the disambiguating phrase as one --core term (e.g. --core "centered simhash") over a bare ambiguous word (--core "centered", which also matches "centered around …" in unrelated chunks). The passage extractor is lexical too, so it will highlight the wrong sense rather than correct it.

  1. Read the returned chunks. Answer from them, and cite chunk ids inline.

The chunks are the source of truth the user installed. When a chunk contradicts your prior knowledge, the chunk wins — say so. When the chunks do not contain the answer, say that plainly rather than filling the gap from memory.

When you cannot expand — RM3 fallback

If the query is outside any domain you can expand confidently, pass it raw with pseudo-relevance feedback. The searcher harvests expansion terms from the corpus's own top hits — model-free, weaker than your expansion, and prone to drift when the first pass is off-topic, so prefer real expansion when you can:

bash
node search.js --query "the user's raw question" --rm3 --k 5

Metadata filtering

Each chunk carries structured meta (e.g. title, source_path, section). Filter on it with --filter (repeatable). Filtering narrows by attribute; it does not rank — combine it with term search.

bash
node search.js --core "factions" --filter "section=blog" --filter "date>=2025" --k 5

Operators: =, !=, ~ (substring), >, >=, <, <= (numeric when both sides parse, else lexicographic — ISO dates sort correctly).

Passage vs. full document

Ranking uses the whole chunk (best recall), but each hit's text is by default the query-densest passage of that chunk (~1200 chars), not the entire chunk — so your reasoning context is signal, not the surrounding noise of a long document. Each matched sentence keeps its neighbours (--context, default 1 each side) so it reads in context rather than as an orphaned fragment, and nearby matches merge into contiguous passages; ' … ' marks elisions between them. When a hit is a passage, the result carries full_chars (the chunk's full length). If you need the complete document for a hit — broader context, a quote in a section the passage elided — re-run with --snippet 0:

bash
node search.js --query "…" --core "…" --snippet 0 --k 3

Tune with --snippet 2000/600 (budget) and --context 2/0 (neighbours).

Output

The searcher prints JSON: {"hits": [{id, score, text, meta, full_chars?}, ...]}, sorted by descending BM25 score. text is the focused passage (or the full chunk if it was already short / --snippet 0); full_chars appears only when text is a passage. Surface the top hits to the user with their ids, then answer using them as authoritative context.

Mechanics

  • Pure stdlib — Node or Python. No npm install / pip install, no model

download, no network.

  • The bundle is self-contained: search.js + search.py (pick one),

index.json, chunks.jsonl. Run the searcher from inside the bundle directory (it defaults --index to its own location) or pass --index /path/to/bundle.

Security

  • Security scanPassed, 95 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
126
Repository forks
7
7-day trend score
24

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/oaustegard/claude-skills/scripts/badge)](https://verified-skill.com/skills/oaustegard/claude-skills/scripts)

Something wrong with this skill or its page? Tell us.