bulk_edit
ChatGPTApply ONE find-and-replace across MANY files in a single call — the sweep tool: renaming a label everywhere, updating every page's nav, fixing a class name site-wide. paths is a JSON array of explicit /www paths (list them from grep or list_files — there is no glob; every file you touch is named on purpose). Every occurrence of find in every listed file is replaced (use edit_file for a single precise change in one file). Set isRegex: true for a regular expression ($1…$n captures in replace). Need several different edits? Issue several bulk_edit calls — they are fast. Safe by design: a find that matches NOWHERE aborts the call with nothing written (fix the string and retry), and every write is conditional on the file's version, so concurrent changes are reported, never clobbered. The result counts replacements per file and — important — lists any unmatched files (listed by you, but the find didn't occur there): check those; a page variant (e.g. an active-class nav) often needs its own follow-up edit. No diffs are returned; spot-check with read_file or the preview if unsure.
check_domain_propagation
ChatGPTCheck whether a custom domain's A record has propagated to our load balancer IP yet. Defaults to the site's custom domain. Use this to tell the user whether their DNS change has taken effect.
check_domain_status
ChatGPTThe newest domain purchase's progress (pending_checkout → paid → registered, or failed with a reason) plus the domain row itself. Once registered, serving progress lives in verify_custom_domain / get_publish_state as usual. pending_checkout means payment wasn't completed; checkout_opened says whether the user ever opened the card's checkout (false = payment never started — nothing failed), and note says what to tell them.
check_live_url
ChatGPTFetch a live URL over HTTPS exactly the way a visitor's browser would and report what happened: ok with the HTTP status and page title, or a classified failure (dns = doesn't resolve, tls = certificate not served at the edge yet, connect, timeout, http = non-2xx). Defaults to checking every host the site should be live on. ALWAYS run this after publishing or after a domain goes active, BEFORE telling the user a URL is live — only report a URL as working when its check is ok.
check_references
ChatGPTStatic-site correctness check — the stand-in for a compiler this site doesn't have. It scans every text file for internal references (href="...", src="...", CSS url(...), and ES import specifiers) and reports the ones that point at a file which doesn't exist — i.e. broken links you'd otherwise only discover in the browser. It also reports orphaned .html pages (other than /www/index.html and /www/_internal/) that nothing else links to. References are URL paths (a URL /x is the file /www/x): external and non-file refs (http(s)://, //, data:, mailto:, tel:, and #anchors) are ignored, relative paths are resolved against the referencing file's directory, a clean URL like /about resolves to the file /www/about.html, and a trailing / resolves to its index.html. Run this after moving or deleting files and before publishing. Returns { broken: [{ from, ref, resolved, line }], orphaned: [{ path }], checked }. from and orphaned[].path are /www-rooted file paths; resolved is the URL path the broken ref points at. The broken list is capped at 200 and orphaned at 200.
check_slug_available
ChatGPTCheck whether a subdomain is usable for this site WITHOUT changing anything. Returns a status: available (free to take), taken (someone else has it), invalid (bad format or a reserved name — see reason), or current (already this site's slug). Use this before set_slug so you can confirm a name is free instead of guessing, and to answer "is X available?".
clear_custom_domain
ChatGPTRemove the site's custom domain: tear down its certificate, unbind it, free its load-balancer slot, and move the site's content back under its slug. The slug host keeps working. Confirm with the user first.
copy_file
ChatGPTCopy a file into the site at an absolute path. from can be a site path (to duplicate a page/template) OR a stored-file id — ast_… (a user asset), att_… (a chat attachment), or dwl_… (a file you downloaded). to is the destination site path (e.g. /www/images/logo.png), served at the path minus /www — reference it from your HTML/CSS as /images/logo.png. This is how you bring an asset, attachment, or download into the rendered site (they aren't part of it until copied). For images you can downscale/convert in one step with optimize_image instead.
create_site
ChatGPTCreate a new site. Returns its site_id (the handle for every other tool) and the reserved free slug it will publish under. Start here for a brand-new website, then write files with write_file.
crop_image
ChatGPTCrop an image to EXACTLY a canonical aspectRatio, subject-aware — the fix for an upload or asset whose shape doesn't match its slot. A vision model finds the subject, then a deterministic crop takes the largest window of the target ratio around it — nothing is stretched, distorted, or regenerated. Pass subject ("the two swans", "the person on the left") whenever you know what must be kept — from the user's words or the page's purpose; omit it and the most prominent subject is used. path is the image's absolute path (e.g. /uploads/photo.jpg); the result is written to destPath (e.g. /www/images/hero.jpg, served at the path minus /www; extension sets the format). Use this BEFORE placing a mismatched image instead of letting CSS object-fit: cover chop it. Set maxWidth to also downscale to display size. Returns the new dimensions plus a preview — verify the framing kept what matters. optimize_image is the shape-preserving cousin (resize/convert only).
delete_file
ChatGPTDelete files by absolute path — up to 50 in ONE call (paths, e.g. ["/www/old.html", "/uploads/draft.png"]). Idempotent: each result says whether a file was there (deleted: false means nothing was). Folders aren't deleted as such — a folder is gone once its last file is. Deleting a /www file removes its URL, so make sure nothing still links to it — run check_references afterwards if other pages might point here. Tool calls made together run at the same time: to delete a file another call is creating or moving, wait for that call's result first.
download_file
ChatGPTDownload a file from the internet into this site's downloads area — for self-hosting a font you found, or pulling an image/video when migrating a site. Give an http(s) url (optionally a filename). Returns a downloadId (dwl_…); the file is NOT on the site yet — bring it in with copy_file (any file) or optimize_image (images) referencing that id. The download is size-capped and restricted to public internet hosts.
edit_file
ChatGPTEdit ONE file with a JSON array of find-and-replace edits applied in order — batch every edit you need in this file into a SINGLE call (parallel edit_file calls on the same file conflict on the version and waste retries; one call = one atomic write). Each edit's find is copied verbatim from the file and must match exactly once — add surrounding context to disambiguate, or set replaceAll: true on that edit; set isRegex: true on an edit for a regular expression ($1…$n captures, no look-around). A later edit sees the earlier edits' output. Atomic: if ANY edit fails to match, nothing is written — fix it and retry. Prefer this over write_file for changing parts of a file; for the SAME edit across many files use bulk_edit. The write is conditional on the file's current version, so a concurrent change is reported rather than clobbered. The result returns per-edit replacement counts and a hunk — line-numbered windows showing every change in place with its NEW line numbers — so you do NOT need to re-read the file afterwards.
fetch_url
ChatGPTRead an external web page or resource. For HTML pages the default digest view returns a structured extraction that answers most needs in one small result: page metadata, the readable CONTENT as markdown, LINKS (the site's nav map), MEDIA (every image URL with alt text, video embed IDs, background images), and ASSETS (stylesheet + font URLs) — use it for reading an existing site you're rebuilding, researching a topic, finding a logo or photos, or mapping a site's structure. All URLs in the digest are exact and absolute — pass them straight to download_file. Non-HTML resources (JSON APIs, CSS, SVG, JS) always return their raw body; pass view:"raw" only when you need a page's actual HTML markup. If a result is truncated it names the exact offset to continue from. urls is a JSON array of 1 to 5 strings — a single page is a one-element array like ["https://example.com"]; pass several to read the key pages of a site in one call. This reads external resources only — it does NOT read this site's files (use the file tools for those).
generate_image
ChatGPTGenerate an original image from a text brief — for hero shots, photos, illustrations, backgrounds, or icons; the way to source every image the user hasn't uploaded. Photographic briefs render as real-looking photographs, so describe subjects, ages, light and lens like a photo shoot when that's the goal. Expect ~15 s per image: fire independent generations in the same turn, in parallel, never one after another. aspectRatio is REQUIRED: pass the ratio of the SLOT the image will fill ("16:9" hero, "1:1" tile, "3:4" portrait card, …) so the image is born the right shape instead of being squeezed by CSS later. path is where the full-resolution image is saved — normally straight into the site (/www/images/hero.jpg, referenced as /images/hero.jpg); the extension sets the encoding. Returns a small preview to check and the saved path. Each generation consumes AI credits.
get_certificate_status
ChatGPTRead the provisioning state of the site's custom-domain TLS certificate (provisioning / active / failed). Use this to explain to the user why a custom domain isn't live yet.
get_domain_hosts
ChatGPTThe site's custom domain as its two hostnames: the canonical host (serves the site — visitors see it) and the redirect host (301s to the canonical), each with its wiring status and, while pending, the exact DNS records still needed. Use this to narrate domain status; use set_canonical_host to swap which hostname serves.
get_preview_link
ChatGPTMint a time-limited signed URL to the LIVE working version of this site — the real files, served exactly as they will publish. The link requires no login. Use it two ways: (1) give it to the user so they can see their site in their browser right now, before publishing; (2) open it YOURSELF in your own browser to inspect the running site — view the rendered result, check layout and content, and debug — it is your window into the live site, not an opaque string to forward. Links expire after 30 minutes; mint a fresh one whenever needed.
get_publish_state
ChatGPTRead the site's full publishing state: whether it's live, its hosts (hosts lists exactly what serves — the slug host only when slug_serving is on, plus the custom domain when active), the custom-domain status and the records the user must add (the A-record target in domain_a_record_target is the load balancer the domain is assigned to). ALWAYS call this first when you take over a publishing conversation, so you reason from real state.
get_site_overview
ChatGPTOne orientation read for an existing site: its files, name, slug, publish state, custom-domain state, and subscription status. Call this before working on a site you didn't just create.
get_subscription_status
ChatGPTThis site's commercial picture: plan (premium/free), status, renewal date, pending cancel, the domain serving it, and whether its included free domain is still unclaimed. Call it before any billing/subscription conversation — and mention the unclaimed included domain when relevant.
grep
ChatGPTSearch every file in the site for one or more strings or regexes, returning each matching line with its file path and 1-based line number. queries is a JSON array of 1 to 15 strings — a single lookup is a one-element array like [".hero"]. When several lookups are related (a handful of selectors, variables, paths), batch them into one call: the files are scanned once for all queries together, which is far cheaper than one call per query. Queries are matched as literal, case-sensitive substrings exactly as written — <, quotes, and backslashes are ordinary characters, so search for <section or class="card" as-is. Never HTML-encode (< will not match <) and never regex-escape (\.hero will not match .hero — write .hero). Set isRegex to true to compile every query as a regular expression instead (a bad pattern returns a clear error). glob is REQUIRED and states which files are scanned — /www-rooted like every other path: /www/css/*.css scans only the css folder (one level), /www/**/*.{html,css} every HTML and CSS file site-wide (braces cover several extensions), /www/** the whole site — the right scope for reference-integrity checks before renaming or deleting a file. Each hit is { path, line, text } where text is the matched line trimmed and clamped to ~200 characters. maxResults caps hits PER QUERY (default 100); a capped query sets truncated: true — there is no pagination, so narrow with a more specific query or a glob and re-run. Returns { results: [{ query, matches, count, truncated }], totalCount }, one entry per query in input order. Binary (non-UTF-8) files are skipped. Use grep for reference integrity — find every place a CSS class, asset file, anchor id, or URL path is referenced before renaming or deleting it — and for locating a rule you already know you need. To survey a whole file's structure (every CSS selector, heading, or id with line numbers) use outline instead; to see how the page actually RENDERS (computed colors, backgrounds, spacing, what visually merges with what) use inspect_preview_css or a screenshot rather than reconstructing the cascade from source.
image_info
ChatGPTGet an image's width, height, format, byte size and nearest canonical aspect ratio without loading its pixels into context. path is the image's absolute path (e.g. /uploads/photo.jpg). Use it before placing an uploaded image: compare nearestAspectRatio with the slot's ratio and crop_image when they differ, and spot a 4000px / 3 MB upload that should be downscaled with optimize_image.
list_domains
ChatGPTThe workspace's domain portfolio: every domain owned through Ullbek with status, registration and expiry dates, who pays its renewals, and which site (if any) it points at. undo_until = our estimate of how long a purchase can still be cancelled for a full refund with revoke_domain; the registry is the judge, so a recent purchase is worth trying even if the field is empty. past = history, not actionable: names this workspace once ordered that are no longer its domains (cancelled and refunded, registration failed, checkout never completed) with when and why — the answer to 'what happened to X'. The place to start any 'my domains' conversation.
list_files
ChatGPTList files and folders. Works like ls with a find mode: list one folder, drill into a sub-folder, list a folder recursively, or find files by glob. Every entry has path (absolute, e.g. /www/index.html; a /www file's URL is its path minus /www), size in bytes, and version. Examples: list_files() → the top-level folders: /www, /uploads, … list_files(path: "/www") → the site's top level: sub-folders + pages list_files(path: "/www/images") → one folder's files list_files(path: "/uploads") → what the user uploaded list_files(path: "/www", recursive: true) → every file on the site, paged list_files(glob: "/www/*/.html") → every page, wherever it is list_files(glob: "/uploads/.{png,jpg}") → the user's images Globs: ` matches within one folder level, ** recurses, {a,b} covers alternatives. Start at a folder and drill in; recurse or glob only when you need the whole set. Long listings page with offset and limit (default 100); the response reports total and truncated`.
list_sites
ChatGPTList every site in the user's workspace: site_id, name, slug, publish state. Call this first on any reconnect to orient — the site_id is the handle every site-scoped tool needs.
load_skill
ChatGPTLoad a curated Ullbek skill: our recommended approach for a recurring build task, returned as a short guide to combine with your own expertise and current web info. Skills are guidance, not rules — keep using your world knowledge. Load one just-in-time when a request fits. Available skills: - form_submit: collecting visitor input (contact, signup, feedback, booking forms) via Ullbek's built-in form backend — submissions are emailed to the site owner and readable with read_form_submissions. - icons: whenever a site needs icons — a curated shortlist of CDN icon libraries matched to the site's aesthetic, with pinned CDN snippets, instead of hand-rolling SVGs for standard concepts. - charts: showing the user's data (growth, results, stats) — chart library ladder from Chart.js up to D3, with the non-negotiables. - selling: taking payments (products, services, subscriptions) via hosted providers like Stripe Payment Links — never first-party checkout. - maps: showing a location, directions, or service area — keyless embeds first, Leaflet for custom pins. - embeds: third-party widgets — appointment booking (Calendly/Cal.com), YouTube/Vimeo video, social posts — with the responsive/privacy rules. - galleries: image grids and masonry with a lightbox, wired to our image pipeline for real thumbnails. - local_seo: publish-time polish for local businesses — LocalBusiness JSON-LD, titles/descriptions, social cards, favicons.
lookup_registrar
ChatGPTFind out who runs a domain, so you can name the user's providers yourself instead of asking them. Returns the registrar of record (via RDAP, with its IANA id) and the domain's authoritative nameservers. IMPORTANT: DNS records must be added wherever the NAMESERVERS point (e.g. *.ns.cloudflare.com → Cloudflare, ns*.wixdns.net → Wix, *.domaincontrol.com → GoDaddy) — that's the registrar's own dashboard only when the nameservers are the registrar's. Some country TLDs publish no RDAP; then registrar is null (see note) and you identify the DNS provider from the nameservers alone.
move_file
ChatGPTMove or rename a file from one absolute path to another (e.g. /www/old.html → /www/new.html). Note: a file's URL is its path minus /www, so moving it changes the URL — afterwards, run check_references (or update any href/src/import that pointed at the old URL) so nothing breaks.
optimize_image
ChatGPTConvert/resize one source image into one or more written site files in a single call. path is the image's absolute path (e.g. /uploads/logo.svg, /www/images/photo.jpg) — raster or SVG; outputs (≤8) each write a destPath (under /www, served at the path minus /www; the extension sets the format unless format is given) with optional maxWidth/maxHeight and quality (1–100, default 80, JPEG/WebP). Raster sources downscale only (aspect preserved, never upscaled) — serving an image at its display size is the biggest performance win. SVG sources rasterize at exactly the requested size (pass maxWidth), so icons from a vector logo stay crisp. ico output packs a standard 16/32/48 favicon.ico. One intention = one call: a favicon set (/www/favicon-32.png 32px + /www/apple-touch-icon.png 180px + /www/favicon.ico) or a responsive srcset (480/960/1600 JPEGs) is a single call with several outputs. Returns a per-output manifest (format, dimensions, size) with per-output errors.
outline
ChatGPTReturn the cheap SHAPE of one site file so you can target a read_file slice (by offset/limit) instead of reading the whole file. Give it an absolute path (e.g. /www/index.html); it picks a strategy by extension and returns a flat list of symbols, each with name, kind, and 1-based line. For HTML: headings (kind heading, name = inner text), every element with an id (kind id, name = the id), and <title> (kind title). For CSS: the selector text before each { (kind selector). For JS/MJS: top-level-ish declarations — function/class/const/let/export (kind decl, name = the identifier). For any other file the symbol list is empty. This uses lightweight regex scanning, not a real parser, so it is approximate. Symbols are capped at 200 and each name is clamped to ~120 chars; use the line numbers to read the exact region you care about.
publish_site
ChatGPTPublish the site live: save it, push its files to the hosting CDN, and mark it published. Idempotent — call again to push the latest changes. Returns the live URL(s). The site serves on whichever hosts are ON: the free slug address (unless turned off via set_slug_serving) and the custom domain when one is active. With no host on at all, this returns blocked.reason: no_host — relay the choice to the user instead of retrying.
read_file
ChatGPTRead files' contents as line-numbered text — up to 10 files or slices in ONE call (files, an array of {path, offset, limit}). Several related reads (a script and its stylesheet, three ranges of one file) belong in one call, not several. path is the file's absolute path (e.g. /www/index.html — a /www file's URL is the path minus /www, so /www/about.html is served at /about.html; or /uploads/notes.md, a file the user gave you). Use this for text files (HTML, CSS, JS, Markdown, JSON, …). For a large file, page with offset (1-based start line) and limit so you only read the part you need. Each result includes a version — pass it to write_file as expectedVersion for a safe conditional overwrite. A file that can't be read reports its own error without failing the others. To LOOK AT an image or PDF instead of reading text, use view_file.
read_form_submissions
ChatGPTRead this site's contact-form submissions (newest first): the submitted fields, which page they came from, the spam verdict, and whether the email notification was sent to the site owner. Use it to verify a form you built end-to-end (submit a test through the live form, then read it back here) and to answer questions like "did I get any messages?". Submissions marked test came from the builder preview. If your own test shows verdict spam, resubmit with a realistic customer-style message - junk text gets filtered.
read_site_info
ChatGPTRead the site's metadata: the name the user typed when creating the site, its slug, whether it's published, its public URL, and any custom domain, plus form_endpoint — the exact URL the site's forms post to. Call it when building or updating the site brief, choosing titles/branding, wiring a form, or answering what the site's URL is or whether it's live. Read-only — publishing actions still go through the publishing specialist.
record_feedback
ChatGPTRecord a piece of feedback into our continuous-improvement log. Use it in two ways. (1) AUTONOMOUSLY: when a tool fails, behaves wrong, or a capability you needed is missing, file it as source: agent with the details — then keep working and solve the user's request by other means. This is a side-channel to the Ullbek team, not a substitute for finishing the job, and you never need the user's permission to file it. (2) RELAY: when the user expresses how they feel — praise or a complaint about the product/agent (not a normal build request) — capture it as source: user with their wording in detail. Pick sentiment positive/negative, a one-line summary, and a short category. Filing feedback is quick and must never block or delay the user's actual request.
resolve_a_record
ChatGPTLook up a hostname's public A records (IPv4) right now, to help debug a custom domain that isn't resolving. Returns the addresses it currently resolves to (empty if it doesn't resolve).
set_canonical_host
ChatGPTSwap which of the custom domain's two hostnames serves the site (the canonical host); the other becomes the redirect host and 301s to it. Answers "make it www.rosie-bean.com instead" in one call. The hostname must already be wired (its certificate live) — check get_domain_hosts first if unsure. The swap runs in the background and takes a minute or two; the returned state's flip field tracks it (poll get_domain_hosts or publish state to see it finish). Tell the user the switch has started and continues on its own — both addresses keep working throughout.
set_custom_domain
ChatGPTBegin custom-domain setup for the site. Assigns the domain to one of our load balancers, provisions a TLS certificate, and returns the DNS records the user must add at their registrar: a CNAME for validation and an A record pointing at the assigned load balancer's IP (read it from domain_a_record_target in the returned state) — just those two; keep the first setup minimal. After they add the records, call verify_custom_domain. Tell the user the exact records. (The domain's other spelling can forward here too — an opt-in via set_redirect_host, best offered once the domain is live.)
set_redirect_host
ChatGPTThe forwarding OPT-IN: set up the domain's other spelling as a redirect host (301 → the canonical host), when the customer wants it. For a domain registered through us the DNS records are written automatically — nothing for the customer to do. For a BYO domain, give them the records from the returned state (redirect_hostname A → domain_a_record_target, plus the redirect_cname_* CNAME); it activates on a later verify whenever they add them.
set_site_name
ChatGPTRename the site — the label the user sees on their dashboard and in the builder, NOT the public URL. Use it when the user asks to rename their site, or when the placeholder name from creation is settled into a real one with the user's agreement. It never changes the slug, domain, or anything published — changing the web address is the publishing specialist's set_slug.
set_slug
ChatGPTChange the site's subdomain (the friendly host {slug}.{suffix}). The slug must be a valid DNS label and globally unique. If the site is live, the new subdomain takes effect immediately and the old one stops resolving.
set_slug_serving
ChatGPTTurn the site's free slug address ({slug}.{suffix}) on or off. The slug and a custom domain are independent places the site can serve — off means the slug address 404s and the site serves only on its custom domain (domain-only hosting, what users mean by 'I don't want the free address'). On (the default) means the slug serves the site — or redirects to the custom domain when one is active. Takes effect immediately on a live site. Confirm before turning it OFF on a live site with no active custom domain: that takes the site fully offline. Returns the fresh publish state.
take_screenshot
ChatGPTRender the site fresh in a stateless headless browser and capture it. Each call renders independently and sees NOTHING you did to the user's preview, so set the state you need here: path — which page (e.g. "about.html", default the root); device — "phone" (390×844), "tablet" (768×1024) or "desktop" (1280×800, the default); width — a custom viewport width when no preset fits (pass one of device/width, not both); run_js — JavaScript run before the shot (toggle a theme, open a menu, freeze an animation); wait_for — extra wait (ms, a CSS selector to await, or "load"); every capture settles briefly on its own. Framing, narrowest first: selector crops to the element matching a CSS selector; section scrolls that element into view and captures one viewport around it; the default is the page's top viewport; full_page: true is the whole page in one image — the page is scrolled through first so reveal animations and lazy media render, and tall pages are downscaled, so fine text won't be legible. To capture what the user is currently looking at instead (their live viewport + state), use capture_preview.
unpublish_site
ChatGPTTake the site offline (docs/73): every address it serves on — its own domain, any www/apex redirect, and the free ullbek.site address — shows a not-found page until it is published again. Reversible and non-destructive: the site's files, its reserved free address, and a connected custom domain (DNS, certificate) all stay, so publishing again restores the same addresses instantly. It does NOT cancel Premium hosting — that is a separate, explicit decision (cancel_subscription, at period end). Requires confirm: true; refused otherwise. Before calling, tell the user which addresses go offline, what stays, and that Premium keeps running — then ask (ask_user). Idempotent on an already-offline site.
validate
ChatGPTCheck a file for structural problems a browser won't report: JS syntax errors (a full parse — a syntax error silently disables the whole script file), unbalanced CSS braces, unterminated strings or comments, an unclosed HTML comment, and the CSS inside <style> blocks. This is the compiler stand-in. write_file and edit_file already run these checks automatically and return any warnings, so you usually don't need to call this — use it to re-check a file, or to validate content before writing it. Returns { path, ok, issues: [{ line, severity, message }] }.
verify_custom_domain
ChatGPTCheck a pending custom domain now: when the certificate is active AND the DNS A record resolves to our load balancer, the domain goes live and is bound to the site. Otherwise it reports what's still pending. Run this after the user has added the DNS records. On activation the response includes a live_check — an end-to-end fetch of the domain. Only tell the user the domain works when live_check.ok is true; a tls failure means the edge isn't serving the new certificate yet (it can take ~15–30 minutes), so say it's verified but still rolling out.
view_file
ChatGPTLook at a file as an image or PDF that you (the model) can see — it loads into YOUR context, not the user's chat. path is the file's absolute path (e.g. /uploads/logo.png for something the user gave you, /www/images/hero.jpg for a file on the site). Use this to view a logo to match, a photo, a sketch to turn into a layout, or a whole PDF at once. A PDF loads whole only on a model that reads PDFs; otherwise this tool points you at read_pdf_as_text (its words, cheap) and view_pdf_as_images (its pages), which work on every model and are the better first stop for a long document anyway. To show an image to the USER (e.g. a generated image to approve), use ask_user with an image preview instead. To READ a text file (HTML, CSS, JS, Markdown, …) use read_file instead — point view_file at text and it will tell you to.
write_file
ChatGPTCreate or overwrite a file at an absolute site path (e.g. /www/index.html). Writes the full content — the file is served exactly as written and is immediately live in the preview at the path minus /www (file /www/about.html is the URL /about.html). Write only browser-native code: HTML, CSS, vanilla JS, ES modules, import maps, CDN imports — there is no build step. Set createOnly to avoid clobbering an existing file, or pass expectedVersion (from read_file) for a safe conditional overwrite. To change part of an existing file, prefer edit_file.