flashlite documentation
Everything the CLI accepts, how permissions work, and what the tools will and won't do.
Overview
flashlite is a personal agentic coding CLI in the style of Claude Code or pi. It provides a streaming chat REPL plus an agent loop with filesystem tools for creating and organizing projects, reading and editing code, searching, copying assets and removal, plus terminal commands for builds, tests and other requested work.
It targets any OpenAI- or Anthropic-compatible chat endpoint. The endpoint and credential are configured locally on first launch and are never bundled with the package or baked into the binary.
Requirements
- macOS. v1 assumes a macOS terminal — raw-mode TTY handling and ANSI output are written for it.
- Node 24 or newer. flashlite runs TypeScript straight from source using Node's native type stripping, so there is no build step.
- Zero runtime dependencies. Only
typescriptand@types/nodeare installed, as devDependencies, for typechecking. - An endpoint and key. Any OpenAI- or Anthropic-compatible chat endpoint you can reach.
Install
npm install -g flashlite flash --version # or run it without installing npx flashlite --version
On first interactive launch, flash asks for your endpoint URL and then your API key with masked input, saving both to ~/.config/flashlite/config.json (chmod 600). Non-interactive runs require an existing config file, or --base-url.
Both flash and flashlite commands are installed. If macOS reports EACCES because the npm prefix is root-owned, install into a user prefix (npm install -g flashlite --prefix ~/.npm-global, then put ~/.npm-global/bin on your PATH) or just run npx flashlite.
From source (for development)
cd flashlite npm install # devDependencies only npm run typecheck # tsc --noEmit npm test # node --test — offline
Configuration
Configuration lives at ~/.config/flashlite/config.json. It is validated before use:
auto_approvemust be a JSON boolean — the string"false"cannot enable it.max_output_tokensmust be an integer from 256–65536.tool_result_budget_bytesmust be 0–4,000,000;0disables tool-result elision.- Base URLs must be HTTP(S) and cannot contain login credentials, query strings or fragments.
Invalid fields produce value-free warnings and fall back to defaults; permission fields fail closed. A committed config.example.json is the safe template — real credentials live only in your local config.
CLI flags
| Flag | Effect |
|---|---|
flash | Start the interactive REPL |
-p "…" | Text-only one-shot turn. No tools, no workspace access |
--agent -p "…" | Non-interactive tool workflow; read-only unless explicitly approved |
--check | Connectivity and model-catalog diagnostic |
--base-url <url> | Use another endpoint for this run only |
--set-base-url <url> | Save the endpoint to config |
--reset-base-url | Clear the saved endpoint |
--resume <id|latest> | Continue a session, in its recorded workspace only |
--model <id> | Set the session model |
--effort <level> | auto, low, medium, high, xhigh, max |
--image <path> | Attach an image; repeatable. Requires a vision model |
--mode <m> | Start in ask, files, auto or unguarded |
--auto-approve | Allow file changes only; terminal commands still ask or deny |
--auto | Guarded auto: arbitrary commands run; five risk categories still ask |
--absolute | Unguarded auto: whole drive plus every command; no gate |
--debug | Transport metadata only — no raw frames or message content |
--no-color | Plain output, no styling or animation |
--help, --version | Usage, or the version string |
--auto, --auto-approve and --absolute are mutually exclusive. --absolute is rejected with -p, --check, or piped input/output.
Environment variables
FLASHLITE_BASE_URL— override the endpoint for a run.FLASHLITE_THEME=light— the warm palette darkens to explicit true-color for light terminals.FLASHLITE_REDUCED_MOTION=1(orNO_COLOR) — disable motion.
Slash commands
Type / to open a live filtered palette below the input. ↑/↓ selects, Tab completes, Enter runs, Esc dismisses.
| Command | Purpose |
|---|---|
/model | Open the model picker; /model <id> sets directly and persists the default |
/compact | Summarize older complete turns, keeping the latest user turn, with a checkpoint in the session log |
/settings | Token saver, boost, API key, default model, effort, permission default, endpoint and Memory |
/sessions | Browse and resume saved conversations |
/effort | Picker for reasoning effort |
/mode | Permissions: ask, files, guarded auto or unguarded auto |
/undo | Revert the previous turn's file changes |
/clear | Start a fresh conversation and transcript |
/help | Shortcuts, permissions and recovery |
/exit | Quit flashlite |
Keyboard
| Keys | Action |
|---|---|
Shift+Tab | Cycle the permission mode from the prompt |
Shift+Alt+Tab | Toggle Boost |
Page Up / Page Down | Scroll history while the input stays anchored; Page Down returns live |
Ctrl+V | Queue a clipboard image for the next prompt (macOS) |
Ctrl+X | Remove pending attachments |
Ctrl+R | Bash-style reverse-i-search over the input history |
Ctrl+C | Stop the active turn (TERM→KILL on the process group) |
Tab | Complete @file mentions and paths |
Permission modes
Modes are session-only and switched live with /mode or Shift+Tab. The /config mode picker can save one as the launch default.
ask
Every file mutation and every terminal command needs a separate explicit yes.
files
File mutations run without prompting; every terminal command still asks. Legacy auto_approve remains file-only.
Guarded auto — flash --auto, /mode auto
Trust-by-default for commands: arbitrary commands and pipelines run without a prompt, including unknown executables, interpreters, builds, tests and file mutations. Exactly five categories still ask, and none can be hidden behind a wrapper, pipeline, env assignment or literal sh -c body:
- Network access —
curl,wget,nc,ssh,scp,rsync,git fetch|pull|push|clone|remoteand similar. - Installs / package managers —
npm install|ci|add,pnpm/yarn add,brew,pip,apt,cargo install,go get,npxand similar. - Privilege escalation —
sudo,doas,su,pkexec. - Paths outside the project — absolute paths,
~, parent (..) traversal and symlink escapes. - Destructive Git —
git reset --hard,git clean -f…,git push --force,git branch -D.
Syntax the classifier cannot reduce to inspectable words — command substitution, backticks, globs, here-docs, eval/source, subshells and background jobs — fails closed and asks. Paths must resolve inside the project, plus the CLI's own ~/.config/flashlite tree for reads.
Unguarded auto — flash --absolute, /mode unguarded
No approval prompts and no guarded-auto ask list. Ordinary rm, builds, installs, Git changes, elevated, unknown and opaque commands all run. File tools can read and change paths across the drive, including absolute paths and ~/, and commands may start outside the project. The mode badge reads unguarded auto.
The only remaining gate recognizes very large irreversible operations: recursive deletion of a filesystem root, whole home/user tree or mounted volume; destructive diskutil operations; formatting a raw disk with mkfs/newfs; dd writing a raw disk; or shell output redirected to a raw disk. Each such command requires an explicit yes, for that command only.
Tool policy
Tools are available in the interactive agent REPL. Launch flash from the folder you want it to work in. In ask, files and guarded auto, filesystem-tool paths are relative to that folder and confined there: absolute paths, ~, parent-directory escapes and symlink escapes are refused. In unguarded auto, tools can use absolute paths, ~/, parent paths and external symlink parents across the drive.
Terminal commands are separately authorized and are not sandboxed. Their starting directory is validated, but their effects can extend to other files and the network.
- No-overwrite.
copy_pathandmove_pathnever overwrite an existing destination. - Bounded trees. Copy, move and remove preflight trees with a 5,000-entry / 100 MiB limit and reject symlinks and special files.
- Protected paths. Outside unguarded auto, tree operations reject
.gitinternals; mutations reject symlink paths, the working directory itself and.gitinternals. - Bounded search.
find_filescaps at 500 results / 5,000 inspected entries;grepcaps at 200 results / 5,000 inspected entries and reports partial results honestly. - Byte pages.
read_file,read_filesandlist_dirpage large files and directories rather than inflating context arbitrarily.
remove_path deletes with fs.rm; there is no recovery store and no restore tool. Git, or a copy made first, is the only recovery. A shell rm is likewise a real deletion. These file-tool protections are not an OS sandbox — an approved command can delete files the tools guard.Tools
| Tool | What it does | Approval |
|---|---|---|
read_file | Read text, UTF-8-safe byte pages up to 256 KiB with continuation metadata | no |
read_files | Read 1–20 files, per-file errors, shared 256 KiB budget | no |
file_info | Type, size, permissions, mtime — no content | no |
list_dir | Sorted directory pages, up to 500 per page | no |
find_files | Find paths by literal substring | no |
grep | Bounded literal search with snippets and partial-result metadata | no |
write_file | Create or overwrite text up to 1 MiB, including missing parents | yes |
edit_file | Replace a nonempty, unique exact match | yes |
make_dir | Create folders and missing parents | yes |
copy_path | Copy a file or directory tree | yes |
move_path | Move or rename | yes |
remove_path | Permanently delete | yes |
run_command | Terminal command with bounded output and time | per mode |
todo_write | Publish a task list; UI-only state with no filesystem or permission effect | no |
Terminal commands
run_command(command, cwd?, timeout_ms?) uses macOS /bin/zsh -f -c with ignored stdin and piped stdout/stderr — not an interactive terminal. cwd must be an existing project directory (default: project root). The default timeout is 60 seconds, maximum 5 minutes; commands are limited to 16 KiB and captured output to a combined 1 MiB, and overflow terminates the command and reports truncation rather than collecting without limit.
When a command needs approval, its full text, canonical cwd and effective timeout appear in chat before the question; control and invisible characters are escaped visibly. Commands run with a minimal environment allowlist (standard path/home/user/temp/locale variables, TERM=dumb), not ambient credential variables, and known router credentials are redacted from captured output.
Cancellation
Ctrl+C, /clear, /exit, timeout and output overflow terminate the process group with TERM→KILL escalation. There is no persistent-background-job or interactive-input API, so programs requiring a TTY or password entry may fail. Descendants that detach into another process group or session can escape cleanup — no sandbox guarantee is made.
Extending
Custom slash commands
Drop markdown files in ~/.config/flashlite/commands/ (global) or <project>/.flashlite/commands/ (project; shadows global by name). The filename is the command (review.md → /review) and the body is a prompt template; $1…$9 substitute positional arguments and $ARGS substitutes them all. No shell interpolation runs — the body is prompt text, not a script.
Memory
~/.config/flashlite/memory.md (global) and <project>/.flashlite/memory.md (project) are loaded into the system prompt, bounded and treated as attributed data, never as policy.
Hooks
Executable scripts named PreToolUse, PostToolUse, Notification or Stop in ~/.config/flashlite/hooks/ or <project>/.flashlite/hooks/ receive one JSON object on stdin. A PreToolUse hook may only block a call with {"decision":"block","reason":"…"} — it cannot approve or widen permissions — and a hook failure fails open.
Todos and undo
todo_write publishes a task list that renders live in a dock strip. Before a mutating file tool runs, the target's original bytes are captured as a per-turn checkpoint; /undo reverts the most recent turn's file changes. Shell side effects are never captured, and deletions are not restored.
Project instructions
Applicable AGENTS.md files — or legacy CLAUDE.md — are loaded from the nearest repository root down to the launch directory, attributed to their source. If a directory has both, AGENTS.md takes precedence. Sources are regular, non-symlink files, bounded to 16 KiB each / 32 KiB total. Project instructions cannot override host permissions or credential protection.
Automation
flash --agent -p explicitly enables tools. It defaults to read-only, ignoring saved auto_approve permissions. Add --auto-approve for file changes, or --auto for file changes plus guarded commands.
flash --agent -p "inspect this repo" # read-only flash --agent --auto-approve -p "update the README" # file changes flash --agent --auto -p "fix the failing tests" # guarded commands
Actions without approval are denied as tool results, never an unattended approval prompt; denied or failed tools produce a non-zero exit code. Headless runs save private transcripts. They use bounded tool rounds and currently do not fetch model context windows or auto-compact, so keep automated tasks scoped. Unguarded auto is interactive-only.
Privacy
- Never print an API key — not even a masked form. Keys live only in the local config file, chmod 600.
- Never log message content to stdout or stderr. Session transcripts are written only to
~/.config/flashlite/sessions/. - Credential redaction. Known router credentials are rejected in commands and redacted from command output and file-tool results before they reach model history.
- Clipboard stays user-triggered. Image paste runs only on Ctrl+V, never in the background or through agent tools.
- Diagnostics are metadata-only.
--debugreports frame sizes and retry metadata, never raw SSE payloads or message content.
This is not comprehensive secret isolation: commands are not sandboxed and can still read local configuration or make network requests. Review what you approve.