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.
frida_devices_find runs frida-ls-devices in a pseudo console on Windows, where it crashed on pipes and hung; frida_targets_list falls back to plain processes; device columns split on two spaces. Fixes#58.
runtime_captures_compare's right input had no description, so its schema was the boolean true and Claude Code rejected the whole tool list in Deep-mode builds. It gets a description, and a test checks every MCP input property schema is an object. Fixes#90.
Linux packages put Ghidra in /opt/ghidra (Arch and derivatives) or /usr/share/ghidra (Debian, Kali) with only a start script on PATH. The engine table lists both folders and the Ghidra lookup falls back to them.
codex exec refuses to run outside a git repository or a folder it trusts unless it gets --skip-git-repo-check, and project folders aren't repositories, so every Codex build failed at once. The adapter passes the flag, once, even when the backend's own args already have it.
The PLT, prologue and pointer scans in disasm/program.rs use checked steps, so code near u64::MAX no longer wraps to 0 and walks the whole address space. Adds open roadmap lines for an A32 STRD/LDRD decoder panic and unchecked header offsets in dart.rs.
WinGet's Links folders, per user and machine-wide, join the folders searched after PATH, so an app started before a WinGet install of Claude Code still finds it.
engines_list, doctor, capabilities and Requires::Engine share Settings::engine_path, which honours the Ghidra folder setting, and locate() finds an engine unpacked into a versioned sub-folder.
A .utoc header naming billions of zero-length compression methods no longer collects empty names until memory runs out: only the 255 a block can point at are read, the rest are skipped by length.
va_to_off added a PT_LOAD segment's file offset to an address delta unchecked, so a segment whose p_offset is near u64::MAX panicked in debug builds and wrapped in release. It now uses checked_add, so such an address maps to nothing. Two regression tests, one with a crafted ELF64.
A group descriptor could point the inode table so far out that an inode started within 128 bytes of usize::MAX; the two checks that an inode fits in the image added 128 unchecked, which panicked in debug builds and wrapped in release. They now use checked_add, so such a root inode is refused and such a child skipped. Two regression tests, and a roadmap line for the same pattern in macho.rs method_list.
`ai test` on a coding agent only runs its `--version` and showed that line as the reply, so it
looked like a working answer while every real message could still fail (not signed in, no model,
no quota). The report now carries a typed `version_only` field (true for coding agents, false for
backends that answered a real request), and the doc comment says what the test does.
Fixes#48
An agent CLI's `model` names the agent (opencode) and the model it should use goes in cli_model,
which nothing in the app shows. People write the program in `command` and the model in `model`
instead (command = "opencode", model = "deepseek/deepseek-flash"), which ran the plain adapter
with the agent's own default model until its free quota ran out. Settings read that way now run the
agent the command names, asked for that model (OpenCode gets --model). A model that names an
agent, a cli_model already set, and unknown programs are left as they are.
Fixes#34
Doctor checked a local (OpenAI-compatible) AI server by its open port alone, so any program on
that port, such as a plain web server on 8080, was reported "ok" while every chat with it failed.
It now asks the server for its model list, as it already does for every other kind of AI, and
reports what came back ("answered 404: 404 page not found") when that fails.
Fixes#37
Builders driven by our own loop (an API model such as Ollama) get file tools whose paths are
relative to the project. Models often write the project's folders from the root (/app/src/…), which
was refused as outside the project, so they could neither list, read nor write app/ and went round
in circles while each check found nothing. A path from the root whose first folder the project has
is now read inside the project (/etc/… and folders it doesn't have are still refused), and a write
outside app/ says so in its result, so a model that leaves out app/ learns where the app goes.
Refs #24
install checked for a pinned download before it looked at the sha256 it was given, so on FreeBSD
(no pinned adb) a malformed hash came back as "no pinned download" instead of "sha256 must be 64
hex characters", and rejects_bad_or_different_hash_before_downloading failed there on every run,
main included. The hash's form is now checked first; a well-formed hash is still compared with the
pin.
Local model servers were found by an open port alone, so any program listening on 8080 (a common
port for local web servers) was offered as "llama.cpp server (local)" with no model, and chatting
with it failed with "answered 404: 404 page not found". A local server is now offered only when
its model list answers; one that answers with an error or a page that isn't JSON is something
else. A server that doesn't answer in time is still offered, as before, since it may be loading.
Fixes#30
OpenCode had no adapter of its own, so it got the plain one: the prompt as its only argument.
OpenCode reads its first argument as the folder to open, so every chat and build stopped at once
with exit code 1. It now runs `opencode run [--auto] [--model …] <prompt>`; builds pass `--auto`
so what OpenCode would stop to ask is allowed unless its own settings deny it, as Codex builds get
a workspace-write sandbox. Flags checked against OpenCode's own `run` command.
Fixes#32Fixes#15
Release builds embed craft-fonts since the switch to the shared workflows, which turns the empty
boxes for Korean, Chinese, Japanese, Thai, Arabic, Hebrew, Hindi and arrows into text. A test now
checks every one of those in each of the app's font styles whenever craft-fonts is built in (as in
CI), so a font change can't bring the boxes back unnoticed. Packages now also ship craft-fonts'
OFL licences (OFL-<font>.txt), which the fonts require, and the release docs, ATTRIBUTION.md and
build.rs say how fonts are built in now (build.rs named the wrong app font).
Fixes#19
When a coding agent or tool crashed with a stack trace, the error's headline was the trace's last
frame ("OpenCode stopped with exit code 1: at <anonymous> (/$bunfs/root/chunk-….js:96:6417)"),
which says nothing about what went wrong. The headline is now the line above the trace (searched
in all of stderr, since a trace can outrun the excerpt), with Java's "Caused by" and Node's
version footer handled; output without a trace keeps its last line.
Refs #15