Skip to content

Built-in Gadgets

The CLI includes 5 built-in gadgets for filesystem operations and command execution. You can import these gadgets directly into your projects.

Terminal window
npm install @llmist/cli
import { ReadFile, WriteFile, RunCommand, ListDirectory, EditFile } from '@llmist/cli/gadgets';
import { AgentBuilder } from 'llmist';
const agent = new AgentBuilder()
.withModel('sonnet')
.withGadgets(ReadFile, WriteFile, ListDirectory, RunCommand)
.ask('Read package.json and list the dependencies');
for await (const event of agent.run()) {
if (event.type === 'text') {
process.stdout.write(event.text);
}
}
GadgetDescription
ListDirectoryList files and directories with metadata (size, age)
ReadFileRead the entire content of a file
WriteFileWrite content to a file (creates directories if needed)
EditFileEdit files using search/replace with intelligent matching
GadgetDescription
RunCommandExecute a command with arguments and return output

Lists files and directories with metadata in a compact format.

import { ListDirectory } from '@llmist/cli/gadgets';
// Schema: { directoryPath: string, maxDepth: number (1-10) }

Reads the entire content of a file.

import { ReadFile } from '@llmist/cli/gadgets';
// Schema: { filePath: string }

Writes content to a file, creating parent directories if needed.

import { WriteFile } from '@llmist/cli/gadgets';
// Schema: { filePath: string, content: string }

Edits files using search/replace with intelligent layered matching. This approach reduces edit errors by ~9x compared to naive text replacement.

Matching strategies (tried in order):

  1. Exact - byte-for-byte comparison
  2. Whitespace-insensitive - ignores differences in spaces/tabs
  3. Indentation-preserving - matches structure ignoring leading whitespace
  4. Fuzzy - similarity-based matching (80% threshold)
import { EditFile } from '@llmist/cli/gadgets';
// Schema: { filePath: string, search: string, replace: string }

Executes system commands with arguments (bypasses shell interpretation).

import { RunCommand } from '@llmist/cli/gadgets';
// Schema: { argv: string[], cwd?: string, timeout?: number }

For building custom filesystem gadgets with the same sandboxing behavior:

import { validatePathIsWithinCwd, PathSandboxException } from '@llmist/cli/gadgets';
try {
const safePath = validatePathIsWithinCwd(userInput);
// safePath is guaranteed to be within cwd
} catch (error) {
if (error instanceof PathSandboxException) {
console.error('Access denied:', error.message);
}
}
import { AgentBuilder } from 'llmist';
import { ReadFile, WriteFile, ListDirectory, RunCommand } from '@llmist/cli/gadgets';
async function main() {
const agent = new AgentBuilder()
.withModel('sonnet')
.withGadgets(ReadFile, WriteFile, ListDirectory, RunCommand)
.withSystemPrompt('You are a helpful coding assistant.')
.ask('Find all TypeScript files and count the lines of code');
for await (const event of agent.run()) {
if (event.type === 'text') {
process.stdout.write(event.text);
}
}
}
main();

Each gadget is exported with two names for convenience:

// PascalCase (matches gadget name - recommended)
import { ReadFile, WriteFile } from '@llmist/cli/gadgets';
// camelCase (internal convention)
import { readFile, writeFile } from '@llmist/cli/gadgets';