Personal AI desktop application with native tools for file operations, shell execution, browser automation, and self-expanding tool forge capability
BLADE provides 18 tools with mostly complete schemas and descriptions. Naming follows verb_noun conventions (blade_bash, blade_read_file, blade_edit_file, blade_glob, blade_browser_*). Descriptions are substantive (100-250 chars typical), explaining WHAT, WHEN, and HOW. However, several critical gaps: (1) No output schemas documented for any tool, LLMs cannot predict return structure or chain calls reliably. (2) Parameter descriptions lack format constraints (e.g., blade_bash timeout_ms has no min/max bounds; blade_glob pattern has no examples of valid syntax). (3) Error handling is implicit, no guidance on retryability, recovery steps, or actionable error messages. (4) x11_* tools (5 tools) are Linux-only with minimal descriptions of search_type enum values. (5) forge_continue_after_cost_block is a UI control, not a domain tool, belongs in a separate 'system' category. (6) No idempotency guarantees stated for write tools (blade_write_file, blade_edit_file could fail mid-operation). Strengths: clear risk classification (READ_ONLY vs WRITE), good use of optional parameters with sensible defaults (cwd, offset, limit, timeout_ms), and descriptions that guide LLM selection (e.g., 'Prefer blade_edit_file for targeted changes').
Execute a shell command and return stdout + stderr. On Windows runs via cmd.exe (/C), on macOS/Linux via sh (-c). Use for: running code, tests, git, npm/cargo/pip, file listing, anything needing a shell. Prefer this over asking the user to run commands. Large outputs (>8 KB) are spilled to a temp file — use blade_read_file to read the full output. Custom tools forged by BLADE live in ~/.blade/tools/ and can be called directly (e.g. `python3 ~/.blade/tools/my_tool.py [args]`).
Click an element in BLADE's managed browser by CSS selector. Use after blade_browser_read to identify the right selector. Examples: '#compose-button', 'button[data-testid="tweetButton"]', 'a[href*="youtube"]'.
Open BLADE's managed browser at a URL so the user can log in manually. Use this the first time BLADE needs to interact with a site. After login, sessions persist permanently.
Open a URL in BLADE's managed browser (Chromium with persistent login sessions). Use this for: posting on X/Twitter, interacting with YouTube, Reddit, any website. Sessions persist — if the user has logged in before, they're still logged in. Prefer over blade_open_url when you need to READ or INTERACT with the page.
Read the current page in BLADE's managed browser: returns title, URL, and visible interactive elements (buttons, inputs, links). Call after blade_browser_open to see what's on screen.
No output schemas documented for any tool. LLMs cannot predict return structure, field names, or types. This breaks tool chaining, e.g., blade_bash returns stdout/stderr but structure is undocumented; blade_browser_read returns 'interactive elements' but field names are unknown.
Parameter constraints missing. blade_bash timeout_ms has no min/max (could accept negative or 999999999). blade_glob pattern has no format guidance (regex? glob syntax?). blade_browser_click selector has no validation hint (CSS selector syntax). LLMs will pass invalid values.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | F | 47 | <=2025-11-25 | v2 |
Take a screenshot of the current page in BLADE's managed browser. Use when blade_browser_read doesn't give enough detail about layout.
Type text into an input field in BLADE's managed browser by CSS selector. Use for search boxes, compose areas, form fields.
Make a surgical edit — replace old_string with new_string in a file. old_string must match exactly (including whitespace/indentation) and must appear exactly once. Returns an error if old_string is not found or appears multiple times — in both cases, use blade_read_file first to get the exact current content. Always prefer this over blade_write_file for targeted changes to existing files.
Find files matching a glob pattern. Supports **, *, ?. Use for: discovering project structure, finding files by type, searching across a codebase.
Read a text file and return its contents. Use for: reading source code, configs, logs, markdown, any UTF-8 text file. Supports offset/limit for large files (offset = line number to start from, limit = max lines). Binary files (images, executables) will return an error — use blade_bash with a hex tool instead. Returns '(empty file)' if the file exists but has no content.
Fetch a URL and return text content. Use for: reading docs, GitHub raw files, APIs, web pages, checking changelogs, downloading data.
Write or create a file. Creates parent directories if needed. Use for: creating new files, writing scripts, saving output. Prefer blade_edit_file for targeted changes to existing files.
Frontend acknowledges the forge cost block and asks BLADE to continue with another budget bucket.
Get the currently focused window ID.
Get window position + size for a window ID.
Get the title/name of a window ID.
Probe whether xdotool can reach an X11 server. Returns one of: Available, NotLinux, XdotoolMissing, WaylandSession.
Search for windows by name/class. search_type ∈ {"name","class","classname","any"}. Returns window-id strings; empty vec means no match.
No error handling guidance. Tools lack recovery hints (e.g., 'If file not found, try blade_glob to discover the path'). No distinction between retryable errors (timeout) vs user-fixable (invalid selector) vs fatal (permission denied). Agents cannot self-correct.
x11_* tools (5 tools) have minimal descriptions and platform-specific constraints not documented. x11_search_window search_type enum values ('name', 'class', 'classname', 'any') are listed but not explained, what's the difference between 'class' and 'classname'? Linux-only availability not stated in tool descriptions.
forge_continue_after_cost_block is a UI control, not a domain tool. It should not be exposed as a callable tool, it's a system message for the frontend. Mixing UI controls with functional tools confuses LLM tool selection and violates single-responsibility principle.