A small CLI agent that uses OpenAI's Responses API + Bun.WebView for browser
automation, plus a standalone Hacker News scraper demo.
Built on Bun 1.3.12+ — uses Bun.WebView, Bun.markdown.ansi,
and Bun.spawn directly, no extra runtime deps.
bun installCreate a .env (already gitignored):
OPENAI_API_KEY=sk-...
# OPENAI_MODEL=gpt-5.4 # optional
Interactive agent CLI:
bun startStandalone Hacker News scraper demo (opens a headless WebView, extracts the top 5 stories, screenshots each linked page, renders them inline via the Kitty graphics protocol):
bun index.tsbun test
bun run typechecksrc/
cli.ts # REPL entry: readline loop, SIGINT handling
agent.ts # Streaming Responses API + tool-call loop
prompt.ts # System prompt + tool cheatsheet
render.ts # Terminal UI: markdown, kitty images, tool trace
tools/
index.ts # Tool registry + JSON dispatch
fs.ts # read / write / edit / ls / grep / find
bash.ts # Shell (cwd=workspace)
paths.ts # Workspace sandboxing (safePath)
tests/ # bun:test — fs, edit, bash, paths, agent (with mock client)
workspace/ # Agent's scratchpad (gitignored)
index.ts # Standalone HN scraper demo
| tool | purpose |
|---|---|
read |
Text (line-numbered), images (shown inline), .md |
write |
Create/overwrite a file |
edit |
Unique find-and-replace (or replace_all) |
ls |
List directory |
grep |
Ripgrep content search |
find |
Ripgrep filename/glob search |
bash |
Arbitrary shell command in workspace/ |
All paths are resolved via safePath() (src/tools/paths.ts), which rejects any
resolution that escapes workspace/.
.envandworkspace/are gitignored.safePathprevents path traversal via../.grep/finduse Bun's$tagged template — arguments are auto-escaped, no shell injection.bashruns arbitrary commands: the sandbox is CWD-only; absolute paths,curl,ssh,cat ../.envall work. Treat this as equivalent to giving an LLM shell access on your machine. If you point the agent at untrusted web content, consider containerizing or adding an allowlist.