At the smallest window the app allows (760×520), the first-run "What brings you here?" step was taller than the window and had nothing to scroll, so its Continue button sat below the window, out of reach.
The first-run steps now sit in a scroll area that stops above the footer (Back and the step counter). When a step fits, nothing changes; when it doesn't, it scrolls.
**Verified:**
- A new smoke test at 760×520 scrolls Continue into view above the footer and clicks it through to the last step. Without the fix, Continue is drawn at y=646 in a 520-high window and the test fails.
- `cargo test -p craft-anything-ui-egui` (all suites), clippy, fmt.
- Rendered the first-run screens at the default size (unchanged, no scroll bar) and at 760×520 (scrolls, ends above the footer).
Fixes#231
ELF files whose section headers were removed (common in NAS and router firmware) now show their functions, imports and exports. The dynamic symbol table is found through PT_DYNAMIC (DT_SYMTAB/DT_STRTAB, counted from DT_HASH, then DT_GNU_HASH, then an estimate with a warning), shared with the Flutter reader. The prologue scan walks executable segments when there are no sections.
Fixes#223
The pseudo-Java for a method with one try/catch rendered the protected region, the handler and what follows, but never the statements before the `try`. So `v0 = 7; try { v1 = 2; } catch (RuntimeException e) {} return v0;` came out without `v0 = 7;`.
- Those statements are now rendered first. A branch from them into the try region falls back to a labelled `goto`, as elsewhere, so the method is no longer marked fully structured.
- The single-handler wrap is now refused when anything sits between the try's closing `goto` and the handler. That code would have been dropped the same way; such methods now get the plain rendering with the "exception handler(s) in the table" note.
**Verified:** a test with the reporter's 152-byte class (it fails without the fix); `cargo test -p craft-anything-analysis` (79), the engine's Java tool tests (9), clippy, fmt.
**Not checked:** `cargo xtask wasm`. The change is pure logic inside an existing function.
Fixes#232
A runtime capture compared a file's size, type and hash. When the file was over the hashing budget (or couldn't be read), neither snapshot had a hash, so a rewrite at the same size was reported as `unchanged`. Now:
- such a file is `unknown`;
- a file is `modified` only when its size or type changed, or both hashes exist and differ;
- a symlink pointed somewhere else with a target of the same length is `modified` (only the target's length was compared before).
**Verified:** a new unit test of `effects` (unhashed on either side, equal and different hashes, a size change, symlink retargets); `cargo test -p craft-anything-platform` (47 passed), clippy, fmt. The test runs on every OS, unlike the shell-based capture tests.
**Not verified:** a live run of the issue's capture probe on macOS.
Fixes#229
Hermes Agent gets its own adapter: it runs as `hermes [-m <model>] [args] -z <prompt>`, never falls back to a plain `hermes <prompt>` (which opens its interactive session), and can run over ACP (`hermes acp`) when ACP is turned on.
A request for a plain HTML and CSS site ("no frameworks", "no build step", "static html") now picks a Plain HTML and CSS stack: index.html and a stylesheet in app/, with nothing to build. Before, the request named no stack and the builder chose Rust + egui.
Fixes#161
A local build by Claude Code, Codex or an ACP agent now checks that craft-anything-cli starts before studying or starting the agent. When it is missing or won't start, the build stops with a plain message and what to do, instead of Claude Code's "MCP tool not found" error. A check that times out lets the build go ahead, and stopping the build ends the check.
Refs #91, #64, #113.
A paused, stopped or failed build only offered Continue or Try again; there was no way to say "enough now". project_build_finish marks the project Ready and adds a Done step to its conversation, keeping everything; the project screen shows It's done beside Continue and Try again when nothing is running.
Fixes#210
web_site_open keeps its browser for one session, and each CLI command is a session of its own that closes its browser when it ends. From the CLI, a capture with no open site now says so, and to run the steps together in an MCP client, the app or rebuild. Documented in tool-status.
Fixes#153
project_play's help says that on Windows a started program inherits the caller's output pipe (#207), and the reproducing test is kept in platform as an ignored test.
Every computed colour was painted on a 1x1 canvas and read back; Brave adds noise to canvas reads, so colours came back one unit off per channel (#F5F2EC as #f4f2ed). Computed rgb()/rgba() values are now read as numbers, and only other notations go through the canvas.
Fixes#154
checked_shl only rejects shift amounts of 64 or more, so payload bits shifted out of the u64 on the tenth byte were dropped; uleb128 now returns None when bits would be lost, and u64::MAX still decodes.
Each method entry's address and its fields' addresses are computed with checked arithmetic, so a method list near the end of the address space ends the list instead of panicking (debug) or reading a wrapped address (release).
An A32 LDRD/STRD with Rt=15 (e.g. 0xc0c7fef3) made the decoder library panic on the nonexistent r16; such a word now decodes as no instruction, before the library sees it.
When the check of codex exec --help didn't find --json, the run fell back to the plain adapter, codex <prompt>, which is Codex's interactive TUI and fails with "stdin is not a terminal". An adapter can now say its plain form doesn't work; Codex keeps its own adapter and the run says the check couldn't confirm the flag.
Fixes#199
Reads Linux registrations from ~/.config/Epic/UnrealEngine/Install.ini, honours a valid UE_ROOT, takes the version from Build.version, and counts the selected engine's own bundled Clang as its C++ tools.
Chrome reports Tailwind v4's rounded-full as its largest length, 3.35544e+07px; the capture now records any corner above 9999px as 9999px and keeps the other corners.
Fixes#155
A visitor's view of a site no longer keeps the page's class names (outline items and unnamed-control examples) or the query strings and fragments on image and link addresses, which can carry deployment ids and tokens.
Fixes#156
Adds an Antigravity adapter (stream-json output, resume by conversation, builder permissions) and lets setup and the doctor connect and check it under `antigravity` or `agy`.
web_site_capture checks where the page is first and refuses, without making the output folder, when the browser is on its own error page or a blank one after a failed open. Fixes#158.
Claude Code's "does not support this model" error says Claude Code is too old, with the fix (claude update for the command-line tool, or another model in Settings → AI), and isn't retried. Fixes#165.
Before each width's full-page screenshot the page is scrolled through, lazy images are loaded and waited on (5 s at most), and it goes back to the top, so scroll-revealed sections and lazy images are in the picture. Fixes#160.
The Settings scroll area no longer shrinks to each tab's content, so every tab has the same width and the scroll bar stays in one place; settings keep 14 points clear of it.
The builder reads the wait a busy or rate-limited service asked for (at most 15 minutes), says so plainly, and tries again then, instead of a fixed 30/60/90 s with the raw error. For #142.
The macOS zip unpacks as Godot.app; it's renamed to Godot_v<version>.app so the engine store finds it, moving a previous install aside and restoring it if the rename fails.
Settings → AI shows each AI's model with Change…, listing the API's own models or Claude's models for Claude Code; craft-anything-cli ai model <name> [model] lists or sets it. Fixes#123 and #127.
npm's global prefix, from NPM_CONFIG_PREFIX or prefix= in ~/.npmrc (its bin folder outside Windows), is searched after PATH with the other usual folders, without running npm. Fixes#132.
Settings → AI gets an Add an AI by its address form; AiHub::add_server asks the server for its models before adding it and picks one that can chat when none is named; ai add --kind openai_compatible --base-url without --model does the same. Fixes#54, #98 and #128.
The engine test no longer connects to the stopped stand-in's port, which another parallel test could be handed; platform::standin_server tests that dropping a server frees its port, trying it for a moment.
Detection picks the first listed model that isn't named for embedding, ranking or speech, and falls back to the first only when that's all there is. Fixes the cause of #127.
console_text waits for the program's output to arrive and settle before closing the console, waits up to 15 s for it, and says so instead of returning an empty screen.
Fallback fonts are ordered sans first (BIZ UDPGothic, then Noto Sans CJK, then other sans faces), with mincho and serif faces last, so Japanese and Chinese interface text isn't set like a book page.
~/.opencode/bin, ~/bin and the bin folders of nvm's Node versions (newest first) are searched after PATH with the other usual folders, so a desktop-started app finds OpenCode from its own installer and agents npm installed under nvm.
The per-file unpack limit is passed per download: 256 MB for pinned tools as before, 1 GiB for Godot, whose download is checked against its official SHA-512 list first. Fixes#100.
Adds Simplified and Traditional Chinese UI catalogs, picks the UI language from the system when Language is System, makes prices and a few labels translatable, recognises Chinese words for games and websites in requests, and adds cargo xtask i18n-coverage and docs/localization.md.
Each local agent app in Settings → AI shows which program runs it, with Choose… and Find it automatically; craft-anything-cli ai program <name> [path] does the same. The not-installed errors point there instead of a setting that didn't exist.
When UI Automation's button or check box proxy fails (it uses SendInput, which needs an interactive desktop), the walkthrough posts BM_CLICK to the control's window instead. PostMessage, so a click that opens a dialog doesn't block the walkthrough; only for buttons and check boxes.
Look for AI reads provider baseURLs from OpenCode's settings and probes those on this computer or its network, so LM Studio on another port or a server on another machine is offered. The JSONC reader moves from setup to formats so ai can use it. Fixes#83.
Taking over a replaced stand-in's port tries a busy port again for up to two seconds, so a restart no longer fails now and then with Address already in use.
The Settings tab column takes exactly what's left of the window with room for the scroll bar, and a path field leaves room for its button, so the Engines tab no longer widens the window. Fixes#68.
The conversation's history counts the item spacing and the prompt row is top-aligned, so the Agent console's panel no longer grows 17 points a frame until its tabs are cut off.