@shiit/forage
v0.1.0
Published
Ranked, tiered, fuzzy tool discovery for code-mode sandboxes. Zero dependencies. Pure functions.
Maintainers
Readme
@shiit/forage — the discovery layer
forage is NEVER a tool in a tools array. It is the discovery layer BEHIND an execute door — exposed to the model's code as in-sandbox bindings (like
codemode.search/codemode.describe). A model with only top-level tools has no use for it.
Ranked, tiered, fuzzy tool discovery for any tool catalog. Zero dependencies. Pure functions. Search and describe any connector surface — MCP, OpenAPI, or your own custom tools.
Quick start
npm install @shiit/forageimport { createCatalog, searchConnectors, describeTarget } from "@shiit/forage";
const catalog = createCatalog({
descriptions: [
{
name: "files",
instructions: "Read, write, list, and delete workspace files",
descriptors: {
read: {
description: "Read a file at the given path",
inputSchema: {
type: "object",
properties: { path: { type: "string" } },
required: ["path"],
},
outputSchema: { type: "string" },
},
write: {
description: "Write content to a file",
inputSchema: {
type: "object",
properties: {
path: { type: "string" },
content: { type: "string" },
},
required: ["path", "content"],
},
},
},
},
],
});
const results = catalog.search("read file");
const docs = catalog.describe("files.read");Sandbox injection
import { createCatalog, bindings } from "@shiit/forage";
const catalog = createCatalog({ descriptions });
const codemode = bindings(catalog);
// Now inject { codemode } as sandbox bindings.
// The model calls:
// await codemode.search("files")
// await codemode.describe("files.read")API
createCatalog(options) → Catalog
Build a searchable catalog from an array of ConnectorDescription objects.
catalog.search(query, opts?) → SearchOutput
Tiered fuzzy search. Results ranked by: exact match > startsWith > phrase > token > prefix/substring > raw includes.
catalog.describe(target) → DescribeOutput
Get full TypeScript type declarations for a tool or connector by path.
Pure functions
searchConnectors(query, descriptions, snippets?)— stateless searchdescribeTarget(target, descriptions)— stateless describegenerateTypesFromJsonSchema(descriptors)— JSON Schema → TypeScriptsanitizeToolName(name)— string → valid JS identifier
bindings(catalog) → { search, describe }
Wraps a catalog as two async functions shaped for sandbox injection.
Types
ConnectorDescription— the data shape describing one connector namespaceConnectorTool— the per-tool runtime definition (includesexecute)JsonSchemaToolDescriptor— the per-tool searchable subsetSearchOutput,SearchResult,DescribeOutputForageError,EmptyCatalogError,UnknownTargetError,EmptyQueryError
Zero dependencies
The core package has zero runtime dependencies. The @types/json-schema
dev dependency is erased at compile time. CI enforces this.
License
MIT — includes attribution notice for derived code from @cloudflare/codemode.
