Repository navigation
shot2code v0.5.2
[0.5.2] - 2026-09-28
Released as shot2code v0.5.2.
Checksums for the published Windows artifacts:
SHA256SUMS.txt.
Added
-
Free image search — shot2code sends no key of its own. A new canonical
search_free_imagestool finds real, ready-to-use photographs through
Openverse's public image API, and is offered to every runtime. It needs no
credential, so it works on a machine with no Replicate, Cloudflare or
OpenAI-compatible configuration at all, and configuring one of those never
switches it off. It is a separate tool fromgenerate_images, never a
silent fallback inside it: the model picks whichever the design needs, and
the activity feed says "Found 3 free images" rather than "Generated". Off by
default, because the query text leaves the machine. -
Free image results are restricted to CC0 and Public Domain Mark, so an
exported project cannot quietly inherit an attribution, share-alike or
non-commercial obligation shot2code could not enforce on the user's behalf.
The licence is re-checked locally rather than trusting the search server's
filter, and a result missing its source page or licence URL is dropped
because it could not be verified. Title, creator, source page, provider,
licence name and licence URL travel with every image, along with an explicit
warning that Openverse aggregates other platforms' metadata and should be
verified before commercial use. -
Found images are downloaded and served locally, so generated and exported
projects never hotlink somebody else's server. Every URL is checked first:
http(s)only, DNS-resolved with private, loopback, link-local and cloud
metadata addresses refused (a mixed answer is rejected outright as a
rebinding attempt), redirects re-validated rather than followed, declared
content type required to match the sniffed bytes within an image allowlist,
and byte and decoded-pixel ceilings enforced. Web image search is
deliberately not used: a picture on a web page grants no reuse right. -
Optional image-generation providers. Placeholder images can now be
generated by Cloudflare Workers AI (account ID + API token) or by any
OpenAI-compatible image endpoint (base URL, plus an API key unless it runs on
localhost), in addition to Replicate. The alternatives are additive:
Replicate stays the default and the existing Replicate, OpenAI, Anthropic and
Gemini keys are never read, replaced or re-routed by the choice. Cloudflare's
daily allocation is quoted from Cloudflare's own pricing page — 10,000
Neurons a day on both the Workers Free and Workers Paid plans, resetting
at 00:00 UTC, $0.011 per 1,000 Neurons above it — attributed to the user's
Cloudflare account, dated, and marked able to change, never as a guarantee.
CLOUDFLARE_ACCOUNT_IDandCLOUDFLARE_API_TOKENsupply the same
credentials to headless runs. -
Both validated Replicate image models are now selectable —
prunaai/z-image-turbo(default) andblack-forest-labs/flux-2-klein-4b—
each with cost wording that names who bills, quotes the provider's own
published figure with the date it was read, links that provider's pricing
page, and says the terms can change. No provider is described as permanently
free anywhere in the product. -
Checked custom Replicate models. Another Replicate model can be used once
it passes a schema check:POST /api/image-models/validatereads that
model's own published OpenAPI schema and accepts it only if it really
declares a stringpromptinput and an image output and requires nothing
else. Replicate models do not share one input schema, so no model outside the
curated list is claimed to be compatible without that evidence. -
GET /api/image-modelsexposes the curated catalog — providers, defaults,
capabilities and cost notes — as a pure read that carries no credential. -
Provider-neutral web search. A shot2code-owned
search_webtool is now
offered to every runtime — native OpenAI, Anthropic and Gemini, GitHub
Copilot and Copilot SDK BYOK — instead of only to Copilot SDK sessions.
Tavily is the default provider (its published plan is 1,000 API credits a
month with no credit card, plus a documented keyless trial that needs no
account); Exa is available as an alternative and always needs a key. Those
allowances are the providers' own and can change — shot2code links their
pricing pages rather than promising anything. Off by default; Settings
states exactly what leaves the device before it can be switched on, and
offers a test-connection button. -
Web search requests go only to the provider's fixed HTTPS endpoint, with an
explicit timeout, no redirects and no raw page content. Each search returns
at most 5 results with bounded titles, snippets and total size, prefixed with
an untrusted-content warning, and is capped at 3 searches per turn and 10 per
generation. Search-provider keys are backend-only and are excluded from
history, commit snapshots and tool arguments. -
Copilot's built-in
web_searchremains available for people who prefer it
and have the entitlement. When the canonical search is configured and usable,
it is enabled instead of the built-in, so a model can never take the
unbounded route past the budgets and the domain allowlist. -
Google Stitch generation now reports real SDK phases — connecting, project
creation, screen generation, output download and import — with elapsed time,
an accessible live status and bounded error messages. The SDK client now uses
the same ten-minute generation timeout the UI promises. -
Dedicated Figma and Stitch input destinations sit beside Upload, URL,
Text and Import. Figma uses its documented REST/PAT frame-rendering path;
Stitch uses the bundled experimental SDK and preserves the selected
shot2code stack/model routing. -
The Preview toolbar now includes accessible 25%–200% desktop canvas zoom,
Fit and 100% controls. Magnified canvases pan without blocking iframe
interaction. -
Help now includes an in-app Bug, Feature request and Feedback form with
authenticatedghsubmission plus copy, Markdown-download and prefilled
browser fallbacks.
Changed
- Copilot's built-in
web_fetchis assessed and deliberately not offered.
It is a real runtime built-in andToolSet.add_builtin("web_fetch")would
reach it, but a built-in's result is produced inside the Copilot runtime and
handed to the model by the runtime — the SDK only notifies the application
afterwards. There is therefore no point at which shot2code could cap that
text, mark it as untrusted, or count it against a budget, andweb_fetch
returns a whole page. The SDK also accepts no URL allowlist at session
creation. Settings now explains this next to the Copilot web-search switch,
as its own unconditional disclosure rather than something coupled to that
switch, and points at the canonicalsearch_webtool, whose results are
capped, labelled and budgeted. - The deny-by-default Copilot permission handler is now installed on every
session, subscription and BYOK, instead of only on sessions that configured
MCP servers. Without a handler the runtime fell back to its own default
policy, so a run using a network-capable built-in had no shot2code-owned
answer to "may this URL be fetched?". Any URL the runtime asks to open is
denied with a reason naming the host and path — never the query string, which
can carry a token. MCP approvals are unchanged. - A
ToolSetthat names a blocked built-in — directly or through a
builtin:*wildcard — now fails when the session is built, rather than
silently granting a capability whose output cannot be bounded. - Image results are normalized in one place. Remote URLs, raw bytes, base64
anddata:payloads all pass through one adapter that either keeps a public URL or writes the image to the served local asset directory, and refuses
anything unsafe (file:, private or loopback addresses that are not our own
assets, oversized payloads). A locally served image is handed to the model as
bytes, because such a URL is not fetchable by Anthropic, OpenAI or Gemini. - Background removal is stated as Replicate-only and behaves that way: the
remove_backgroundstool is simply not offered without a Replicate key, and
no other provider's model is substituted. Image editing runs on Replicate, or
on an OpenAI-compatible endpoint that actually implements/images/edits—
a missing route there is reported as a capability gap, not a credential
problem. - Figma MCP is no longer advertised or activated. Figma officially limits both
its desktop and hosted MCP servers to clients in the Figma MCP Catalog, so
shot2code filters registry results, disables migrated entries and uses the
supported scoped-PAT REST workflow instead. Figma 429 responses now preserve
retry, plan, limit-type and upgrade guidance.
Fixed
- Image generation no longer reports success for a batch that produced
nothing. Every per-prompt failure used to collapse intoNone, the tool
still returned success, and the activity feed counted the empty results as
generated images — three blank grey tiles under "Generated 3 images". Each
prompt now keeps its own classified outcome (429 rate limit, 402 billing,
authentication, timeout, or a generic provider error), a batch that produced
nothing returns a failure with the reason and what to do about it, a partial
batch truthfully reads "Generated 2 of 5 images", and no success-shaped
result ever carries an empty URL. The same counting fix applies to
remove_backgroundsandedit_images. - The activity feed replaces the unexplained grey "Failed" tile with an
accessible alert carrying the classified reason and the action to take, so a
screen reader announces the failure instead of reading an empty box. - Image-provider credentials are excluded from commit snapshots, project
history and streamed tool arguments, mirroring the existing BYOK, MCP and
web-search secret handling. - A manually configured Copilot SDK BYOK model is tested directly when an
OpenAI-compatible gateway does not expose a working optional/models
endpoint. Credential failures still fail immediately, and a connection with
no configured model still receives an actionable discovery error. - Non-maximized preview resizing is coalesced through one ResizeObserver and
one animation-frame write. Unchanged geometry and hidden zero-sized panes no
longer rewrite iframe dimensions or repeatedly report scale, eliminating the
resize flicker without rebuilding the preview document. - The selected preview tab, HTML/Stack source, view mode and zoom now survive
restart through validated preferences. The desktop also restores validated
on-screen window bounds/maximized state, while the active project, version
and file continue to restore from SQLite rather than being duplicated in
local storage. - Restoring a saved project no longer reopens on a cancelled option when the
same generation has a completed option. shot2code selects and persists the
completed sibling; when every option was cancelled or failed, the sidebar
now offers Retry instead of incorrectly telling the user to select a
completed option that does not exist. - The packaged
file://renderer now obtains the runtime backend HTTP and
WebSocket addresses synchronously from the Electron main process instead of
relying on a mutable environment variable visible to preload. History and
API calls can no longer fall back to invalidfile:/api/...URLs. - The Electron preload no longer imports Node's
cryptomodule. Electron 44
runs the preload in a sandbox where that module is unavailable; the import
prevented every desktop bridge from loading even though the backend itself
had started successfully. - The in-app feedback IPC handler is registered during application startup
rather than inside the Stitch import callback, so Bug, Feature request and
Feedback submissions work before any Stitch action has run.