Release notes
What’s new.
Release notes for Foxl, including new features, improvements, and bug fixes by version. Foxl Agent, Foxl Code, and Foxl Notes ship under one version number, so every entry below covers all three.
Open Settings › General in Foxl to check your installed version. Updates install themselves; download the latest build if you are starting fresh.
Features
- Remote chat: on the accounts it is offered to, Foxl can now answer while your computer is offline. Turn it on with the card in an empty chat or under Settings > Chat > Remote chat, and a new chat started in the iPhone, iPad or Android app or at app.foxl.ai while your computer is away is answered from Foxl's cloud on your Foxl credits, with a Cloud label beside the model while it is. Stop ends the reply in the cloud; closing the app does not, and the chat shows the finished reply when you open it again. These conversations are stored in Foxl's cloud (Amazon S3 in the US West region, encrypted at rest) and come back to your computer when Foxl is next open on it, under the same conversation; once you continue one there, it is your computer's. Deleting a cloud conversation on your phone or at app.foxl.ai while your computer is away deletes its stored copy; a delete on your computer, or one that reaches it because it is online, moves it to the trash, which keeps the stored copy so it can be restored, and deleting it for good (Delete permanently, Empty trash, or the trash's 7-day cleanup) deletes the stored copy too. Retry and Edit are not available in a cloud chat. A desktop chat continued in the cloud with Continue here says "Continued from" and the original's title above its first message. Images too large to keep in a cloud chat are named by count where they were. Fable 5.1, Fable 5, GPT-6 Astra, GPT-5.6 Sol and GPT-5.6 Terra do not run in the cloud: a cloud reply picked for one of them uses Sonnet 5.5, and says so. Nothing changes while your computer is reachable.
- GPT-6.1 Sol is in the model picker when you sign in with ChatGPT Plus/Pro, as it already is with your own AWS account: reasoning always on (
lowtomax), and a 500K-token context window on that connection. GPT-6 Sol, the one that can switch reasoning off, moves behind Show older model versions there too, as on Amazon Bedrock. GPT-5.5 leaves the ChatGPT list: OpenAI no longer serves it to ChatGPT accounts, so every message to it failed with "not supported when using Codex with a ChatGPT account". If GPT-5.5 was your model, the message box moves to GPT-6 Astra on the same ChatGPT sign-in and a new chat says so, and a schedule set to it runs on Foxl Agent's model with a note in its result. GPT-5.5 is still available through Amazon Bedrock or an OpenAI API key.
Improvements
- Settings has a new Chat pane with the settings about how a chat looks and behaves, which used to be spread over three panes: Send messages with, Show plan checklist and Show files changed (from Appearance), Open links in other apps and Show "Explain details" on selected text (from General), Remember the model for each chat (from Model & provider) and, on app.foxl.ai and in the phone apps, Offline chat history (from General). Each keeps the choice you already made, and the command palette finds each one by name. On code.foxl.ai the pane has the two that Foxl Code uses, Send messages with and Open links in other apps.
- With a Claude Pro/Max sign-in, Foxl now uses Claude's prompt cache. The part of a chat Claude has already read (Foxl's instructions, its tools and the conversation so far) is read back from the cache instead of in full again when the next call comes within five minutes, as it does between the steps of a reply that uses tools: on Opus 5.5, the second call of such a step read 4,621 of its 4,698 prompt tokens from the cache, where every call used to read none. The Usage page counts those cached tokens once, at the cached price, and a Claude reply that is still running when you pick a ChatGPT model in another chat is no longer listed under ChatGPT.
- In the Android app on Android 16, a Back swipe on a first screen, such as a new chat, now shows Android's own preview of the home screen while your finger is still down, as other Android apps do; let go and Foxl goes to the background, and it opens again where you left it. Android 13 shows the same preview with the developer option for predictive back animations turned on. Back still closes an open menu or the drawer, and goes back a page, before it leaves the app.
Fixes
- The phone approval set-up now says that the phone's passcode or screen lock works too, and its Set up, Cancel and Stop buttons are easier to tap on Android and in a phone's browser.
- A reply no longer waits without end when the network drops the model's connection, as in-flight WiFi does. A model call that receives nothing at all for 5 minutes, not even the keep-alive a provider sends while the model thinks, is closed and tried again once, so a reply that spun until the Mac woke up (35 minutes in one case) now recovers or says what happened. Models running on your computer or your own network are left alone. On Claude and ChatGPT sign-in, a dropped connection or a server error is also retried, where it ended the reply on the first failure.
- A message waiting in the queue above the message bar now shows a long paste the way your sent message will: as a chip with the paste's title, beside the words you typed, and a conversation you referenced as its title. The queued row used to print the paste's hidden markup instead (
<attached-text title="...">followed by the start of the pasted text), which filled its one line before anything you wrote. On every device.
Features
- Allow a computer-use step from your phone. Set the phone up once: tap Approve from this phone under the approval card (or Set up in Settings > Desktop), then accept the phone in Foxl on your computer, which shows the same six-digit code as the phone. From then on the phone answers a computer-use step with the same Deny, Allow and Always allow as the computer, and in the iPhone, iPad and Android apps every Allow first asks for Face ID, Touch ID, a fingerprint, or the phone's passcode or screen lock (Android 9 or later). A phone's browser can be set up too; it asks for nothing before an Allow, so anyone using that browser can approve, and the computer's card says so before you accept it. A phone is accepted in Foxl on your computer, not from the phone, and Settings > Computer use > Devices that can approve lists them and removes one at once. This keeps a phone from allowing computer use by itself; it is not a sandbox, and a connected device can still run commands on the computer through the terminal and shell tools as before. Deny still works from any phone without setting it up. Your computer needs this version too; until then the phone says to update it.
- On a phone (the iPhone and Android apps, and a phone's browser), you can now pull the sidebar's Recent chats down to refresh the list: with the list at its top, pull it down and let go, and the list loads again from your desktop while a circle spins above it. The chat you have open stays open, and the chats you had already loaded further down stay loaded. A new refresh button beside Recent chats does the same with a tap. If your desktop is offline, a message says the list shows the chats saved on this device, and if the list could not be loaded, a message says so and the list stays as it was. Only the list reloads, never the whole app, and the desktop app is unchanged.
Improvements
- On a Mac, the on-device model's first answer after a reload can come much sooner. Once the model has prepared the chat's long opening prompt (Foxl's instructions, what it remembers about you, your recent conversations and its tools), Foxl keeps that preparation on disk and reads it back the next time the model loads, for example after a recording on a Mac with less than 16 GB of memory stopped the model, or after it was unloaded for sitting idle. It helps only while that opening prompt is unchanged: with memory on it changes about half an hour after each conversation, and whenever Foxl saves a memory or your tools or instructions change, and then the model prepares it from scratch as before. Measured on an M5 with Gemma 4 E2B, with an unchanged prompt the first answer after a reload came in about 1 second instead of about 8, and it was the same answer. A saved prompt takes about 95 MB of disk with Gemma 4 E2B (more with a larger model), at most two per model, in Foxl's own folder, and none is saved when less than about 2 GB of disk is free. The saved prompts are deleted with the model and when you sign out. Windows and Linux are unchanged.
- While Foxl Notes transcribes on this device and the on-device model answers a chat at the same time, the line of words still being recognized now holds still until the answer is done, and the finished sentences keep arriving. Both run on the same chip, and redrawing that line slowed both: measured on an M5 with Gemma 4 E2B, a new chat's first words came about 1 second sooner (6.5-6.8 s instead of 7.5-8.1 s), and the sentence finished during the answer arrived about half a second sooner. A Notes request, such as a translation or a summary, does not pause the line.
Fixes
- Channels no longer opens on a blank screen when you come back to it. In the iPhone, iPad and Android apps and on app.foxl.ai, a room you read before shows its last messages right away, also after more than a minute away and after the app was closed, and new messages, edits and deletions arrive a moment later; a picture of up to 4 MB that you already saw there is not downloaded again. What the device keeps for this is small and limited: the room lists of up to 8 Workspaces, the newest 50 messages of up to 24 rooms and up to 48 MB of pictures, encrypted like the chat history Foxl already keeps on the device, and anything you have not looked at for a week is dropped the next time you use Channels. It is all deleted when you sign out or another account signs in, the messages of a room you can no longer open are removed the next time Foxl loads its Workspace's rooms, and blocking someone on this device removes the saved rooms so their messages do not come back. The desktop app and code.foxl.ai also open a room you come back to on its messages, but keep nothing once closed.
- In the iPhone app, a file that arrives while the message bar is folded (shared to Foxl from another app, kept for you while you sign in, or picked with + > Files) now opens the message bar with the file in it, where an empty white box showed before. A plain text (.txt) file shared from the Files app is now attached as well: shared alone it got a message saying Foxl could not attach it, and shared together with other files it was left out without a word.
- In the iPhone, iPad and Android apps and app.foxl.ai, when your desktop runs a Foxl older than 0.9.0, the model selector now shows GPT-6 Astra's Ultrafast switch greyed out, set the way your desktop has it, with a line saying to update Foxl on the computer to change it from the phone; before, the switch was simply missing. Messages from the phone still run at the desktop's setting, as before. And when your desktop is too busy to answer for a moment while the app is open, the model selector keeps your desktop's models, the model you picked and your Ultrafast choice; before, your desktop's models dropped out of the list, and your next message could go out on a different model or without your Ultrafast choice.
Features
- Settings > Connect > Channels lists ten more channels, each with its own logo: Discord, iMessage on a Mac (nothing to install: Foxl reads your messages and sends its replies through its own Foxl Messages app, which is the app macOS asks for Full Disk Access and, when you press Start, whether it may control Messages; SMS and RCS chats included; Foxl answers only messages from another account, so a message you send to yourself gets no answer and Start refuses an allowed number or email that belongs to the Apple Account Messages uses on that Mac: to write to Foxl from your own phone, sign Messages on the Mac in to a separate Apple Account for Foxl), Matrix, Mattermost, Feishu / Lark, Nextcloud Talk, IRC, Twitch, Nostr and Zalo. Each answers only the people you list, and an SMS is answered in your iMessage or RCS conversation with that person when there is one. An SMS sender's number can be forged, so an allowed number is weaker proof over SMS than over iMessage; Settings > Safety > By where a run comes from > Channels sets what a message from any channel may do. Connecting iMessage asks for Full Disk Access with one button, the way Computer use asks for its permissions: System Settings opens with a panel beside it to drag Foxl Messages into the list, and Foxl starts the channel once it can read your messages. If macOS does not let Foxl Messages control Messages, the iMessage row says replies cannot be sent and where to allow it. Typing indicators and read receipts are not available over iMessage. Nostr was tested with real messages; iMessage's reading was checked against a real Messages database, but a reply to another person has not been sent yet, so iMessage, IRC (its refusals and its sending were tested, an allowed account was not) and the others are marked Preview until they have been. Microsoft Teams, Google Chat, LINE, Synology Chat and SMS through Twilio are not offered: those services deliver messages only to a public web address, which the desktop does not accept. Their notifications share one new switch, Settings > Notifications > Other channels.
- Connecting iMessage on a Mac opens on the recommended setup: an Apple Account of Foxl's own, so you message Foxl like any other contact instead of writing to your own number. The dialog suggests its address from your Foxl account (for a Gmail address,
you+foxlbot@gmail.com, whose mail arrives in your own inbox; use another address if Apple refuses the+), links to Apple's page for creating it, makes a second user on this Mac for it behind macOS's administrator prompt, and checks off each step up to the first message from your phone. That user stays logged in in the background (fast user switching). The dialog's iMessage setup guide link opens the iMessage part of the Channels page in Foxl's docs, which links a new step-by-step guide with a screenshot of each step, what to do after the Mac restarts and how to undo the setup. This setup has not yet been run end to end on a real Mac, one more reason iMessage is marked Preview. - You can DM the Slack bot directly. Only people in Allowed Users can, and the Slack app needs the
message.imevent, theim:historyscope and the Messages tab turned on in App Home. - Switch on a channel in Settings > Connect > Channels and the people you allowed are on the Channels screen right away, each as a conversation with no messages yet, with or without a Workspace, so you can write first (on Telegram only to someone who has messaged your bot before: Telegram does not let a bot start a conversation). When one of them writes, it continues that conversation instead of opening a second one. This works for Telegram, Signal, Slack, Discord, iMessage, Mattermost, Nostr and Zalo the first time the channel connects; Matrix, Feishu, IRC, Twitch and Nextcloud Talk still show a conversation once someone writes, and a channel that already has conversations keeps just those.
- The mini-game behind the version row (tap the version in Settings > General > About seven times) is now Sticker Pop, and it replaces the Foxl Den. Foxl's pets are die-cut patch stickers piled on a cutting mat: tap a sticker nothing covers to peel it into the tray, and three of the same stick in your album. Seven different ones fill the tray and end the round. Every board can be cleared, the levels keep coming (every fifth one from level 10 is a bigger Hard level, and the next is a breather), and each level adds new stickers until your album holds all 120, some of them holographic. Undo, Pocket (lifts three stickers out of the tray) and Shuffle each help once a level, there is sound and haptics, and a round you leave is still there when you come back. It plays the same by touch in the iPhone, iPad and Android apps and in a phone browser, and with a mouse on the desktop. There is nothing to buy and nothing random to win. The den's summon, care, catch, daily tasks and its weekly notification are gone; the companion that walks around the app is unchanged, and Settings > Pet is where it is drawn now.
- In the iPhone and iPad app, opening Foxl while signed out now starts on a welcome screen. Foxl's pets float round the Foxl wordmark as stickers and the fox peeks over a glass planet at the bottom of the screen (Liquid Glass on iOS 26 and later; a starry night in dark mode). Swipe up (or tap Swipe up to enter) and the planet follows your finger, then shrinks into a small glass orb that a collage of stickers bursts out of: the pets, speech bubbles, today's date and little cards for a meeting recording, a pull request and a terminal. Tap a sticker to make it bounce, or the orb to pour them out again, and Get started takes you to sign-in as before. With Reduce Motion on, the screen fades between its steps instead. When Foxl opens from a link, such as a sign-in link from your email, it goes straight there without the welcome.
- The iPhone app now looks like its welcome screen inside too. A new chat, the Notes home and Foxl Code's first screen sit under the same soft sky (a starry night in dark mode) while Settings > Appearance > Color theme is Foxl, with Foxl's pets as stickers where the Foxl mark used to stand alone: the fox with friends on a new chat, two pets beside Start Recording, the frog and two pups on Foxl Code. Sign-in continues the welcome with the same sky and stickers, Continue with Google as a solid pill, the other ways in as white pills and a round email field. Buttons across the iPhone app are now pill-shaped, outlined ones as white pills with a soft shadow, and Desktop offline is a white pill. An empty notification list shows a sleeping cat, and a search with no results a hedgehog. The iPad, the desktop and app.foxl.ai are unchanged, except a new chat in a phone's browser, which now looks like the app's (below).
- Skills > Sync now brings the updated Claude Code and Codex skills: ask Foxl, from the desktop or your phone, to have Claude Code or Codex do something on this computer, then ask how it is going, answer its questions or send it more instructions, and stop it. On a Mac and on Linux, instructions sent while Claude Code is busy wait their turn and go in when it finishes what it is doing, in order, instead of being refused or cutting it off. Each task runs in the background in its own copy of the repository, and Foxl answers "how is it going" with one line per task, leading with anything that needs you. Both skills ship turned off; turn them on in Skills.
- Skills > Sync also brings a refresh of every skill in the library: each one was re-checked against Foxl's tools and the current versions of the apps and services it uses, and the ones that told Foxl to run commands that no longer exist (voice calls, local text-to-speech, the security health check, Git, Gemini CLI sign-in) now give it commands that exist. The Word, PDF, PowerPoint and Excel skills were rewritten as our own work under the library's MIT-0 license.
- In the iOS and Android apps, Foxl is now in the share sheet for documents: share a PDF, Word, Excel, plain text, Markdown, CSV or RTF file from another app to Foxl and it is attached to a new chat, ready for your question, and nothing is sent until you send it. Several files in one share are attached together. PowerPoint files and photos are not offered yet, and a shared link or text selection is not attached: Foxl says which files it can attach.
- Gemini 4 Argon, Google's new flagship reasoning model, is in the model picker for OpenRouter, Google AI (your own API key) and Gemini CLI, with its 1M-token context. Its reasoning cannot be turned off, so there is no off switch; on OpenRouter you choose Low, Medium or High. Google offers it on paid API keys only, not on the free tier or the Google AI Pro plan, so a free AI Studio key is refused with a quota error.
- foxl.ai/design shows Foxl's design system: its type in the real typefaces, the phone apps' type scale, ink, paper and Foxl Blue, the sky and its glass, motion, which pet each kind of empty screen shows, and Foxl's pets as 120 patch stickers, 15 pets in 8 poses each, to download as PNG one by one or as a single ZIP. The footer links to it under Resources.
- On a phone, the tab bar gets smaller while you scroll, shaped like Safari's toolbar: as soon as you scroll a page away from its bottom, up or down, the whole bar shrinks to two thirds of its size, icons and all, staying centred at the bottom of the screen. In a Foxl Agent or Foxl Code chat the message bar comes down with it by the same distance, so more of the conversation shows, and the jump-to-latest button above it comes down too. At the very bottom of the page (a chat's newest message, the end of a list) it is full size again, as it is when you open a chat, tap the small bar or open another page; a page too short to scroll keeps the full bar, and a new reply, the keyboard and older messages loading do not change it. In the iPhone app this needs iOS 26 or later (on earlier iOS the bar stays as it was); the Android app, and app.foxl.ai and code.foxl.ai in a phone's browser, do the same, and their bar is now only as wide as its tabs, like the iPhone's, instead of always spanning the screen. There, with a hardware keyboard, choosing a tab on the small bar opens it at once. Nothing else on the page moves.
- Gmail, send only, in the desktop app: connect it in Settings > Connect > Integrations while signed in to your Foxl account, and Foxl can send email from your own Gmail address when you ask it to, in a chat or a schedule. Foxl cannot read, search or delete your mail. The access is stored encrypted on your computer, and disconnecting asks Google to revoke it. This is the first release with Gmail, so tell us if connecting or sending fails. Until Google finishes reviewing the app, its sign-in may show a "Google hasn't verified this app" screen.
- Foxl Notes can put names on the speakers in a transcript. After a recording or an import with two or more voices, Foxl sends the transcript to a fast model on your AI provider and replaces Speaker 1, Speaker 2 with a person's name when the conversation says it: someone introduces themself, or is addressed by name and answers. A calendar invitee's full name can be used when the conversation says that name, for example Tom for Tom Lee. When the transcript split one person into two speakers (a voice that moved away from the microphone, a long pause), it makes them one speaker again. This happens before the summary is written, so the summary, the title and the report use the names too. A name nobody says in the conversation is never used, a speaker you renamed keeps your name, two speakers who keep answering each other's questions are never merged, and a speaker without a name stays Speaker N. A message lists what changed, with Undo. It is off by default: turn it on in Settings > Notes > AI features > Name speakers automatically. Each recording with two or more voices then sends one more short request to your AI provider.
- GPT-6 Astra's Ultrafast switch is now in the model selector on your phone and iPad too (the iPhone, iPad and Android apps, and app.foxl.ai), when the GPT-6 Astra you picked runs on your desktop's own AWS account. It works as it does on the desktop: it takes the place of Reasoning's "Always on", and with it on, the messages you send from that device run on Amazon Bedrock's Ultrafast tier, at six times the Standard price. Until you change it there, the switch shows your desktop's own setting and those messages run on it, as before. The choice belongs to that device: it does not change the desktop's own switch, no other model gets it, and GPT-6 Astra on Foxl credits still has no Ultrafast tier. It needs your desktop on this version; with an older one the switch does not appear.
Improvements
- On a phone (the iPhone and Android apps, and app.foxl.ai in a phone's browser), Files is now a folder browser: one folder per screen, its name at the top with how many items it holds. Tap a folder to open it, and Back (the link under the top bar, a swipe from the left edge in the iPhone app, Android's Back button or the browser's) goes up again. A folder shows as a list (each file's name, when it changed, what kind of file it is, and its size in a column of its own) or as icons, with photos, PDFs (when your desktop is a Mac) and the first lines of notes as small previews. The "..." menu switches between the two, sorts by name, kind, date or size, groups by kind or date, and makes a new folder or file; Foxl remembers the view for each folder on that device, and a folder that is mostly pictures opens as icons. Press and hold a file or folder for its menu: open, share, ask the agent, rename, duplicate, copy, cut, paste, copy path and delete. Search looks in the folder you are in as you type, or everywhere: by name for any kind of file, and inside your notes. Recently changed now shows on every phone, not only the iPhone. Files also opens much faster: the phone asks your desktop for one folder at a time instead of the whole workspace (on a workspace of 11,000 files, about 3 KB per visit instead of 2 MB), shows a folder it has seen before at once while it checks for changes, and loads previews only for what is on screen. A file still opens in the same viewer as before. The desktop app and the iPad keep the file tree; with a desktop that has not been updated yet, the phone reads the whole workspace as it did before and shows no previews.
- On a phone (the iPhone and Android apps, and app.foxl.ai in a phone's browser), the chat's message bar now rests as one slim line: the attach button on the left (the + in the iPhone app), the words that open it, and the microphone on the right. Tap it and it opens into the full message bar you know, with the model, the tools and the send button, growing with the keyboard as it comes up; leave it empty and it folds back down. A draft, an attachment or dictation keeps it open, and while a reply is coming the resting bar shows Stop in place of the microphone. In the iPhone app on iOS 26 and later the resting bar is the system's Liquid Glass, the material of the Search conversations bar and of the tab bar; open, and everywhere else, the bar keeps today's frosted look, so the conversation behind it never shows through. The desktop, the iPad and wider browser windows keep today's message bar.
- In the iPhone, iPad and Android apps, Get started on the welcome screen is set in Fredoka, a round typeface that belongs with the pet stickers, with NanumSquareRound for Korean. Everything else keeps its typeface.
- In the iPhone and Android apps, more empty and error screens show one of Foxl's pets, and a pet always means the same thing: the calico asleep when there is nothing yet (an empty inbox, no schedules or runs, no summary or report yet, nothing running), the hedgehog when a search or a filter finds nothing, the frog crying when Foxl can't reach your desktop or something failed to load, and the bunny waving when something needs connecting first (your desktop for Agents, Usage and Tasks, a channel, a team workspace, GitHub in Foxl Code). A screen that is nothing but an empty state, such as an empty inbox or Channels while your desktop is off, sits under the same sky as a new chat. The iPad, the desktop and app.foxl.ai are otherwise unchanged; on every device, Channels while your desktop is off now says "Can't reach Foxl Desktop" with the reason under it.
- In the iPhone app, chat answers and your own messages are now 17 points, the size of the message bar you type in (they were 15), and the schedule, last run and next run on a Schedules card are larger. On every device, a quoted line in a chat answer is now upright instead of slanted.
- Foxl Notes can now copy or export each part of a note on its own. Right-click a tab above an open note (Notes, Transcript, Summary, Background or Report) and choose Copy, Export (.md) or Export (.docx) for that tab: the transcript comes out as the note's title, then each speaker's turn with the time it starts in the recording and what they said. The sidebar's right-click menu now has two groups with a divider between them, and every row says what it takes: Copy my notes and (once the note has one) Copy AI summary, then Export summary + notes (.md) and (.docx), which write the whole note with the summary first (Export notes before there is a summary), and Open saved file on the desktop. These replace Copy as Markdown, Export as .md and Export as .docx. On a phone, which shows no tabs, and in a window too narrow to show them, the two groups also have Copy transcript, Export transcript (.md) and Export transcript (.docx) for a note with a transcript. On the desktop, Settings > Notes > Auto-save and export has a new What to save choice for Word, Markdown and plain text files: Summary (the AI summary and your notes, what auto-save wrote until now and still the default), Transcript, or Summary and transcript.
- Foxl Notes' live translation now asks the translating model, where speech recognition misheard a word (a sound-alike word, or a name or term from earlier in the meeting), to translate what was most likely said, and to phrase each caption as an interpreter would rather than word for word. The transcript keeps the words as they were recognized.
- On the desktop, on app.foxl.ai and in the mobile apps, the window that opens when you select a skill in Integrations > Skills is redesigned: the skill's name, an Enabled or Disabled label, its description and its tags sit in one row at the top, SKILL.md is one card with Reveal and Edit beside its path, and Delete and Enable or Disable stay at the bottom of the window while the rest scrolls. Those two buttons used to be cut off when a skill had a long description, as the bundled Excel skill does, in a laptop-sized window and on an iPhone, so the skill could not be turned off or deleted from there. The Run button, which could never be pressed, is gone, and in dark mode the Enable button now has a visible shape.
- In Foxl Notes on the desktop, click the time or title of a meeting still to come in the Today list to open its brief: your last two notes from a meeting with the same title or the same people, their open action items, and the meeting's description from your calendar. Click a note to open it. The brief is put together from the notes already on this computer and sends nothing anywhere.
- iOS app: on the welcome screen, FOXL is hand-lettered in puffy white balloon letters, each at its own tilt and size and round at every corner, with the system's own Liquid Glass over them, on a steel-blue sky with cumulus clouds (a black starry night in dark mode). Foxl's pets stream out of the glass planet and gather round the lettering; swiping up rolls the planet so a blue iris comes round, lifts it off the bottom edge into a sphere and fades the lettering away, and the sphere shrinks into the + orb, which pours a collage of stickers out while the headline writes itself in. The headline reads "Your AI agent that works around the clock". Get started is the system's glass button.
- Android app: the same welcome screen opens the app before sign-in, the sign-in screen carries the same white balloon FOXL lettering with Foxl's pets, and the Notes home puts Start recording in the middle of the screen with Import and Add context under it, as the iPhone app does.
- iPhone and Android apps: an empty chat, the Notes home, the Foxl Code home and the sign-in screen sit under the welcome's sky, which fades into the page before any text. The sky belongs to the Foxl colour theme: with another one picked in Settings > Appearance > Color theme, those screens show that theme's own colours, as every other screen does, and the pets stay (on sign-in they take the place of the white FOXL lettering, which is drawn for the sky); the message bar and the tab bar have a rim of light along their edge, and Foxl's pet stickers keep empty screens company on both apps.
- The sidebar no longer shows the Foxl logo at its top left, on the desktop, on the web and in the iPhone, iPad and Android apps. Its header is the product's name (Foxl Agent, Foxl Notes or Foxl Code), which now starts on the same left edge as the icons and section labels under it, and the collapsed sidebar on a computer starts with its first row (New chat, New note or New task).
- The chats under Recent chats in the sidebar now line up with everything else in the sidebar instead of sitting indented. In the phone apps and on app.foxl.ai, a chat that is not fully on this device yet (only its title has downloaded, or its newest messages are still on your desktop) shows its title in a lighter grey instead of a cloud icon; holding or right-clicking it still says which and offers "Download to this device" or "Sync now". The unread dot and the spinner of a sync you started now sit right after the chat's title.
- Sign-in: Continue with Google is first again in the iOS app, as the black button, with Continue with Apple second.
- In the iPhone app, the "..." in an open channel's top bar now opens the same glass menu as the one in a chat or a note, growing out of the button (Liquid Glass on iOS 26 and later). Leave channel and Archive channel, or Hide conversation in a direct message, are red there, and the member count stays beside Add people. It used to open a plain list. In some languages a row whose name is too long for the menu ends in "..." there.
- On a phone (the iPhone and Android apps, and app.foxl.ai in a phone's browser), Channels picks its workspace the way Tasks picks its repository: the title reads "Channels" with the workspace's name under it, and tapping it opens the list of your workspaces. The workspace's name is no longer the list's big title. The unread total that sat under it is not shown there any more: each conversation still shows its own count, and Mark all as read in the "..." menu shows the total. In the iPhone app the title is in the top bar, and the list's "..." menu (mark all as read, create a channel, new message, the list's layout, switch workspace) is the button at the top right. The desktop and the iPad are unchanged.
- On a Mac, computer use can now press the buttons and other controls inside the window of an app built on Electron (Slack, VS Code, Notion and Discord are built on it), a window in the background that was never in front included. Those clicks used to be refused, or reported as pressed while the page did nothing. While Foxl operates such an app it asks the app to describe its whole window to accessibility, which adds two to three seconds to the first step of each turn, and turns that off again when the turn ends or Foxl quits, because it costs the app some memory while it is on. An app that VoiceOver, Switch Control or another assistive app is already using is left exactly as it is. Chrome and the other Chromium browsers are not changed.
- With an OpenRouter key whose account has less than $0.50 of credit left, the model picker now offers only OpenRouter's free models, which need no credit: OpenRouter holds back the cost of a whole reply before answering and refuses a paid model once the balance cannot cover it. The model you already have selected stays in the list, so nothing switches it for you. Your OpenRouter balance is shown in Settings > Model under the provider's options as soon as the pane opens, and on macOS and Linux in the titlebar status panel, with a note while the list is limited to free models. Adding credit brings the paid models back within a minute; nothing changes when the balance cannot be read, or for a key that belongs to an OpenRouter organization. In the macOS and Linux app, the first-run tour now has a card for the green dot in the title bar, which opens that status panel: what is running, the tokens and cost of the chat, and what is left on your plan or credits.
- In the iPhone app, the switches between views or choices (an open note's Summary, Transcript, Notes and Report, Settings choices such as Light, Dark and System, the Schedules views, Foxl Code's tabs) are now a white capsule with a thin outline (dark in dark mode), the chosen one on a grey pill, with every label and icon in full ink at a larger, bolder size; with Increase Contrast on, the chosen one also has an outline. The unchosen ones used to be grey on a grey track.
- On a phone, the tab bar at the bottom of the screen shows only its icons by default, the selected one on its pill. Settings > Tab bar > Show labels puts the names back under them, and a screen reader reads each tab's name either way.
- The iPhone and iPad app's launch screen now shows the Foxl logo with the name Foxl AI beside it, on the welcome screen's sky (its starry-night colours in dark mode), so a signed-out launch flows straight into the welcome. The desktop app, app.foxl.ai and code.foxl.ai keep the Foxl logo alone while they load.
- In the iPhone and Android apps, setup (Settings > Appearance > Show setup again or Reset onboarding) now looks like an iPhone setup screen: a round Back button, page dots and Skip along the top, a centred title, System, Light and Dark as three small phones with a check under the one in use, every color theme and every answer as a row in a list with a check beside your choice, and one wide Continue button at the bottom. The tour cards that follow look like iPhone tips: each card has its own icon, a close button that skips the tour, and a pill-shaped Next button. On the iPad, the desktop, app.foxl.ai and code.foxl.ai, setup and the tours look as they did.
- Once the mini-game is unlocked (tap the version in Settings > General > About seven times), it has its own row in the sidebar, under Schedules, on every device, and it opens over the page you are on. The iPhone, iPad and Android apps had no way into it, and with your computer off even a link to it opened a connect-your-desktop screen instead of the game. On the desktop the row replaces the game-controller button at the top of the Agents page.
- In Foxl Notes, the sidebar with no notes yet is a quiet two-line caption where your first note will appear, "No notes yet" and "Your recordings and notes will appear here.", lined up with the rest of the sidebar. It replaces a centred microphone tile that repeated the editor's own Start Recording prompt beside it. The notice for notes that cannot be read on this device takes the same layout.
- The sidebar's type is one system across Foxl Agent, Notes and Code. Every chat, note and task title is now the size and weight of the rows around it (note titles were smaller and bolder, task titles smaller still), section headings such as Extend, Recent chats and Workspace are smaller and semibold so they no longer read as rows, and the selected row is shown by its highlight without turning bold, so its title no longer shifts when you select it. The line under a Foxl Code task (its repository, agent and age) is larger and darker: it was too faint to read comfortably. Lengths, times and pull request numbers use the same typeface as the rest of their line.
- On a phone, the model picker now runs edge to edge down to the bottom of the screen, rounded only at the top, instead of floating above it with a gap underneath. In the iPhone app the Settings and notifications sheets do the same, and so does the search sheet in the Android app and a phone browser.
- Setup is now remembered for your account. Once you finish or skip it on one signed-in device, your other signed-in devices skip it too, and Settings > Appearance > Reset onboarding starts it over for your account: it opens on the device you pressed it on straight away, and on each of your other devices the next time you open it (the iPhone and Android apps included), until you finish or skip it on any one of them, which completes it everywhere. Signed out, a reset is still just for that device.
- The iPhone app's text is now iOS's standard 17pt size: replies, the message box, list rows, menus and Settings are a size larger, and the smaller text on screens such as Files and Agents and on a Settings page's buttons is a step larger too. In the side menu the text is a size larger, the page names a heavier weight in the full text colour, and the product name at the top is larger and semibold. The iPad keeps its text sizes, and the desktop app, app.foxl.ai, code.foxl.ai and the Android app keep theirs.
- On a phone (the iPhone and Android apps, and app.foxl.ai in a phone's browser) the side menu is laid out like the desktop sidebar: New chat at the top, the Extend and Recent chats headings, and your chats in their own list under the pages, filling the menu down to your name. The icons and your profile photo line up in one column. In a chat, the first message starts further below the buttons at the top of the screen.
- Foxl Code's sidebar is now laid out like Foxl Agent's, on the desktop, app.foxl.ai, code.foxl.ai and in the side menu of the iPhone and Android apps and a phone's browser. Its first row is New task, which opens an empty composer from any Code page the way New chat does (like the + button, it clears a conversation on the Tasks home that has not started a task yet), and your tasks are listed under Recent tasks below the pages, using the rest of the sidebar's height, with the number of unread notifications from tasks waiting on an answer from you beside the heading. It replaces the Tasks row: from inside a task, Escape, the back arrow or the task counts at the top of the page return to the list on a computer, and the Tasks tab or Back does on a phone. With the sidebar collapsed, New task and the pages are shown without the task list, as in Foxl Agent.
- In the iPhone and Android apps and on app.foxl.ai in a phone's browser, a new chat no longer opens with the big "What can I help you with today?" heading. Foxl says hi instead, the way the stickers talk on the welcome screen: two speech bubbles pop up above the fox, "Hi" with your first name (from your account's name, or "Hi there!" without one) and "Where should we start today?". In a phone's browser the new chat now looks like the apps' too: the fox and its friends take the place of the lone Foxl mark, under the same sky while Settings > Appearance > Color theme is Foxl. In the iPhone app, when you send the first message, the bubbles, the fox and its friends now fade out where they stood. The iPad, the desktop app and a browser wider than a phone keep the heading.
- In the iPhone and Android apps, Settings and the model pickers now give haptic feedback, as the notifications sheet already did. In Settings: every switch, choice and dropdown, opening a section and going back (with the back button, or a swipe on the iPhone), the search and close buttons, Settings > Tab bar and the memory filters. In the model picker: tapping the model name in the message box to open it, its close button, starring a model and the Reasoning switch, and a model the desktop refuses to switch to gives the failure haptic. Foxl Code's model and repository pickers now give the same feedback as Foxl Agent's.
- In the iPhone and Android apps, every button, row, tab and switch now answers a tap with a haptic, not only Settings and the model pickers: the side menu's rows, tabs and segmented choices, the switches and tool chips in an agent's settings and on the Skills page, menus and their rows, dialogs, and the buttons on every screen. Choosing something (a switch, a tab, a segment, a picker row, a side-menu row) is a selection tick, which on the iPhone is now its own crisper feel instead of a light tap; Send, Stop, New chat, New task, New note, starting and stopping a recording and the confirm button of a confirmation alert are a firmer tap; confirming a delete with the red button of a confirmation alert, or in the system sheet, gives the warning pattern once; and holding a chat in the side menu, the pet, a source chip or a message in Foxl Code is felt as its menu or preview opens. Tapping a choice that is already selected, typing on the terminal's key row, scrolling and plain text stay silent, and a reply that fails gives the failure haptic wherever its message appears (it did only when the error showed in the chat itself).
- In the iPhone app, the "..." menu on a new chat no longer lists Search conversations when the search bar is at the top of the screen, since that bar opens the same search. An open chat's "..." menu still has it, and so does a new chat at the largest text sizes, which have no search bar.
- In a phone's browser (app.foxl.ai and code.foxl.ai) and in the Android app, the Settings and notifications sheets are now the iPhone app's frosted glass: a light tint over a blur of the screen behind, running edge to edge from the bottom of the screen with its top corners rounded and its groups on lighter cards. It was a nearly solid panel with a grey border, set in from the edges. With Increase Contrast turned on, with Reduce Transparency where the browser reports it, or in a browser that cannot blur, the sheet is solid. The iPad, the desktop and a wider browser window are unchanged.
- On a phone, a file opened from Files now opens on the document. Its name is the screen's title, with its folder under it, where "Files" and the file's name used to take two title rows; a Markdown file such as AGENTS.md shows formatted instead of as its source in the code editor; and one Edit button, which becomes Done, switches between the two, with Save beside it once there are changes. In the iPhone app these are in the top bar, with a back button under it named after the folder it returns to; in the Android app and a phone's browser they are in the file's own row. The Refresh button, which reloads the list of files, leaves the top bar while a file is open. The iPad, the desktop and a wider browser window keep the Edit and Preview switch, which on a phone was cut off at the edge of the screen.
- On a phone, the line under the Schedules title now says what is next: the next run when one is coming, otherwise how many schedules are on. The sentence that sat on a row of its own under that line is gone; the desktop keeps both. In the Android app and a phone's browser, the status and sort menus and the List, Calendar and Runs switch now share one row on Schedules in Foxl Agent and in Foxl Code, as they already did in the iPhone app; in a longer language, with a longer status or sort chosen, or on a phone narrower than an iPhone, the switch can still move to the next line. Schedules and Agents also no longer leave an empty band under the title on a phone.
- In the iPhone app on iOS 26 and later (and on an iPad when its window is phone-narrow), a page you opened in Settings goes back when you swipe right from anywhere on it, as iOS 26's own apps do, not only from its left edge (in Arabic, swipe left). A sideways drag on a text field or on a row that scrolls sideways still does what it did, and on earlier iOS versions the swipe still starts at the edge.
- On a phone (the iPhone and Android apps, and app.foxl.ai in a phone's browser), the green dot at the top of the side menu now opens more than "Desktop Connected": the chats still replying to what you sent from this phone or opened on it, tool approvals waiting for you, new replies and unread notifications, each one tap away, then how full the open chat's context is and, with a Claude or ChatGPT sign-in on the desktop, your plan's 5-hour and weekly limits. A reply the desktop started by itself, such as one typed at the desktop, a schedule or a message from a channel, is not listed there. Details holds how many chats are downloaded to the device and the desktop's settings. The grey dot, the iPad and the desktop are unchanged.
- Toasts can now be closed at once: each has a small X at its end, on the desktop, on app.foxl.ai and code.foxl.ai, in the quick chat window and in the iPhone and Android apps, including a toast with a button such as Undo or Reload and one that stays until you act on it (a progress toast, which goes away by itself, has none). On a phone you can also swipe a toast up or to either side. A toast also waits while it has keyboard focus, as it already did under the pointer, and Esc closes the toast that has focus. Closing one toast leaves the others where they are.
- In Foxl Code, the Ops page is now called Operation: its sidebar row, its title, the command palette (Code Operation) and the tab bar, in every language, and its notifications, which now begin with "Operation:" (or say "Foxl ran a fix" after a fix it ran by itself). The page opens on what is broken: each open incident is one row, highest severity first, with its severity, what Foxl concluded and, in the same row, the plan waiting for your approval, and the line under the title says how many incidents are open and how many plans wait for you. The alert sources and what Foxl has learned are under Sources and Learning, a switch at the top. Every incident's details now end with what happened to it and who did it (the alert source, Foxl or you), and in the iPhone app an incident's title no longer sits under the status bar.
- Every right-click and long-press menu Foxl draws itself now has the shape of the menu you get by holding a chat in the sidebar, and so do the "..." menus beside rows and in toolbars (the system's own menus, such as the one a text field or a link opens in the desktop app, are unchanged): rounder corners on the menu and on each row (rounder still on a phone), a little more room around the rows, and one icon size and icon spacing in all of them, on the desktop, on the web and in the phone apps. The menus in Files, Notes, the note editor, Foxl Code's tasks, repositories and channels, on chat images and on the pet used to be square cornered with smaller icons. On a touch screen every row of a "..." menu is now at least 44 points tall, as the long-press menus already were. On a computer or a tablet, the menus whose longer labels would otherwise have gone onto a second line are a little wider; on a phone a long label in some languages can now take two lines. The Liquid Glass "..." menu in the iPhone app's top bar keeps its own shape.
- On a phone (the iPhone and Android apps, and app.foxl.ai and code.foxl.ai in a phone's browser), Settings has moved into the account menu at the bottom of the side menu: tap your name, then Settings, just above Sign out. The separate Settings row that sat over your name is gone, and the account menu now has the same shape as the menu you get by holding a chat. The sidebar on a computer and on a tablet is unchanged (a desktop window narrowed to phone width shows the phone's side menu, as it already did), and a side menu with nobody signed in keeps its Settings row.
- In Foxl Notes, the Transcript tab no longer starts with a bar and a row per speaker showing how long each one talked, which took up the top of the transcript on a meeting with several speakers. Each line still names its speaker, and the Report tab still shows your speaking share. It was shown on the desktop app, the iPad and app.foxl.ai in a wide window; the phone apps never had it.
- In the iPhone and Android apps, the sidebar follows your finger. Swipe in from the left edge, or push the open sidebar back from the page beside it, and the page moves with you from the start of the swipe instead of waiting and then sliding on its own. A quick flick is enough, you can change your mind before you let go, and a swipe can catch the page while it is still moving. In those apps and in a phone's browser, a sheet that springs back after a short pull (Settings, notifications, the model picker, search) can be caught the same way, and no longer jumps when you pull it again.
- On a phone (the iPhone and Android apps, and app.foxl.ai in a phone's browser), Recently changed at the top of Files folds away: tap its heading to hide the files under it, and tap it again to show them. Foxl remembers your choice on that device.
Fixes
- In chats and on a subagent's page, in Foxl Agent and Foxl Code, a step that is still running now lines up with the finished steps above it: every line of its title starts at the left edge (the right edge in Arabic). A long running title, such as a search for many words at once on a phone, used to be centered line by line under its icon.
- On a phone (the iPhone and Android apps and a phone's browser), Foxl Code's Repository sheet, the repo menu on Tasks, is no longer sparse: each repository is a 44-point row, taller only when a long name wraps, whose star, name and GitHub link reach its edges (it was 64 points, with a strip above and below the buttons that did nothing when tapped), the names start nearer the edge without the same branch icon on every row, and the shaded "REPOS" band above the list is gone. With favorites or recent repositories the groups are still labelled, as plain text. The sheet also opens on the repository you are using rather than at the top of the list. In a wider window, on a computer or most iPads, the menu is unchanged.
- In the iPhone and Android apps and on app.foxl.ai in a phone's browser, an approval card at the top of the screen, such as "Waiting for approval on your computer - Allow Foxl to use Microsoft PowerPoint?", no longer covers the side menu. It used to sit over the menu's top rows, so tapping them hit the card instead. While the menu is open the card now steps out of the way and keeps waiting, and it comes back when the menu closes; the green dot at the top of the menu lists it meanwhile. A computer-use step waiting on your computer now shows this card, with Deny, in the Android app and in a phone's browser too, not only in the iOS app, and when it is allowed or denied in Foxl on your computer the card says so instead of disappearing. Allowing a computer-use step still works only in Foxl on your computer.
- In the iPhone and Android apps and on app.foxl.ai, a reply your desktop is writing no longer turns into "Request couldn't finish" with "Load failed" (on Android "network error") and the same words at the top of the screen when you switch away from the app and come back, or when the connection drops for a moment. The error showed for a moment and then the reply appeared by itself, because your desktop had carried on. The app now asks your desktop first and shows the reply, or picks it up where it is still being written, and shows the error with Try again only when your desktop cannot be reached within a few seconds. Opening a chat right after coming back to the app also tries again by itself instead of opening a new chat with "Could not open that conversation".
- In the iPhone and Android apps and on app.foxl.ai, Agents > Runs no longer keeps reloading when it opens. With Today, 7 Days or 30 Days selected it fetched the whole run history from your desktop, page after page, although that range shows only its own runs: on a desktop with 723 runs, two of them that week, opening Runs made 17 requests in under six seconds, and again on every visit. It now stops as soon as it has every run in the selected range, and All still loads older runs as you scroll. The list still updates on its own while it is open, and when you come back to the app.
- In a phone's browser (app.foxl.ai in Safari or Chrome), the keyboard no longer covers the message bar. The bar now sits on top of the keyboard while you type, with the top of the screen and the new chat's greeting still in view, as in the iPhone and Android apps. Safari used to raise the keyboard over the bar and leave it hidden, or slide the whole page up so the top of the screen went out of view.
- The phone apps and app.foxl.ai no longer drop off your desktop for a few seconds when one request to a busy desktop is slow. The connection to the desktop used to be cut whenever a single request went 10 seconds without an answer, even while the desktop was answering everything else, so every phone and tab showed it offline and reconnected, and on a loaded computer the reconnect's own refresh could set off the next one. Now that one request fails on its own and the connection stays up; it is still closed, as before, when the desktop stops answering altogether (for example a computer that went to sleep).
- In the iPhone, iPad and Android apps and on app.foxl.ai, a message you add to the queue while Foxl is working now goes in as soon as the step Foxl is running finishes, as it does in the desktop app. It used to wait until the whole reply had finished and then go as a new message. A queued message is also no longer sent twice when the connection to your desktop drops while it waits (the phone going to the background, for example): your desktop now remembers which queued messages it has already taken, in the desktop app too. A message queued with a photo or a file still goes when the reply ends, and with Foxl on your desktop older than this release queued messages wait for the end of the reply as before.
- Pressing Start on a channel in Settings > Connect > Channels now shows Connecting right away and Connected once the channel is up. The row used to say Stopped, with the Start button and any earlier error still showing, until the page refreshed up to ten seconds later, so on iMessage Start looked as if it had done nothing. While a channel is connecting, its button is Stop.
- Restarting your desktop from the phone or app.foxl.ai (Desktop > ... > Restart desktop) no longer leaves it unreachable when "Keep running when closed" is on. The desktop started its new server before the old one had stopped, and an open Foxl window then took the gap for a crash, restarted the background service over the restart and switched "Keep running when closed" off, which left the desktop unreachable from the phone until Foxl was quit and reopened, and "Keep running when closed" off until it was switched back on. The Desktop page now also tells you when Foxl on your desktop is back ("restarted and is ready"), or that it did not come back within 2 minutes, instead of only that the request was sent.
- On the desktop, a chat with an on-device model (Gemma 4) no longer fails on its first message with "This conversation is longer than the on-device model's context window" when you have many tools, an MCP server or long memory files. The on-device model now gets a short set of tools (files, the shell, the web, the checklist and recall) and the start of each memory file and skill description, so a new chat's first request leaves most of the model's window for the conversation. MCP servers, custom tools, connected apps such as Gmail, the browser, schedules and subagents are no longer offered to the on-device model. Cloud models still get every tool you turned on and the whole of each file.
- In the iPhone app, dragging the Notifications or Settings sheet and letting it spring back no longer makes it drop off the screen and slide up again a moment later, which briefly uncovered the screen behind its glass.
- In the iPhone app, swiping right from the left edge of the Settings sheet now goes back from the setting you opened to the Settings list, following your finger as everywhere else in iOS (let go early to stay where you are). The swipe used to open the sidebar behind the sheet instead, which made the sheet flicker and stutter and left the sidebar open once Settings closed. Swipes at the screen's edges also no longer open the sidebar or the terminal behind any other open sheet or dialog.
- While a channel is set up, the conversations that arrive through it no longer appear in Recent chats; they are on the Channels screen, as intended, including the ones from before this version, and search and Export everything still include them.
- Telegram replies show bold, italics, headings, links and code blocks instead of raw asterisks, and a rate-limited Telegram reply is retried instead of being resent as raw text. Slack replies show bold and italics, and a link as its label followed by the address, Signal replies no longer show Markdown symbols, and a long answer split into several messages no longer turns the text after a code block into code.
- Settings > Dictate anywhere shows the Service tier row only when the cleanup model offers one on your own AWS account (Gemma 4, Grok and Kimi K3 take Priority and Flex), and lists only the tiers that model takes. It used to appear whenever your Model & provider was Amazon Bedrock, and named GPT-5.x as supported, but every GPT model on Bedrock refuses Priority and Flex: with one of them cleaning up your dictation and Priority or Flex chosen, every dictation was typed out as the raw words, unpolished. A tier the model does not take is no longer sent, so those dictations are cleaned up at the Standard tier.
- Skills > Sync on the iPhone app now shows the list of updates to review, as the desktop does, instead of seeming to just refresh the screen. When many skills had changed, the review drew every line of every change at once, and the iPhone reloaded the app before it appeared. The review now lists one row per skill, and a skill's files and their changes open when you tap them. Each skill has a checkbox, all ticked to start, and only the ticked skills are updated ("Update 3 of 5"), so you can take some updates and leave others for later; the backup and Undo cover exactly the skills you updated. Sync also says so when everything is already up to date, and shows an error when it fails, where it used to say nothing. On the phone the review is shorter so its buttons stay above the tab bar. Choosing skills needs this version of Foxl on your computer; with an older one the review applies every update, as before.
- On the desktop, the AI Assistant in the Foxl Notes Live panel now writes its answer as it comes in, also while the main Foxl window is behind your meeting, closed or minimized. Before, it did so only while the main window was on screen; otherwise nothing moved until the whole answer appeared at once.
- In Foxl Code, Retry on a task you start with Plan first from this version on starts it with Plan first again: it writes a new plan, changes no files and waits for Approve plan. It used to run the request as an ordinary task when the plan run had failed, so it changed files and opened a pull request you had not approved. A Plan-first task started before this update still retries as an ordinary task, because nothing recorded the choice for it.
- On a Mac with Settings > Safety > Run shell commands in a sandbox on, the commands and terminals the agent runs in a chat that has its own folder can now write in that folder, so the agent can edit and build there. The
.git,.claude,.codex,.agentsand.awsfolders at the top of it stay read-only, as do itsAGENTS.mdandCLAUDE.md, Foxl's own sign-in files and the other files your system prompt is built from, and a chat folder that is your home folder, or that holds Foxl's own folder, stays read-only. It used to refuse every write in the chat's folder and tell the agent to run the command outside the sandbox. - In Foxl Code, a GitHub comment that asks Foxl for a review in everyday words, such as "@foxl, review this please", "@foxl: review", "@foxl please review" or "Can you review this? @foxl", now runs Foxl's read-only reviewer, as
@foxl reviewdoes. It used to be read as a task, so on a pull request a Foxl Code task opened it reopened that task with the comment as its next step, which spent credits on a coding run instead of a review. A comment that asks for work as well, such as "please review the error handling and fix the null check", is still passed to the task. A mention inside an HTML comment (<!-- -->), which GitHub does not show, no longer counts. - On the desktop, a hook in
~/.foxl/hooks.jsoncopied from Claude Code with an"if"filter such as"if": "Bash(rm *)"now runs when the call matches that filter, and not on every tool call. It used to ignore the filter, so a guard meant forrmthat blocks unconditionally refused every shell command. Where Foxl cannot tell whether a call matches, the hook runs, as in Claude Code. A hook that answers{"continue": false}now stops the call it was asked about, with itsstopReasonas the reason, where the call used to go ahead. - On the desktop, when the agent's file edit removes a line break, joining two lines into one, the change shown under the step now shows the joined line as changed. It used to show the line below as untouched and claim the file no longer ended with a newline, so neither you nor the agent could see that two lines had become one, for example
}function b() {after a closing brace. - In Foxl Code on the desktop, on app.foxl.ai and in the iOS app, Remote and This computer now each remember their own model, so using Remote no longer replaces the model This computer runs on your own provider. Before, opening Foxl Code on Remote, which v0.8.7 made the default, saved Remote's model over This computer's, and going back to This computer in Settings > Code > Coding agent moved Code to Foxl Agent's model. A device that already opened Foxl Code on Remote with v0.8.7 lost that choice then: pick This computer's model once more and it is kept from now on.
- On the desktop, the on-device model (Gemma 4) and on-device transcription now work on a computer with an HTTP proxy set in its environment (an
http_proxyexported in the shell, or on Windows a system proxy). Foxl sent its own requests to the on-device engine, which runs on this computer, to the proxy, so Gemma 4 never loaded on a Mac or Linux computer and the speech engine never finished installing on Windows or Linux, each after about three minutes and with a message that blamed the engine. Requests to this computer itself now always skip the proxy, and every other request still uses it. - On the desktop, a reply you watch finish in a chat popped out into its own window no longer also raises a "Reply ready" notification. Foxl used to hold the notification back only while the main window was in front, so a reply read in the popped-out window was announced again.
- On every device, Schedules in Foxl Agent and Foxl Code, For You and the iOS app's notification sheet now say "tomorrow" only for a run on the next calendar day, and "in 2 days" for the day after. They used to count hours, so on a Thursday night a Saturday morning run said "tomorrow", and early on a Thursday a Friday run said "in 2 days". The same holds for "yesterday" beside a recently changed file in Files on a phone and beside a session on the Agents page, in every time zone and across a daylight saving change.
- On a Windows PC without the Microsoft Visual C++ Redistributable, downloading Gemma 4 or on-device transcription now says that this PC needs it and offers a "Get it from Microsoft" button beside Retry, in Settings > Model & provider > On this device, in the empty chat and in first-run setup. Settings and the empty chat used to say "The download stopped. Check your connection and try again." for it, and for any other on-device runtime that cannot run on the computer, such as a Linux computer missing a system library, so Retry downloaded the same files again. Those failures now say the runtime cannot run on this computer, with the reason under Details.
- On the desktop, Foxl Notes' live translation now appears in the Live panel while it is being written, also when the main Foxl window is behind your meeting, closed to the Dock or minimized. It used to show each translated line only once its whole translation had finished.
- On the desktop, a chat or a Foxl Notes job set to an on-device model you deleted now says that model is not downloaded on this computer, instead of quietly running on another downloaded one. With Gemma 4 E2B and E4B both downloaded and E2B deleted, chats on E2B used to load E4B in its place without a word, which on a computer without a graphics card meant minutes of waiting for the first answer, and opening Chat loaded it ahead of time too.
- On the desktop, on app.foxl.ai and in the iPhone and iPad app, Foxl Notes' AI Assistant now dates a saved meeting from when it started. It used to take the moment the recording was stopped, so a 14:00 meeting read as starting at its end, and a call that ran past midnight was dated the next day, which put every "tomorrow" said in it a day late. A note recorded before this update is dated from its end minus its length.
- On a Windows PC and on a Linux computer, Settings > Model & provider > On this device now says Gemma 4 E4B needs about 6 GB of memory and E2B about 3 GB. Since v0.8.7 it said about 4 GB and about 2 GB, the sizes measured on a Mac, where Foxl reads the model's large lookup table from disk as it is needed; on Windows and Linux Foxl loads the whole model file as before, which in our measurements took about 6.3 GB for E4B and a little over 3 GB for E2B on a Windows PC. On a Mac the sizes are unchanged.
- In Foxl Notes, a recording whose notes are its transcript now shows the first thing that was said under its name in the sidebar, in the phone's Recent list and in search, on every device. It used to show "2 participants", or "Speaker 1" when one person spoke, under every such meeting.
- In the iPhone app, a notification's preview in the notification sheet no longer drops asterisks that belong to its text. Code and file patterns read as written, so
2**10no longer reads 210 and "rm *.log *.tmp" no longer reads "rm .log .tmp"; only the agent's own bold and italic markers are left out, as before. - On a Windows PC, Cancel during the last step of installing on-device transcription now stops the speech engine, and waits for it to exit, before it removes the downloaded files. It used to remove them while the engine was still starting, which Windows refuses for files a running program holds, so about 1.3 GB could stay on the disk with nothing in Settings to delete it. If some files still cannot be removed after a Cancel, Settings now says so.
- In the Android app, Export my data (JSON and CSV, under Settings > Account) and exporting a chat now open the Android share sheet with the file, so you can save it to your files or Drive or send it on, as the iOS app has done since v0.8.3. Before, tapping them did nothing on Android.
- On the desktop, the Foxl Notes Live panel's darker background (70% on its Transparency slider) now also reaches a computer that ran Foxl before v0.8.7. There, Foxl had stored the earlier 40% default as if it were a choice, so the panel stayed at 40% although nobody had picked it. A transparency you pick from now on is kept, 40% included; if you had set exactly 40% before this update, set it once more.
- In the Android app, Back on a note's AI Assistant page now returns to the note, as the back button at the top of the page does. It used to leave the note for the screen you were on before it, and the assistant was still open when you came back.
- In the iPhone and Android apps and on app.foxl.ai, a notice that your computer reached, or came close to, a daily or monthly spending limit on your own keys now says which limit it is and that you change it in Foxl on that computer, and opens the Notifications list when you tap it. It used to show the dollar amounts and send you to Settings > Usage, where the phone and the browser have no spending limit to change. The desktop's own notice is unchanged.
- In the iPhone and Android apps and in a phone's browser, the reasoning Effort levels in the model sheet now fit their buttons at every text size and in every language: when the words do not fit on one line, the levels continue on a second line. They used to run off the screen (in Russian at 120% or larger), and in Foxl Code's model sheet a two-word level such as "Sehr hoch" or "Très élevé" spilled out of its button. At the default text size in English nothing changes.
- On the desktop, when your account reaches the relay's daily limit of messages from the desktop, Settings > Mobile/Web now says so and when your phone and app.foxl.ai can reach the computer again (after 00:00 UTC, shown in your own time), and the desktop waits until then to reconnect (the app still tries once when the computer wakes from sleep). It used to show no reason and try the relay again about once a minute until then.
- The email Foxl sends when you have used 80% or all of your Foxl credits for the period no longer suggests topping up, upgrading or adding more credits, since there is nothing to buy. When your account's credits refill by themselves (the free monthly credits), it now says they refill at the start of your next period, and its button opens your usage.
- On Windows, Foxl Code's Review changes, New terminal in a worktree (and removing one), Check out locally, cloning a repository for a local pane, and the agent's code search now run Git (and grep) from where Windows has them installed, never a program of that name inside the repository or folder they work in. A branch you reviewed or checked out that carried its own
git.comorgit.execould otherwise run it on your PC in Git's place. macOS and Linux were not affected. - On the desktop, a hook in
~/.foxl/hooks.jsonwritten in Claude Code's exec form ("command"with"args") now runs that program with those arguments. It used to run the program with no arguments, so a guard written that way never ran its check and the tool call went ahead."onFailure": "block"now blocks the call when such a hook cannot run, andCLAUDE_PROJECT_DIRis set for every hook. On Windows"shell": "bash"now runs a hook in Git Bash, where Claude Code runs hooks there by default, and"shell": "powershell"runs it in PowerShell; every hook used to run in the Windows command prompt, and a hook without"shell"still does, so one written for it keeps working. A hook Foxl cannot start as written is listed in Settings > Safety instead of looking loaded and doing nothing. - On the desktop, a reply you watch finish in Quick Chat, with the Quick Chat window in front, no longer also raises a "Reply ready" notification. It used to, because Quick Chat did not tell Foxl which chat it was showing.
- On Windows and Linux, the Settings tour's Dictate anywhere card now says to press Control+Alt+D (or the shortcut you chose), speak, and press it again, which is how dictation works there. In every language it used to say to hold one key while you speak, which only a Mac can do.
- The command palette and search (Cmd+K or Ctrl+K) on app.foxl.ai, in the iPhone, iPad and Android apps and on code.foxl.ai no longer offer settings that only the desktop app has, such as Keep this computer awake, Launch at login, Beta updates and the banner settings under Notifications (Sound, Only when in background, Reply ready and the rest). Picking one opened General or Notifications without it. On code.foxl.ai Explain details on selected text, Show plan checklist, Show files changed and Bio are no longer offered either, nor Launch at login on the Linux desktop, which has no login item.
- In the iPhone, iPad and Android apps, three exports now open the share sheet with the file: Download Report under Settings > Advanced, exporting your custom tools on the Tools page, and Save as Markdown in a Foxl Notes note's Save As dialog. Before, tapping them did nothing, and Save as Markdown said Saved although no file was made. The desktop app and browsers download the file as before.
- On app.foxl.ai and in the iPhone, iPad and Android apps, a picture in a chat (a browser screenshot, or an image the agent viewed or made) no longer offers Show in folder when you right-click it or press and hold it. It opened the folder on your Foxl desktop, out of sight, or did nothing while the desktop was offline. Save image as and Copy image are still there. The desktop app keeps Show in folder.
- Settings > Tab bar is now only on a phone or tablet (the iPhone, iPad and Android apps and a mobile browser), not on a computer: app.foxl.ai and code.foxl.ai in a desktop browser no longer list it, and neither does the desktop app. On a computer the bottom bar appears only in a very narrow window, and keeps the tabs it has.
- With Foxl in Arabic, English chat, note and task titles in search and the command palette (Cmd+K, Cmd+Shift+F, the search field at the top of the Mac and Linux app, the iPhone search page and Foxl Notes' search) and English notifications now read left to right, as they do in the sidebar since v0.8.6. They showed their question mark at the wrong end, and a long title was cut at its beginning, so two notes starting the same way could not be told apart. The same holds for Arabic text in any other language.
- In the iPhone and Android apps and on app.foxl.ai, a chat with your computer that stops because the computer reached a spending limit on your own keys now says so in your language and tells you to open Foxl on that computer to see the amount or change the limit. It used to show the dollar amounts and point to Settings > Usage, where the phone and the browser have no spending limit to change. The desktop's own message is unchanged.
- In every language other than English, a chat without a title is called New chat in your language in search results and in the tooltip of its sidebar row, as everywhere else. It read "New chat" in English there.
- On the desktop, Settings > Connect > Channels now lists only the channels Foxl can run, instead of 41 platforms, 38 of which saved your token and then refused to start with "No adapter implemented". Each channel's Connect dialog links to that service's own setup guide. A channel you saved for one Foxl still cannot run is listed, with Remove, so what was saved for it can be deleted.
- On a Mac or Linux computer, Signal can now be linked in the app: its Connect dialog shows a QR code to scan in Signal on your phone (Settings > Linked devices > Link new device), fills in your number once the link is made, and says so when signal-cli is not installed. Before, Start answered "Use the Link Device button to scan a QR code" and there was no such button.
- On the desktop, Stop on a channel now waits for it to disconnect, and no longer stops a different channel of the same kind that was started from another saved entry.
- Settings > Notifications > Channel Messages has a Signal switch and a Signal test, and the WhatsApp switch and test, which no message could ever reach, are gone; Discord and the other channels added in this version share the new Other channels switch. A choice you saved for the old Other channels switch carries over to Signal, and if you had turned it off, the new one starts off too.
- The Email (IMAP/SMTP) skill now shows a plain envelope icon, in the same style as the other built-in skills, instead of a dark illustrated picture.
- On the desktop, the Gemini CLI model list no longer offers Gemini 3 Pro, which Google shut down on March 9, 2026. If you had picked it, your chats now run on its replacement, Gemini 3.1 Pro, instead of asking Google for a model it no longer serves.
- On the desktop, when connecting Microsoft 365 or Slack in Settings > Integrations does not finish (you cancel on the sign-in page, the service refuses the sign-in, or nothing comes back within five minutes), the page now says so and why, instead of spinning and then going quiet.
- On the desktop, Settings now tells you that Refuse providers that train on your data (Settings > Model & provider, for OpenRouter) does not cover Foxl Notes transcription yet. While the switch is on, a line under it, and under the OpenRouter model in Settings > Notes when OpenRouter transcribes your meetings, says that this audio follows the training setting in your OpenRouter account's privacy settings instead. Before, nothing said that the switch left the meeting's audio out.
- As the companion that walks around the app, the Stray Tabby, Cheek Hamster, Reed Frog, Sparrow, Acorn Hedgehog and Kerchief Piglet now walk side-on with their legs moving. Every stride used to turn them to face you and cheer, and the Reed Frog and the Cheek Hamster walked holding a stick and a leaf. The Sparrow can now wave, eat and cheer, the Reed Frog and the Acorn Hedgehog can cry and the Stray Tabby can eat, where before each of them stood still instead.
- In a phone's browser, in the Android app and in a window too narrow for the Settings sidebar, going Back from a Settings pane now plays the list's short slide back into place to its end. Since v0.8.3 it was cut off about 20 ms after it started, so the list snapped back instead. With Reduce motion on, in Foxl or on the device, there is still no slide. The iPhone app is unchanged.
- On the Operation page, an incident analysis now stops at its budget even while several of its model calls run at once: Foxl Relay holds each call's maximum cost against the analysis's limit before the call starts and refuses the one that would not fit. The analysis then stops there and shows the findings it already has, or Stopped at its spending limit when it has none. Because each call is held at its maximum cost, an analysis can stop a little before what it has really spent reaches the limit. Its credential also reaches only the models the analysis uses. Before, the limit was an estimate checked between steps, so one step could go past it.
- In the iPhone app, the Settings and Notifications sheets open smoothly again. Tapping the gear in the Notifications sheet the first time no longer turns the whole screen white for about a third of a second before Settings appears, both sheets now rise from the bottom of the screen instead of appearing already open after a pause, a section you open in Settings slides in all the way instead of jumping most of the way there, and the tab bar no longer shows over a sheet as it rises.
- With the Foxl desktop app open on a Mac, app.foxl.ai in a browser no longer shows a second notification for a finished or failed run, a schedule or a question while you are using that Mac and the Mac shows its own, now also on home, office and VPN networks where it used to show both. While you are at the Mac, its notification is the one you get, in any browser signed in to your account. When you have been away from the Mac for a minute or more, it is locked or asleep, or that kind of notification is turned off in the desktop app's Settings > Notifications, the browser notifies you as before.
- With on-device transcription in Foxl Notes, every moment of a sentence now reaches the speech engine when it tells speakers apart. Before, the short stretches around and between the parts it judged to be speech were left out, along with any very short word on its own. A Korean line that comes back with letters of another alphabet in it is now transcribed once more with the line before it, and the cleaner version is kept.
- In the iPhone, iPad and Android apps, Settings > Appearance > Reset onboarding now starts setup over: the main screen opens with the look picker and the short tour of what Foxl can do. It used to go back to the main screen and show nothing, even after signing out and in again. Show setup again is now in Settings > Appearance in these apps too. A new install still opens on sign-in, with no setup screens. If you pressed Reset onboarding on an earlier version, setup opens the first time you open this one.
- On the desktop, the question box of the AI Assistant in the Foxl Notes Live panel now takes more than one line. Shift+Enter starts a new line and Enter sends (or Cmd+Enter, Ctrl+Enter on Windows and Linux, if that is your send key), and a pasted question keeps its line breaks. The box grows with what you type up to four lines and then scrolls inside itself, so the answer above stays in view, and a long line, a link for example, wraps instead of scrolling sideways out of sight. Enter that confirms a Korean, Japanese or Chinese word still never sends. The box also follows the panel's text size now, and the Live panel no longer redraws the whole transcript and every answer on each keystroke and each tick of the recording clock.
- In the Mac app, zooming in (View > Zoom In, Cmd+) on a small window no longer turns it into the phone layout, with a tab bar at the bottom, the sidebar hidden in a drawer and a round menu button floating over the chat. A window too small for the zoomed page now grows to fit it, and Zoom Out or Actual Size takes it back to the size and place it had, unless you resized it in between; a window that is already big enough keeps its size. The close, minimize and zoom buttons stay in line with the title bar as it grows. Zoom In and Zoom Out also stop at the largest and smallest sizes the window can show, where they used to keep counting presses, so after going past one end the next presses the other way changed nothing.
- On a phone, in the apps and in the browser, the screen behind a sheet such as the model picker shrinks back a little, and its edges no longer show a thin line while the sheet is open.
- In dark mode, the iMessage, Telegram and Twitch logos in Settings > Connect > Channels and on the Channels screen now show their white speech bubble, paper plane and inside, as in light mode, on the desktop, the web and the phone apps. The dark background used to show through those shapes.
- On a phone (the iPhone and Android apps, and app.foxl.ai and code.foxl.ai in a phone's browser), a toast that shows up while Settings or the notifications sheet is open can now be closed with its X or swiped away, and holding it keeps it on screen. A tap on a toast used to go through it to whatever was under it in the sheet, such as its Search button, and the toast stayed. Closing a toast now leaves the sheet open, and on every device the same goes for a toast over a dialog such as the command palette (Cmd+K or Ctrl+K).
- In the iPhone app, the chat moves with the keyboard as one piece. The message bar, the messages above it and everything docked on the bar start rising together, in a smaller first step. With messages queued, the queue held still while the keyboard opened and then jumped into place at the end (and dropped in one step as it closed), and the conversation jumped at the start; the jump-to-latest button did the same while you were reading further up. Queueing a message while a reply streams also no longer pushes the end of the reply out of sight behind the queue.
- In Foxl Notes, the Summary tab now opens at the top of the summary, on the desktop, on app.foxl.ai and in the phone and iPad apps. A note with a summary opens on that tab, and opening one such note after another left every summary but the first scrolled to its last line.
Features
- On a Windows PC (64-bit Intel or AMD) and on a Linux computer (x64), Foxl can now run AI on the computer itself, as it does on a Mac with Apple Silicon: Settings > Model & provider > On this device offers Google's Gemma 4 (E2B, and E4B on a PC with 16 GB of memory) and Qwen's speech recognition for Foxl Notes, free, private and working offline. On-device transcription in Notes separates speakers and shows the live line as you speak, as on the Mac; in our measurements on a 4-core PC with no graphics card, a 5-minute recording of two voices came back word for word with every line given to the right voice, each line about a second after it was said. Both use the graphics card when llama.cpp finds one it can use through Vulkan (we measured an NVIDIA GPU), and the processor otherwise, without a setting: on a PC with an NVIDIA T4, the first message to Gemma 4 E4B after it loaded answered in about 17 seconds and each transcript line came about a third of a second after it was said. On the processor alone the first message after each load is slow while Gemma reads Foxl's instructions (the sidebar shows it preparing): about a minute and a half with E2B and three minutes with E4B on that 4-core PC, and longer on a slower one; the next messages start in about a second. So on a Windows PC or a Linux computer the one-step setup (Run Notes on this computer, Run AI on this computer) downloads E2B, and E4B is one Download away. On Windows the on-device runtime needs the Microsoft Visual C++ Redistributable, which most PCs already have; on one without it, the download says so and links to Microsoft's installer. On Linux nothing needs to be installed by hand (Foxl downloads its own tools for the speech engine), and it was measured the same way: on a 4-core computer with no graphics card, two scripted meetings came back with both voices told apart and each line about a second after it was said, and Gemma 4 E2B's first message after it loaded took about three minutes, the next under a second; with an NVIDIA T4 each line came about a third of a second after it was said and E2B's first message took under a minute.
- On the desktop, on app.foxl.ai and in the iOS app, Foxl Code now works the way code.foxl.ai does by default: chat runs on the Foxl Code service with its models and your Foxl credits, and tasks run on Remote or a machine you registered. Settings > Code > Coding agent has a new Where Foxl Code runs choice for each device: Remote, or This computer to go back to chat in Foxl Desktop on your own model provider, with this computer offered for tasks in a local terminal. A device that already used Foxl Code with your own model provider moves to Remote too, and the Code page tells you so once, with a button that opens that setting. Tasks already running on this computer keep running, and are listed while This computer is selected.
- On the desktop, during a meeting, Foxl Notes' AI Assistant has a What to say quick action, first in the row, left of Catch me up, in the panel beside your note and in the Live panel. It answers with one or two lines you could say next, based on what was just said and in the language of the meeting, and it shows from the first transcript line. Suggest Questions stays beside it.
- On the desktop, a Claude Pro/Max or ChatGPT Plus/Pro subscription now shows how much of its limits you have used. Select Claude Code (OAuth) or OpenAI (OAuth) in Settings > Model & provider and Plan usage lists the 5-hour and weekly limits (and a model's own weekly limit, when the plan has one) as a percentage with a bar and the time until each resets, read from Anthropic or OpenAI with the sign-in Foxl already uses. On macOS and Linux the status panel behind the green dot at the top right shows the same limits for every plan you are signed in to. Gemini is not included: an API key has no plan limits.
- On the desktop, connecting a calendar to Foxl Notes now takes one click, in Settings > Notes > Calendar; the first time you open Settings, its tour ends on it. First-run setup no longer asks about a calendar. On a Mac, Connect next to Calendar on this Mac reads the calendars in the Mac's Calendar app (the iCloud, Google, Exchange and other accounts added to the Mac) after macOS asks you once. On a Mac, Windows and Linux, Connect next to Outlook signs in with Microsoft in your browser, the same sign-in as Microsoft 365 on the Integrations page, and reads your default Outlook calendar; disconnecting Microsoft 365 there stops it. Any other calendar can still be added from its iCal link, under Use an iCal link instead. Meetings you declined in the Calendar app or in Outlook are left out of today's list, as cancelled meetings are.
- On the desktop, Foxl Notes auto-save can now write plain text (
.txt) and subtitles (.vttand.srt) as well as Word and Markdown: pick one under Format in Settings > Notes > Auto-save and export. Plain text is the same note as the Markdown file without the formatting marks. A subtitle file holds only the transcript, not the summary or your notes: each line with its time, and who said it when more than one person speaks or a speaker has a name. It opens in a video player or caption editor, and Foxl can import it back as a note. A note with no transcript saves no subtitle file.
Improvements
- On the desktop, the Provider list in Settings > Model & provider now shows the providers marked Ready first, so the ones you can already use are at the top. On this device leads the list, and moves below the Ready ones until it is set up.
- In the iPhone and iPad app and on app.foxl.ai, Foxl Notes' AI Assistant is now the same one the desktop has while your desktop is online: a Foxl Chat conversation on your desktop, with its tools, the model picker, attachments, skills and voice input, the quick actions and the requests written from your meeting, answers you can copy, regenerate, edit or insert into the note, and Open in Foxl Chat to continue it there. Each note keeps its own conversation, listed with your chats, and your first question attaches the transcript so far while every later one attaches only the new lines, instead of the whole note again. On a phone and an iPad its buttons are sized for a finger, and Open in Foxl Chat and New chat sit at the top of the Ask AI sheet. With your desktop offline the simpler assistant answers as before.
- In the iPhone app and on app.foxl.ai in a phone's browser, Foxl Notes' AI Assistant is now a page of its own beside your note: swipe left from the transcript (or your notes, the summary or the report) to reach it and right to come back, or use Ask AI and the back button at its top left. Both stay full screen and keep their place, instead of the assistant opening as a sheet that covered the note, half the screen while you recorded, where an answer showed about two lines and the transcript above it could not be scrolled. The first time a note can be swiped, the page slides a little to show the assistant's edge and says Swipe for the AI Assistant. While you record, the top of the assistant shows the timer and the newest line of the transcript as it is spoken; tap it to go back to the transcript. Swiping is off while you type in your notes, and in the app a swipe from the left edge of a note still opens the sidebar. After your first question the quick actions take one row, with +N for the rest, and the box you type in sits right above the keyboard instead of about 45 points above it.
- On the desktop, on app.foxl.ai and on an iPad, a Foxl Notes note's transcript is now a Transcript tab right after Notes, shown in your notes' place, and AI Assistant in the toolbar opens and closes the assistant at the right edge of the window by itself, instead of the two sharing one panel. You can read your notes or the transcript with the AI Assistant beside either one, so the window never splits into more than two columns. Switching between the Notes and Transcript tabs keeps your place in each, and transcript lines are now the size of your notes. Foxl remembers whether you left the AI Assistant open, so the next note and the next recording open the same way. In a narrow window AI Assistant is in the toolbar's ... menu, and in the iPad app, when the toolbar is short of room (such as in portrait with the sidebar open), Import is there too.
- On a Mac, the on-device models need much less memory, which leaves an 8 GB Mac more room for everything else. Gemma 4 E2B holds about 2.4 GB instead of about 4 GB, and Gemma 4 E4B about 4.3 GB instead of about 6.5 GB: Foxl now reads their large per-word lookup table from disk as it is needed instead of locking it in memory, with the same model and the same answers at about the same speed. On-device transcription needs about 550 MB less at its peak and is about a quarter faster per sentence, with the same transcript. There is nothing to change in Settings; Settings > Model & provider > On this device shows the new sizes.
- On the desktop, Settings > Notes calls the floating meeting panel the Live panel everywhere, the same name as the button that opens it, instead of mixing in "Meeting HUD": the switches and the transparency slider now read Live panel, Close the Live panel when the meeting ends, and Live panel transparency.
- On the desktop, the Foxl Notes Live panel's menu now has Transcription language at the top of Captions, above Live translation: the same setting as Settings > Notes, so you can set the language of a meeting from the panel. Like the Settings row, it applies to your next recording.
- In the iPhone app, opening a section of Settings and going Back is quick again: the screen still slides in from the side, but it arrives in under a third of a second instead of about two thirds, so a tap answers about as fast as it did in v0.7.
- In the iOS app on an iPhone, Read all in the notification center is now a button beside the All / Unread switch, one tap away, instead of an item inside the ... menu. The ... menu keeps Clear all.
- On the desktop, the Integrations and Skills pages now show each product's own logo instead of drawn look-alike icons: Outlook and Outlook Web, Word, Excel and PowerPoint (Docx, Xlsx, Pptx), Email (IMAP/SMTP) (the Himalaya mail client's), Spotify and Spotify Player, Sonos, Voice Call (Twilio's), Claude Code, Codex CLI, Gemini and Gemini CLI, Git, Electron, tmux, Video Frames (FFmpeg's) and GitHub, plus draw.io, KakaoTalk, Signal, Kiro, Amazon Bedrock and AWS for skills with those names. Skills that are not a product, such as Exec, Web Fetch, Browser, Weather and Pdf, use a plain line icon in the app's own style that follows light and dark mode, instead of a colourful drawing; GitHub's mark no longer sits in a white box in dark mode. Quip is deprecated and no longer listed under Integrations; if you have it installed it stays on the Skills page, where you can switch it off.
- On the desktop, a Foxl Notes model set to Automatic in Settings > Notes now shows one short line naming the model it is set to, such as "Set to Gemma 4 E2B (On this device).", instead of a paragraph listing what Automatic picks with each provider.
- Search opened from Foxl Notes now fits Notes on every device, using the same search as Chat. In the iPhone app the search page lists your recent notes before you type, the way Chat's lists your recent chats, and its field says it searches notes first. While you are in Notes, a note found by its name shows its first line under the name instead of "in Foxl Notes".
- On the desktop, the Foxl Notes Live panel now opens where you last left it and at the size you left it, with the AI Assistant beside it if you had it open, also after Foxl restarts or updates. Before, every start put it back in the top-right corner at its first size with the AI Assistant closed. Turning off Always on top in its menu is remembered too. If the screen it was on is no longer connected, it opens in the top-right corner of your main screen at the size you left it, and a panel that no longer fits its screen is moved and shrunk to fit.
- On the desktop, the product menu at the top of the sidebar now shows each product's shortcut beside it: ⌘1, ⌘2 and ⌘3 on a Mac, Ctrl+1, Ctrl+2 and Ctrl+3 on Windows and Linux, the same keys as the View menu.
Fixes
- On the desktop, a first message to the on-device model sent while the model was still loading, such as right after its download finished, no longer waits for the model to be prepared twice. Foxl prepares the model with its instructions as soon as it loads, and a message sent during the load was then read again from the start because its instructions differed slightly from that preparation; now that message is the preparation. On a Linux computer's processor this took the first answer from about 7 minutes to about 3.
- On the desktop, when the on-device model (Gemma 4) cannot start, Settings and the chat now say why, instead of "the on-device model load was stopped before it finished (another model's load or an unload took its place)", which it said for any model that stopped while loading.
- In Foxl Code, Diff on a Needs you card in the right-hand panel or under a task's conversation now says when Foxl can no longer reach that repository, as it does on the Work page. Before, in the panel the press did nothing, and under a task it opened a window that never loaded.
- On app.foxl.ai and in the iOS app, the menu of a Foxl Code terminal on This computer that runs in its own worktree no longer offers Open folder: it opened the folder on your desktop computer, out of sight, or did nothing while the desktop was offline. The desktop app keeps it.
- On the desktop, clicking a notification banner that opens Notifications or Settings, such as a spending-limit notice, or choosing Settings... in the app menu, no longer moves you from Foxl Notes or Foxl Code to Foxl Agent: the page opens over the product you were in, as it does from the notification list and the banner's Open button.
- In the sidebar, clicking the row of the page you are already on now clears the number beside it. Before, on the desktop, when a scheduled run finished while you were on Schedules, the Schedules row showed "1" and clicking it left it at "1" until you went to another page and came back. The Tasks row in Foxl Code clears the same way.
- On code.foxl.ai, the notification bell now lists your Foxl Code tasks that finished or failed and the questions waiting for your answer, and clicking one opens its task. Before, the bell there was always empty. It lists what happens while a code.foxl.ai tab is open, whether or not browser notifications are turned on.
- On a phone, a tab-bar tab for For You, Settings, Usage or Integrations no longer moves you from Foxl Notes or Foxl Code to Foxl Agent before opening it: the page opens over the product you were in, as it does from the notification list. A For You page opened while you are in Foxl Code now scrolls and keeps its margins, on the phone and on the desktop, where before everything below the first screen could not be reached.
- Foxl Notes' AI Assistant now knows the date of a meeting, on the desktop, on app.foxl.ai and in the iOS app, so a deadline said as "next Wednesday" or "this Friday" can be answered with its date. Before, it said it needed to be told the meeting date. This applies to a note's conversation started from now on; for a recording or transcript you imported, the date is the day you imported it.
- On the desktop, when a Foxl Notes note's AI Assistant could not open its conversation, such as after you deleted that chat in Foxl Chat, the next question no longer goes out without the meeting's transcript: the assistant now says your first message attaches the transcript so far, and it does. Before, it said the chat had the whole transcript, started a new chat with none of it, and every later question on that note lacked it too.
- On the desktop, a code block in an answer in the Foxl Notes Live panel's AI Assistant, such as a script it drafted for you, now wraps inside its bubble instead of running past it and scrolling the panel sideways. A long link in a question or an answer wraps too.
- On a Mac with no AWS account set up, recording, dictation and chat no longer wait about two and a half minutes before reporting that no AWS credentials were found; the answer now comes at once.
- On a Mac with Apple Silicon, "Install on this Mac" for on-device transcription now works on a Mac without uv or a newer Python: Foxl downloads its own copy of the uv installer (checked against a pinned hash) and Python 3.12 instead of using the Mac's built-in Python 3.9, which stopped at "could not install mlx-qwen3-asr (pip install)". With no internet connection the install says so and what to do, without running the Mac's built-in Python, and Delete removes the downloaded Python too.
- With Automatic transcription, when the desktop takes longer than 30 seconds to say which engine to use, Foxl now asks once more before falling back to Amazon Transcribe.
- Foxl Flow no longer asks Amazon Transcribe for a session every two and a half minutes in the background on a computer with no AWS credentials; it tries again when you dictate or change its settings.
- On a Mac with less than 16 GB of memory, the on-device model (Gemma 4) handles one request at a time and keeps a smaller cache, so a chat no longer slows down to finish together with every other request sent at the same time. When the model becomes your chat model after its download, it is loaded right away rather than when you send your first message, and the chat's greeting suggestions are no longer generated on it or on a provider that is not set up.
- On a Mac with Apple Silicon, on-device transcription in Foxl Notes uses less memory during a long recording: Foxl now limits the engine's buffer cache, which in our measurements brought its peak from about 2.3 GB to about 1.7 GB, and to about 1.4 GB with the tighter limit Macs with less than 16 GB of memory get. If it ever falls more than 10 seconds behind the conversation, Foxl now says so while it keeps recording, instead of the transcript seeming to stop; every line still arrives. Settings lists its memory need as about 2 GB.
- On a Mac with less than 16 GB of memory, the on-device chat model (Gemma 4) and on-device transcription are no longer loaded side by side unless you are using both. Starting a recording or voice input with on-device transcription first frees Gemma if it is not answering, so your next message to it loads it again (it says Loading model...); opening Notes does not load the speech engine next to Gemma, opening Chat does not load Gemma while you are recording, and the speech engine kept ready after a recording is let go when Gemma loads. Notes now loads the speech engine ahead of time only after you have used it once. While an on-device model loads, the sidebar says so, like a download, with about how long it took last time on this Mac. We checked this on a larger Mac set to behave like an 8 GB one, not yet on an 8 GB Mac.
- With the on-device model (Gemma 4) as your chat model, the first message of a new chat now usually starts answering in under a second instead of after 15 to 20 seconds: Foxl prepares the model with the chat's instructions as soon as it loads and when you open Chat, and a message you send while it is still preparing says Loading model... until the answer starts. Settings > Model & provider > On this device now says whether each on-device model is in memory or loads when used, and how long it stays after its last use.
- On the Mac and Linux desktop app, the status dot at the top of the window now pulses slowly while Foxl is working or an MCP server reports a problem, instead of blinking several times a second.
- On the desktop, a Heartbeat item in the notification center (the lightbulb rows, also sent as a system notification when it is urgent) now opens the Heartbeat run that wrote it when you click it, showing what Foxl read and did to write it, instead of leaving you on the notifications list. The same goes for its banner and, in the iPhone app, its push while your desktop is online. On the desktop, a run opened before it has finished fills in when it does. Items from before this update have no run to open. Everywhere except the iPhone app's notification list, a notification whose text is cut off now has Show more under it to read the whole thing in place.
- In the iPhone app, closing the search you opened from a chat's ... menu (Search conversations) no longer leaves the chat unresponsive. Before, once that search closed (going Back, for one) the chat stopped taking taps, so you could not type in the message box or tap anything in the conversation until you restarted the app.
- In Foxl Code, after you change which repositories the Foxl GitHub app can access on GitHub, you come back to Repos with a Sync repos button that shows the new list. Before, Repos said GitHub's redirect was missing the install id or OAuth code and offered Try again, which sent you back to GitHub.
- A notification that a scheduled run finished or failed now opens that run's conversation, with the way back to Schedules above it, from the notification list on every device and from the desktop's banner, as tapping it on your phone's lock screen already did. Before, it opened the Schedules page with nothing selected. A notice that a schedule was paused still opens Schedules.
- On a Mac, the Open button on a notification banner now also moves the sidebar to the product the page belongs to. Before, Open on a chat, agent or schedule notification while you were in Foxl Notes or Foxl Code showed that page but left the sidebar and Cmd+N on Notes or Code; clicking the banner itself already switched.
- On the desktop, a spending-limit notification (80% of a limit, or the limit reached) now opens Settings > Usage, where the limit is changed, from the notification list, the system banner and the banner's Open button. Before, clicking one did nothing or only brought the window forward, although the reached notice says new model calls on your own keys are paused until you change the limit there.
- Tapping a product-update notification in the notification list now closes the list as it opens the page or link. Before, the list stayed open, and an in-app page opened behind it.
- On app.foxl.ai, clicking a browser notification about your desktop's work now opens what its row in the notification list opens: the agent run, the scheduled run, or the task waiting for your answer. Before, the click only brought the Foxl tab forward.
- On code.foxl.ai, the settings button in the notifications panel now opens Foxl Code's notification settings. Before, it opened Settings on a page without them, General in a wide window and the list of settings on a phone. The panel also no longer offers "View all notifications", which only led back to Tasks there.
- In Foxl Code, opening a Foxl Ops notification, from the bell, a desktop banner or a phone notification, now opens the incident it is about instead of leaving you on the Ops list to find it.
- In the command palette (Cmd+K or Ctrl+K) on the desktop, app.foxl.ai and code.foxl.ai, picking "Account" or an Account setting such as Password, Delete account, Export my data or Sign out everywhere while signed in now opens your Account page. Before, it opened Settings on General, and with Settings already open it changed nothing.
- On code.foxl.ai, the command palette no longer offers the five "This computer" settings (Clone folder, Start folder, Permissions, Agents act without asking, This computer), which opened Settings on General there because that site has no This computer pane. On app.foxl.ai and in the iOS app, it no longer offers Usage > Spending limits, Daily limit and Monthly limit, which opened a Usage page without them: spending limits are set in the desktop app.
- The command palette (Cmd+K or Ctrl+K) lists "Show older model versions" twice, under Model & provider and under Foxl Notes' AI features, instead of six times, four of which opened a Notes settings page without that switch. Foxl Notes' AI features, Auto-save & export (Export outside the desktop app) and, on the desktop, Calendar settings can now be found in the palette by name, and their settings no longer read "Settings > ...".
- On a phone, in the app or on app.foxl.ai, the Desktop tab now opens the Desktop page while your desktop is offline too, showing when it was last seen or that no desktop is paired, instead of the plain Settings list; Settings lists Desktop then as well. In the iPhone and Android app, that page no longer offers a Turn on desktop button, which opened the app you were already in.
- In Foxl Code, Diff on a Checks failed or Reviewer asked for changes card in Needs you now opens that pull request's changes, instead of a "#NaN" window that never loaded. A card whose task has not opened a pull request yet no longer offers Diff, and on the Work page Diff for a repository Foxl can no longer reach says so instead of doing nothing.
- On the desktop, the agent link under an Agent launched step in a chat now opens the subagent that step launched, shown by its label when it has one. Before, it opened the main agent, or an error page when the subagent had a label. The link no longer appears while the subagent is starting or when it failed to start.
- In a chat, an opened tool step now lists every argument the call was made with. It showed only the first four, with nothing saying more were left out, so what a new schedule will do or that a command ran outside the sandbox could be missing.
- On the desktop, the update card in the sidebar now says the new version is ready to install, as the notification does. Before, it said Foxl was already updated to that version while the update was only downloaded and still needed a relaunch.
- On the desktop, the Agents page no longer shows a chat that is replying as a running agent: the row it added opened an error page, and the page said 1 agent running when no agent was. The Completed and Failed numbers at the top of the page, which counted only agents that finished in the last five minutes, are gone; the counts for the selected time range stay on the filters below.
- In Foxl Code, when an issue could not start an agent, its card in Needs you now shows the whole reason and what to do about it instead of cutting it off after two lines, and on the Tasks list the row shows it in full when you hover it. When the coding credential is the cause, the instruction to re-sync it in Settings > Agent credentials now comes before the error, so a long error can no longer cut it off.
- On app.foxl.ai and in the iPad app, the Files page no longer shows Open workspace folder: it opened the folder on your desktop computer, out of sight, or did nothing while the desktop was offline. In the desktop app, Open workspace folder now says so when the folder cannot be opened, instead of doing nothing.
- In Foxl Code, when an action in a task's header fails, such as Resume or Reconnect, the reason now stays in the header until you dismiss it with its X, a newer action replaces it, or the task's status changes, instead of disappearing after 8 seconds, and the arrow beside it opens the whole sentence (such as why the workspace is gone and what Retry does) instead of leaving it cut off after a few words.
- In Foxl Code on a phone, the model name in the message box no longer lies over the + button at a larger text size, and in the iPhone app at UI text size 120% or 130% it no longer squeezes the microphone: when the row has no room for the name, the model control shows its icon, and a screen reader still reads its name. In a phone browser the repository's name now gets that room at 100% too, where it used to show only its icon.
- In Foxl Code, when six terminals are already open on the Runtimes page, the rows under Running no longer look like they can be opened and then do nothing when pressed: they are dimmed, lose their hover highlight and arrow, and show the terminal limit when you hover them.
- In Foxl Code, Resume on a task's right-click menu (in the sidebar and on the Work page) now brings a finished task back the way Resume in the task's own header does: it reconnects the agent to the task's saved workspace instead of always failing with an error that printed the request's technical details. The menu no longer offers Resume for a coding agent that cannot be reconnected, and a failed menu action now shows a sentence, in your language where Foxl has one, instead of the request's technical details.
- Check for updates and Restart desktop on the Desktop page (Mobile/Web in the desktop app) now say what happened: that the request was sent to your desktop, that your desktop is offline so nothing was sent, or that it could not be sent. Before, neither showed anything.
- On the desktop and on app.foxl.ai, the number beside Recent chats in the sidebar now counts only the unread chats listed under it, not chats filed in a project, and a collapsed project shows a dot while one of its chats has an unread reply.
- Pointing at a set-up skill's button on the Integrations page now shows a settings icon instead of a red disconnect icon, since clicking it opens the skill's settings. The example prompt above the Integrations and Skills lists shows the whole prompt when you point at it, and screen readers now call that row Show the next example, which is what it does.
- On the desktop, "Open saved file" on a Foxl Notes note that was never saved no longer says Foxl could not open that file: it looks for the note in your other saved formats, then opens your save folder and says there is no saved file yet, or says the save folder does not exist yet when nothing has been saved there.
- On the desktop, the "Open Folder" button on the message after you import a recording into Foxl Notes now appears only when the import saved a file to your save folder. With Auto-save off, the default, nothing is saved, and the button opened nothing.
- In Foxl Notes, "Export as .docx" in a note's menu now says so when the Word file could not be made, instead of doing nothing, and on the web and on iPhone and iPad "Save as Word (.docx)" in the save dialog no longer says "Saved" when the Word file could not be made.
- On the desktop, clicking a Foxl Notes meeting reminder now names the meeting in Foxl Notes with a Record button, instead of only opening whatever note you had open. On Windows and Linux, where the reminder has no Record button of its own, this is how you record the meeting from it. Nothing records until you press Record.
- In Foxl Notes, a note's Report tab now says why it cannot make a report, "Sign in to use AI features" or "No transcript to analyze yet.", instead of describing the report with no button to get one. After you delete the note you were reading on the Report tab, the tab row shows Notes again.
- On the desktop, when Start in the Foxl Notes Live panel cannot start a recording, such as when the microphone is blocked, no transcription service is set up or an import is still running, Foxl now brings its main window forward so you can read why. Before, the reason appeared only in the main window, often hidden behind your meeting, and Start seemed to do nothing.
- On the desktop and the iPhone, "Copy link" on a channel or a message in Channels now copies an app.foxl.ai link a teammate can open, instead of an address only your own computer could reach, and the link opens the room in its own workspace. A "Link copied" confirmation now appears.
- On the iPhone and app.foxl.ai, Channels with only Slack, Telegram or other connector conversations no longer says "No messages yet" and empties its list while your Foxl desktop is off: the conversations it last showed stay, opening one says the desktop can't be reached instead of showing no messages, a reply typed there says it was not sent, and with no conversations to show the page says the desktop can't be reached.
- "Create a workspace" on the Channels page now opens Settings at the Workspace section, where a workspace is created, without reloading the app. Before, it reloaded the app into Settings and left you to find Workspace.
- On the desktop, deleting a subagent or restoring the starter subagents now says when it could not be saved, instead of closing the dialog and changing nothing, and a schedule's Feed Generator prompt says when HEARTBEAT.md could not be read instead of calling it empty.
- On app.foxl.ai in a browser, Settings > Notes no longer offers an Auto Save switch and an Auto-save Format that did nothing there: notes are saved to a folder automatically only by the desktop app. The section is now called Export, as in the iOS app, and keeps File name, which names the notes you export from the list.
Changes
- On the desktop, Dictate anywhere now has its own place in Settings, in the App group after Computer use, instead of under Notes: it works in every app, not just in Foxl Notes. Its settings are the same and are kept.
- On the desktop, the Foxl Notes Live panel now starts with a darker background, 70% on its Transparency slider instead of 40%, with 13px text and the Dark theme, so captions are easier to read over a busy screen. A setting you already chose is kept.
- On the desktop, the Foxl Notes Live panel no longer has a Suggest tab: Live reply suggestions (a card each time the other person finished talking, with Agree, Push back, Ask and Suggest under it, the Own window and the card text size) are gone, along with their switch and Suggestion model in Settings > Notes > Recording. Use What to say in the AI Assistant when you want a line to say.
- On the desktop, the Foxl Notes meeting reminder now comes 5 minutes before a meeting by default, and can be moved to 1 or 15 minutes in Settings > Notes > Calendar. The 10-minute choice is gone, and a reminder set to 1 or 10 minutes in an earlier version now comes 5 minutes before until you pick again.
Removed
- Foxl Notes no longer has its own search window: it uses the app's one search, which finds your notes by title, text and transcript and, while you are in Notes, lists them first, above your chats. On the desktop on Mac and Linux, while the search field is at the top of the window (the default), the magnifying glass beside AI Assistant is gone and Cmd+Shift+F goes to that field; Cmd+F with no note open no longer opens a search there, as in Foxl Agent. In the browser, on Windows and on iPhone and iPad, where there is no search field at the top, the magnifying glass, Cmd+Shift+F and Cmd+F with no note open open that same search. Type at least two characters; the example note Foxl adds on first launch is opened from the sidebar.
- The Enhanced column in Foxl Notes, which filled in the lines you typed from the transcript during a recording, is gone, along with its settings. Enhanced lines already written for earlier notes stay saved with those notes but are no longer shown. Transcript in my notes in Settings > Notes still writes the transcript into your notes if you want it there.
- On the desktop, Settings > Notes > Calendar no longer imports an .ics file, which never updated by itself. A calendar you imported from a file before still shows its meetings and can be removed; to keep it up to date, connect it through the Calendar app, Outlook or its iCal link instead. Calendars added from an iCal link are unchanged.
Features
- On the desktop, the Foxl Notes home now asks for the microphone and for audio from other apps before your first meeting, under "Ready for your first meeting", instead of in the first seconds of the recording. Allow asks the system for it, and a row reads Allowed only once the system reports the permission granted; if one was turned down earlier, the row says it is blocked and Open System Settings (Windows Settings on Windows) takes you to the system's privacy settings for it, since the system asks only once. The rows disappear once everything is allowed and never stop you from recording. On a Mac, audio from other apps needs both System Audio Recording and Screen & System Audio Recording, and the row checks both. Windows needs no permission for it, so there only the microphone row can appear; Linux shows the microphone only.
- Foxl Notes can make a note from a meeting transcript you already have, with no audio: import a Zoom or Teams
.vtt, a Teams.docx, an.srtor a.txtwith the import button or by dropping it on Notes, or choose Paste a transcript in the Notes ... menu and paste the text, such as the transcript Google Meet saves to Docs. Foxl reads each speaker's name and the time of each line, shows what it found as you paste, and asks which speaker is you so the coaching report measures your talk time. In a caption file with no speaker names, such as a Zoom.cc.vttor a plain.srt, a sentence that starts with a phrase and a colon, such as "The bottom line: we need two more weeks.", stays part of what was said instead of becoming a speaker, and so does a pasted line like "Next step: ..."; names that recur, or that a header or the timed speaker lines give, are read as speakers. The note then gets its title and summary like an imported recording. - On the desktop, Foxl Agent and the Notes assistant can answer from your Foxl Notes meetings, transcripts included, without switching anything on first: ask "what did we decide about the beta" or "who owns the landing page" and the answer comes from what was said. Each note an answer used is listed under it as a source with its title, date and, for something said in the meeting, the time in the recording (12:04); hover to see the matched lines, and click to open the note with the transcript scrolled to that line and highlighted. A question in Korean finds English meetings and the reverse, and a speaker the transcript does not name is not given a name. If you used an earlier version, the update turns both on once (a search you had turned off after including transcripts stays off); turn either off in Settings > Notes > AI features and it stays off. On the phone and app.foxl.ai, a cited note that lives on your desktop shows as a source you can preview.
- On the desktop, Foxl Notes can show today's meetings. Add a calendar's iCal link (Google Calendar, Outlook or iCloud) or an .ics file in Settings > Notes > Calendar, and the Notes home lists today's meetings, each with a Record button. A note recorded this way is titled after the meeting and lists who was invited, and the AI summary does not rename it. A minute before a meeting with other people a reminder appears: on a Mac it has a Record button, and on Windows and Linux clicking it opens Notes. You can switch it off or move it to 5 or 10 minutes in the same settings, and it follows Settings > Notifications like every other Foxl notification. Nothing records until you press Record. Calendar links are kept on your computer.
- Foxl Notes in Foxl Desktop has an Enhanced column beside your notes while you record. Jot a few words for each point, such as "beta date" or "installer", and a few seconds later the column reads what was actually said about each one, with names, dates and numbers as they were said, in the language you take notes in. A line about something not discussed yet says so and fills in once the topic comes up. Your own text is never changed: hover an enhanced line to see which of your lines it belongs to, click it to open the transcript where it came from, and use Insert into my notes or Copy to take it with you. After Stop the column stays with the note, and you can edit it, choose Standard or Concise, or regenerate it. It runs on a fast model from the provider you already use for Foxl, chosen by "Run live features on" in Settings > Notes (Automatic by default), with one request at a time. It does not fill in on OpenRouter's free models, whose 50 requests a day one meeting you type through can use up; there the transcript goes into your notes as before. For a new setup the transcript now stays in the Transcript tab instead of being written into your notes; if you used Foxl Notes before, your notes keep receiving it, and "Transcript in my notes" in Settings > Notes switches that either way. A summary of typed notes now also reads the transcript, so facts you did not type are still in it.
- On the desktop, Foxl Notes can answer questions asked in a meeting from your own notes, once you turn it on. When someone asks something your notes hold, such as how fast Business support tickets are answered, a card appears a few seconds later at the top of the AI Assistant, under Answered from your notes, in the main window and in the Live panel: the question, a one- or two-sentence answer, and the notes it came from as sources you can hover to preview and click to open at the line. While the AI Assistant is not in front, its button shows how many new answers arrived. It looks in the note's Background, what was already said in the meeting and, with Let Foxl Agent search your notes on, your earlier notes, and a question in one language can find notes written in another. It is told to leave rhetorical questions, requests and "how is it going" questions alone and, when nothing in your notes answers a question, to say so on the card rather than guess. Each card can be copied, followed up in the same AI Assistant conversation or removed, and the cards stay with the note. It is off by default: turn it on with Answer questions asked in the meeting in Settings > Notes > AI features. It uses the model for Notes' live features, with one short request for each turn that might be a question (about one turn in six in a real meeting, roughly 100 to 300 an hour of conversation) plus one for each question it answers, and it does not run on OpenRouter's free models, whose 50 requests a day a meeting would use up; turn it off again from the menu next to Answered from your notes or in the same setting.
- On a Mac with Apple Silicon, Foxl can run AI on the computer itself: Settings > Model & provider > On this device downloads Google's open Gemma 4 (about 5.2 GB, with progress, pause and resume) and runs it with no account, no key and no internet. It is added next to your providers and never replaces the one you use; a Mac with nothing else connected starts using it right away. The same offer is in an empty chat and on the Foxl Notes home.
- First-run setup on the desktop now has one "Set up Foxl Notes" screen, where everything is optional. On a Mac with Apple Silicon, "Run Notes on this Mac" installs the on-device speech engine and Gemma together (about 6.5 GB; only the part you are missing), shows how much is left, can be paused, and keeps going in the background after you continue; on other computers the transcription row offers an AssemblyAI key, and a computer that can already transcribe just says Ready. The same screen asks for the microphone and audio from other apps, can add a calendar from an iCal link or an .ics file to show today's meetings and remind you, and holds the Live translation switch that used to have its own screen. Before, a computer that could already chat was never offered transcription during setup. The Connect screen now only connects a chat model, and on a Mac with Apple Silicon adds "Run AI on this Mac" unless the Notes screen already offered that download. While an on-device model downloads, a thin progress line sits at the bottom of the sidebar. The side panel explains what runs on your computer, what goes online and how much is downloaded.
Improvements
- On a Mac with Apple Silicon, Foxl Notes' on-device speech recognition (Qwen3-ASR 0.6B, about 1.4 GB) is now listed under Settings > Model & provider > On this device next to Gemma 4, with its size, memory need and install progress. Cancel stops the install and removes what it had downloaded, and Delete frees the space again. Installing it from the Foxl Notes home is the same install, so its progress shows in both places.
- Foxl Notes' live translation now translates each line together with the lines before it and a short running summary of the meeting, so a sentence split across two lines reads as one and names and recurring terms keep one spelling. On a lively call the running summary reads only the newest stretch of talk, so its request stays small however long the call runs. A long sentence still appears while it is spoken and is replaced by one clean translation when it ends, and lines that arrive while one is being translated go out together instead of queueing behind it, with their translation under the last of them. In a scripted 40-line meeting replayed on four model setups, no line was lost and a blind review rated the captions more accurate and more consistent on every model. On models that cache prompts the earlier lines are mostly read from the cache; on others they are paid as extra input, about 5 cents more per hour of nonstop conversation on Gemma 4 31B.
- On the desktop, Foxl Notes' live translation, reply suggestions and automatic titles set to Automatic now run on a faster model with Amazon Bedrock, a Gemini API key or OpenRouter's free router, picked by measuring live translation speed and quality on each. On Amazon Bedrock that is Gemma 4 31B, which answered sooner than GPT-6 Luna and translated sentence fragments and speech-recognition slips more faithfully; if your AWS account refuses it, Notes moves to GPT-6 Luna and then Claude Haiku 5.5 on its own. With a Gemini API key it is Gemini 3.5 Flash-Lite instead of Foxl Agent's own model, which on Gemini 3.8 Flash took several seconds per line and often failed when Google was busy. On OpenRouter's free router it is Gemma 4 26B (free) instead of whichever model the router picked for each line. With an Anthropic key it is still Claude Haiku 5.5; with only a Claude subscription it runs on Foxl Agent's own model, as before. Settings > Notes names the model that runs.
- On the desktop, "Keep this computer awake while Foxl is working" in Settings > General is now "Keep this computer awake", a plain switch: while it is on, the computer does not go to sleep on its own for as long as Foxl is running, not only while a reply or a run is in progress, so a scheduled run also finds it awake. It now works whether or not "Keep running when closed" is on, and with that on it keeps working after you quit the app on macOS and Windows, where it used to work only while the app was open. On Linux, with the app quit, the background service asks systemd-logind to hold off idle sleep, and whether your desktop's own power settings follow that request depends on the desktop. The screen still turns off to save power, and closing the lid or choosing Sleep still sleeps the computer. It is off by default. If you had the earlier switch on, it is still on, and it now keeps the computer awake for as long as Foxl runs rather than only while Foxl is working, which uses more battery; you can turn it off in Settings > General. If the background service cannot keep the computer awake, Settings says so under the switch.
- On the desktop, the Foxl Notes Live panel's AI Assistant is now the same assistant as the one beside your note: one conversation, the same suggestions from the meeting and quick actions, and the same answers, whichever window you ask in. In the Live panel it is a button with the purple sparkle in the title bar rather than a tab: it opens the assistant on the right of the transcript and widens the panel by as much, so the transcript stays in view while you ask, and pressing it again closes the assistant and gives the width back. The Live panel's tabs are Live, Suggest and Background; the assistant's chips replace the Agree, Push back, Ask and Suggest chips under the transcript (those four stay on the Suggest tab), and the Notes tab is gone, since the note is written in the main window. With "Use Foxl Agent tools" off, the Live panel still answers on its own, without tools.
- On the desktop, Transcript and AI Assistant in the Foxl Notes toolbar are now one switch for the side panel: the panel in front is the one that looks pressed, pressing the other brings it forward, and pressing it again closes the panel. Start Recording opens the panel you chose last, so with AI Assistant chosen a meeting starts on the assistant, and AI Assistant is there to switch to from the first second of a recording. The Live panel always starts a recording on its Live tab, with the assistant open beside it when that is the panel you chose.
- When Foxl credits run out, the chat banner, voice input and Foxl Notes transcription no longer tell you to upgrade a plan, since there is no paid plan to buy. The chat banner keeps one button, Use own keys; voice input says it works again when your credits refill; Notes also names the transcription providers that keep working now. A model your account cannot use, shared files and workspace invitations no longer mention a Pro plan either.
- The Account page no longer shows a plan: the Free / Pro badge beside your name, the Subscription section with its plan, Manage button and included-features list (in the iOS app, the "Manage your plan and billing on the web" row) and the past-due payment banner are gone on every platform, and the page's description no longer mentions a plan. On Foxl Code the usage and credits section stays, without its Manage subscription link, which opened a page that does not exist (it is gone from the Usage page too); everywhere else the description and the data-export line no longer mention usage or credit grants either.
- On a Mac with Apple Silicon, Foxl Notes' on-device transcription keeps up with you: the gray live line now updates as often as your Mac can transcribe it, about every half second on a recent Mac instead of every 1.3 seconds, and a sentence is finished sooner after you stop talking, because the engine starts transcribing it at the first pause. That keeps the Mac's graphics processor up to about twice as busy while you speak, so a long on-device recording uses more battery than before. Recording also starts transcribing sooner: the speech engine is loaded when you open Notes and kept for five minutes, and kept for five minutes after each recording, so pressing Record in that time, or Resume after a pause, no longer waits two to three seconds for it to load, and Foxl no longer checks the engine's installation again on every press.
- Foxl Code's cloud tasks run the latest coding agents: Claude Code 2.1.296, Codex 0.162.1, Kiro CLI 2.29.1, Cursor Agent 2026.10.01 and OpenCode 1.19.0 (Hermes 0.19.0 was already the latest). A Codex task that reaches your plan's limit on simultaneous model requests now waits and retries a few times before it fails, where it used to fail at once, and GPT-6 Astra runs in Codex with its own model settings instead of generic ones; GPT-5.4, an older model, now gets the generic ones. A Claude Code task still works in a 200K-token context on every model except Claude Opus 5.5, as before.
- In Foxl Code, the autonomous loop of an account that has never saved a chat model in Settings now runs on Claude Sonnet 5.5 instead of Sonnet 5, which costs fewer credits; a chat you send yourself still uses the model in the picker. When the model list cannot be loaded, the model picker's own list now includes Claude Fable 5.1.
- On the desktop, the Foxl Notes home's setup card is calmer and quicker to finish. "Notes is almost ready" lists each missing step with one line and one button: Install on this Mac for on-device transcription (about 1.3 GB, on a Mac with Apple Silicon) and for the summary model (Gemma 4, about 5.2 GB), or Install both to start them together, with Settings one link away. A step leaves the card when its install finishes, and the microphone and other-app audio rows are part of the same card. While a step is missing, the home shows only this card instead of "No note selected" with Record and Import above it. The card is no longer orange.
- On the desktop, until a model has been connected for the first time, a new chat shows only "Connect a model to start", without the message box under it, since nothing could answer a message yet. The message box appears once a model is connected, and Foxl checks the model list again when you come back to its window. If a model you used before stops answering for a while (a local model server that is not running, an expired AWS sign-in), the card shows above the message box as before. When Foxl could not read the model list at all, the message box stays and the card no longer claims that nothing is connected.
- On the desktop, ask Foxl Agent how Foxl itself works (a feature, a setting, how to set something up) and it reads the answer from the Foxl docs at foxl.ai/llms.txt instead of guessing.
- On the desktop, app.foxl.ai and the iPad, Foxl Notes' toolbars are quieter. The editor toolbar has the phone's seven tools (Undo, Redo, Text style, Bold, Italic, Bullet list, Checklist) and one More formatting menu with the rest, instead of twenty-three buttons in a row that scrolled sideways once the side panel was open. The side panel no longer repeats Transcript and AI Assistant as tabs under the toolbar's own switch (in a narrow window, where that switch moves into "...", the side panel keeps its tabs). The Summary, Background and Report tabs show their names without icons, and New note is in the sidebar instead of also in the toolbar (it stays in the toolbar on phones).
- In Foxl Notes, the editor toolbar's heading button is now Text style, a menu of Body text and Heading 1 to 4 whose button shows the level of the line you are in, on every platform. It used to make only a Heading 2, with Heading 1 and 3 in the More formatting menu and no Heading 4; a Heading 4 is saved with the note like the others.
- On the desktop, Foxl Notes transcription with Gemini now uses the Gemini key you already connected in Settings > Model & provider, so there is no second key to paste; a key pasted under Notes still takes precedence. In Settings > Notes > Recording and Dictate anywhere, the provider lists now mark each provider this computer can already use as Ready (AWS credentials, the installed on-device engine, an API key), like the Model & provider list, and list those first. Automatic still never picks a provider that bills your own API key, so where Notes says transcription is not set up (under Automatic in Settings, on the Notes home and in first-run setup) it now offers one button, such as Use Gemini, when such a key is already on the computer, and says beforehand when that provider's free tier may use the audio to improve its products.
Fixes
- With Foxl in Arabic, English text now reads left to right where it used to come out scrambled: an English message or reply showed its question mark or full stop at the wrong end ("?Thanks! Can you ..."), a link put its trailing "/" in front, typed English in the message box moved its punctuation as you typed, and an English note title cut off its beginning instead of its end. Each paragraph of a reply, each line of your message and of a meeting transcript, each conversation, note and task title, and what you type now take their direction from their own first letter, so Arabic reads right to left in any other language's app too, while titles stay lined up with the rows around them. In Arabic, the search field and filter fade on the Integrations, Skills and Tools previews sit on the right like the rest of the page, the count beside each group name has its space back, and the Notes Live panel's chat bubbles point toward their side.
- On a Mac and on Linux, quitting Foxl, force quitting it or a crash of the app no longer leaves Foxl's local server running, and what the server started no longer outlives it: the Signal channel's receiver, the on-device transcription engine and its install, MCP servers, hooks and the ChatGPT sign-in stop with it, even when the server itself is killed outright. A command the agent left running in the background, such as a dev server it started, now stops when you quit Foxl too, where it used to keep running with nothing left to stop it. "Keep running when closed" still keeps the server, and what it started, running on purpose.
- Starting a recording in Foxl Notes now ends the Notes tour, so its last card, which points at Record, no longer stays over the Stop button of the meeting you just started.
- On a Mac, Foxl Notes' on-device transcription with the language on Automatic no longer turns some Korean speech into Chinese or Japanese text. A sentence the engine hears as Chinese or Japanese while your app language or your notes say Korean is transcribed again in Korean, so in a meeting that is mostly Korean a short sentence really spoken in Chinese or Japanese can come out in Korean too. English, and English words and sentences inside a Korean meeting, come out as before, and the setting stays on Automatic.
- On the desktop, Foxl Notes' live translation no longer runs at the reasoning effort chosen for chat. With a ChatGPT subscription model picked for translation, a caption took about 7 seconds and up to 14 in a replayed meeting; it now shows in about 1.5 seconds. A caption that gets no answer is retried after 8 seconds instead of holding up the next ones for 20.
- On the desktop, usage and cost recorded for GPT-6 Luna, GPT-6 Sol, GPT-6.1 Sol and Kimi K3 on Amazon Bedrock no longer count cached input twice. Records from before this version keep their earlier figures.
- On the desktop, long Claude conversations on your own Anthropic key or on Foxl credits now count the cached part of the prompt when Foxl decides whether to compact them. With prompt caching on, the size estimate left it out, so compaction could start much later than it should. On your own Anthropic key compaction starts near the model's context limit; on Foxl credits, Claude Opus 5.5, Sonnet 5.5, Fable 5.1 and Haiku 5.5 conversations compact at about 180,000 tokens.
- Foxl Notes: starting a new recording now always opens a fresh AI Assistant beside your note. On the phone, on app.foxl.ai and with Use Foxl Agent tools off, a question asked with no note open before you pressed Start Recording stayed on screen in the new meeting's assistant, and your next question continued that earlier conversation.
- On the phone, the model picker sheet has a Close button in its header, opposite search.
- Channels and Notifications with nothing in them now show the same empty-state layout as the rest of the app.
- Settings > This computer and Settings > AI features no longer show their title twice.
- In Foxl Code, OpenCode tasks on Claude Opus 5.5 (the default), Sonnet 5.5, Haiku 5.5 and Fable 5.1 failed on their first request with "Bedrock answered 400". They run now.
- In the iOS app, a switch's knob is white in dark mode too, as on every iOS switch. An off switch's knob was the colour of the page and all but invisible on its dark track, and an on switch was a dark circle on a pale blue track; it is now a white knob on a deeper blue.
- In the iPhone app, the model picker no longer opens with a black ring around its Close button.
- The System tools page, opened by its older address (
/tools), now highlights System in the tabs above it, not Integrations. - The "more" buttons beside the Files search field, at the end of a Foxl Code task's toolbar and on an agent terminal are now the same horizontal "..." as everywhere else, instead of three vertical dots.
- On the phone, Settings > Desktop no longer shows its title twice, and in the iPhone app neither does Foxl Code's Files.
- In the iOS app, the sign-in screen offers Continue with Apple first, as the main button, then Google and GitHub.
- Settings > Desktop on the phone and app.foxl.ai, and Settings > Mobile/Web in the desktop app, now say "Connected to 1 device" (or "Connected to 2 devices") where they said "Streaming to 1" beside a "1 Web clients" badge, which also counted the iPhone you were holding as a web client.
- In the iPhone app, section headings and small labels are written the way the rest of the app writes them, in normal capitalization at one size, instead of small spaced-out capitals: "Needs you" in Tasks, "Channels" and "Direct messages", "Recently changed" in Files, "All files" in Foxl Code, "Tools" and "Model" on the agent cards, "Repeats" and "System" in Schedules, the provider names in the model picker and "Messages" and "Tool runs" in Notifications.
- In the iPhone app, an open channel or direct message names itself in the top bar, with its workspace underneath, and tapping the name takes you back to the channel list. Huddle and the channel menu are buttons in the bar, the member count and Switch workspace are in that menu, and the second header row under the bar is gone, so the conversation starts higher on the screen.
- In the iPhone app, subagent and schedule cards no longer end in a row of bare icons with a red trash can on every card. A schedule card shows a labelled Run now button and a "..." menu, and a subagent card has the "..." menu beside its name. The menu holds Edit, Duplicate or Open latest task where they apply, and Delete last, in red.
- In the iPhone app, Agents adds a subagent from the + button in the top bar, like Schedules and Tasks, instead of a large black button in the page, and the phone no longer shows the line describing the page under its title.
- In the iPhone app, an open Foxl Code task has a back arrow in front of its name at the top of the screen, and tapping the name takes you back to your task list. It used to start a new task instead; the + button beside it still does that.
- In Korean, most of the app's messages, the Account page included, and all of Foxl Code's now read in a friendly 해요체, where many still used the formal 합니다체 of a manual. Much of Foxl Notes still uses the formal style.
- In the iPhone app, Foxl Code's Work page shows all five views (Needs you, Not started, In flight, Done and Activity) on screen at once, on a second row when they do not fit one (a third at the largest text sizes). Done and Activity used to sit past the right edge of the screen, where you had to know to swipe the row sideways to find them.
- In Foxl Code, the Needs you rows on Tasks and the "also" lines on Work's cards no longer say one thing twice: "Ready to merge · Approved and waiting on you to merge." is now "Ready to merge", and "also: Reviewer asked for changes - A reviewer asked for changes." is now "also: Reviewer asked for changes". In other languages the translated label is no longer followed by the same sentence in English. The pull request number and age at the end of each Needs you row now line up down the list, whether or not the row has a dismiss button.
- In every language other than English, more of Foxl Code and Schedules is now in your language: the Tasks composer's "Describe a task, Foxl opens a pull request", the ages in the Tasks list and on Work's cards ("10d", "7h", "10d ago" read "10일", "7시간", "10일 전" in Korean), and the heartbeat's "every 24h" on Schedules. English reads as before. A schedule whose cron expression Foxl cannot put into words now says "Custom schedule", with the expression underneath, instead of showing only the expression.
- In the iPhone app, Foxl Code's Schedules no longer split a time or a date across two lines (in Korean, "07:" on one line and "00 UTC" on the next), and Repos no longer break a language name in the middle ("Pyt" / "hon") or wrap a long branch name over several lines: the branch stays on one line and is cut short. The same holds on code.foxl.ai and in the desktop app.
- In the iPhone app, the search fields on Agents, Schedules, Files and Foxl Code's Files, Schedules and Repos are now one shape: a filled, rounded field with no border and the magnifier in the same place, in light and dark mode. Some were white boxes with a border and others a small grey box.
- In the iPhone app, Foxl Agent's Files, Channels, Agents and Schedules use the same rounded buttons and switches as Foxl Code. Buttons such as Run now and "..." are fully rounded instead of square-cornered boxes. Schedules' List, Calendar and Runs switch, Agents' Subagents and Runs, and the Edit and Preview switch on an open file in Files are now one filled, rounded track with a rounded selected segment, not a bordered box of squares. Schedules' status and sort menus are filled and rounded, as in Foxl Code's Schedules, and in English they now fit on one row with the view switch, except on the narrowest iPhones (the mini and SE models), where the switch moves to a second row as before. Chat, the desktop and app.foxl.ai are unchanged.
- On the desktop, a large Notes library (about a thousand meetings with transcripts) reaches Chat's notes search again: it used to be refused for its size, so answers silently missed the newest meetings. A library still too large is no longer re-sent on every edit, and Settings > Notes says so with its size and suggests leaving transcripts out.
- With a transcription language chosen (not Automatic), the on-device engine no longer turns faint noise before the first voice into a one-word line such as "The." that took Speaker 1 and moved every real speaker up a number. Real short replies such as "Yes.", "Okay." and "네." still come through.
- Starting an on-device recording no longer contacts Hugging Face: once the speech engine is installed it runs with no network, as Gemma 4 does.
- In Foxl Notes, Bold and Italic in the editor toolbar now look pressed as soon as you select text that is already bold or italic, and the More formatting menu marks what the selection already has. Before, the toolbar caught up only on your next keystroke, so selecting bold text with the mouse left Bold unpressed.
Features
- On the desktop, Foxl Notes' AI Assistant is now a Foxl Chat conversation beside your note: the same messages, tool cards, model picker, attachments, skills and voice input as chat. It is listed with your chats in Foxl Agent, and Open in Foxl Chat continues it there. Your first message attaches the transcript so far and every later one only the lines added since (counted under the message box; your message in the chat shows only what you typed); your saved note's text goes once and again after you edit it. A follow-up asked within a few minutes of the last one is answered from the model's prompt cache instead of re-reading the whole meeting. Continuing the conversation in Foxl Chat while you record attaches the new lines the same way. The quick actions now come in your language, with icons, and add Catch me up while recording; the suggestions under From this meeting show the whole request they send and are written only while the assistant is open. With Use Foxl Agent tools turned off in Notes settings, the assistant stays the simpler panel without tools. On the phone and app.foxl.ai the assistant keeps its own panel.
- Foxl Notes has a Summary tab between Notes and Background, on the desktop, app.foxl.ai and the iPad. The AI summary is written there instead of over your notes, so what you typed in Notes, and the transcript it started from, stays as it was. A note opens on its summary when it has one, and a note summarized in an earlier version shows that summary in the tab. An empty Summary tab has the Generate AI Summary button and says why when it cannot run yet (during a recording or an import, or while another note's summary is being written) or why the last try failed; a summary can be edited in place, and Regenerate at the end of its toolbar writes it again from the transcript and your notes. On the phone, the Summary view likewise shows only the summary, which you can edit there, and Notes keeps what you typed. Share, Copy, the Markdown and Word exports and the auto-saved file put the summary first and your own notes under it, and search reads both.
- Computer use is now available on the Windows desktop. Foxl asks before using an app, captures only that app's window, and operates accessible controls with its own gray pointer while your pointer stays put. It supports text entry, selection, scrolling, sliders and Ctrl shortcuts; shortcuts that need focus briefly bring the app forward and then restore your window. Terminals, system apps, password fields and administrator apps are refused. No additional runtime installation is needed.
- Report an issue straight from the app, with no Discord account: Settings > About > Send a report, Report this beside an error, or Send a report on the crash screen. Describe what happened, optionally leave an email for a reply, and choose whether to include the open conversation's messages (off unless you tick it). On the desktop a diagnostic report is attached unless you untick it. Your app version, platform and language are always included, and your Foxl account if you are signed in. Keys, tokens and your account name in file paths are removed before the report leaves your device. If it cannot be sent, the dialog keeps your text and offers to copy it or send it by email. Discord and email remain available as well.
Improvements
- The desktop's System report (Settings > Advanced) now leads with recent problems: chat failures you were shown, tool failures and warnings. It includes the state of each MCP server, every log level including debug, a per-route summary of requests with the failed and slow ones, the end of the previous run, and the desktop app's own log. Before, it was mostly request lines. Server logs are now also kept in a daily file for a week, so they survive a restart. Message text and chat titles in the logs are left out unless you choose to include messages.
- In the iPhone app, the screen's name in the top bar is larger: 20 points at the default text size, and never smaller than before at larger text sizes.
- In the iPhone app, an open chat's top bar is back to how it was in v0.8.3, with only the sidebar and ... buttons over the conversation and no title. A new chat's top bar is a search field instead, in the same Liquid Glass as the buttons beside it. Tapping it opens search as a full screen, with the field at the top, your recent chats listed before you type and the keyboard already up. Search conversations in the ... menu opens the same screen.
- In the iPhone app, the Notifications sheet is laid out like the Settings sheet: a close button, the title in the middle with how many are unread under it, and the settings button. The large title under the buttons is gone, All and Unread are a pill switch, and Mark all as read is in the ... menu next to them. Each day's notifications are one card with a thin line between them, as in Settings, where every notification used to be its own card with their corners running into each other, and each shows its title on one line and two lines of its text without the stray
**and*of the agent's formatting. - In the iPhone app, the Notes home has a large round record button in the middle of the screen, with Import a recording and Add context under it and your recent notes below. The Start Recording bar at the bottom of the screen now shows only inside a note.
- In Foxl Code, on every platform, the cards that ask you to decide something (in Work and its board, inside a task, and in Ops) and the card that ends a task share one design and are shorter. The title has the card's first row to itself, with the repository and how long ago it happened on one line under it, and what kind of card it is shows in the colour of its icon and in its main button. The upper-case line above the title (READY TO MERGE), the sentence that repeated the button (One press merges it), a ready pull request's branch name, an "also" line that only repeated the card's own state, and the hint beside the Your call heading are gone. A card about a problem, such as failed checks, requested changes, a refused merge or a question, still says what went wrong, a second problem on the same task still shows under it, an alarm keeps its title, and the card that ends a task still explains a failure's cause and how to close a task with no pull request.
- In the iPhone app, Foxl Code's buttons are rounded like the rest of iOS. Merge, Diff, Open pull request, New terminal, the filters and the view switches are pill-shaped, and the search fields are filled. Inside a task, the status, the pull request, the Conversation and Changes switch and the ... menu no longer push each other off the screen: the status shortens instead, a warning about the task gets a line of its own under them, and the CI fix and issue links are in the ... menu. On Tasks and Work, the repository shows under the screen's name in the top bar, and you tap the name to change it; on Runtimes the machine shows there the same way, so the screen's name is centred again. On Tasks the machine picker is a Liquid Glass button like the others in the top bar; Work, Repos, Schedules, Ops and an open task no longer show it in the top bar, so choose the machine on Tasks, on Runtimes or in Settings under Machines. Schedules' filters take two rows instead of three, and Repos shows its GitHub App details as one card. Runtimes no longer suggests Ctrl+T, and the gap under the top bar on Work, Repos, Schedules and Ops is gone. The iPad, the desktop app, the web and code.foxl.ai are unchanged.
- Foxl Notes' coaching report reads like the note beside it: one column with the same margins and text size as the Notes tab, instead of a grid of boxed cards. Your score leads, followed by the coach's comment and your speaking share, turn share and pace. Each skill is a bar with its score. Feedback is split into What went well and To work on, and every point shows its explanation, what you said and a better way to say it, with nothing to expand; the category filter above the list is gone, and each point names its category under its title instead. Points to work on are no longer shown in red. The sample report's notice is a quiet line instead of a yellow box, the report shows when it was made, and Regenerate report sits at the top, so you can see it working. A long link in the report wraps instead of running past the edge. French, Spanish and Portuguese report text has its accents back, and the Korean text reads more naturally.
- The Agents page's Runs tab no longer has its own goal box with Run and Stop all buttons, and shows the run history only. Agents start when a chat hands them work, and you stop them from the bar above that chat's message box, a chat at a time, or from a run's own page, opened from the Runs tab.
- On the desktop and app.foxl.ai, the Foxl Notes toolbar above a note is back to its earlier layout: Import a recording, Start Recording, the Live panel (in the desktop app), AI Assistant, Transcript, Search, New note and "...". AI Assistant now shows a purple sparkle, and the side panel's button is labelled Transcript; each shows or hides its own tab in the side panel, and an open panel offers both tabs once the note has a transcript and AI is set up. Summarize is no longer in the toolbar, its "..." menu or the side panel's suggestions: a summary is made in the note's Summary tab. With a note open, the Search button's tooltip now names Cmd+Shift+F (Ctrl+Shift+F on Windows and Linux), which opens note search, instead of Cmd+F, which finds text in the note. On a narrow window the same controls show as icons and in the "..." menu, and the phone is unchanged.
- The Foxl Notes sidebar now starts with a New note row, the way Foxl Agent's starts with New chat, on the desktop, app.foxl.ai, the iPhone and the iPad.
- Foxl Notes now writes a summary when a recording stops (Auto Summary is on) and, on the desktop, no longer saves every note to a file by itself (Auto Save is off), on a new desktop and on any phone or app.foxl.ai setup where no Notes setting was changed. A desktop that has run Foxl before keeps its settings, as does any device where a Notes setting was changed. When no model answers, the note's Summary tab says why.
- On the desktop, Foxl Notes' meeting window shows each speaker with their own colour, keeps a speaker's consecutive lines under one name with the time they started (and the time again each minute while one person keeps talking), and shows the recording time as one clear badge. Its Options menu is grouped into Display, Captions and Window, uses one kind of switch for every on/off setting, and adds the settings you reach for during a meeting: the language to translate into, Translation only (the translated line in place of the original), Show times, and closing the window when the meeting ends.
- The suggestions above the Notes AI Assistant's message box now wrap onto two rows instead of one row that scrolled sideways, with a +N button that shows the rest, and they are written as a few words that fit on the chip instead of a sentence cut off with an ellipsis. The conversation, the message box and the suggestions also line up on one margin in the narrow panel, and headings in an answer are sized for it.
Fixes
- On a phone, a chat you scrolled back in now reopens on the line you left it at when a flick was still moving as you opened the menu. It used to come back slightly off, by up to a few lines in a long reply, because the place was measured while the open menu drew the chat slightly smaller.
- A notification you switch off in Settings > Notifications now stays out of the Notifications list too, not only off the banner. On the desktop, the switches under This device decide both, so with Agent notifications off an agent run that finishes no longer appears in the list either. In the phone app, the push categories decide both, so with Chat replies off (or Scheduled tasks, for a schedule) a run finishing on your desktop no longer lands in the app's list. Quiet feed items still appear on the Notifications page, a reply Foxl could not send back to Telegram, Slack or another channel still appears there with that channel's messages switched off, and entries already in the list stay until you clear them.
- In Foxl Code, Merge on a finished pull request's card now merges only the approved commit while the card shows "Approved", as the "Ready to merge" card already does. If new commits reached the pull request after that approval, the press no longer merges them: it says the pull request is waiting for review and opens its diff. A pull request with no new commits since its approval merges as before, and a card that does not show "Approved" merges the pull request as it stands, as before.
- On the desktop, dropping many files onto Shared no longer reloads the whole Shared list after every file it adds, so a large drop finishes sooner. The list is reloaded once when the drop is done.
- With auto-approve off, or for runs from a source set to Ask first, Foxl now asks before the Chrome extension clicks at a point on a page or presses a key, as it already asked before a click on a page element or typing. Both used to go ahead without a question. Hovering still does not ask, and with the default settings (auto-approve on, every source on Full access) nothing changes. Settings > Web Access also no longer says that the extension connects through Chrome itself, which no published version of the extension does yet.
- Foxl Code's live view now also limits how many messages one account's connections send in a day, 200,000 per UTC day across all of them, so opening new connections no longer gets around the per-connection limit and uses up the daily allowance every account shares. The Foxl apps send at most about half of that even with six tabs open around the clock, so they are not affected.
- A Foxl Code cloud task, scheduled checks included, no longer opens a pull request whose only change is a regenerated file: a
package-lock.jsonnpm created in a repository that had none, one where only its own version number or dev markers moved, or a sitemap whoselastmoddates were all reset to the same day. Such a run pushes no branch, and its result names the files and says how to get a pull request for them anyway. A run that changed anything else opens its pull request as before, lockfile included, and so does a task whose request starts by naming the lockfile or the sitemap, or by asking to pin dependencies, make installs reproducible or fix CI. - The connection between your desktop and Foxl's relay now has a daily limit per account: 1,000,000 messages from the desktop per UTC day, counted across every reconnect. Past it, the desktop cannot be reached from app.foxl.ai or the phone, and its notifications no longer reach the phone, until 00:00 UTC, when it reconnects by itself. The desktop app itself keeps working. The busiest account so far sent at most about a sixth of that in a day. A terminal that prints nonstop sends about 20 messages a second while a phone or browser is connected to your desktop (on desktop versions before 0.8.1, whenever the desktop is online), so about 14 hours of nonstop output from one terminal, or 7 from two, reaches the limit. A terminal printing faster than about 320 KB a second sends more than that and reaches it sooner.
- While your desktop reconnects over and over (more than twice a minute, or more than 250 times in a day), the device list and Session History now catch up with it once a minute instead of on every reconnect, so a flapping desktop no longer uses up the daily database allowance every account shares. The desktop still reconnects as soon as it can, app.foxl.ai and the phone still see right away whether it is connected, and an ordinary reconnect is recorded exactly as before.
- If you unsubscribed from Foxl's emails, deleted your account and later signed up again with the same address, Foxl no longer starts sending you product-update emails again. The new account's email settings show the emails you turned off as off, and turning them back on there or on the email preferences page works as before.
- Changing your profile photo is now limited to 20 times an hour and 50 times a day per account, and loading the per-model usage breakdown (the Account page and Foxl Code's Usage page) to 10 times a minute and 100 times a day, so one account can no longer use up the daily database allowance every account shares. Past a limit the photo change says the server refused it, or the usage breakdown is not refreshed (empty if it had not loaded yet), until the window passes. A photo larger than the upload limit is now refused without the server reading all of it first.
- Channels now also limit the live signals one account's connections send in a day, such as typing indicators and huddle call signals, to 200,000 per UTC day across every channel, so connecting to many channels no longer gets around the per-connection limit and uses up the daily allowance every account shares. Chat messages themselves are not counted, and the Foxl apps send far less than that even in an all-day huddle on several devices, so they are not affected.
- When Foxl asks before using an app on your computer ("Allow Foxl to use Calculator?"), in a chat or on the approval card a scheduled or channel run shows, the app's name is no longer repeated on a second
app: Calculatorline under the question. The step's other details, such as where it clicks or what it types, are still shown, even when what it types is the app's name. - On app.foxl.ai and code.foxl.ai, signing out now also cancels any sign-in started in that browser before it, so a sign-in link requested earlier no longer signs the browser back in when it is opened afterwards; request a new link instead. A completed sign-in also cancels any other sign-in still pending in the same browser. Signing out also clears the rows you hid in Foxl Code's Needs you list on that device, so they no longer hide the next account's rows for the same pull requests, and the repository names they mention no longer stay in that browser. After you sign back in, a row you hid shows again until you hide it again.
- Previewing a shared HTML file in Foxl Code's Shared panel no longer pulls in files of the same name from your own desktop. The page is shown from the shared file alone, and the images and stylesheets it refers to by a relative path are listed above the preview as not loaded. In the desktop app the preview now shows the shared file itself, where it used to show your own file of that name or an error, and its Download button saves the shared file.
- An SVG picture on a PowerPoint slide is now shown the way the file viewer already shows an SVG file, so opening that picture in a new browser tab no longer opens it as a page of the Foxl web app. Slides look the same as before; an SVG picture larger than 4 MB is left out of the slide.
- Once app.foxl.ai or the phone app has had an encrypted connection to your desktop, terminal output and terminal tabs that arrive unencrypted while that encryption is being set up again, for example after the desktop reconnects, are now ignored instead of shown. Encrypted output resumes as soon as the connection is encrypted again.
- When you share an internet address with other people (a mobile carrier, an office network or a VPN), someone else on it signing in many times a minute no longer makes your phone's push notification setup, abuse reports, pet gifts, data exports or connecting Slack answer "Too many requests". They now share a separate limit of 10 a minute per address. A malformed sign-in return from Google, Apple or GitHub, or a damaged email preferences or unsubscribe link, now gets the usual refusal instead of a server error. The relay's administrator access and its logging are also hardened.
- Turning a restricted shared folder back to "everyone in the workspace" now clears its access list. The people who had been on it used to stay on record: anyone in the workspace could see the old list in the folder's sharing dialog, and restricting the folder again could bring those people back without anyone ticking them. Restricting it again now starts from an empty list with you on it.
- A shared skill that a workspace admin archived now stays archived when its author saves it again. In a workspace where members can publish skills, the author could republish it, so it came back in shared search and on the computers of everyone subscribed to it. Bringing an archived skill back is up to an admin, as Archive already was.
- If you send someone a pet as a gift and they delete their Foxl account before taking it, the pet now comes back to your collection, as the gift dialog says. It used to be lost.
- In the iPhone app, the search bar at the top of a new chat no longer gets squashed when you open the sidebar. Its magnifying glass and "Search conversations" were squeezed into a thin sliver at the edge of the screen while the sidebar was open; they now keep their shape and are cut off by the screen edge like the rest of the page. The buttons at the top also keep their shape while the page slides back after you pick something in the sidebar, and the search bar's text stays centred when a new chat is opened from there.
Features
- Settings > Model & provider has a new switch, Remember the model for each chat. With it on, opening a chat switches the model picker to the model you last used in that chat, so each conversation keeps its own model; as when you pick a model yourself, it also becomes the model new chats, schedules and channels use. It is off by default, which keeps today's behaviour: every chat uses the model you picked most recently.
- Computer use works on the Linux desktop app too, on an X11 desktop session. As on the Mac, the agent asks in the chat before it uses an app, takes screenshots of that app's window only, and presses buttons, fills in text fields, selects text and scrolls through the app's accessibility interface, with its own small gray pointer gliding to each control, so your pointer never moves. A key press, or typed text with a line break in it, brings the app's window forward for a moment and then puts your window back, because X sends keys only to the window in front. On Linux, shortcuts use Ctrl. Apps built with GTK (GNOME and Xfce apps, for example) can be used; many apps built with Qt, Chromium or Electron do not describe their windows to accessibility, so Foxl refuses to click in them and says so. Terminals, run dialogs, the system settings, password managers and Foxl itself can never be used. A Wayland session keeps every app's windows private, so there computer use is not available and Settings > Computer use says to choose an Xorg (X11) session at the login screen. Without a compositor, Foxl only takes a screenshot of a window that nothing covers.
- A computer-use step waiting for approval in the iOS app now says it is waiting on your computer, not your Mac, since the desktop can be a Linux computer too.
Improvements
- In the iPhone app, View all at the foot of the Notifications sheet, and the last row of the Settings sheet, now rest above the home indicator, so a tap there no longer competes with the swipe home. View all is a row on the same card as the notifications above it, and the list fades into it instead of stopping at a line.
- In the iPhone app, the space under the message box is filled with the page colour, so a long reply no longer shows through between the message box and the tab bar, beside the tab bar or under it.
- In the iPhone app, Foxl Notes' Start Recording button floats above the tab bar, lined up with the message box, without the toolbar strip behind it. Schedules sizes its status and sort controls to their labels, so they share a row with the view switcher where they fit, and shows each schedule as its own card.
- In the desktop app and on the web, the message box has its paperclip and Terminal buttons back, as before v0.8.1, in place of the "+" menu: the paperclip attaches photos and files in one click, and the Terminal button opens and hides the terminal and shows how many sessions are running. The "+" stays in the iOS app.
- In the iOS app, "+" no longer lists Ideas, the suggestions your desktop writes for you. The message box still shows one of them as its placeholder.
- In the iOS app, the attach sheet's recent photos now fill the sheet edge to edge as square tiles with thin gaps, and the Camera, Photos and Files buttons, the Recents heading and Choose more line up on the same margin on both sides.
- On phones and tablets (the iOS and Android apps and mobile browsers), while Foxl is getting ready to reply, the reply now starts with three softly pulsing dots. In the iOS app they replace the Foxl logo; the Android app and mobile browsers showed nothing there before. The first word of the reply appears exactly where the dots were. The desktop app and desktop browsers are unchanged. With Reduce Motion on, the dots only fade gently instead of moving.
- Foxl Notes' live translation, reply suggestions and note titles now run on GPT-6 Luna when their model is set to Automatic and Notes AI runs on your Foxl desktop through Amazon Bedrock: when Foxl Agent uses Amazon Bedrock, or when Foxl Agent's provider has no Claude Haiku 5.5 and an AWS account is set up on the computer. GPT-6 Luna runs with reasoning off, so a translated line takes no longer than before, and its list price is the same as Claude Haiku 5.5's ($0.10 / $0.50 per million tokens). Everywhere else Automatic stays on Claude Haiku 5.5, as before. If your AWS account cannot use GPT-6 Luna, Foxl answers on Claude Haiku 5.5 instead and stops trying GPT-6 Luna for 10 minutes. Settings > Notes names the model Automatic runs on, and a model you picked yourself, Claude Haiku 5.5 included, stays as you picked it.
- Live translation in Foxl Notes is easier to find, and it works without a second step. First-run setup on the Foxl desktop has a Live translation screen, off unless you turn it on there; turning it on shows the language to translate into, already set to the app's language. In Settings it is now the first Notes pane, Live translation, instead of the last block of AI features, and searching "translate" in Settings opens it. Turning translation on from the meeting HUD, or anywhere else that set no language, now translates into the app's language; it used to translate nothing.
- In the iOS app on iPhone, the top bar now names the screen you are on, in the middle between the sidebar button and the screen's own buttons, the way Settings already did. A chat shows its title there (a new one says New chat), an open note shows its name with how long ago it was recorded and its length, and Schedules and Notifications show their status line under the name. The big title most screens used to repeat in their own row under the bar is gone, so lists and notes start right under the bar. Screen buttons moved into the bar as round buttons: Schedules' Refresh and New schedule, the Notifications settings button, and in Foxl Code the Refresh buttons of Work, Schedules and Ops, Add schedule, and Repos' Sync and Connect. In an open note, Search and New note are now at the end of the ... menu, as they are in a chat, which leaves the note's name room to show. When a long reply scrolls up, it fades out under the bar instead of running behind the title. With text larger than 125%, screens keep their title in the page, where it is never cut short. iPad, Android, the web and the desktop app are unchanged.
- In the iPhone app, the Settings and Notifications sheets are now Liquid Glass, like iOS's own sheets. The sheet floats just above the edges of the screen with every corner rounded, the screen behind it shows through softly, and its edge catches the light. Settings' groups sit on the glass as light translucent cards without grey borders, the round buttons at the top are raised glass buttons, search is a rounded iOS search field, and the list fades out under the title and at the bottom instead of being cut off. With Reduce Transparency or Increase Contrast on in iOS's accessibility settings, the sheets are solid, with borders. The iPad, the desktop app and the web are unchanged.
- In the iOS app on iPhone, Foxl Code's repository picker moved from the message box up to the top bar, next to the machine picker, and inside a task the task's repository shows under its name. The message box now reads like Foxl Agent's: + and the microphone on the left, the model and Send on the right. Repository names used to be cut to a few letters there (pil..., ac...). The repository list also opens without raising the keyboard over it. iPad, the desktop app and the web keep their layout.
- In Foxl Code, while the model list is still loading, the model button shows the model's name (Sonnet 5) instead of its id (claude-sonnet-5).
- On the Mac desktop, the tour that opens the first time you open Settings now has a card for computer use, right after the browser extension card: it opens Settings > Computer use, where Allow computer use stays off until you turn it on. On Windows and Linux the tour is unchanged.
- On the Mac desktop, the description at the top of Settings > Computer use now says when Foxl asks: the first time a chat needs an app, and choosing Always allow stops the question for that app. It used to say Foxl asks before every action, which stopped being true for chats in v0.8.2.
Fixes
- On the Mac desktop, computer use now asks macOS for its permissions as its own app, Foxl Computer Use. With Keep running when closed on, Accessibility used to ask to allow
node-arm64, a nameless program in the list that you could not add with the + button, so computer use could not be turned on. Settings > Computer use > Open settings now opens System Settings with a panel attached to it, as Codex does: drag Foxl Computer Use into the list (or turn on its switch), and the panel moves on to Screen Recording and then back to Foxl. You no longer need to quit and reopen Foxl after allowing it. Permissions you gave Foxl ornode-arm64for computer use in an earlier version do not carry over, so allow Foxl Computer Use once. - On macOS 26, Foxl's icon no longer shows shrunk inside a gray square at small sizes, such as the app lists in System Settings > Privacy & Security and Finder's sidebar and list view. The Dock icon and the Windows icon are unchanged.
- On the Windows desktop, Settings no longer has a Computer use pane, and search no longer offers it or its settings. Computer use works on the Mac and on Linux, so on Windows the pane could only say it is not available.
- On OpenRouter and other OpenAI-compatible providers, a chat no longer stops with "has empty content" when a tool returns nothing, such as reading an empty file. The model is told the tool returned no output and carries on, and reading an empty file now says the file is empty.
Improvements
- Opening the iOS app shows the Foxl logo from the first moment again: on iOS 27 the launch screen was plain black, because iOS refused to draw it. The logo now stays the size and place it has on the launch screen, with no blank moment before the app's own loading screen and no blurring back in larger, and it fades into the app rather than jumping when the app is ready. In dark mode the launch screen and the loading screen use the app's own dark background, so the whole screen no longer brightens when the app appears.
- Claude Haiku 5.5 is available with your own Amazon Bedrock account or Anthropic API key, in Foxl Notes and in Foxl Code. It lists at $0.10 / $0.50 per million tokens for prompts up to 100,000 tokens, a tenth of Haiku 4.5, and five times that above 100,000 tokens. It has a 1-million-token context window and effort levels. Haiku 4.5 moves to the older models (Settings > Model & provider > Show older model versions) and keeps working wherever it is selected.
- Foxl's small helper jobs now run on Claude Haiku 5.5: Foxl Notes' title, live translation and reply suggestion models on Automatic (and a helper still on Haiku 4.5, the earlier default), the greeting suggestions, session summaries on Amazon Bedrock, and the chat model of Foxl Code's orchestrator. They run with thinking off, as on Haiku 4.5, so a title or a translated line takes no longer than before.
- In Foxl Code, Claude Sonnet 5.5 cache reads now cost $0.10 per million tokens, half the earlier $0.20, as on the Claude API and Amazon Bedrock.
- On the desktop, Settings > Memory now shows everything the agent remembers, not only what it saved with memory_save: MEMORY.md one entry at a time, and every file in your workspace's memory folder (the daily journal, sessions/, topics/ and any other folder there), each place with a count. The list loads more as you scroll, a search box finds words anywhere in the text, and each row has a delete (click the trash twice), or check several rows and delete them together after one confirmation. Deleting a MEMORY.md entry removes only its lines, deleting a topic also removes its line from MEMORY.md's Reference Index, and your next message is answered without what you deleted. Searching "MEMORY.md", "journal" or "topics" in Settings finds the pane. The Memory pane in the iOS app is unchanged.
- In the iOS app, the screen that Notes' Add context for better AI opens is now called Add context for better AI, with the name centred as the screen's heading and a round back button like Settings. It used to be called Background, beside a small bare arrow in a bordered row.
- In the iOS app, Settings > Notes > Auto-save & export is now Export and shows only File name, which names the notes you export from the list. Its Auto Save switch and format did nothing on the phone, and its text pointed at a folder that is not there.
- In the iOS app, switches are the size of iOS's own switches, with the larger knob, in Settings and everywhere else they appear. They used to be the desktop's smaller switch. The desktop app and the web are unchanged.
- In the iOS app, Settings > Data controls looks like the other Settings screens: its rows sit on one card, Withdraw permission is a regular button in red, and tapping the words Privacy policy opens the policy, not only the small icon beside them.
- On the Mac desktop, computer use no longer takes your pointer. The agent presses buttons, fills in text fields, selects list rows and scrolls through macOS accessibility instead of moving the mouse, and its own small gray pointer glides to each control and presses it, so you can watch what it does while your mouse and keyboard stay yours. The app it is using is no longer brought to the front for every step, so you can keep working in another app: only a shortcut with Command, Control or Option brings it forward for a moment, and the app you were using is put back in front right after. A spot that accessibility cannot operate, such as a drawing canvas, is refused with a message rather than clicked, and the agent uses the keyboard there instead. Apps built on Chromium or Electron describe little of their pages this way, so there many clicks and scrolling a page are refused for now, and a press inside a page is checked against the next screenshot, because it does not always reach the page. Hovering, middle clicks and dragging content are not available this way; sliders and scroll bars can still be dragged. While another window covers the app being used, the Foxl pointer is drawn faded. With Reduce motion on in macOS, the pointer moves without gliding.
- In the iOS app, opening a section of Settings now slides it in over the list the way iOS does, with the list easing back underneath, and Back slides it away again to the same place in the list. It used to swap in place and return to the top of the list. With Reduce motion on, it changes without moving.
- In the iOS app, Settings > General > Report an issue can send your report by email as well as on Discord: Report by email opens your mail app with a message to support@foxl.ai that already has your version, platform and language in it. If no mail app opens, Foxl shows the address with a button to copy it. The report now says it came from the iOS app; it used to say only "Web / mobile".
- The "Files changed" card under a reply that edited files is now hidden by default. To see it again, with each file's added and removed lines, its diff and Undo, turn on Show files changed in Settings > Appearance. The setting applies to that device only.
- The plan checklist above the message box can be closed or hidden. The X on its header closes the plan in that chat: it stays closed while the agent works through it, and the checklist comes back when the agent starts a new plan. The eye button beside it, or turning off Show plan checklist in Settings > Appearance, hides the checklist in every chat, and Settings > Appearance is also where you turn it back on. It is hidden on that device only, and the agent still plans its work the same way.
- In the iOS app, Settings has a Personality pane right under General while your desktop is connected. Edit SOUL.md opens the file in your workspace that sets your agent's persona and tone, in Files, ready to edit.
- In the iOS app, a switch that is on is now the accent blue, as iOS switches are, instead of a black track in light mode and a white one in dark mode.
- Foxl Notes can transcribe with OpenRouter: pick OpenRouter under Settings > Notes > Recording, then choose a model from the speech-to-text models OpenRouter offers, such as MAI-Transcribe 2, Universal-3.5 Pro, Whisper or Voxtral. If you already connected OpenRouter under Settings > Model & provider, that key is used and there is nothing to paste. The audio is paid for from your OpenRouter credits, and OpenRouter transcribes audio only for an account holding at least $0.50 in credits, so a free OpenRouter account cannot use it. OpenRouter transcribes one passage at a time rather than as a live stream, so each line appears shortly after the speaker pauses, with no live preview and no speaker labels, and Stop and Pause wait a moment for the last passage. Like the other bring-your-own-key engines it needs the Foxl desktop app. A passage OpenRouter cannot transcribe is reported and the recording continues; a refused key or an account without enough credits stops the recording with OpenRouter's reason.
- The plan checklist above the message box can be hidden. Click the eye button on its header, or turn off Show plan checklist in Settings > Appearance, which is also where you turn it back on. It is hidden on that device only, and the agent still plans its work the same way.
- In Foxl Code, a cloud task on Opus 5.5 (the default coding model) now runs Claude Code with Opus 5.5's full 1-million-token context. Until now Claude Code treated the model as a 200,000-token window there, so a long task's conversation was summarized before it reached 200,000 tokens, which loses detail. Opus 5.5 costs the same per token past 200,000. A turn with a large context still costs more credits, because every request reads the whole context, and Foxl Code sets credits aside for the largest possible request before it runs: with a very large context (about 250,000 tokens or more) a request needs about 155 credits available, counting what the account's other running requests hold, where the old limit needed at most about 95. An account with less than that available sees that turn refused instead of summarized. Other models, and tasks that run on your own machines, are unchanged.
- In the iOS app, while your computer is connected, the notifications sheet you open from the bell also shows your next scheduled runs, timed the way Schedules shows them. It reuses the list from your last visit to Schedules or the Notifications page in the past five minutes, so opening the sheet asks your computer for nothing; with no recent list the sheet looks as before. Tap a run or View all to open Schedules.
- In the iOS app, an account with no Foxl desktop online now sees before the first message that chat runs on the Foxl desktop: a line under "Desktop offline" says to open Foxl on your computer, signed in to the same account, and the message box says the same instead of suggesting a prompt. A message you send anyway stays in the message box, so you can send it once the desktop is back, and the card that answers it offers Connect desktop instead of a Try again that could not work while the desktop is offline. With the desktop online, or on an account that chats without one, nothing changes.
- In the iOS app on iPhone, Files now starts with a Recently changed section: up to five of the files most recently changed in your workspace on your computer, newest first, with how long ago each changed. Tap one to open it. It leaves out the agent's own memory notes and shared files, and it appears only while your computer is connected.
- In the iOS app, the "+" menu in the chat's message box now lists Ideas: the personal suggestions your desktop writes from what it knows about you and your recent chats. Until now only one of them showed, as the message box's placeholder. Tap one to put it in the message box, where you can edit it before sending; nothing is sent until you do. Ideas are listed while the message box is empty, so picking one never replaces what you have typed.
- In the iOS app, schedule cards no longer say "CRON". A repeating schedule's label now says Repeats (a one-time one already said One-time), beside the line that says when it runs. You can still see and edit the schedule's exact timing in the schedule's edit form.
- In the iOS app, "Install Foxl to use ..." (Agents, Usage and the other screens that need Foxl on your computer) now has a Send link to my computer button. It opens the share sheet with a link to foxl.ai, where Foxl for your computer is downloaded, so you can AirDrop it to your Mac or send it to yourself by Messages or Mail. The app itself still offers no installer download.
- In the iOS app, Settings now has a Memory pane while your desktop is connected, as the desktop app does: read the memories the agent saved and delete one, with Undo for a few seconds after each delete, and, with Foxl 0.8.1 or later on the computer, turn Save memories and the daily journal on or off. Changes apply to your desktop. With the desktop offline the pane is not shown.
- In the iOS app, the screens that need your computer connected, such as Agents and Usage, now say in plain words what they show and that they appear once your computer is connected, instead of naming parts of how Foxl works inside.
- In the iOS app, Files shows one search field and one "..." menu holding New file, New folder, Collapse all and Go to file, instead of four small icons where the last was a second magnifier. On a phone the search field now lines up with the Files title.
- In the iOS app, sending the first message of a new chat no longer swaps the whole screen at once. The greeting fades out where it is, your message rises into place at the top of the chat, and the greeting no longer jumps when the message box empties. With Reduce Motion on, both stay instant.
- On a phone, the search, new note and more buttons at the top of Foxl Notes are now the same round glass buttons as on every other screen, so they have a visible tap area instead of being bare icons. In the iOS app they use the system's own glass, like the chat screen's buttons.
- On a phone, more of the screens you open from the sidebar now name themselves with the same large title at the top: Files, the Foxl Notes home and an empty Channels screen always, and Agents, Usage, Integrations and its tabs while no computer is connected. Before, Files used a smaller title, Integrations and its tabs a centred banner, Agents, Usage and the empty Channels screen no title at all, and Notes a small grey word in the top bar with "Record a meeting" as its heading. While no computer is connected, the descriptions under the Integrations banners are no longer shown on a phone.
- In the iOS app, the message box's "+" menu no longer offers Terminal when no desktop is connected, since it could only ask you to install the desktop app, and its "Add" heading is gone. The install prompt now names Terminal in your language.
- In the iOS app, the message box's "+" now opens a native attach sheet, the way Instagram and Messenger attach photos: Camera, Photos and Files across the top, your Ideas under them, and your recent photos as a grid you pick from in place. Tap photos to select them (each shows its number, in the order you picked) and tap Add; drag the sheet up to see more. Until now a photo took three taps through menus before any photo was on screen. The grid needs access to your photo library, which the sheet asks for only when you tap Allow access; with Select Photos the grid shows just the photos you chose, with Choose more to add others, and with access off it says how to turn it on in Settings. The Photos button opens your library in every case, and only the photos you add are sent. On iPad the sheet opens beside the "+" and also has Terminal while your desktop is connected.
- In the iOS app on iPhone, Terminal moved from the message box's "+" menu to the "..." menu at the top right of the chat, so "+" only adds things to your message. It is listed there while your desktop is connected. A running terminal still shows its button beside "+", and on iPad Terminal stays in the "+" menu.
- On a phone, Start Recording in Foxl Notes now has one place: the bar at the bottom of the screen, on the Notes home as well as inside a note, within reach of your thumb, instead of a button at the top of the home. If you cannot record yet, the same button signs you in.
- In the iOS app, after you send a message, the Foxl mark now glows softly where the reply will start until its first words, its first step or the model's own thinking appear. Until now nothing appeared there while the model got started, so the Stop button was the only sign the message had gone through. The first words take the mark's place without the reply moving, and the mark also goes away when you press Stop. With Reduce motion on, it pulses gently instead.
- In the iOS app, the Send button looks dimmed while a tap would send nothing, such as on an open chat's empty message box, and returns to full colour as soon as you type or attach something. In a new chat that shows a suggestion it stays in full colour, because a tap there sends that suggestion.
- In the iOS app on iPhone, Settings text no longer gets smaller after you tap into a section. Row names are the same size as in the Settings list, section headings look like the list's headings, and buttons such as Allow notifications, Edit profile and Sign out are 14 points instead of 12. The plan name on the Account screen is at body size. The desktop app, iPad and the web are unchanged.
- In the iOS app, once a chat has used half of its context window, a small ring and its percentage appear in the message box beside the model name, and tapping it shows how many tokens of the window are in use, as the desktop's titlebar does. It turns amber from 75% and red from 90%, so a long chat no longer reaches the point where its history is summarized without warning. It shows while Foxl is connected on your computer, which is where the figures come from. The desktop app and the web are unchanged.
- In the iOS app, the chat menu (the button at the top right of a chat) has Export chat, which saves the chat as a Markdown file through the share sheet, so you can keep it in Files or send it on. The file is named after the chat and the day you exported it (for example "Weekend trip plan - 2026-10-07.md") instead of an internal id; a chat with no title is still named by its id. The desktop app and the web are unchanged.
- In the iOS app on iPhone, Settings > Appearance no longer shows Use pointer cursors or Send messages with: an iPhone has no cursor, and its Return key always starts a new line while the send button sends. On an iPad they stay where they apply (Use pointer cursors with a trackpad or mouse connected), and in the iOS app UI text size now says in plain words what it does. The desktop app and the web are unchanged.
- In the iOS app, VoiceOver now says who wrote each message in a chat: every message starts with "You said" or "Foxl replied", and the Headings rotor moves from message to message. On iPad, the chat's title is the screen's main heading. Nothing on screen changes, and Find in this chat does not count these words.
- In the iOS app, the model picker looks like the desktop's: no drag handle in front of each model or on the group headings, model names in the desktop's medium weight, the selected model shown by its check mark and darker name instead of a grey band, and quieter group headings and stars. To reorder, touch and hold a model (or a group heading) until it lifts with a tap of haptics, then drag it; a drag that starts right away still scrolls the list, and a hold you release without moving picks nothing. On iPad the same hold reorders the picker's models by touch. The phone browser and the desktop are unchanged.
- In the iOS app, the model picker's models, and its group headings when there is more than one group, have Move up and Move down buttons for VoiceOver (for example "Move Sonnet 5 up") in place of the drag handles VoiceOver used to land on, so the list can be reordered without dragging. A move is kept like a dragged one. Nothing changes on screen, and the phone browser and the desktop are unchanged.
- On a phone, the formatting bar on a note's Notes tab now fits the screen at every text size: Undo, Redo, Heading, Bold, Italic, Bullet list and Checklist as full-size buttons, and the rest of the formatting, including tables, links and alignment, behind one More formatting button. It used to be a row of 23 small buttons that ran off the edge of the screen.
- On a phone, an open note in Foxl Notes now shows its name at the top of all four tabs, with when it was recorded and how long it is, as the list in the sidebar does; a long name stops at two lines, and the name steps aside while the keyboard is up so typing keeps its room. And on every device, a note whose Notes tab is filled from its transcript, such as an imported recording, is headed with the note's name instead of "New Transcript".
- On a phone, the Recent list on the Foxl Notes home lines up: a note without a summary now shows a microphone and its first transcript line, as a note with a summary shows its summary, so the titles start at the same place and the rows are the same height.
- Foxl Notes now names speakers in your language: in Korean a transcript reads 화자 1 and 화자 2 instead of Speaker 1 and Speaker 2, on the Transcript tab, in the speaking-time breakdown and in the body of a new note, and the same in the other languages. A speaker you renamed keeps the name you typed, and notes you already have keep their text.
- In the iOS app on iPhone, rows on the Notes home, in the menus that open from a button (such as a note's "...") and in Settings now share one text size, 16 points, and the line under or beside a row (a time, a description) is 13 points; before, these screens drew rows at 13, 14, 15 or 16 points. Rows in the sidebar stay at 14 points, now including your notes, and Notes settings labels are in sentence case. The desktop app, iPad and the web are unchanged.
Fixes
- In the iOS app, when the app opens, the tab bar and the round buttons at the top of the screen now arrive with the app instead of appearing on top of the loading logo a moment before it, and in dark mode the tab bar no longer shows a light frame as it appears.
- In the desktop app, Foxl Notes now writes summaries, titles and answers in the language the app is set to. After you changed the app's language in Settings, Notes AI went back to the language the app was first opened in at every restart, so a Korean meeting could get an English summary. The floating meeting HUD answers in the app's language too, and a change in Settings reaches it on your next question; its own labels, and those of the detached suggestion cards, now switch language right away instead of after a restart. Dictate anywhere with Auto-detect, which leans toward the app's language, had the same problem and now leans toward the current one.
- In the iOS app on iPad, the main controls are now as easy to tap as on iPhone: Send, Add (+) and Voice input in the message box, the model chip, the search and files buttons at the top of a chat, and the open sidebar's rows and its Quick Chat, New chat and Notifications buttons are 44-point touch targets instead of the 28 to 36 points sized for a mouse. The sidebar button at the top of a chat keeps its size and glass; only the area you can tap grows. The desktop app, the web and Safari on iPad keep their compact sizes.
- In the desktop app, Settings > Mobile/Web no longer says "No desktop" and asks you to install the Foxl desktop app before remote access is turned on. It now says that remote access is off and that turning it on lets you use this computer from your phone or the web. When this computer is registered but not connected, it now says to check your internet connection and choose Refresh in the device menu, instead of asking you to launch the app you are using. app.foxl.ai and the phone apps are unchanged.
- In the iOS app, the first screen after you sign in no longer shows a Tasks tab that disappears a moment later, with the tab bar shrinking under your thumb. Tasks belongs to Foxl Code, which is in a private beta, so the tab now waits until the app has confirmed this account can use Code, and appears then if it can.
- In the iOS app, an account that has not connected a Foxl desktop yet no longer sees an orange "Desktop offline" warning on its first screen. The chat now says calmly that it runs on your Foxl desktop and how to connect one; "Desktop offline" still appears when a desktop you have connected before is switched off.
- In the iOS app, the first message of an account with no Foxl desktop online is no longer answered by a "Request couldn't finish" error with a paragraph about model inference and buttons to copy or share it. The reply says in two short sentences that chat runs on your Foxl desktop and how to open it, with Connect desktop.
- In the iOS app on iPad, opening the model picker from the message box no longer brings up the keyboard, which covered most of the list in landscape, including Reasoning and Effort. The search field is still there; tap it to type. The desktop app and the web, including Safari on iPad, still put the cursor in search so you can type to filter at once.
- In the iOS app on iPad, a chat you have scrolled up no longer shows a sliced line of the reply in the thin strip below the message box. The strip is now filled with the chat's background, so nothing is drawn under the message box. iPhone, the desktop app and the web are unchanged.
- In the iOS app on iPad, the notifications panel from the sidebar's bell is now a card with rounded corners in the middle of the screen, the size of an iPad form sheet, with a long list scrolling inside it. It used to be the iPhone's sheet stretched to the full height of the screen, mostly empty. On iPhone it is unchanged.
- In the iOS app on iPad, conversations are easier to read: replies and your own messages are now 16 px, the size of the text you type, instead of 14 px (smaller than on the iPhone), and on a larger iPad the chat column is a little narrower, so a line holds about 80 characters instead of more than 100. The message box narrows with it. On iPhone it is unchanged.
- In the iOS app, renaming a chat near the bottom of the sidebar list now scrolls it into full view first. The name field used to stay where the list fades out, so its text was dimmed and its edge cut off while you typed.
- When a chat moves up the list in the sidebar, because you pinned it or a new reply brought it to the top, its title no longer slides through the other titles with the two drawn on top of each other. The moving chat now glides over the others as one solid row, in the iOS app, on app.foxl.ai and in the desktop app.
- In the iOS app, a chat's menu no longer starts with desktop sync rows on an account with no Foxl desktop paired: the greyed Refresh and Sync all rows, "Connect your desktop to sync" and a Remove download that did nothing are gone, so the menu starts with Pin. With a desktop connected, the sync rows stay, and Remove download and Refresh from desktop are no longer offered on a chat you started on the phone, whose only copy is there.
- In the iOS app, Settings > Account > Active Sessions names the device you are holding "This iPhone" or "This iPad", with a phone or tablet icon. It used to call it "Web Browser (macOS)" with a monitor icon.
- In the iOS app, a computer use step that is waiting for approval on your Mac now shows a card that says so, with a Deny button. The app used to show nothing, so the chat looked stuck with no reason. Allowing a computer use step still works only in Foxl on your Mac.
- In Korean and the other non-English languages, two kinds of text that stayed in English are translated. The line under the Amazon Bedrock status in Settings > Model & provider (for example "SSO session expired or not started. Use SSO Login to sign in." or where your AWS credentials were found) is now in your language; messages that come from AWS itself are still shown as AWS wrote them. Short times such as "21m" or "3h" in Settings > Mobile/Web, in search results, and in Foxl Code's sidebar task list, Work board and Activity feed now read like "21분" and "3시간" in Korean. English is unchanged.
- On the iPhone app, Settings > Tab bar no longer lists tabs your bar cannot show as if they were in it. A tab this account cannot use, such as Foxl Code's Tasks outside its beta or Channels on a plan without the Workspace, is now shown greyed, with one line saying why. It stays in your layout and comes back to the bar when the account gets access.
- A Foxl Code schedule now has one pull request open at a time. A schedule used to start again while pull requests from its own earlier runs were still waiting for review (up to three of them before v0.8.2, and with no limit once they were 3 days old since v0.8.2), so a daily check could open the same change again. Its scheduled run is now skipped while one of those pull requests is open, including a draft from a run whose checks failed, or while an earlier run is still going, and the schedule says which pull request or task it is waiting for. Merge or close the pull request, or cancel its task to keep the pull request open, and the next scheduled run starts as usual; a task with no activity for 14 days is cancelled automatically, its pull request left open, and the schedule then runs again. The 3-day limit from v0.8.2 still lets your other schedules start. Run now is not affected.
- In Foxl Code, when a task finishes, its model requests that were cut off partway (Foxl's server can be stopped in the middle of a request) stop holding your credits and your plan's concurrent request slots (8 on Pro). Each such request used to hold its credits and a slot for up to 15 minutes, so your other tasks could be refused with "Too many requests in flight", or told the credits they needed were held by open requests, although those requests were no longer running. A request cut off while its task is still running, or in its first moment before Foxl has recorded which task it belongs to, now gives them back on its own as well (next entry).
- In Foxl Code, Merge on a "Ready to merge" card now merges the commit that was approved. If new commits were pushed to the pull request after the approval, the card no longer merges them: it says the pull request is waiting for review and opens its diff. A pull request with no new commits since its approval still merges from the card as before.
- A model request that is cut off partway now gives back the credits it was holding and its concurrent request slot (2 on Free, 8 on Pro) within about 90 seconds, in Foxl Code, app.foxl.ai, the iOS app and Notes. It used to keep them for up to 15 minutes, so your next messages or tasks could be refused with "Too many requests in flight" because of requests that were no longer running. A request that keeps running keeps its slot until it finishes and is charged once, for what it used. A request cut off after it had already run for several minutes can keep its slot for about as long as it had run, never more than 15 minutes.
- While your desktop reconnects over and over (on a weak Wi-Fi, for example), Session History keeps at most four connect and disconnect lines a minute for your account. After that, the newest line is updated to show whether the desktop is connected right now, instead of a new line being added for every reconnect, so each further reconnect writes about half as much to the service's daily database allowance, which every account shares. The desktop still reconnects as soon as it can, as before, and an ordinary reconnect is listed exactly as it was.
- With GLM 5.3, the checklist above the message box no longer disappears and reappears while the agent works: it stays on screen until every step is done, then goes away a few seconds later. The same fix stops a reply's tool rows from showing another call's command or output and staying "running" until the reply ended. GLM 5.3 numbers each reply's tool calls from zero (
call_0,call_1), so the calls of one task shared ids; Foxl now gives each call its own id, in the desktop app and on Foxl credits, including Foxl Code. - A subagent, schedule or heartbeat run on GLM 5.3 now saves each tool call with its own output. It used to save every call with the last call's output, so the run's transcript showed one result several times.
- When the agent sends its checklist as text-encoded JSON instead of a list (seen from Claude Opus 5.5), the update is accepted and shown instead of being refused, which left the checklist a step behind.
- A reply whose lines start with "•" now shows them as a bulleted list, one item per line. Each "•" line used to run into the line before it, so a list written this way read as one long paragraph with the dots in the middle. A line of text before the dots stays a paragraph, other text with single line breaks looks as before, and a reply that is still being written turns into the list as it goes. This applies to chat in the desktop app, the web and the phone apps, Foxl Code and Foxl Notes.
- The daily journal's "Tools used" line now lists the tools' names instead of internal call ids.
- On the Mac desktop, the agent is now told whether computer use is on, and why not when it is not. With computer use off it says so and points to Allow computer use in Settings > Computer use. Before, some models said so while others, such as GLM 5.3, drove the app with shell commands and full-screen screenshots, skipping the per-app question, and called that computer use. A shell command you ask for by name, such as screencapture or osascript, still runs. A model that cannot see images, such as GLM 5.3, no longer gets the computer use tools, because every step answers with a screenshot; the agent says so and suggests switching to a model that can read images. Turning Allow computer use on or off now takes effect in chats that are already open, from their next message.
- With a chat open in two desktop windows (a popped-out chat window and the main window), a message with an attachment queued in each window while a reply runs no longer goes out at the same moment as the other window's when the reply ends. The second send stopped the first, so one of the two messages was left without a full answer, and a model call could be spent for nothing. Now one window's message is sent when the reply ends, and the other keeps its message, attachment included, until that answer finishes and then sends it. A chat open in one window queues and sends as before.
- Menus, tool rows and labels now follow Settings > Appearance > UI text size and iOS text size. About a thousand of them had a fixed pixel size, among them the code in a reply, the model name in the composer, the model picker's rows and headings, sidebar labels, badges, settings descriptions and, on a phone, the messages themselves, so turning the text up enlarged some of the screen and left the rest as small as before. Nothing changes at the default size. The phone tab bar's captions and the product name at the top of the sidebar keep their size, as the iOS tab bar's own captions do, so a larger setting does not cut them off. In the desktop Foxl Notes meeting HUD, tabs that do not fit across the window can now be scrolled to instead of being cut off.
- In the iOS app, on iPhone and iPad, the Deny, Allow and Always allow buttons of a tool approval, in the chat and on the approval card, are now 44 points tall with more space between them, so they are easy to tap without hitting the one beside it. They were 24 points tall, the size meant for a mouse. The desktop app and the web keep their compact buttons.
- In the iOS app, more small controls are now as easy to tap as a 44-point button without looking any different: the tabs at the top of Integrations and Skills, the JSON and CSV export links and the Sign out everywhere and Delete my account links in Settings > Account, and the remove badge on each slot in Settings > Tab bar. The remove badge's larger target reaches only into empty space, so a tap meant to change a slot never removes one.
- In the iOS app in dark mode, the trash icon on the Delete button you get by swiping a chat to the left in the chat list is now a brighter red, so it stands out from the button. It was a dark red that was hard to see on the dark background. Light mode is unchanged.
- In the iOS app, a message that could not be sent from the chat (for example because chat runs on your Foxl desktop and it is offline) shows its reason once, in the conversation, instead of also in a pop-up with the same text. On a phone, in the app and in the browser, pop-up notices now appear at the top of the screen, under the header and under an approval card waiting there, so they no longer cover the message box, its Send button, the tab bar or the card's buttons.
- In the iOS app, connecting Microsoft 365 or Slack under Integrations now tells you to finish in Foxl on your computer, signed in to the same account, instead of opening a sign-in that could not complete. That sign-in returns to Foxl on your computer, so on the phone it ended on a page that would not load while the row kept spinning for five minutes. Once it is connected on your computer, the agent can use it from your phone too, while your computer is on.
- In the iOS app, a reply that starts with a bold heading no longer flashes
before the heading appears. While a reply is still being written, bold or italic markers at the very end of the text that follow a space or start a line (and the first half of a closing) wait for the words they belong to instead of showing as stars for a moment. Finished replies look the same as before. - On the phone, the tabs at the top of Integrations (Integrations, Skills, Channels, System, Custom) now show that the row scrolls: the next tab peeks in at the edge and fades out, and the tab you are on is scrolled into view. Before, the last tab sat off the screen with nothing to say it was there, and opening Custom left its own tab out of sight.
- In the iOS app, Export my data (JSON and CSV, under Settings > Account) and exporting a chat now open the iOS share sheet with the file, so you can save it to Files, AirDrop it or send it on. Before, tapping them did nothing on the phone: no file and no message. The desktop app and the web keep downloading the file as before.
- In the iOS app, the tab bar now draws Chat as one speech bubble and Channels as two, matching the icons in the sidebar and Settings > Tab bar. The two were swapped on the tab bar, so the two-bubble icon you knew as Channels opened Chat.
- On a phone, a reply scrolled up to the top of the chat now fades out under the sidebar and menu buttons instead of running at full contrast beside and under them. The fade used to stop halfway down those buttons, so a line could be cut off behind one while still drawn sharp.
- On a phone, the main button on several screens is now a full-size touch target (44 points) instead of 32 points tall: Connect and Try in chat on Integrations and Skills, Allow notifications and Open Settings in Settings > Notifications, Edit profile, Sign out and Manage in Settings > Account, and Open channel settings on an empty Channels screen. In the iOS app, Sign out is now an outlined button like Edit profile beside it, instead of grey text that looked disabled. The desktop keeps the compact size.
- In the iOS app, the "Install Foxl to use ..." dialog now hides the tab bar and the sidebar button while it is open, as the app's sheets do. Both stayed bright above the dimmed screen, so the dialog did not look modal and Chat or Notes could still be tapped behind it.
- In the iOS app, Settings > Recording no longer shows the desktop's Amazon Transcribe setup: the AWS region field, the list of places a computer looks for AWS credentials, and a warning that no Foxl desktop can sign the connection. One sentence now says where a recording from the phone goes: it uses your computer's AWS account through Foxl while Foxl is open there, and if your account can use Foxl Relay, Foxl transcribes it with your credits when it is not. The desktop app and the web are unchanged.
- In the iOS app, Settings > Notifications now starts with push notifications for your phone. It used to open with a "This device" section saying banners need the Foxl desktop app, which read as if the phone could not get notifications at all.
- On a phone, the switches in Settings > Tab bar, Pet, the Notes panes and Code > This computer now sit at the right of their row, as they do in the rest of Settings, instead of alone on a line under the description. In the iOS app, the tab bar's Show labels row now just says it shows the name under each icon.
- On a phone, the Notifications sheet's close and settings buttons now sit on the same round glass buttons as the Settings sheet's header, so the two sheets the sidebar opens side by side look like one app. The model picker's "Model" title is now set like the other sheets' titles instead of in small grey type that looked disabled.
- In the iOS app, "Sign in with a password instead" and "Email me a link instead" on the sign-in screen are easier to read and to tap: their text is a little larger and each takes a full-size touch area under the button above it, instead of a thin line that was easy to miss or to tap into that button. The password hint under them is a little larger too.
- On a phone, the Start Recording and Ask AI buttons in Foxl Notes now sit a little above the tab bar, leaving the same space the chat message box does, instead of touching its top edge.
- On a phone, Settings > Account no longer prints "Account" a second time under the sheet's own title, with a line promising a monthly usage section the page does not have. On an iPad, the iOS app's Account page now lists what it holds: your profile, plan and signed-in devices.
- In the iOS app, Settings no longer describes the desktop app. General's Display group says what is in it (language, links and text selection) instead of repeating Appearance, the links setting names apps you can have on a phone (Obsidian, Slack or Notion) rather than VS Code, the Tab bar pane no longer calls the same bar "Bottom bar", and the Foxl Notes panes no longer mention a HUD or "this computer" and, in English, use the same capitalisation as the rest of Settings.
- In the iOS app, a reply that contains a table no longer shows its header as a line of
|characters while it is being written and then jumps into a table. When the table's rows start with|, as models usually write them, the header row now appears as soon as the table can be drawn, and its rows fill in under it. Finished replies look the same as before. - In the iOS app, while a reply is being written, the line above a table written without leading pipes, or above a bulleted list, no longer turns into a large heading for a moment. The table's first line shows as plain text until the line of dashes under it is complete, and then the table appears; a list appears once its first item has text. Finished replies look the same as before.
- In the iOS app in a language other than English, the plan card under Settings > Account no longer says "Manage your plan and billing on the web." in English; that line is now translated into every language the app ships. In Korean, the two lines of the install-Foxl dialog now read as plain, friendly sentences.
- In the iOS app, signing in with a password goes straight to chat. The app used to reload itself right after the sign-in: the screen went blank, the loading mark and the tab bar's entrance played a second time, and only then did chat appear. Nothing of a previous account is carried over: Sign out still clears it, and if a previous account's session ended without a Sign out, signing in as someone else still restarts the app.
- In the iOS app, the reasoning effort levels in the model picker, and the one shown beside the model name on the message box, now appear in the app's language (in Korean, for example, 낮음, 보통, 높음, 매우 높음 and 최대) instead of Low, Medium, High, xHigh and Max in every language, in Foxl Agent and Foxl Code. In English, and in the desktop app and the web, they are unchanged.
- In the iOS app, on the sign-in screen in Korean and Japanese, the privacy policy link is now just the policy's name (개인정보 처리방침, プライバシーポリシー). The words after it, saying that you agree, used to be part of the link, so they were underlined and opened the policy when tapped. The desktop app and the web are unchanged.
- In the iOS app, Settings > General > About no longer shows Data Directory and Workspace rows with nothing after them. Those are your computer's folders, so the iPhone and iPad now list only the version, the platform and the time zone, the Platform row has a phone icon instead of a disk, and the heading no longer mentions updates, which the iOS app gets from the App Store. The desktop app and the web are unchanged.
- In the iOS app, the EULA, License, GitHub, Discord and Docs buttons under Settings > General > About are now 44 points tall, the same as the Report buttons above them, instead of 32, and Docs is translated. The desktop app and the web keep their compact buttons.
- In the iOS app, opening Settings no longer leaves the sidebar button drawn on top of the sheet for a moment. The header's round buttons now fade out, icon included, before the rising sheet reaches them, and with Reduce Motion on they go at once.
- In the iOS app, a reply no longer jumps up when it finishes. The Copy and Regenerate row under the newest reply used to appear only at the end, pushing the text you were reading up by about two lines in one frame; its space is now kept while the reply is written, and the row fades in when it is done. It still cannot be pressed until the reply has finished.
- In the iOS app, the model picker's row for older versions now counts properly: "Show 6 older versions" and "Show 1 older version" instead of "Show 6 older version(s)", with real plurals in the other languages where the language has them. The desktop app and the web are unchanged.
- In the iOS app, VoiceOver now reads the sidebar button at the top of every screen as "Toggle Sidebar" instead of an unlabeled "button", on iPhone and iPad.
- In the iOS app, a table in a reply that is wider than the screen now shows that it continues: the side with more columns fades out instead of ending on a closed border, so an eight-column table no longer reads as a complete four-column one. Swipe it and the fade follows to whichever side still has columns; a table that fits is unchanged. This works while the reply is still coming in, and in right-to-left languages.
- With VoiceOver on a phone, the model sheet now reads each model's drag handle as "Reorder" and the model's name, instead of an instruction about arrow keys before every model, and the refresh button on Schedules now has a name instead of being read as just "button".
- In the iOS app, the Effort levels in the model sheet (Low to Max) are now 44 points tall like the rest of the sheet, instead of 36, so the one you mean is easier to hit. With VoiceOver, on a phone in the app or the browser, the sheet now says which level is selected and that the levels belong to Effort.
- On the iPhone app, the Rename and Delete buttons you get by swiping a chat to the left in the chat list are now as tall as the row, with larger icons; they were smaller than a fingertip. Rename and Delete are also in the menu you get by pressing and holding a chat, so you can rename or delete a chat without swiping.
- In German, Foxl, Foxl Notes and Foxl Code now write ä, ö, ü and ß everywhere. About 340 words were spelled with ae, oe, ue or ss instead, or had lost the umlaut altogether, such as "laeuft" for "läuft" in the Install Foxl dialog, "fuer", "Schliessen", "Gerat" and "Loschen".
- In Foxl Notes, the speakers in a new recording or import are numbered 1, 2, 3 in the order they first speak, so their numbers match the participant count: a note that says 2 participants names Speaker 1 and Speaker 2, where it could read Speaker 1 and Speaker 3 before. Notes you already have keep their speaker names.
- In the iOS app with large text, theme names under Settings > Appearance wrap at their spaces instead of being cut off, so High Contrast, AMOLED Midnight and AMOLED Grey Calm read in full; a word is never split, and a one-word name too long for its tile still ends in an ellipsis. A page title on a phone, such as Schedules at 130% UI text size or Notifications in German, keeps its word whole: the buttons beside it move under the title instead of the word breaking across lines. A title that already fits beside its buttons stays where it was, and the two longest AMOLED names, which were already cut off on a smaller iPhone at the default size, now wrap there too. The desktop app and the web are unchanged. (Drop 'or Notifications in German' if patch 3528-notifications-title-sibling is not taken.)
- Channels and Foxl Code's live view now apply their existing size and rate limits to every message a connection sends, including the kinds the Foxl apps never send, which used to skip those limits. The Foxl apps are not affected.
- The phone pushes Foxl sends for your desktop's notifications (a schedule's result, a finished agent run) are now paced: up to 60 at once, then one every 20 seconds, well above what real schedules and agent runs produce. Every notification still reaches app.foxl.ai and an open app as before; only the phone pushes past that pace are skipped.
- Creating, saving and renaming shared documents, saving shared skills and changing whether they are published now count toward a per-account limit of 2,000 a day, like posting in Channels. That is enough to drop a folder's worth of notes (up to 2,000 files, as many as one workspace can hold) onto Shared in one go, and normal editing stays far below it. Over the limit the change is refused and nothing is saved; your edit stays in the editor, so you can save it again later. The "started a huddle" line in a channel now counts toward the Channels posting limit like any message; an account past that limit still starts the huddle, just without the line. Before, one account saving the same document over and over could use up the shared daily database allowance, which would stop sign-in, chat and Foxl Code for everyone until midnight UTC.
- On the email preferences page you reach from a Foxl email, turning emails back on now works up to 20 times an hour and 50 times a day; past that the page says the change was not saved and to try again later. Unsubscribing, from that page or with your mail app's Unsubscribe button, is never limited, and doing it again once you are unsubscribed no longer saves anything new.
- A new channel's description now keeps its first 2,000 characters, the same limit that already applied when you edit a description. Creating a channel used to store a description of any length.
- On the desktop, dropping files onto Shared no longer reloads the whole Shared list twice for every file, only once, so dropping many files at a time finishes sooner. Each file still appears in Shared as soon as it is added.
- In Foxl Notes, Ask AI and the meeting HUD's ask bar now hand the model the transcript and your notes clearly marked as reference material that holds other people's words, not instructions, and a suggestion chip written from the transcript is marked the same way. Before, the transcript arrived as part of your own question, so something said in the meeting could read to the assistant, which can use this computer's tools, as if it came from you. The tools and every control are unchanged.
- With tool approvals turned on, an approval prompt now shows what the call will do. In the chat, the prompt for a tool other than a shell command lists the call's arguments (the file it would write, the address it would send to) instead of only the tool's name. On the approval card, a call with more than four arguments used to leave the rest out without saying so; the card now shows "+N more", which lists them on the card when you click it. Allow and Deny still take one click.
- In Foxl Notes, Settings > Recording now describes the transcription provider you picked. It used to say that Amazon bills your AWS account, and that Amazon detects the language, whichever provider was selected. With your own Deepgram, AssemblyAI, OpenAI, ElevenLabs or Gemini key it now says that the provider bills the account the key belongs to, and with the on-device engine, that nothing is billed. With AssemblyAI or OpenAI the Transcription Language row now says that the setting is not sent to them, so it has no effect there. The link under the key field reads "Get an API key from AssemblyAI" instead of "Get a AssemblyAI API key", and the notice shown while a file is imported no longer says the file is transcribed in real time.
- In the iOS app, importing a recording into Notes no longer races to 99% in a few seconds and then sits there for most of the wait: the percentage now follows how far the transcript has got. The progress shows once, in the banner on the Notes screen, instead of also in a pop-up drawn over it; the message when the import finishes is unchanged. The desktop app and the web are unchanged.
- In the iOS app, a note's Summary and Report tabs show the same empty state before anything is generated: a heading (No summary yet, No report yet), one line saying what you get, and the same 44 point outlined Generate button, so Start Recording stays the one filled button on the screen. The Report tab's button was a small 32 point button with 12 point text. The desktop app and the web are unchanged.
- In the iOS app on iPhone, tapping a text field low in a Settings pane (such as My context for AI in Notes > AI features) no longer leaves it under the keyboard: the pane moves up with the keyboard as it opens so the field stays in view, and when the keyboard closes the pane settles back with it instead of dropping at once. With Reduce Motion on, the field is still brought into view, without the movement.
- On a phone, in the iOS app and in the browser, a command sent from the terminal's command field now runs on the first tap of send in a full-screen program such as Codex or Claude Code on your computer. The command and its Enter used to arrive together, which those programs read as pasted text, so the command stayed in their message box until you tapped send again. The Enter now follows the command a fifth of a second later, in a plain shell too.
- On a phone, in the iOS app and in the browser, a terminal you open shows your shell's prompt right away. After you closed a terminal and opened a new one, the new terminal often stayed black until you typed a command: the prompt was printed while the phone was still connecting to it, and the shell's redraw for the phone's screen size came too early to reach the phone. The phone now sets the size once it is connected, so the shell's redraw shows the prompt.
- In the iOS and Android apps and on app.foxl.ai, the chat list now keeps up with your computer while it is connected. A chat you delete, archive, restore or rename on the computer changes in the phone's list right away, a chat you start there appears, and the list comes from your computer as soon as the app opens. Before, a chat deleted on the computer stayed in the phone's list until the app was reloaded, and after you opened the app the list stayed on the copy saved on the phone until you left the app and came back.
- In the iOS and Android apps and on app.foxl.ai, with your computer connected, the model name on the message box now shows the model your computer has selected, and your messages run on it, until you pick a model on the phone. The phone used to keep the first model it saw on your computer as its own choice and send it with every message, which also switched your computer back to it: after you chose Free Models Router at your desk, messages from the phone still ran on Opus 5.5. When your computer has no model connected, the button now says Connect a model instead of naming one. A model you pick on the phone works as before: the phone keeps it, and a message you send switches your computer to it too.
- Settings > Mobile/Web lists each phone, tablet or browser once, with a name such as "iPhone - Foxl app" or "Mac - Chrome". A phone running the Foxl app used to show up two or three times, once for each connection it keeps open (status, chat and each terminal), and every row was titled with the browser's full user-agent text. The full text is still there when you hover over a row, and Disconnect now disconnects all of that device's connections at once.
- In the iOS app, the "No Foxl desktop connected" card under Settings > Notes > AI features no longer squeezes its message into a narrow column one or two words wide and no longer cuts off its own title. The message now uses the card's full width, and its buttons are 44 points tall: Check again, plus Model & provider when your computer answered but has no model set up. With no computer connected, the Model & provider button, which opened nothing there, is gone. The desktop app and the web are unchanged.
- In the iOS app on an iPad in portrait with the sidebar open, an open note's Notes, Background and Report tabs now all fit at the top of Foxl Notes. The labelled buttons beside them used to keep their full width, so Background was cut to "Back" and the selected Report tab could be scrolled out of view; they now fold into icons and the More menu whenever the tabs would not fit, as they already did in a narrow window.
- On a phone, the "..." button in Foxl Notes now opens the same menu as the one in Chat: a rounded glass menu that grows out of the button, with the same row size, instead of a small square-cornered card below it. In the iOS app it merges with the button as Liquid Glass, as Chat's does.
- On a phone, Foxl Notes' Ask AI sheet now opens like the app's other sheets, with a round close button and its title at the top. Its first row used to be a collapse control: one tap on it emptied the sheet, and it opened with a focus ring around it. The suggested questions are now full-size buttons in the app's usual colours instead of small violet and green pills.
- In Foxl Code on a phone, a command sent from a cloud task's terminal command box now runs on the first tap of send in Claude Code and Codex. The command and its Enter used to arrive together, which those programs read as pasted text, so the command stayed in their message box until you sent again. The Enter now follows the command a fifth of a second later. The instructions Foxl types into a running terminal task for you, such as a request to fix a failing check, are sent the same way.
- Items that other Foxl products add to shared search now count toward the adding account's 25 MB of shared documents and skills, the limit documents and skills already have, so one account can no longer fill the storage that every Foxl user shares. A request over 4 MB to add one is refused before it is read. No Foxl app adds such items yet, so nothing changes for you today, and your shared documents and skills are counted exactly as before.
Changes
- In Foxl Code, a task that runs on one of your own machines now pushes through Foxl, the same way a task on Foxl's cloud already does: unless it runs in a terminal you opened yourself, it can no longer push to a repository's default branch and pushes its own branch for you to review instead. A terminal you opened yourself still pushes anything. This needs the machine agent on that box to be version 0.3.2 or newer, so re-run the installer on any machine whose row says an update is available; until then that machine keeps working exactly as before.
- Foxl Notes can transcribe with Gemini on your own Google AI Studio key: pick Gemini under Settings > Notes > Recording and paste the key. It uses Google's live transcription model, and a free-tier key works at no charge. Like the other bring-your-own-key engines it needs the Foxl desktop app, and like OpenAI it does not separate speakers while transcribing live. On the free tier Google may use the audio and transcripts to improve its products; the key field says so, and a key on a paid plan is not used that way.
- GLM 5.3 is available. It is Z.AI's newest model on Amazon Bedrock, built for agentic coding and long multi-step engineering work, with a 1M-token context and text input, at $1.848 per million input tokens and $5.808 per million output tokens (cached input $0.3432, cache writes $2.31). Pick it in Foxl Code on Foxl credits, or in the desktop app under Amazon Bedrock with your own AWS account. Amazon gives GLM 5.3 only to AWS accounts it has approved, and serves it from the us-east-1 and us-west-2 Regions only (us-west-2 is Foxl's default). Its reasoning effort runs from none to max. GLM 5 stays in the older models, still selectable with Show older model versions on.
- On a desktop where nothing can answer a chat yet (no AWS credentials, no Claude or ChatGPT sign-in, no Ollama, no provider key), first-run setup now ends with a Connect a model screen. Connect with OpenRouter opens OpenRouter in your browser; after you sign in and authorize Foxl, the key OpenRouter creates is stored on this computer and chats start on OpenRouter's free models, which have a daily limit (pick any other model in the composer). You can also paste a key you already have, or open Settings to use another provider. The same screen sets up meeting transcription for Foxl Notes when nothing can transcribe yet: on an Apple Silicon Mac, the free on-device engine (a one-time download of about 1.3 GB) or an AssemblyAI key; on Windows, Linux and Intel Macs, an AssemblyAI key. A computer that can already answer a chat does not see the screen, and every part of it can be skipped.
- Foxl Notes now labels speakers when it transcribes with your AssemblyAI key, as it already does with Amazon Transcribe, Deepgram, ElevenLabs and the on-device engine: each line shows "Speaker 1", "Speaker 2" and so on instead of one speaker for the whole meeting. A line under about one second keeps the speaker before it. AssemblyAI charges for speaker labels on top of the transcript, and Settings > Notes says so under the AssemblyAI key.
Improvements
- In Foxl Code, when the relay refuses a task's model request because the account's credits are used up or held by its other running requests, the refusal now also says how many of the account's model requests were running and how many the plan runs at once (8 on Pro). Claude Code prints the refusal in its error, so a refusal caused by several parallel tasks holding credits can be told apart from a balance that has run out.
- On the Mac desktop, computer use now asks for each app in the chat. The first time the agent needs an app in a chat, the chat asks "Allow Foxl to use Calculator?" with Deny, Allow and Always allow. Allow lets that chat use the app, and its clicks and typing then go ahead without a question for every step, until you press Stop on the "Foxl is using" bar, turn computer use off, quit Foxl, or leave the app unused for an hour. Always allow lets every chat use it without asking. Runs that are not a chat, such as the heartbeat, still ask before every step unless the app is always allowed. There is no list to fill in first: Settings > Computer use shows the apps you chose Always allow for, and removing one there means Foxl asks again the next time. Apps you added in an earlier version without Always allow are no longer listed there and are asked for in the chat instead. Terminal apps, Script Editor, Automator, Shortcuts, System Settings, Keychain Access, Passwords and Foxl itself still can never be used, and only the Foxl window on that Mac can allow an app.
- If Gemini CLI keeps your Gemini API key in its own encrypted file (it does when it cannot use a system keychain, or when
GEMINI_FORCE_FILE_STORAGEis set) and you have not saved a Google key in Foxl, the desktop app now uses that key for Google's Gemini models, so you do not have to paste it in twice. Gemini then runs with all of Foxl's tools and in scheduled and background work, which the Gemini CLI models cannot do. Settings > Model shows when the key comes from Gemini CLI (only its last four characters) and has a button to stop using it, and a key you save there is used instead. Foxl does not read a key Gemini CLI keeps in the macOS keychain, because macOS would stop and ask for your password to allow it, and it does not use a Gemini CLI Google account sign-in, because Google's terms do not allow other apps to use it. - The checklist the agent keeps for a task with several steps is now pinned above the message box instead of under the reply that set it. A chat has one checklist, so a task that stops to ask you and carries on after your answer keeps counting in the same list, and the agent is reminded of unfinished steps when you reply. Once every step is done the checklist goes away after a few seconds; tap its header to fold it to one line. On a phone it starts folded, showing the step the agent is on.
- The first-run setup screens (Pick your look, Tell Foxl about you) have a cleaner design. The left panel is no longer a solid block of colour: it is a soft surface with a small preview of the app that changes as you pick a color theme or mode. A chosen option is marked with a grey fill and a check instead of a long blue highlight. How technical you are is now three cards side by side, each saying what it changes: full technical detail, concepts without the internals, or plain language.
- In the desktop app, the Foxl Notes meeting HUD now closes by itself when the recording stops. To keep it open between back-to-back meetings, turn off Close HUD when the meeting ends in Settings > Recording. In the HUD's mini mode, the stop and restore buttons in the corner are spaced further apart, so reaching for one no longer risks pressing the other.
- In the desktop app, first-time setup now offers to bring your Claude Code or Codex setup over, but only when it finds one on the computer with something Foxl does not have yet. A third screen, Bring your setup, lists the same instructions, skills and MCP servers as Settings > Advanced > Import and export, with everything new ticked; Import brings over what is ticked, and Skip all brings nothing. Without a Claude Code or Codex setup that has something new for Foxl, the screen is not shown.
Fixes
- A picture sent in a channel or direct message now shows in the conversation, as in Slack, instead of as a file name whose click opened a long storage address in a new browser tab (on a phone, in Safari). Click it (or press Enter on it) to see it full size, zoom in, or save it. Pictures you pick show as small previews in the message box before you send, and your own picture appears as soon as you send it. A picture appears once it scrolls into view, in a space of fixed height, so the conversation does not jump when it loads. Files that are not pictures, pictures over 8 MB, and formats your browser cannot show (HEIC in Chrome, for example) stay as a file you can download. Opening a picture full size in a chat or channel now fits the whole picture on screen; a tall phone photo used to be cut off at the top and bottom.
- Gemini CLI chats work again. Current Gemini CLI versions (we checked 0.40 through 0.62) refuse to answer a request from a folder you have not trusted, and Foxl runs the CLI from its own folder, so every message failed. Foxl now tells the CLI to trust the folder it runs in for that one request (it still respects
GEMINI_CLI_TRUST_WORKSPACE=falseif you set it). A Gemini CLI you install while Foxl is open now shows up in the model picker without restarting Foxl: about half a minute after installing it, open Settings or leave Chat and come back. Gemini 3.8 Flash and Gemini 3.5 Flash-Lite are now available through the CLI. - In Foxl Code, a task on a repository with a setup script is now told how many minutes it really has. The script runs before the coding agent starts and its time comes out of the task's clock, but the agent was still told the full number of minutes, so on a repository whose setup takes ten minutes the minutes it was given and the stop time it was given disagreed by ten minutes. Repositories without a setup script are unaffected.
- Foxl Code cloud tasks now run on Foxl's current default coding model, Opus 5.5, unless you picked a model in Settings. Saving any setting used to store that day's default as if you had chosen it, so accounts that had saved Settings kept running Opus 5 after Opus 5.5 (stronger, and cheaper per token) became the default. A model you pick from now on is kept, including an older one such as Opus 5. A stored Opus 5, Opus 4.8 or Opus 4.7 (or GPT-5.5 for Codex) cannot be told apart from a saved default, so an account holding one moves to the default with this update; pick it again in Settings to keep it. Choosing the model that is currently the default means following the default, so your tasks move to the next default when it changes. The same applies to the Codex model.
- A Foxl Code schedule no longer stays stopped while three of your earlier scheduled tasks wait in review on pull requests nobody has merged. A scheduled task waiting for review stops counting toward that limit 3 days after its run finished, and your schedules start again on their own within about 2 hours of that. The task stays in review and its pull request stays open and untouched, so you can still merge or close it. A schedule that is waiting on the limit now says which tasks it is waiting for, with their pull requests and since when, and when the first of them stops counting.
- A Google AI Studio API key can be saved in Settings > Model again. AI Studio has issued only a new kind of key, starting with
AQ., since May 28, 2026, and Foxl refused every one as "Invalid key format". Keys starting withAIzastill work. - In the desktop chat with your own Amazon Bedrock credentials, turning reasoning on for GLM 5 or Kimi K2.5 now makes the model reason. Foxl was sending those two models a reasoning setting they ignore, so they answered without reasoning. Reasoning is on unless you have turned it off, so these two models now think before they answer.
- In Foxl Code, a message sent to a running task in the last moment before it finishes is no longer accepted and then lost. It had been possible for the task to report the message as delivered while its agent had already stopped reading, so nothing was done with it; such a message is now turned down with the usual "this agent has finished its work" note, so you can send it as a follow-up instead. A task that finishes in that moment also wraps up straight away rather than sitting idle for up to twenty seconds first.
- In the desktop app on macOS and Linux, a tall dialog such as Tools > Import MCP servers no longer starts underneath the bar at the top of the window, where its top edge was hidden. Dialogs now fit in the space below that bar.
- When the agent changes a file and reads or views it in the same step (for example rendering a diagram to a PNG with a shell command and then looking at it), the read now waits for the change to finish. It used to start at the same moment, so the agent got "file not found", or silently saw the previous version of the file, and then guessed at a cause that did not exist. Nothing else waits: reads that do not follow a change, web page fetches, plan updates, and several shell commands asked for together still run side by side as before. A tool from an MCP server that declares it read-only counts as a read.
- In Foxl Code, Settings > Coding agent now names the real default for the Codex model, the way it already does for the Claude one, instead of a model name written into the help text. The sentence came from the text rather than from the server, so it would have gone on claiming a model was the default after the default moved, which is what made the Claude line read as the page contradicting its own picker.
- In Foxl Code, the right panel now shows an issue task's ask the same way the conversation does. The panel still printed the whole request Foxl writes for the coding agent: the note telling it the issue text is untrusted, the marker lines that wrap the issue body, and the two closing instructions. The last release fixed this in the conversation and the terminal and missed the panel. Only what you asked for is shown now, with Show full prompt for the rest, and a task with no title is named after its issue instead of after that note.
- An .html file opened in the Workspace preview whose script keeps data in localStorage or sessionStorage (a game keeping its best score, a page remembering a setting) now runs. The preview is sandboxed so a file cannot reach your account, and in that sandbox simply reading that storage is an error, so such a page drew itself and then ignored every click and key. The sandbox is unchanged; the page now gets storage that lives only while the preview is open, so a saved score resets when the preview reloads. A page that needs IndexedDB or cookies still cannot use them in the preview.
Changes
- Settings > Advanced > Import and export can bring your setup over from Claude Code or Codex on the same computer: your CLAUDE.md (or Codex's AGENTS.md), added as instructions to the end of Foxl's AGENTS.md; your skills from
~/.claude/skills(or~/.agents/skillsfor Codex); and your MCP servers from~/.claude.json(or Codex'sconfig.toml). Preview lists everything first and marks what Foxl already has, which is left as it is, so nothing you have is replaced; untick anything you do not want. Tools > Import MCP servers now lists Claude Code's servers too, and reads a Codexconfig.tomlthat has hooks or multi-line text, which it used to refuse as a whole. In the desktop app, Export everything in the same place saves all your chats, archived ones included, with the files attached to them, plus Foxl's settings, skills and workspace files as one .zip file. The keys and sign-ins Foxl stores are left out, and so is anything in your settings, tools or skill files that looks like a key; chats are exported as they are, so a key pasted into a chat or printed by a tool there is in that chat's file. - In the desktop app, a chat can be popped out into a window of its own: Pop out in a chat's menu in the sidebar, or the Pop out button at the top of an open chat. The window keeps above your other windows, has the full message box and model picker, and has buttons to open the chat back in the main window or add it to another chat; popping out a chat that already has a window brings that window forward. File > New Chat Window (Cmd+Shift+N, Ctrl+Shift+N on Windows and Linux) opens a new chat in one. The main window can show the same chat at the same time: a reply started in either window appears live in both, and a message you send in the other window while it is replying waits its turn instead of stopping the reply.
- On the Mac desktop, the agent can now see and operate apps you choose. Turn it on in Settings > Computer use (it is off until you do) and add the apps it may use from the ones that are running; common terminal apps, Script Editor, Automator, Shortcuts, System Settings, Keychain Access, Passwords and Foxl itself cannot be added. The agent opens one of those apps, looks at a screenshot of that app's window only (computer use never captures your whole screen), and clicks, types, presses keys and scrolls inside that window. It asks you before every step, even with "Auto-approve all tools" on, unless you choose "Always allow" for that app; each step's screenshot shows in the chat. While it works, the Foxl window and the menu bar say which app Foxl is using (for example "Foxl is using TextEdit"), with Stop, which also ends the step that is running. macOS has to allow Foxl Screen Recording and Accessibility first; Settings > Computer use shows both and opens the right page.
- The product menu at the top of the sidebar shows what is going on in each product: "Recording 4:12" (or "Paused") under Foxl Notes while a recording runs, "2 running" under Foxl Code while tasks are running, and "1 replying" under Foxl Agent while a chat is still answering. A product with nothing going on shows no extra line. Foxl Code's task list refreshes only while you are in Foxl Code, so seen from Agent or Notes its count says how long ago it was checked, for example "2 running · 12 min. ago".
- Workspaces, Channels and huddles are part of the Pro plan, and on other plans Foxl now also hides the settings that belong to them: the Channel list option in Appearance, the Channel messages and Huddle invites switches in a phone's notification settings, and the Workspace and shared-skills results in the search. Those switches keep their values for when your plan includes them.
- On any plan, Channels appears while a Slack, Telegram or other connector is switched on in Integrations > Channels, and shows the conversations people have with your bots. Without Pro it shows only those conversations, and with no conversation yet it points you to the connector's settings instead of to workspaces.
- On a plan without workspaces, an invitation to a workspace says that workspaces are part of the Pro plan, instead of offering to join one you could not open.
- Channel messages and huddle invites no longer ring the phone of someone whose plan does not include Channels, since tapping one could not open it.
- The Account page no longer says "All features unlocked" on the free plan.
- New on macOS: Settings > Safety > "Run shell commands in a sandbox", off by default. Turning it on runs the commands the agent runs and the terminals it opens inside a macOS sandbox. It is designed to let them write only inside the Foxl workspace and temp folders, keep them from reading Foxl's own sign-in files, and cut off their network unless you also turn on "Allow network", which then leaves only Foxl's own server out of reach. It covers shell commands and terminals only, not the agent's other tools such as writing files, fetching web pages or the browser. A command the sandbox stops fails with a line saying so. When a task needs more, the agent can run that one command outside the sandbox; that needs the same approval as any shell command, so with auto-approve on the agent can do it without asking, and with auto-approve off the prompt says the command runs outside the sandbox. Not yet on Windows or Linux, where the switch is shown unavailable.
- Settings > Safety has a new "By where a run comes from" group: your chats, schedules and the heartbeat, Slack / Telegram / Signal, and the Notes assistant can each be set to Full access, Ask first or Read only. All four start on Full access, which is how Foxl worked until now. Ask first makes those runs ask before shell commands, file writes, the browser and sending, as if auto-approve were off. Read only gives those runs only the tools that read, so for example a Slack message can no longer make the agent write a file or run a command; it can still read files and fetch web pages, and its reply can quote what it read, so Read only does not keep your files private.
- With auto-approve off, a tool approval prompt (a shell command, a file write) can now be answered from the Foxl app on your phone or app.foxl.ai while it is connected to your desktop, not only in the desktop window. The prompt shows in the chat that asked, or as a card at the top right on any other screen, and it waits the same 60 seconds. The desktop then shows the call as allowed or denied from your phone or the web. A phone or browser that connects while a prompt is open is shown it then. This needs the desktop app and the Foxl web app or phone app from this release, and between those the prompt and your answer travel end-to-end encrypted, the same way terminal output does. A step that operates another app on the Mac is allowed there, not from the phone.
- On a Mac, the notification Foxl shows when a tool is waiting for your approval now has a Deny button, so you can turn the request down without opening the window. It shows the whole request (the full command and its folder) when it fits, and otherwise asks you to open Foxl to read it. To allow it, click the notification and answer in Foxl: there is no Allow on the notification, because Foxl cannot make a notification button require an unlocked Mac.
- On app.foxl.ai and code.foxl.ai you can turn on browser notifications (Settings > Notifications > This device, or Foxl Code's Settings > Notifications). Your browser asks for permission when you press Turn on, never before. While Foxl Code is open in a tab that is showing and you are working in another window, a Foxl Code task that finishes or fails, or a run that needs your answer, shows a notification; a tab that is minimized or behind another tab gets no Foxl Code updates, so it shows none for them. On app.foxl.ai, an agent run or schedule on your desktop that finishes shows one even while the tab is in the background. Clicking a Foxl Code notification opens that task. Not available in mobile browsers.
- When the Foxl desktop app is running on the same computer as your app.foxl.ai tab, a finished agent run or schedule shows only the desktop app's notification, not a second one from the browser; it is still listed in the tab's notifications. A tab on another computer still shows its own. Foxl recognizes the same computer by its IPv6 address. Where it cannot (both connect over IPv4, which a whole home or office network shares, or through a VPN), the browser still shows its notification as well.
- status.foxl.ai publishes its measurements for monitoring tools at
/metrics(Prometheus format) and/api/v2/metrics.json: for each component whether the latest check passed, how long it took, its uptime, and how fast it is spending its error budget over one hour, six hours and three days, and for AI inference each model separately. - In Foxl Code, a daily schedule's time and days are set on your own clock: the editor shows your time zone instead of UTC, the schedule is saved with it, and it keeps running at that time through daylight saving changes. The Next run column also shows the date and time of the next run on your clock. The autonomous loop's quiet hours work the same way once you change them. Schedules and quiet hours saved before this keep running at their UTC times, and the list still marks them UTC; opening one in the editor shows its time on your clock.
- In the desktop app, the "ready to install" notice for an update now has a collapsed "What's new in this update" section that shows the start of that release's notes, with a link to the full changelog. The notice is also in your app language now instead of always English. Help > What's New opens the changelog on foxl.ai.
- While Foxl starts, and while a page or a cloud terminal is loading, the Foxl logo drifts gently out of focus and comes back into focus as a soft light passes across it. It used to fade deep in and out of focus, so the logo was never quite legible.
- With a Claude Pro/Max sign-in, Foxl now says which of its tools the agent does not get. The model picker shows it under the Claude Code models, and Settings > Model & provider, while that sign-in is selected, lists every unavailable tool by name, including your own MCP and custom tools, with the reason: Anthropic serves a request from your subscription only when its tools are Claude Code's own, so the agent gets Bash, Read, Grep and WebFetch only. Before, this was said once, in a dialog that named a few tool families, and schedules, memory and skill-provided tools then did nothing with no explanation.
- A remote MCP server that asks you to sign in now shows Sign in on its row in Settings > Tools/MCP > Custom. One click opens the server's sign-in page in your browser, and once you approve there the row connects and lists the server's tools, with no key to paste. Foxl renews the sign-in on its own, and Sign out removes it from this computer (it does not revoke the grant at the server). If the server keeps refusing a renewed sign-in, the row asks you to sign in again. If signing in fails, the row says which step failed and shows the server's own message. It works with servers that let an app register itself during sign-in; the sign-in is kept on this computer and is not sent to the phone or app.foxl.ai.
- In Foxl Code on the desktop, Runtimes can open a terminal in its own git worktree: New terminal in a worktree in the Runtimes menu (the ... button) makes a separate copy of the repository picked in the header, so two agents on one repository no longer edit the same files, and your own checkout is left as it is. The branch button in that terminal's header shows its branch and folder, opens the folder, and removes the worktree. Removing asks first only when the worktree has uncommitted changes, and is followed by Undo, which for a few seconds puts the worktree back and reopens its terminal; commits that were on no branch come back with it, and stay in the repository under
refs/foxl/removed-worktrees/for 7 days. - In Foxl Code on the desktop, a cloud task's menu has Check out locally: it fetches the task's branch into a new worktree on this computer and opens a terminal there, so you can try or finish the change yourself.
- New Settings > Memory pane in the desktop app. It lists what the agent saved with
memory_save, with a delete button on each entry (a deleted entry can no longer be recalled), and has two switches, both on by default: "Save memories" (off, the agent gets no memory tools and USER.md, MEMORY.md and the list of recent sessions stay out of what it is sent) and "Write a daily journal" (off, Foxl writes nothing tomemory/by itself: no excerpt after each reply, no session summary, no line for a scheduled run or the heartbeat). Nothing is deleted by turning either off. Searching Settings for "memory" now finds the pane. - In Foxl Code, you can mention Foxl in a GitHub comment.
@foxl reviewon a pull request runs Foxl's reviewer on it, which posts its findings and never merges.@foxlwith a request on an issue starts a task for it, and on a pull request a Foxl Code task opened it passes your comment to that task. Foxl reacts to the comment when it picks it up, and replies with a link when it starts or continues a task. It acts only for people linked to Foxl who can push to the repository, and a task started this way spends your credits like any other. - In the desktop app, Foxl Code's Runtimes menu has Review changes: a reviewer reads a checkout on this computer (your uncommitted changes, your branch against its base, or one commit) and lists what to fix, from P0 (must fix) to P3 (minor), with the file and line of each. It runs on the model you use in Foxl Agent and changes nothing in the folder.
- In Foxl Code, each repository on the Repos page has automation settings. Under Issues you open you can keep every issue starting a task (still the default), start one only for issues labeled
foxl(when opened, or when you add the label later), or turn it off. Review every pull request when it opens runs Foxl's reviewer on each new pull request a Foxl task did not open, on your credits; it is off by default and never merges. The settings are yours, and the repository's row shows when either is changed. - Foxl Code's automatic pull request reviewer now runs on Opus 5.5, the coding agent's default model, instead of your chat model. It reads the pull request's own latest commit, which it can search across the whole repository to find the code that uses what the pull request changed, and the checks that ran on that commit. It treats what a pull request says about itself, such as "all tests pass" or "nothing else reads this field", as claims to check, and says when it could not check one. A review uses about three to four times as many credits as it did on the chat model. When a review fails, for example because the model provider returns an error, Foxl runs it once more. If that also fails, Foxl comments on the pull request that the review failed and nothing was approved, and records why on the task, instead of leaving the review pending with no word. A failed review never counts as an approval.
- In Foxl Code, each repository can have an environment for your cloud tasks: on the Repos page, open a repository's settings and choose Environment. A setup script runs with
bash -ein the repository before the coding agent starts, for up to 10 minutes; its output is in the task log, and if it fails the task stops there and shows the script's exit code and its last lines. A service it starts in the background, such as a database, keeps running for the coding agent, and files the script creates are left out of the pull request. Secrets reach the setup script and the coding agent as environment variables. They are stored encrypted and kept out of the task log, and once saved a value is never shown again: you can replace or delete it. Both are yours alone: other people's tasks on the same repository do not get them, and a task on your own machine runs in that machine's environment. The coding agent itself can read the secrets, as it can any environment variable. - In Foxl Code, the task composer's + menu has Plan first, off by default; while it is on, a small Plan first chip beside the + turns it off again. With it on, the coding agent reads the repository and writes a plan without changing any files or opening a pull request. The plan appears in the task's conversation with Approve plan, which has the same agent continue from its plan, implement it and open the pull request. It works for Claude Code tasks in Foxl's cloud; a task that would run another coding agent or on one of your own machines is refused instead of started without a plan, and while new tasks run on one of your own machines the + menu says so. Until you approve it, the task is listed as Plan ready on the Tasks list, in the sidebar and in its header, and its notification says the plan is ready for review.
- On the desktop, the agent can change part of a file instead of rewriting all of it: the new file_edit tool replaces an exact piece of text, once or everywhere, and the chat shows the change as a diff. It follows the same approval rule as writing a file, so a rule you set for file writes also covers edits.
- In the desktop app, Settings > General has a new switch, "Keep this computer awake while Foxl is working". When it is on, the computer does not go to sleep on its own while a chat reply, the subagents it starts, a local Foxl Code task or a scheduled run is in progress, including runs started from your phone. The screen can still turn off, and closing the lid still sleeps the computer. It is off by default, and with "Keep running when closed" on it works only while the app is open.
- In the desktop app, when a chat reply that took 30 seconds or more finishes while the Foxl window is in the background, a silent "Reply ready" notification titled with the chat's name appears, and clicking it opens that chat. Shorter replies show none. A reply that stops with an error says so. A chat that hands work to subagents shows one notification for the final answer, not one for the hand-off, and a reply to a message sent from your phone or app.foxl.ai shows none on the computer. Turn it off in Settings > Notifications > Chat.
- The "Explain details" button that appears when you select text in a reply can now be turned off in Settings > General > Display. It is on by default. With it off, selecting text shows nothing, so you can select and copy without the button in the way; Quick Chat's own shortcut still opens Quick Chat.
- The agent's own browser can show its window: turn on Show browser window in Settings > Web Access to watch it work, or to sign in to a site yourself in its Foxl profile so the agent can use that login. It stays hidden by default, as before.
- A screenshot the agent takes with either browser tool now appears in the chat as a picture in its tool step (in a finished reply, open its steps to see it); click it to see it full size. The agent sees the screenshot in the same step too, so checking how a page looks no longer takes it a second step through
view_image. Images opened withview_imageshow in the step the same way. - When the agent opens a page on your own computer with a browser tool, for example a dev server it started on
localhost:5173, its step offers Open preview (in a finished reply, open its steps to see it), which opens that page in your browser. It appears in the desktop app and in a browser on the same computer, not on your phone or on app.foxl.ai, wherelocalhostwould be a different device. - Images that tools from MCP servers return, such as a screenshot from Playwright MCP, now reach the model as pictures it can see, and show in the tool step like other images. They used to reach it as a long run of text it could not read, which also used up the chat's context.
- In Foxl Code, you can paste, drop or attach (Add images in the composer's + menu) up to four images on a message, such as a screenshot of a bug, and the chat's model reads them with your request. A coding agent it starts gets the task the model writes, not the pictures. Large screenshots are shrunk before they are sent. If the chosen model cannot read images, Foxl says so instead of answering without them. If the images do not reach the model, for example because the Foxl app on the computer running it is an older version, Foxl says so and puts them back in that chat's message box, so you can send them again without attaching them again.
- In the desktop app, a schedule is set without cron: Repeats offers every day, weekdays, weekly on the days you pick, or once at a date and time, each with a time, and shows the cron it saves. A custom cron expression is still there as the last option, and a schedule whose cron the picker cannot show opens in it unchanged. A new schedule can now be one-time from the editor too. Each schedule can also run on its own model, picked in the editor; by default it uses Foxl Agent's model as before, and if the chosen model is no longer available on the computer the run uses Foxl Agent's model and its result says so.
- A skill can be edited in the app: Edit in a skill's details opens its SKILL.md in the same editor as Files. A line under the editor says whether the front matter is complete (the
---block with aname:and adescription:), and Save stays off until it is. Renaming a skill in a way that would change its id is refused, since its on/off setting and mentions use that id. It works in the desktop app. If SKILL.md changed on disk after you opened it, Save leaves it as it is and says so; Save again replaces it with your version. - If you turned off Auto-approve all tools, the chat message box shows a small Asks first label next to the "+". Click it to switch auto-approve back on, or to open Settings > Safety. With auto-approve on, which is still the default, nothing about approvals appears in the message box.
- In the desktop app on Mac and Linux, Settings > Model & provider > OpenAI (OAuth) has a Sign in with ChatGPT button. It runs the official Codex sign-in for you (
npx -y @openai/codex@0.153.0 login, one fixed version), which opens your browser; the panel shows the sign-in page's address in case the browser did not open, offers Cancel, and picks up the new sign-in by itself when you finish. If it cannot start or does not finish, the panel says why and shows what the Codex CLI printed. It works from the Foxl window on the computer itself, not from the phone or app.foxl.ai. - Foxl Code: the Tasks list can be tidied. Groups fold and stay folded, Done has Clear (on this device, with Undo and "Show cleared"; history is kept), Needs-you rows have the same dismiss as Work, and a budget or stop alarm about a task that settled more than a week ago no longer counts as needing you.
- Foxl Code: tasks are easier to tell apart. Issue tasks are named after the issue, rows say which agent ran them, task rows are links that open in a new tab on the web, the task header no longer squeezes the repo to one letter, and an agent's output wraps. Nothing shows through or under the message bar, and the cookie notice no longer covers the list, the right panel or the sign-in logo.
- A Code task run on this computer now deletes its copy of the repository in
~/.foxl/code-tasksonce its work is on GitHub. The copy stays when the push fails or it holds anything GitHub does not have: uncommitted or new files, unpushed commits, a stash, another worktree or a submodule. Files the repository ignores, such as.env, are not kept. Copies left by earlier versions are removed at startup once they are three days old and hold nothing GitHub lacks. - A Codex or Cursor pane opened in a subfolder of a repository or worktree no longer stops at Codex's "Trust this folder?" question: Foxl trusts the repository root, which is the folder Codex asks about.
- A reply in which the agent created or edited files ends with a Files changed card: each file with how many lines it added and removed, a diff you can expand, and Open. It shows what the whole reply changed, so a file the agent wrote twice shows the end result. Files changed by a shell command are not listed yet.
- Undo on that card puts every file the reply wrote back the way the reply found it, and removes a file the reply created. If a file was changed again after the reply, Foxl asks before overwriting those later changes. The earlier versions are kept in Foxl's own folder on this computer for 30 days, at most 4 MB per file and 256 MB in all, and are deleted when the chat is deleted for good.
- After an Undo the card offers Redo, which puts the files back the way they were right before the Undo (asking first if a file was changed after the Undo), and your next message in that chat tells the assistant which files Undo or Redo changed, so it does not keep working from edits that are no longer there.
- In the Foxl Agent message box, type @ to pick a file from your workspace (on app.foxl.ai and the phone apps while your desktop is connected): the list narrows as you type and puts this chat's own files first, and the file you pick goes into your message the same way dragging it in does. Type / at the start of a message for your installed skills and three commands: /new starts a new chat, /model opens the model picker and /clear empties the message box. Use the arrow keys and Enter or Tab to pick, or Esc to close the list.
- New keyboard shortcuts in Foxl Agent: Alt+Up and Alt+Down go to the previous and next chat in the sidebar's order, Cmd+L goes to the message box (in the desktop and phone apps; in a browser Cmd+L stays the address bar's, and you can pick another key for it in Settings > Shortcuts), Cmd+Shift+C copies the last reply, Cmd+Shift+M opens the model picker and Cmd+Shift+E shows or hides the files panel (Ctrl instead of Cmd on Windows and Linux). With the message box empty, the Up arrow edits your last message. Each one can be changed in Settings > Shortcuts.
- Cmd+/ (Ctrl+/) shows every keyboard shortcut Foxl answers to, including the ones you changed, with a button to Settings > Shortcuts.
- Cmd+K (Ctrl+K) opens a command palette in the desktop app on every system, on app.foxl.ai, on iPhone and Android with a keyboard, and on code.foxl.ai. Type to jump to a page, a Settings pane or a single setting, or run an action: in Foxl Agent new chat, choose a model, stop the reply, show the files panel, export the chat and turn Auto-approve all tools on or off (with your desktop reachable), and everywhere switch between light and dark or show the keyboard shortcuts. Opened with nothing typed, it lists those actions. Search (Cmd+Shift+F) shows the same pages and settings above your conversations, tasks and notes, and its hint no longer says it searches files, which it does not.
- Esc now stops a reply that is running. It used to do that only while you had another message waiting to send.
- In Settings > Shortcuts, removing a shortcut with its x shows "Shortcut removed" with an Undo button that puts it back, and the search field says what it matches instead of repeating its label.
- Optional daily and monthly spending limits in Settings > Usage on the desktop, off unless you set one. They apply to the estimated cost of models billed to your own keys (Amazon Bedrock, API keys, OpenRouter); a Claude or ChatGPT subscription and local models are neither counted nor stopped, and calls on Foxl credits are neither counted nor stopped. At 80% of a limit Foxl sends a notification, and at 100% it stops before the next model call, including inside a task that is already running, schedules, the heartbeat and channel messages; the chat on the desktop says which limit was reached and where to change it.
- On a new desktop install whose default model cannot run on your computer - without AWS credentials, for example - the desktop app picks a sign-in it finds on the computer, in this order: your Claude Code sign-in, your ChatGPT sign-in, then Ollama. It keeps the same model when that sign-in offers it, makes it the app's selection everywhere (Settings included), and says so above the message box ("Using your Claude Code sign-in") until you pick a model yourself or dismiss it. With Claude Code it also says that Foxl's own tools such as memory and subagents are off in that mode. A model you already chose is never changed this way.
- When a task takes several steps, the agent shows its plan as a checklist under its reply: each step marked done, in progress or still to do, with how many are done, updated as it works. A Claude Pro/Max sign-in does not get the checklist, and schedules, the heartbeat and Slack, Telegram or Signal replies do not use it.
- In Foxl Agent you can group chats into projects. Point at the Recent chats heading and a small "New project" button appears; once you have a project, a Projects section sits above Recent chats. Drag a chat onto a project, or use Move to project in its menu, and use the button on a project's row to start a new chat in it. A project can have a folder on your computer: chats started in it, and chats you move in that have no folder yet, work in that folder. A project folds and unfolds with a click, and deleting it keeps its chats; Undo on the "Project deleted" message that follows puts the project back with its chats in it. On a phone the chat list stays one list.
- Pinned chats are now saved with the chat on your computer instead of in one browser's storage, so another window or browser showing this computer's chats shows the same pins, and there is no longer a limit of eight. Chats you had pinned before move over the first time you open Foxl after updating.
- Foxl Code: a task's conversation, terminal and pull request are on one screen. On a wide window the conversation stays on the left and a panel on the right has the task's Terminal and its Changes (its plan and its pull request review: checks, changed files, line comments, Request changes and Merge) as tabs; a running task opens on its terminal, a finished one on its changes, and pressing the open tab closes the panel. On a phone or a narrow window the header switch shows one at a time. A tab appears only when it has something to show, so a task opened after its run ended has no empty terminal. The decisions waiting on a task - a red build, requested changes, a merge Foxl could not make - now appear in its conversation, and a finished Claude Code task in review has Resume on its outcome card. The Needs you rail no longer opens beside a task, since its review and decisions are in the task itself.
- Foxl Code: a task's changes can be reviewed before it opens a pull request. As soon as a cloud task pushes its branch, its Changes tab shows that branch compared with the repository's default branch and reads it again on each push; a task running on this computer shows its own copy of the repository, including changes not committed yet and new files, while it runs. While the agent is still on the run, each file has Discard, which asks it in the task's conversation to put that file back as it is on the default branch; a finished task's changes are read-only.
- In the desktop app, files attached to a chat message are now kept with the conversation, in its own folder in Foxl's data directory (
~/.foxl/data/attachments), outside your workspace, so another chat's agent never finds them. After a restart or a model switch the model still sees the ten most recently attached documents (at most five PDF or Office files at a time; an older text file goes in as text), and Retry and Edit send the message again with its files instead of asking you to attach them again. The folder is removed when the chat is deleted for good. A message can now carry up to 10 files instead of 5, of which at most 5 PDF or Office files; files over the limit are not attached and the message box says so. A text file past the five most recent documents in a chat is sent to the model as text, so it stays readable. - In the desktop app, editing a message no longer deletes the replies that came after it. The edit becomes a new version of the message, and < 1 / 2 > under it switches between the versions, each with its own replies; the model continues from the version on screen. The other versions stay with the chat (also after a reload) and are deleted with it.
- In the desktop app, an answer that read web pages now lists them under the answer as N sources: the pages it opened with
web_fetch, its own browser or the Chrome extension, and the pages the model's own web search cited. Click the line to see them and open one. - Foxl Code now fixes a red CI on its own pull requests. When CI fails on a pull request a Foxl Code task opened and that task has already finished, Foxl starts one follow-up task on the same pull request, with the same coding agent, and gives it the failing checks and the failing step's log; its fix is pushed to the same branch, so the pull request updates instead of a new one opening. It happens at most once per commit and twice per pull request, uses credits like any task, and stops at your daily spend cap for unattended work. The follow-up shows in your task list as "Fix CI: ..." and as a CI fix button on the original task. Turn it off on Foxl Code's Schedules page under Autonomy > Advanced > "Fix red CI automatically"; you are still told when CI fails.
Improvements
- In Foxl Agent and Foxl Code chats, a finished reply now shows only its answer under one quiet "Worked for 1m 12s" line. The thinking, the tool steps and the notes the assistant wrote along the way are folded behind it; click the line to see them. Each thinking step there shows the first line of what the assistant thought, with how long it took beside it, so you can follow the work without opening every step. While a reply is still running, the line counts the time ("Working for 8s") and shows only what the assistant is writing and the step it is on right now. A step waiting for your approval and a picture the assistant generated always stay on screen, and Find in chat opens a folded reply when it finds a match inside.
- In the light theme the sidebar and the frame around a conversation are white instead of gray, with one thin line between the sidebar and the conversation, and the selected chat in the sidebar still stands out. The sidebar's section names (Extend, Recent chats, Workspace in Foxl Code) are larger and easier to read. In the desktop app and in Chrome and Edge, the bar at the top of a conversation or page no longer has a line under it; in a conversation and in Settings a line appears only while the content is scrolled up under the bar. Safari, Firefox and the iPad app keep the line as before. The colors of the dark theme and of the color themes in Settings > Appearance are unchanged.
- In Foxl Agent, the message box shows one "+" button instead of separate attach and terminal buttons. It opens a menu just above the message box with Add photos and files and Terminal. While a terminal is open or still running, its button stays next to the "+" with the number of sessions, as before. Ctrl+T (Cmd+T on a Mac) still opens and hides the terminal in the desktop app, and dragging or pasting a file still attaches it.
- Web addresses printed in a terminal are links. Hold Cmd (Ctrl on Windows and Linux) and click one, such as the address
npm run devprints, to open it in your browser. A plain click still selects text. This works in the desktop terminal and in Foxl Code's agent panes. - On the desktop, GPT-5.5 and GPT-5.4 on your own AWS account can now search the web while answering, with Amazon Bedrock Web Search: the agent searches only when a question needs current information and cites the pages it used. Searches stay inside AWS and are billed by AWS. Claude and GPT-6 models on Amazon Bedrock have no web search there, and Settings > Web Access says so; the new Web search switch there turns it off.
- On the desktop, a chat can have its own folder: pick one with the folder button in the chat header, before the first message or later. The agent's shell commands then start in that folder, file paths that name no folder point into it, and the agent follows the folder's AGENTS.md or CLAUDE.md files from the repository root down to it, 32 KB together at most. Project instructions under the folder shows exactly which files are sent, with their text. A file that links outside the folder and its repository is left out and listed there.
- Code blocks in chat replies are syntax highlighted, in light and dark mode and in every colour theme, for about 40 languages including TypeScript, Python, shell, Go, Rust, Java, SQL, HTML and YAML. A block is coloured as soon as it has finished arriving; the one still being written stays plain until then. The colours for a language are downloaded the first time a reply uses it. A very long block, over about 20,000 characters, stays plain.
- A mermaid diagram in a chat reply opens on the diagram as soon as the reply has finished writing it, instead of on its source; until then the source shows. Diagrams use the app's colours in light and dark mode and in every colour theme, and switch when you change the theme or your system goes dark while one is open. A diagram that cannot be drawn shows its source with a note. HTML and SVG previews use the app's colours too. A diagram never loads anything from the internet: a picture it links to is not shown.
- Math in chat replies is typeset:
$...$inline and$$...$$as a centred formula, and also\(...\)and a\[...\]block on lines of its own, the forms some models write. It used to show as dollar signs and raw LaTeX, and a spacing command such as\,lost its backslash. Dollar amounts like $5 and an escaped bracket in a sentence, such asarr\[0\], stay as they were, and a formula still being written shows as text until it is complete. The math fonts ship with Foxl and are only downloaded the first time a reply contains a formula. - Import MCP servers on the desktop: the Custom tab of Settings > Tools/MCP reads the servers you already set up in Claude Desktop, Codex and Cursor and lists them as a checklist; the ones you tick are added with their command, arguments and environment (or URL and bearer key). Anything Foxl cannot carry over, such as a working folder or an extra header, is named under the server instead of being dropped.
- An MCP server can be given a longer tool call timeout, up to 10 minutes, in its row on the Custom tab, for tools that take longer than the 30-second default. Codex's
tool_timeout_secis carried over on import, and a Codex server without one keeps Codex's own 60-second default. - You can add your own hooks on the desktop: commands in
~/.foxl/hooks.json, in the Claude Code hooks format, that run before a tool call (PreToolUse), after it (PostToolUse) and when a chat or channel reply finishes (Stop), with the event as JSON on stdin, in the chat's folder when it has one. A PreToolUse hook that exits with code 2 blocks the call, and its message is what the agent sees and what the tool row shows; one that answers"ask"shows the usual approval prompt for that call. Matchers accept Claude Code tool names too, so a block written forBashapplies to Foxl's shell tool. Settings > Safety lists the hooks Foxl loaded, the parts it does not run, and why a file that is not valid JSON runs none. - foxl.ai tells Windows visitors, before they download, that Windows may stop the installer with "Windows protected your PC" because it is self-signed, and how to continue (More info, then Run anyway), with a link to the docs section that explains it. foxl.ai/download now opens the home page and its download button instead of a page that says it does not exist.
- An MCP server can be given a longer tool call timeout, up to 10 minutes, in its row on the Custom tab, for tools that take longer than the 30-second default. Codex's
tool_timeout_secis carried over on import. - You can add your own hooks on the desktop: commands in
~/.foxl/hooks.json, in the Claude Code hooks format, that run before a tool call (PreToolUse), after it (PostToolUse) and when a turn ends (Stop), with the event as JSON on stdin. A PreToolUse hook that exits with code 2 blocks the call, and its message is what the agent sees and what the tool row shows. Matchers accept Claude Code tool names too, so a block written forBashapplies to Foxl's shell tool. Settings > Safety lists the hooks Foxl loaded, the parts it does not run, and why a file that is not valid JSON runs none. - The version number in Settings > General can be selected by dragging over it and copied, for example into a bug report.
- The notification panel says "Read all" in words, at its top right next to the close button (on a phone, next to the settings button). It used to be a double check mark with no label. Swiping a notification to mark it read, and the empty Unread list, show an open envelope instead of a check mark.
- Notifications on a phone fit more on screen and read more cleanly. The sheet closes with an X instead of a back arrow, and its title is the same size and weight as every other screen's, on the Notifications page too. Each notification's time now ends its title line, with the "..." menu beside it, so a one-line notification is about a quarter shorter, and a notification's own actions, such as "Open PR", look like buttons. The desktop panel uses the same rows.
- In Foxl Code, a Claude Code cloud task started from a prompt now takes messages while it works. A line typed in its terminal, or a follow-up the assistant passes on to it, reaches the agent at its next tool call, and the terminal shows it as a
[user]line when the agent takes it; until now both were refused until the run ended. Once the agent has finished its work and is wrapping up, the terminal says so instead of saying the task does not read input.
Fixes
- Foxl Code: the rules a cloud task's coding agent is given (work on a branch, open a pull request, check the work the way the repository does) now say how much time it has, in minutes and as the time it will be stopped, and to put a time limit on its test runs. A Claude Code or Codex task gets them also when the repository ships its own CLAUDE.md or AGENTS.md; before, that file replaced them. Codex and Kiro tasks no longer start the repository's tests after the time limit has stopped them: the pull request opens as a draft with the work so far, as it already did for Claude Code.
- Run now for the Feed Generator (Settings and the Schedules page) runs at any hour. Outside its active hours (7:00 to 23:00 by default) it used to do nothing; the active hours still apply to the timed runs.
- In Foxl Code, the autonomous loop no longer files an issue that is already open, already fixed or declined in the last 30 days, a copy of an issue it filed itself, or work a coding agent cannot finish (one that needs a key, a device, a repository setting, someone to click through a dashboard, or a change to GitHub Actions workflows). Foxl checks the repository's issues and pull requests before the issue is created, and files nothing when it cannot check. The loop also stops starting tasks for an issue that has already failed twice, and stops filing for a while when its last three issues all ended without a pull request. You can still start any of those yourself.
- In Foxl Code, the test output kept with a Cursor, Hermes or OpenCode task whose tests failed now has Foxl's own credentials removed from it, like the rest of that task's log.
- A Foxl Code task that runs on Foxl's cloud without you can no longer push to your repository's default branch or push a tag, whatever a CI log, an issue or the repository itself tells the agent. That is a task started with a prompt (from chat, the composer or the API), from an issue, Solve or an
@foxlcomment, by a schedule or the autonomous loop, the follow-up Foxl starts for failed checks, a retry of any of these, and any of them reopened with Reconnect. Its GitHub access cannot write your repository, and its pushes go through Foxl, which refuses the default branch and tags. Work still arrives as a branch and a pull request, and a branch the agent names itself is still pushed. A Remote terminal pane you open yourself is not restricted: from it you can still push to the default branch and push tags. Its pushes now also go through Foxl, and the pane's own GitHub access can read the repository and open pull requests but no longer write to the repository through the GitHub API. Tasks on your own machine are unchanged. - Foxl Desktop no longer sits on its startup screen for about 30 seconds when a Foxl server left over from an earlier run (for example after the app was force quit) still holds its local port. It now stops that server and opens in a few seconds.
- With "Keep running when closed" on, when another program is using Foxl's local port (13847), the background service now waits for the port and starts its server within about 30 seconds of the port coming free, and Foxl's startup screen says the port is used by another program. It used to stay offline even after the port came free, until the app was opened or the computer restarted.
- On Windows, when another program is using Foxl's local port (13847) as Foxl starts, Foxl now asks "Port 13847 is in use by <program>. Quit it so Foxl can start?" and closes that program only if you choose Quit, leaving any programs it started running. It used to force-close whatever held the port, together with everything that program had started, without asking. A Foxl server left over from an earlier run is still stopped without a prompt, as on macOS and Linux.
- With Keep running when closed on, a spending-limit notification sent after you quit Foxl, for example by a schedule overnight, now reaches your iPhone as a push (under the Scheduled tasks switch) and appears when you next open Foxl, as long as it is still true. It used to be sent to nobody and was never shown again. While the Foxl app is running, including with its window closed, the notification shows on the desktop as before.
- While a reply is streaming, a bold, italic, strikethrough or code marker no longer shows as raw
**,*,~~or a backtick until its closing marker arrives. A*inside a word or a number, such as5*3, is shown as typed. - Cloud Claude Code tasks stop coding shortly before their time limit (five minutes before it at the default 30 minutes), so the work done so far is committed and opened as a draft pull request. A task that runs out of time no longer re-runs the repository's tests before delivering.
- A local (stdio) MCP server keeps running between tool calls, so a server that holds state keeps it. With Playwright MCP,
browser_take_screenshotnow captures the pagebrowser_navigateopened; it used to capture a blank page, because every call started the server again. Calls after the first also no longer pay the server's start-up time. Your own chats keep one server running between calls; a Slack, Telegram or Signal thread or a scheduled run gets its own server, which stops when that run ends, so a message that arrives through a channel never sees a page your chat opened. If such a run needs a server your chat holds idle, your chat's server is restarted. Your chats' server stops after 15 minutes without a call, and any server stops when its tool is switched off, changed or deleted, and when Foxl quits; with Keep running when closed on, quitting the app leaves Foxl's background service running, so your chats' server then stops after those 15 minutes. - A reply you stop now says Stopped under what it had written, in the chat and after a reload. A stopped reply used to look finished, and one stopped before its first word showed "[Cancelled]" as if the assistant had said it.
- When the desktop app starts on a Mac, the Foxl logo stays on screen from the startup window until the app appears. For a moment it used to give way to a blank white window, followed by a white panel with only a blurred smudge in the middle.
- In the web app, the logo now hands over straight to the app. A blank page used to show for about a third of a second in between, white even in dark mode.
- On iPhone in dark mode, the launch screen shows the Foxl logo on the dark background. It used to show it on a white square, and in light mode on a faint grey one.
- On the desktop, "create demo.txt in your workspace" or "look at sample.png in your workspace" now uses your workspace folder on the first try. A file path the agent wrote without a folder used to point inside the app's own folder, so new files seemed to disappear and existing ones were not found; shell commands the agent runs without naming a folder now start in the workspace too.
- The agent's own browser (the
browsertool) now runs one fixed, reviewed version of agent-browser instead of downloading and running whatever version was published last on every call. It also uses a session of its own instead of the one other programs on your computer that use agent-browser share, and keeps its screenshots in Foxl's folder (~/.foxl/data/screenshots). Each browser command now leaves one line in Settings > Logs saying which command ran and how it ended, without the text it typed. - On Windows, the agent's own browser works. Every call used to fail before it started, because Windows runs
npxas a script that Foxl could not launch. It still needs Node.js with npm, and Google Chrome or Brave, installed. - With the Chrome extension, the agent is told the element names the extension really uses (
ref_12). It used to be told two other formats, so its clicks and typing could miss and cost it extra steps. A name from the other browser tool (@e12) is refused with a message telling the agent to take a fresh look at the page, and nothing in your Chrome is clicked. - Screenshots taken through the Chrome extension are saved in Foxl's folder (
~/.foxl/data/screenshots). They used to be written next to the app itself. - With the Chrome extension, when a click, typing or a choice in a list fails - for example because the element is gone - the agent is now told so, with the extension's reason, instead of being told it worked.
- While the agent works in your Chrome through the Foxl extension, the page it is working on now shows the extension's glowing border and a Stop Foxl button, also when the run was started from your phone. Pressing it stops that chat's run, the same as Stop in the chat. The border goes away when the run ends. Before, the border and the button never appeared, and the button would not have stopped a chat.
- In the desktop app, the Preview of a mermaid diagram in a chat reply showed the diagram's source text instead of drawing it. It draws now. Mermaid ships with Foxl instead of being downloaded from a third-party site each time a diagram opens, so diagrams also draw offline.
- Mermaid diagrams and HTML previews in chat replies are no longer cut off at the bottom.
- A tool step in a chat that failed now says so in a reply's steps. Viewing an image that does not exist reads "Couldn't view sample.png" with an alert icon and the tool's own error, and a command that exits with an error shows its exit code. These steps used to read as if they had worked. A collapsed group of steps shows how many of them failed.
- Steps that wrote or edited files are no longer grouped under "Read files": the group says "Wrote files", or "Read and wrote files" when it did both.
- A step whose approval prompt is waiting for you says "Waiting for your approval" instead of "Executing command...".
- Image and Git steps in a chat are shown in your language.
- Your own messages in a chat show exactly what you typed. They used to be formatted like a reply, so triple backticks turned part of a message into code, a backslash before a comma disappeared, a line starting with # became a heading, and -> was drawn as an arrow. Line breaks and indentation are kept, and web links are still clickable. A file path in backticks in your own message is now plain text, so Cmd-click no longer opens it there; in replies it still does.
- On a desktop with no model connected yet, the empty chat shows "Connect a model to start" with a button to Settings > Model & provider, and the model button in the message box reads "Connect a model" instead of naming Opus 5.5. A message that fails because nothing is connected now offers Open Model & provider next to Try again.
- Settings > Model & provider says whether Amazon Bedrock can run on this computer: "No AWS credentials found on this computer" and what to do about it, the reason credentials that were found cannot be used, or the credentials it is using. A Check button looks again after you set them up. With nothing to pick from, Default Model says so instead of showing an empty list over a model id.
- On a new desktop install, the agent's first reply does what you asked instead of introducing itself and asking your name, timezone and what you want help with. It may end that one reply with a single short question, such as what to call you, and does not ask again in later chats. If you answered the role and technical-level questions when setting up Foxl, it asks nothing at all.
- The Claude Code, OpenAI (OAuth) and Gemini CLI sign-in panels in Settings no longer show a success check mark when you are not signed in, draw their commands as code instead of between literal backticks, say when you are signed in, and are translated into all ten languages, along with the note about these unofficial integrations.
- In the desktop app, on Android and in Chrome, End (Cmd+Down on a Mac) in a chat goes all the way to the newest message and keeps following a reply that is still streaming. It used to stop short of it while the reply grew.
- In the desktop app, on Android and in Chrome, the jump-to-bottom button catches up with a reply that is still streaming in about half a second. It used to take several seconds.
- With reduced motion turned on, in your system or in Foxl's settings, End and the jump-to-bottom button go straight to the newest message without gliding, and keep following a reply that is still streaming.
- With reduced motion turned on, Find in chat (Ctrl+F, Cmd+F on a Mac) jumps to its match instead of gliding there.
- In the desktop app and in Chrome, going back to a chat you left partway through a long reply opens it at that place again. It could open thousands of pixels further down.
- Going back to a chat opens it on the exact message you were last looking at, even when messages above it changed size while you read. It could open a short way off.
- Opening a tool result, or a reply's steps, at the bottom of a chat keeps what you clicked under the pointer and opens it below. Opening a tool result there used to push it up by the height that opened.
- Opening a chat from a notification or a link shows its newest message again, instead of the place where you last left that chat. Picking a chat in the sidebar still returns you to where you were.
- Going back to a chat returns you to where you were even when that was a message you sent or a reply written while you watched. It used to open at the bottom.
- On a phone, the jump-to-bottom button goes all the way to the newest message. In a long chat it could stop short.
- Scrolling with the mouse wheel or a finger while the chat is gliding down to the newest message stops the glide where you take over. The wheel used to be ignored until the glide ended.
- Find in chat (Ctrl+F, Cmd+F on a Mac) reaches a match far up in a long chat. It could leave the match off screen, or jump straight back to the newest message. Scrolling with the wheel while it moves to the match now takes over at once.
- Switching to another chat while the current one is still gliding down to its newest message opens the other chat exactly where you left it. It could open one message off.
- On iPhone and iPad, the "..." menu at the top right of a chat grows out of its button in one smooth motion, and its items appear in place. It used to step and stutter while opening and closing, its labels slid and were cut off mid-word, and the button's outline flickered back after it closed.
- A finished subagent that you or the agent ask a follow-up answers it from what it already did. If it answered without running a tool again, it used to be told it had not used any tool and pushed to redo its task, which cost an extra step and could repeat what it had done.
- Editing a message whose attached file can't be sent again now says so in the editor, and that removing the file lets the edit save. It used to say a reply was still running when none was.
- Regenerating the answer written from subagents' results now works when the message that started them had a file attached. It was refused as if the file had to be sent again, though rewriting the summary never sends it.
- In the desktop app, Inkling through OpenRouter is sized by the 524,288-token window OpenRouter states for it, so a long chat is compacted before it reaches that limit and the context meter reads its real fullness. It was sized at 1,048,576 tokens. For every OpenAI-compatible provider, a window the provider's own model list states now takes precedence over the one Foxl ships with.
- When the agent starts subagents and then writes its full answer anyway, the reply written from their results adds only what they change, also when starting them was the first thing the agent did. That case used to get the whole answer a second time. And when the agent writes a long plan before starting them, the reply from their results is the full answer, not a short note.
- When a message is refused because your Foxl credits ran out, or because your provider's balance cannot cover the reply (OpenRouter's "more credits, or fewer max_tokens", for example), the files attached earlier in that chat are still there for the model when you ask again after adding credits or lowering the maximum reply length. They used to drop out of the chat's context without a word.
- While your phone or browser is connected to your desktop, terminal activity - terminal names, folders, commands and output - is no longer also sent in a form the Foxl relay can read after you send a chat message, reopen a chat that is still replying or preview a file. Each of those made the desktop add a readable copy beside the encrypted one, and it lasted until every phone and browser had disconnected. Bringing the phone app back from the background did the same until the phone reconnected, usually within a second.
- While no phone or browser is connected to your desktop, the output of terminals and Foxl Code panes you use on the computer itself no longer goes to the Foxl relay at all. It used to be passed to the relay in a form it could read, with nobody there to receive it.
- When you come back to the Foxl app on your phone after it was in the background, your desktop now answers the first things the app asks for - the chat list, a conversation, your files - instead of refusing them. They used to fail with an error until the app had reconnected, usually about a second later. This is fixed on the desktop side, so it works with the phone app you already have once your desktop is updated. If your desktop itself reconnected while the phone was in the background (it slept, or its network changed), the app now renews its connection and asks once more by itself for anything that only reads; a request that changes something, such as saving a file, is not sent a second time, so it fails with an error and you can retry it. On iPhone and Android that part comes with this release's app update; app.foxl.ai has it right away.
- In Foxl Notes, live translation, titles and reply suggestions on Automatic no longer switch to Claude Haiku 4.5 on Amazon Bedrock, billed to your AWS account, when Foxl Agent uses another provider and this computer's only AWS access comes from outside
~/.awsand your environment, such as an EC2 instance role or a profile in a customAWS_CONFIG_FILE. They run on Foxl Agent's model, as they did before v0.8.0, and the Notes and Dictate anywhere model pickers no longer offer Bedrock models there. With Foxl Agent on Amazon Bedrock, or with AWS keys or a profile in~/.aws, they still run on Claude Haiku 4.5 on Bedrock. - In Foxl Notes, with transcription on Automatic, Check again on the "Finish setting up Notes" card asks again for this computer's AWS credentials, such as an EC2 instance role or a profile in a custom
AWS_CONFIG_FILE, so access you have just fixed shows up at once and Record works. It used to repeat the earlier answer for up to five minutes. In Settings > Notes > Recording, the "not set up" line under Automatic now has its own Re-check button. - When the AWS sign-in (SSO) for the profile Foxl uses has expired, Dictate anywhere says so and tells you to run aws sso login, instead of saying transcription is not set up, and Settings > Dictate anywhere shows the expired sign-in too.
- Voice input in the chat, Quick Chat and Code message boxes types what you say when transcription runs on the on-device engine, including when Automatic picks it on a Mac with no AWS credentials. It used to listen and never type anything. With a bring-your-own-key provider picked for Notes, pressing the microphone now says it cannot use that provider yet, instead of listening and typing nothing.
- On iPhone, Android and app.foxl.ai, a subagent the agent starts shows up in the bar above the message box right away. It used to appear only after you reloaded or left the chat and came back.
- In the first-run tour on the desktop, Skip (or Escape) takes you back to Chat instead of leaving you on the page the card had opened, such as Schedules. The Chat card says "your agent is ready" only when a model can answer, and otherwise says to connect one on the next card. The last card sits above the provider menu instead of over the Settings list, and Done takes you to Chat when a model already works.
- On a new installation of the desktop app on Windows, quitting, updating or reloading Foxl before you finish the first setup screens no longer leaves Start Foxl when I sign in off without asking. The setup screen opens again with the switch on, also on an installation where this already happened, and Foxl starts at sign-in only if you leave it on. Installations that have already answered are not asked again.
- In search (Cmd+Shift+F, Ctrl+Shift+F), your notes come first only while you are in Foxl Notes. Elsewhere conversations come first and notes follow them, so pressing Enter opens the top conversation instead of a meeting note that happened to contain the word, and no longer switches you to Notes.
- On app.foxl.ai, the first sign-in of a new account opens the look and profile setup and the feature tour, as on the desktop. Your own sign-in used to count as proof the browser had been used before, so web users never saw setup. An account with a paired desktop, or one created more than a day ago, still goes straight to Chat, also in a new browser or a private window, and Settings > Appearance > Show setup again opens it at any time. While no desktop is connected, the tour's Chat card says your agent answers once Foxl Desktop is running, instead of saying it is ready.
- On Windows, Foxl updates a taskbar pin you made from its window in version 0.7.36 or earlier to the app identity Foxl runs under now, which is what Windows uses to show the Foxl window on that pin instead of as a second taskbar button. If you still see two Foxl buttons, unpin Foxl and pin it again.
- In Foxl Code, a cloud task on a repository with no CLAUDE.md or AGENTS.md of its own no longer tells the agent to avoid emoji and em dashes. Those were Foxl's own style rules, so the agent could restyle your code and pull request text to match them. The agent is now told to follow your repository's own conventions, and still to work on a branch, open a pull request and run the tests.
- In Foxl Code, a cloud task that has used 80% of its task budget now tells you while it is still running, under Needs you in Work, instead of only stopping once it reaches that budget.
- In Foxl Code, the Usage section of your account shows the date your credits refill. Each recent ledger entry is labeled Compute or Storage in your language and names the task it was for; click the task to open it.
- On Foxl credits, chat titles on Opus 5.5 and Sonnet 5.5 now ask for the lowest reasoning effort, as they already did with your own Anthropic key, instead of the model's default effort.
- When a model on OpenRouter or another OpenAI-compatible provider is rate-limited and the provider does not say when to retry, Foxl no longer retries it twice over: a throttled turn sends 5 requests instead of 15 and shows the rate-limit message after about 2 seconds instead of 7 to 9. A free-model daily limit that is already used up is sent once instead of three times. Retries the provider asks for, server errors and dropped connections are retried as before.
- Saving an OpenRouter API key now checks the key with OpenRouter first. A key OpenRouter does not accept is not saved, and Settings says so, instead of the first chat failing. If OpenRouter cannot be reached, the key is saved as before.
- With OpenRouter, a Notes summary, title, translation or dictation cleanup made right after Foxl starts no longer runs out of room on a reasoning model. Foxl now asks the model not to reason for these short tasks from the first request, not only after the model list has been opened.
- With OpenRouter, a reasoning model's reasoning is now handed back to that model in full between tool calls, in the form OpenRouter documents. Before, only its plain text went back.
- On iPhone and iPad, the "Update available" prompt now follows the country of your App Store account rather than your language setting.
- Foxl Code asks its server for your account and Code settings less often: opening Tasks reads your account once instead of up to six times and your Code settings at most twice instead of four times, the setup checklist no longer re-checks them every five seconds while it is open (it now checks for ten minutes after you press Install Foxl Code, and when you come back to the window), and while the Foxl Code service cannot be reached it waits longer and longer between attempts instead of retrying every few seconds.
- In Foxl Code, an account that has not finished setup now sees the setup checklist as a card above the message box on Tasks, so you can type a question right away. The checklist used to open as its own page in place of the message box, once per visit, until you pressed Skip onboarding, which on the card still hides it for good on this device.
- With reduced motion turned on in your system settings, menus, dialogs, sheets and popovers open and close without animating. Most of them still animated unless you also turned on Reduce motion in Foxl's own settings.
- In the desktop app, clicking a feed notification banner opens the Notifications page. It used to open an empty new chat. Clicking a Slack, Telegram or other channel message banner opens that thread in Channels instead of Agent chat, and clicking a "device connected" banner opens Mobile/Web, the same places the notification opens from the bell.
- In Foxl Code, an issue opened in a connected repository starts its agent. The hand-off to the task's runner was being dropped, so most issue tasks sat in Queued with nothing running and held your task slots until they were cancelled; Foxl Ops investigations had the same gap. Each such issue now runs a task on your credits; to narrow that, change Issues you open in the repository's automation settings on the Repos page.
- In Foxl Code, a cloud task whose pull request exists now ends in review instead of Failed when the agent sandbox's own test run is red, and the status no longer flips between the two depending on which update lands last. A scheduled task that ends this way still does not count toward the limit of 3 open scheduled tasks, so its schedule keeps running. A pull request the coding agent opened on its own branch is now linked to its task, so the task no longer shows Failed with no PR beside an open one.
- In Foxl Code, Retry runs the task again on the same coding agent with the instructions it started with (a Codex task no longer retries on your default agent, and a Solve note is kept), and tasks started from the composer can be retried. The Retry button on a finished task says which agent it uses. To pick up an issue you edited since, start it again from Work.
- In Foxl Code, on Work > Not started, Start names the agent it will run and lets you pick another, Close issue moved into the row's menu, and an issue whose agent run has ended no longer says an agent is on it.
- On app.foxl.ai with no desktop connected, the Desktop page's download link gives the Windows installer on Windows and points to foxl.ai on Linux, instead of the Mac disk image on every computer. In the iPhone and Android apps that page no longer offers a desktop download.
- Settings > Safety says which built-in tool rules still apply while Auto-approve is on: built-in blocks still apply, and built-in prompts are skipped. It used to say only that the built-in rules still apply. The built-in rules are listed there, read-only.
- Opening a Foxl Code link while signed out, or while your account does not have Foxl Code access yet, opens Chat with a notice that says why, and the address bar shows /chat. It used to show Chat under a /code address, or switch to /chat without saying why.
- A model request that ended without settling, for example a dropped stream, now releases its credit hold after 15 minutes instead of two hours, so a few failed requests can no longer block every Foxl Code task on the account for two hours. When held credits are the reason a request is refused, the error now says how many credits open requests are holding.
- Settings > Archived chats uses one name for the place a deleted chat goes. It used to call the same list "Archived chats", "Deleted chats" and "trash" on one screen. It now says that a chat you delete is kept there for 7 days and then deleted for good, and its button reads Empty archive.
- Deleting the open chat with Cmd+D (Ctrl+D) now shows "Chat deleted" with an Undo button for 8 seconds, as Notes does. Undo brings the chat back, pinned where it was, and reopens it. Before, the shortcut removed the chat you were reading with nothing on screen to say so or to take it back. A chat that exists only in your browser on app.foxl.ai, with no desktop, still has no archive to restore from.
- Foxl Code: pull requests a cloud task opens are titled after the change (the agent's own commit message, or the issue's title with its number), never cut mid-word, and describe it: a link to the task, whether the repository's tests passed in the agent's sandbox, the end of the agent's report, and
Closes #Nfor a task started from an issue. Commits say what they are, with aTask:line. When those tests fail, the pull request now opens as a draft with the failure at the top instead of leaving the work on an unlinked branch. When the coding agent already opened its own pull request, Foxl links it instead of pushing a duplicate branch. A retry that reuses the previous attempt's workspace no longer commits files that attempt left behind. - Foxl Code: a cloud task can now check its work with the repository's own command. Commit a
.foxl/verifyscript and a task runs it, instead of the test command Foxl guessed, before it opens the pull request; a.foxl/verifythat contains only comments says there is nothing to check. Without one, Foxl still runs the test command it recognizes, and the pull request now says that this was Foxl's guess and that other checks the repository's CI runs did not run in the sandbox. Before, a repository whosenpm testneeds a running server failed this check on every task. - A failed Foxl Code cloud task now says why its coding agent stopped (out of credits, too many requests at once, the time limit, or the CLI's exit code) and keeps the last lines the agent printed. It no longer blames the repository's tests for a run that changed nothing. Cloud Claude Code tasks now show their progress in the terminal while they run (assistant text, tool calls, retries) instead of a blank screen until the end.
- A failed Foxl Code task's page says what the run left: the pushed branch or "Nothing was pushed", what it cost in model and compute, and "Out of credits" links to Account. A pull request whose sandbox tests failed shows as open instead of "no pull request". Task pages also show the issue as the ask, with "Show full prompt" for the agent's full prompt, name that task's own agent and model in the header, and show the live cost and "N of 30 min" while it runs. Settings names the real default model, and Usage labels the credits bar's used and left ends.
- Foxl Code no longer starts more Claude Code, Codex, Hermes or OpenCode tasks than your plan can run model requests at once (Pro 8, Free 2): an extra task is refused up front with "no free model slot" instead of starting and failing on a 429 or 402. Terminal sessions are not counted. A relay refusal caused by the in-flight cap is now always reported as
429 too_many_in_flight, never as "insufficient credits" beside a larger balance. Every model request also waits on one D1 round trip fewer before the model is called. - Foxl Code no longer counts its automatic review of a coding task's pull request as an approval before the pull request's checks have finished. A review with no blocking findings now shows "No blocking findings; approval waits for CI" until every check on that commit has passed, and only then counts as approved or offers "Ready to merge"; a failed build takes the approval back. On a repository with no CI checks a clean review approves as before. The reviewer is also asked to trace each changed field to the code that reads it, and it reads the repository's MERGE-REVIEW.md when there is one. Cloud coding agents now have the
sqlite3command, and Codex tasks use the model settings Codex ships for GPT-5.6 Sol, Terra and Luna, GPT-5.5 and GPT-5.4 instead of fallback metadata. - foxl.ai, docs.foxl.ai and the Foxl Code private beta page now say that Foxl Code is in private beta for invited accounts and that you can ask for access at support@foxl.ai, instead of offering to join a waitlist or saying you will be notified. The code.foxl.ai sign-in page now says it is a private beta before you sign in. foxl.ai's "Try in Browser" link is now "Open in browser", with a line saying the browser version needs Foxl Desktop running on your computer.
- When a GPT-5.4, GPT-5.5 or GPT-5.6 reply searches the web through Foxl's servers with Amazon Bedrock Web Search, which Foxl Code's Codex tasks can do, each search is now charged to your credits at AWS's price of $0.012 per search (a third of a credit), on the same usage line as the reply. Opening a page from the results is not charged. These searches used to go uncharged.
- Notifications for finished and failed agent runs and schedules, a schedule paused after repeated failures, and a Slack, Telegram or Discord reply that could not be sent now appear in the app's language: in the desktop app's bell and banner, and in app.foxl.ai's bell and browser notification. So do the Skills install result, the Delete action on Tasks, the Open and Dismiss buttons on macOS notifications, the Mac's "Foxl Code needs your answer" notification and its reply field, and the push-device count in Foxl Code settings. The iPhone app's notification list follows from its next build. Phone lock-screen pushes stay in English, and an error message inside a notification is shown as the service wrote it.
- In Foxl Code, a Claude Code terminal session in the cloud on a private repository keeps your uncommitted changes when its machine is recycled. While the session is open, they are saved to your repository every two minutes (as a ref, not a branch, so no pull request is opened; a file over 10 MB is left out), and reconnecting puts them back, uncommitted, with a line in the terminal saying so. They used to be lost when the machine went away before the session ended. On a public repository nothing is saved this way, and the terminal shows one line saying uncommitted changes are lost if its machine is replaced.
- In Foxl Code, a task started from an issue written by the repository's owner, a member of its organization or a collaborator now gets the issue as its specification, followed by the newest comments those people left on it (up to 10, each with who wrote it and when). The coding agent used to be told the issue's text was not an instruction, and never saw its comments. An issue from anyone else, including one Foxl's own app opened, is still passed on as untrusted text, and comments from anyone else are left out. The task view shows the issue and those comments without the wrapping the agent receives. The notes Foxl Code keeps about a repository now say when they were last updated, are left out once they are more than 30 days old, and no longer pass on what the task queue looked like the day they were written. Past-failure notes that only link to a red CI run are left out as well.
Changes
- On iPhone, the message bar sits just above the tab bar instead of floating well above it, and lists and pages end at the tab bar instead of leaving an empty strip above it.
- On phones, chat messages use more of the screen width, and the space between messages is tighter: the hidden Copy / Share / Edit row under a message no longer leaves a gap when it is not showing. Tap a message to show it, as before.
- On phones, the background behind a sheet or dialog is dimmed less, closer to how iOS presents sheets.
- On phones, the Settings list draws its dividers from the label instead of under the icons, and Notes shows Add context and Import a recording as one grouped list.
- With OpenRouter, Foxl's chat and Notes requests now name the app as Foxl (https://foxl.ai), so OpenRouter can count that use toward Foxl on its app pages and rankings, listed under personal agent and general chat. Only the app's name and web address are sent, the same on every computer, and nothing about you or your account.
- Settings > Safety now says why "Auto-approve all tools" is on for a new install and what that costs. It is on so scheduled runs, runs from your phone and channel messages never wait on a prompt nobody is there to answer; while it is on, anything the agent reads - a web page, a file, a message - can lead it to run a shell command without asking you. Turning it off makes shell commands, file writes and other risky tools ask first. The default itself and your current setting are unchanged.
- On a new installation of the desktop app on Windows, Foxl no longer sets itself to start when you sign in before you have seen that choice. The first setup screen now shows Start Foxl when I sign in, turned on, and Foxl is added to your sign-in apps when you leave setup with it on. You can turn it off there or later in Settings. Existing installations keep their current setting.
- On the desktop, a chat shows its running subagents in a bar attached to the top of the message box: how many are running, what the newest one is doing and for how long. Click it to see each subagent on one steady line with its task and time, open one, or stop it, or stop all of them at once when two or more are running. Their tool calls no longer appear in the chat itself.
- The answer a chat writes from its subagents' results now sits under a divider saying how many subagents it is from, and how many failed or were stopped. It is written in the language of the chat. Regenerating that answer rewrites only the summary, from the same results, instead of running every subagent again.
- You can talk to a subagent from its own screen. A running one reads your message right after the step it is on, and a finished or stopped one picks up where it left off, with everything it already did and with its own tools, and its new answer comes back to the chat like the first one. This works for the newest 100 subagents of the last 7 days, also after Foxl restarts, but not for one that was still running when Foxl quit. Deleting the chat deletes what was kept for this.
- The agent can do the same: it can correct a running subagent or ask a finished one for a follow-up instead of starting a new one that redoes the work.
- A subagent that still has a sibling running can send it a short message, at most 10 per run, when it finds something the other needs. The read-only researcher and code-reviewer types cannot.
- A subagent now starts with a fresh context: it gets the task the agent writes for it instead of a copy of the whole chat, so in a long chat the work it does costs a fraction of what it did. A new built-in fork type starts from a copy of the conversation, and the agent picks it when a task depends on what was said. A general-purpose subagent whose prompt, tools and model were never changed moves to the fresh default once; one with your own prompt, tools or model keeps your setting.
- A subagent's screen shows what it wrote between its steps, in order, instead of only the tools it ran.
- Switching between chats keeps your place in each one: going back to a chat opens it exactly where you had scrolled to, and a chat you were reading at the bottom opens at the bottom. It appears there at once instead of scrolling down to the last message.
- Cmd+Shift+F (Ctrl+Shift+F) also finds your Foxl Notes, from any product: the search shows a Notes group that matches a note's title, what is written in it and its transcript, and picking one opens it in Notes. On the macOS desktop, where the shortcut goes to the search field in the title bar, notes could not be searched from there at all before. The filter menu has a Notes switch, and Notes' own search now also finds a note by what you typed into it.
Fixes
- Opening a search result from another chat lands on the matching message even when that chat takes a moment to load. On a slow connection it used to open at the bottom instead.
- A chat that started several subagents answers once, when the last of them finishes. If your own message ended while some were still running, the chat used to answer with only the results that were ready and then answer again later with the rest.
- Pressing Stop in a chat no longer lets an answer from subagents that had already finished start right after it.
- A subagent that was running when Foxl last quit no longer shows as running forever in the sidebar.
- On a subagent's screen, a long step such as a search for a long pattern ends in an ellipsis, as in the chat, instead of widening the page and adding a sideways scrollbar.
- A subagent that starts fresh now gets its task as the agent wrote it, without the instructions meant for a subagent that copies the chat. It used to read those on every step, about a conversation it never saw, and could spend its first step working out what they meant.
- Attaching a file to a chat right after a reply that used tools no longer fails with "tool_use ids were found without tool_result blocks", and a conversation that hit that error no longer repeats it on every later message.
- Attaching a file with the same name as one attached earlier in the conversation no longer fails; the later copy is numbered (for example
notes 2.txt). Files attached earlier stay readable when you attach another, up to the five most recent; an older one is left out with a note so the model can ask for it again. As before, earlier files drop out of the model's view after a restart or a model switch. - A conversation reopened after a restart or a model switch now keeps the order its replies were written in: text a reply wrote after running tools is no longer replayed as if it came before them.
- A conversation with an image in it no longer fails on every later message on a model that cannot view images, for example after switching to one, or after an OpenRouter model refused the image; the model is told an image was there instead.
- Text files (txt, md, csv, html, json, xml) now attach on ChatGPT sign-in and on OpenAI-compatible providers such as OpenRouter: the file's text goes into the message. Before, ChatGPT refused every text file, and OpenRouter's free models asked for a paid balance to read one.
- When a model refuses an attachment (for example "This model doesn't support documents"), the next message in the conversation works again instead of failing with the same error.
- Retrying or editing a message that had a file attached, after the conversation was reopened, no longer sends it without the file. Foxl asks you to send it as a new message and attach the file again, because attached files are not kept with the conversation.
- With OpenRouter, the model list now shows each model's own name instead of its id, and Foxl reads from OpenRouter which models take tools: a model that takes none, such as NVIDIA Nemotron 3.5 Content Safety, is now chatted with without them, instead of failing every message with "No endpoints found that support tool use".
- With OpenRouter, an image a tool opens for the agent (for example with
view_image) now reaches a model that can see images. Before, every OpenRouter model was sent a note saying the image was left out and to switch to a vision-capable model, even when it was one. A model that cannot see images still gets that note, and so do the other OpenAI-compatible providers until each is checked. - With OpenRouter, reasoning models now show their reasoning in the chat as it streams, and the Reasoning switch and effort levels appear for them in the model picker, offering the levels OpenRouter lists for each model. Until you change Reasoning, every model keeps OpenRouter's own default and each message is sent exactly as before, and the picker shows that default. Once you turn Reasoning on or off or pick a level, your setting is sent with every message: Off turns reasoning off, and the level sent is the one the picker shows. If you had already changed Reasoning, for example for Amazon Bedrock, that setting now applies to OpenRouter models too. Short helper requests such as Notes summaries and titles ask for no reasoning, so a 100-token Notes answer is no longer cut off by reasoning you never see.
- With OpenRouter, Refuse providers that train on your data now applies to Foxl Notes too. Notes summaries, titles, live translation and Flow cleanup used to be sent without it, so a provider that trains on requests could answer them. Maximum reply length for an OpenAI-compatible provider now also limits Notes, Foxl Code chat on this computer, subagents and the Notes assistant, not only chat: a Notes summary used to ask for up to 32,000 tokens whatever you set, which OpenRouter refuses when your balance cannot cover it.
- With an OpenAI-compatible provider such as OpenRouter, Foxl now sizes each model by the context window the provider states for it, instead of treating every model as 200K. A long conversation on a 1M-token model is no longer summarized at 180K, and a 32K model is summarized before a request would overflow it.
- With OpenRouter, each reply now records its token usage and the cost OpenRouter reports, so the Usage page, the reply's cost and the context meter include OpenRouter turns.
- Claude models used through OpenRouter now mark Foxl's instructions for prompt caching, which OpenRouter needs before it caches a Claude request. Before, every step of every answer paid full price for the same instructions again. In a direct test of this request shape, the repeated call cost about a tenth as much. Every other OpenRouter model is sent exactly as before.
- A PDF attached in an OpenRouter chat on a free (
:free) model is no longer charged for OpenRouter's paid PDF reader. It was the only charge on a model the picker lists as free, and it ran again on every later message in the conversation, because each message sends the conversation's files again; Foxl now asks for OpenRouter's free PDF converter on those models. That converter reads only a PDF's text, so a scanned PDF comes through empty on a free model; paid models keep OpenRouter's reader, which handles scans. - When an OpenAI-compatible provider such as OpenRouter answers a Foxl Flow cleanup or a Notes reply suggestion with an error instead of a reply (for example, a busy free model), Foxl now treats it as a failure and the desktop log names the provider's reason. Before, it was treated as an empty answer. Flow still pastes your words as you said them, and reply suggestions still skip that card. A cleanup the provider cut off with an error is no longer pasted as if it were complete.
- The provider and model you pick for Foxl Agent stay picked after Foxl restarts. An update, a crash, a reboot or the background server restarting used to put the agent back on Amazon Bedrock with Claude Opus 5.5 until a window sent your choice again, or, if you were not signed in, until your next chat. With OpenRouter or another provider chosen, scheduled tasks and other work that runs without a chat open went to Bedrock in the meantime, or failed with "Could not load credentials" on a computer without AWS credentials, and three failures in a row paused a schedule. A choice you made before this version is saved the first time a Foxl window opens after the update. If the saved choice names a provider this version does not have, or the Foxl relay after you signed out, Foxl starts on Amazon Bedrock as before. A saved provider whose key or sign-in has since gone stays selected, and its scheduled runs say what is missing.
- Foxl Notes no longer defaults to Amazon Transcribe on a desktop without AWS credentials it can sign with. A new Automatic transcription setting picks Amazon Transcribe when this computer has AWS credentials (unchanged for everyone who records with it today), otherwise the on-device engine once you have installed it, and otherwise says plainly that transcription is not set up, before the microphone opens, with the Install engine button on Apple Silicon. A provider with your own API key stays something you choose. The live-translation, auto-title and reply-suggestion models now default to Automatic and Settings names the model that actually runs (Claude Haiku 4.5 where a provider on this computer serves it, otherwise Foxl Agent's own model); Dictate anywhere's settings say when there are no AWS credentials, and reply suggestions get their own model row.
- The Windows installer no longer closes a running Foxl the moment it opens. Foxl keeps running while you go through the installer's pages, and if you cancel; it is closed only once you click Install. When Foxl is installed just for you, the installer asks first. When an earlier version is installed for all users, and for an automatic update, Foxl is closed without asking.
- Clicking or double-clicking the Foxl icon in the Windows system tray now opens the Foxl window, so a window you closed comes back without going through the right-click menu. On Linux the window opens on a click wherever the desktop reports one to the app. On macOS a click on the menu bar icon still opens its menu.
- A desktop window narrower than 640 pixels (the smallest window on Windows, a half-screen snap on many laptops, or zooming in) no longer shows the sidebar and the bottom tab bar at the same time. It now uses the same narrow layout as app.foxl.ai at that width: the bottom tab bar, with the sidebar one click away behind the sidebar button. Wider windows keep the docked sidebar.
- Settings > Dictate anywhere on Windows and Linux now shows the shortcut that starts and stops dictation (Control+Alt+D unless you change it) instead of opening on "Hold a key while speaking" with an Fn key picker and an orange "Hold-to-talk is macOS-only" warning. Holding a key to talk needs macOS, so on these systems the shortcut was already what worked; the screen now says so. A hold setting you saved earlier is kept, and macOS still defaults to holding Fn.
- On Windows and Linux, Ctrl+R and Ctrl+Shift+R no longer reload the whole app, so pressing Ctrl+R while typing a message leaves the window as it is. View > Reload is still in the menu, now without a shortcut. In the terminal Ctrl+R still goes to the shell. On macOS Cmd+R is unchanged.
- On Windows and Linux, Foxl now uses that platform's wording where it used macOS wording: Settings > General says "Show in system tray" instead of "Show in menu bar", Appearance offers Ctrl+Enter instead of Cmd+Enter and names the platform's own cursor convention, and the Notes search and composer formatting tooltips show Ctrl shortcuts. The Files menus' "Open in Finder" item now reads "Show in File Explorer" on Windows and "Open containing folder" on Linux, and Foxl Code's This computer row names Ctrl+T, the shortcut Runtimes uses there. On Linux, the titlebar search uses the same wording. On Windows, Notes > Recording describes system-audio capture without "this Mac" or a macOS permission, and its no-system-audio warning no longer points at macOS System Settings. macOS text is unchanged.
- Before you connect a model provider, the model button in the chat, Quick Chat and Notes composers now reads "Opus 5.5" instead of the raw model id "claude-opus-5-5". Other Claude models chosen before a provider is connected are named the same way.
- On Windows, Foxl now runs under the same app identity as its Start menu shortcut, which is the identity Windows shows notifications for and uses to group a pinned Foxl with its open window. Before, the two did not match. Launch at login is now registered under that identity too, and the startup entry earlier versions created is removed (again if an earlier version is reinstalled and adds it back), so Foxl does not start twice when you sign in.
- A mistyped or outdated foxl.ai link now opens foxl.ai's own "page not found" page, with the site menu and links back to the home page, the changelog and the docs. Before, the page came back empty and the browser showed its own error screen instead.
- Right-clicking selected text in a text field, such as the chat message box, no longer lists Copy twice. Selected text elsewhere, such as a chat reply, still offers Copy.
- The first-visit Notes walkthrough now draws a complete highlight ring around the Background tab and the recordings list. Both rings used to be cut off at the edges, so the one around Background read as "( Background )".
- On Linux, the File / Edit / View / Window / Help menu bar no longer takes a row at the top of the Foxl window, where it also stayed light in dark mode. Press Alt to show it; keyboard shortcuts such as Ctrl+Q work whether it is shown or not.
- Foxl Notes on Linux no longer offers "Capture system audio" or its test, because the Linux app cannot capture system audio. Settings > Recording now says that the Linux app records your microphone only, and a recording on Linux no longer requests a screen capture or warns that system audio is unavailable. Live translation still translates what your microphone hears.
- Choosing View > Foxl Code (Ctrl+3, or Cmd+3 on a Mac) while signed out now stays on the current screen and shows "Sign in to use Foxl Code" with a Sign in button, instead of switching to Agent chat without a word. An account still waiting for Foxl Code's private beta is told that instead.
- On Linux, closing the window with the tray icon turned off now quits Foxl instead of leaving it running with no window, and Settings says so. With the tray icon on, closing still keeps Foxl running, and the first time it does, a notification says so and how to get back to it.
- On Windows and Linux the menu bar and the tray icon's menu now follow the app's language, for example Korean when Foxl is set to Korean, and the Window menu no longer lists Zoom, a macOS item that did nothing there. Right after a fresh install the menus are English until the Foxl window has loaded once. On macOS the menus are unchanged.
- The Files search field shows "Search files" in full instead of "Search file", and typing in it shows one clear button instead of two that covered the last letter you typed. The same goes for the Settings search field, and in languages whose wording is longer than the field, the placeholder now ends with an ellipsis instead of being cut mid-letter. In Notes, the "Finish setting up Notes" card now wraps the long AWS setting names inside the card instead of running into its edge.
- When a chat message fails, Foxl's own wording now appears in the language you chose for the app, in Foxl Agent, Quick Chat and Foxl Code chats: the suggestion about what to do next, such as "No model provider is connected yet...", and Foxl's own failure messages, such as "You're offline", a reply that stopped before it finished, or chat being unavailable while your desktop is unreachable. The provider's or server's own error text is still included unchanged, so you can copy it into a bug report.
- When a desktop chat on your own OpenRouter key, or another OpenAI-compatible provider's, fails, the suggestion now names that provider instead of Foxl: a refused key says to check it under Settings > Model & provider (it used to say your Foxl session had expired), a balance too low for the request points to the provider's credits and the maximum reply length instead of Foxl's Account page, and a rate limit is described as the provider's. When OpenRouter says the model's host refused the request, the host's name and its own reason now appear in the error, and Foxl no longer makes five attempts at a request that OpenRouter refused for its daily limit on free models, as if it were a passing rate limit. Account under the OpenRouter options also shows the account's credits and today's free-model requests.
- On the app.foxl.ai and code.foxl.ai sign-in pages, the analytics cookie notice now sits at the very top of the page instead of below an empty band, and on code.foxl.ai at desktop width it spans the page instead of being squeezed into the sign-in half. Once you are signed in it stays where it was, below the header and beside the sidebar.
- A terminal tab now shows the shell's name instead of the start of its file path: on Windows the default terminal is titled "PowerShell" (or "PowerShell 7" when PowerShell 7 is installed), where it read "C:\Windows\Sys...", and a terminal running Command Prompt, WSL or Git Bash is titled "Command Prompt", "WSL" or "bash". Hover a tab to see the full path. A terminal restored from an earlier version shows the same name. macOS and Linux tab names are unchanged.
- When Dictate anywhere cannot start, its pill now says why for five seconds instead of vanishing almost at once with no message. With transcription not set up (for example Amazon Transcribe selected and no AWS credentials on the computer) it reads "Transcription is not set up · open Settings > Dictate anywhere"; a microphone that will not open and a connection Amazon refuses each get their own line, the second saying what was refused in a few words (for example "Your AWS credentials can't use Amazon Transcribe") and never showing the AWS account number or role that Amazon's own message names. The pill also no longer draws a white rectangle around itself in the light appearance on computers without the macOS window glass effect, such as Windows and Linux.
- When Amazon Transcribe refuses voice input in a chat composer (Foxl Agent, Quick Chat and Foxl Code) or a Foxl Notes recording, the error now says what was refused in a few words, for example "Your AWS credentials can't use Amazon Transcribe", instead of Amazon's own message, which showed the AWS account number and the role or user it was checking. Any other refusal or start-failure message on these surfaces has AWS account numbers, ARNs and access key ids removed.
- docs.foxl.ai now draws the same slim scrollbar as foxl.ai, in light and dark, instead of the wide grey scrollbar with arrow buttons that Chrome and Edge show on Linux and Windows.
- On Windows, the tray menu's recent chats and usage are now refreshed every minute while the tray icon is shown, so the menu is at most a minute old when you open it. Before, it could keep showing what it had when the icon appeared. macOS and Linux are unchanged.
- Notes and Settings now look for AWS credentials the same way Amazon Bedrock chat and Notes transcription do. On a computer whose only AWS credential is outside ~/.aws (for example a credential_process in a custom AWS config file, or an EC2 instance role), Notes no longer says "No AWS credentials found" or calls its summary model unconfigured. Foxl remembers the answer for a few minutes and asks again when you press Check again. With no credentials at all, Notes still shows its setup card.
- On Windows and Linux, the tray icon is now drawn from images made for tray sizes. Before, it was the app icon with its white tile, shrunk to 14 pixels and then scaled up, which looked blurry on high-resolution displays. On Windows it is the Foxl mark on a transparent background, in a light or dark version picked from "Choose your default Windows mode" when Foxl starts, and Foxl checks that setting again every minute and when the PC wakes or unlocks. On Linux, GNOME and Ubuntu, whose top bar is dark, get the white version of the mark; other desktops get the mark on a light rounded tile, which stays visible on both light and dark panels. macOS is unchanged.
- Stopping one subagent, from the sidebar, from the new bar or by the agent itself, no longer sends its unfinished output into the chat's summary as though it had finished. The other subagents' results still arrive, and the summary says which ones you stopped instead of saying their results are still coming.
- Foxl runs at most five subagents at once across all chats, as documented. Before, a sixth could start.
- A subagent's screen shows its messages and steps in the order they happened. Two that happened in the same millisecond could appear swapped.
- A chat that hands work to subagents no longer answers the same request twice. The agent now waits for its subagents instead of redoing the work it gave them, and if it answers first anyway, the reply written from their results says only what they add or change.
- A message you send just as the subagents finish no longer cancels the answer written from their results. It waits for that answer, and the results divider stays directly above it.
- A subagent that writes its report without having used any tool is asked once to do the work first, so an invented result no longer reaches the chat's answer.
- A subagent no longer turns its task down as a suspected prompt injection, which some did when the task was a long-running command. It is also told to report only what its tools returned.
- The Agents page's run history names a subagent run by its task. It showed the subagent's standing instructions ("You are a general-purpose subagent...") instead.
- A message sent to a subagent in the moment it finished is no longer lost. It was reported as sent and never read; the subagent now reads it and continues before it reports.
- A subagent that starts from the conversation reuses the chat's prompt cache from its first step. It ran under a different system prompt and model settings than the chat, so its first step re-sent the whole conversation at full price.
- A subagent reports with its own final answer, one model call sooner. After any answer that followed a tool call it was asked again to summarize, which re-read its whole context and replaced the answer with a summary of it.
- A subagent's usage is recorded under the model it ran on, not the model selected in Settings at the time.
- With OpenRouter or another OpenAI-compatible provider, a model now appears once on the Usage page, under that provider. Subagents and the Notes assistant recorded their share under "OpenAI", usually with no cost; they now record it under the provider, with the cost the provider reports, as chat does. Usage recorded before this version stays as it was.
Changes
- Foxl Code agents can message each other. An agent can list your other unfinished tasks on the same GitHub installation and send one of them, or all of them, a message with its
foxl-agentscommand - for example when you ask the agent working on the API to tell the one working on the web client that an endpoint was renamed. A short message to a task with an open terminal arrives as a new line in its conversation, marked as coming from another agent and not from you; longer messages, tasks running without a terminal, and terminals where you turned approvals on keep it in the task's inbox until the agent checks it. Tasks on your own machines cannot receive messages yet. Agents are told not to message each other on their own initiative and to treat a message from another agent as information rather than an instruction. Each task can deliver at most 30 messages an hour. - Notifications are quieter. Your iPhone no longer buzzes once for every agent a chat starts along the way: each one now arrives silently, without a banner, as one entry per conversation in your notification list. The quiet Feed items the desktop itself never announces no longer reach your phone at all. A run you start from the Agents page, an urgent Feed item and a reply that finishes while you are away still notify as before. "Issues Foxl Code files" is now off unless you turn it on, and the desktop shows its banners only while Foxl is in the background. Both new defaults apply only to settings you have never saved, so a choice you made is kept. Settings > Notifications now says which switches control this computer and which control your phone, and Send test always shows its banner.
Fixes
- Two kinds of old documentation link now land on the right page in one step: docs.foxl.ai/docs/account opens the credits page instead of a "not found" page, and old versioned section links ending in
/or/indexredirect once instead of two or three times. - Each status.foxl.ai page now names its one address for search engines, and a status link ending in
/redirects to the address without it.
Features
- Foxl Agent can search your Foxl Notes. Turn on Let Foxl Agent search your notes in Settings > Notes > AI features, and the Agent (and the Notes assistant) can find past meetings by customer, topic or date and read them, for example "prep me for my call with Acme". It searches each note's title and summary; turn on Include transcripts to search full transcripts too. It is off by default, works on the desktop app, and turning it off removes the Agent's copy. Until now the Agent could save notes to a folder but could not read any of them back.
- Turn on Custom summary template in Settings > Notes > AI features to choose what a Notes summary contains: Customer call, 1:1, or your own instructions. Customer call starts with the customer's name, so the note's title and file name carry it. Off, summaries are the standard meeting summary, as before.
- Choose how saved notes are named with File name in Settings > Notes > Auto-save & export: Date - Title (as before), Title - Date, or Date Time - Title. Or turn on Name files with AI and describe the name in your own words, for example "customer name, then the topic, then the date": AI names each automatically saved file from the note. It is off by default, and the File name setting is used whenever AI is unavailable.
Changes
- The foxl.ai footer now links to the status page, status.foxl.ai, in its bottom row.
- The Foxl-credit price of Claude Opus 5.5, Opus 5, Opus 4.8, Opus 4.7, Opus 4.6, Fable 5, Sonnet 4.6 and Haiku 4.5 rises 10%, to match what Amazon Bedrock charges for the US-region inference profiles Foxl runs them on. Every token type moves together: Opus 5.5's base rate, before Foxl's margin, is now $4.40 / $22 per million input / output tokens instead of $4 / $20. Sonnet 5.5, Sonnet 5 and Fable 5.1 keep their prices.
- foxl.ai/brand publishes the Foxl brand kit: the logo in color, flat, reversed, white and black, the stacked lockup, the mark, the wordmark, the Foxl Notes and Foxl Code lockups, app icons, social images and the color palette as SVG and PNG, with a guidelines PDF and a single ZIP download. The footer links to it under Resources.
Fixes
- Keep running when closed now refuses to start from a folder another account on the computer could change, on Windows and Mac as well as Linux. A background service already set up in such a folder (for example a Windows copy unpacked into a folder directly under
C:\) is turned off the next time Foxl opens, and Settings says why. Opening Foxl on a Mac from its disk image or straight from its download no longer moves the background service onto that temporary copy; the service stays on the copy in Applications. - On iPhone and Android, a link that opens Foxl to record now asks before it turns the microphone on. The New Recording shortcut on the iPhone home screen still starts recording straight away.
- On iPhone, a page shown inside a chat or file preview can no longer stop a live Notes recording or use the app's native features. Only the app itself can.
- The iPhone and Android apps now refuse to run scripts that are not part of the app, the same protection app.foxl.ai already had. Chat and file previews keep working.
- The email Foxl sends when you have used 80% or all of your credits is tried again on your next request when the mail service refused it or the connection dropped. Before, that failed attempt used up the period's one email, so it never arrived.
- When several people join a channel huddle at the same moment, all of them now appear in the call. One join could save over another, leaving a member who had joined off the participant list that every device shows.
- Foxl Code's autonomous loop now notices activity on a new task. It woke only when the highest activity number across all your tasks went up, and every task numbers its activity from 1, so once an earlier task had logged six events, a new task's first six went unnoticed and the loop treated it as idle. It now keeps track of each task separately.
- On the desktop, when Foxl cannot open its Notes folder (for example after a restore or a sync tool changed its permissions), the Notes list now says so, names the folder and gives the reason, instead of showing an empty list as if there were no notes. Nothing is deleted, and the notes are listed again the next time Foxl opens once the folder can be read.
- On an OpenAI-compatible provider (OpenRouter, DeepSeek, Groq and the other compatible vendors), Ollama, or an OpenAI key, a reply that calls several tools at once now runs every one of them. Before, only the last call of such a reply ran, and the model lost the sentence it had written before its tool calls from its own history.
- Deleting a channel message now removes only the files attached to it in that channel. Before, a workspace member could remove a file they had uploaded anywhere in the workspace, including a folder they can only view, by naming it in a message and then deleting the message, and the deletion did not appear in the workspace audit log.
- Settings > Shortcuts is now on code.foxl.ai, and stays on app.foxl.ai in a desktop browser while your Foxl desktop is off; before, it appeared there only while a desktop was connected. On code.foxl.ai it lists the Foxl Code shortcuts only.
- When the checks on a Foxl Code task's pull request fail while the task is still running (after Reconnect or Fix it, for example), its agent is now told if its terminal can take input, as it already was for a task in review, and you get the "Checks failed" notification. Before, both happened only for a task in review, and the same failure was not reported later. The notification now also comes for a task that failed with its pull request still open, and a reviewer's requested changes now reach a running agent too. A Terminal pane running a plain shell is no longer typed into.
- With tool approvals turned on, the prompt for a shell command now shows the folder it runs in and any environment variables the agent set for that one command, and marks the ones that can change which program runs (such as
PATHor git's settings). A variable that holds a password, token or key shows its name only. Before, it showed only the command text, although those variables can make an ordinary-lookinggit statusrun something else. The approval card also shows up to 4,000 characters of a long command, and says so when it is longer, instead of silently cutting it at 200; and for other tools it lists the call's arguments (for example which file a write would replace) instead of only the tool's name. - A Foxl Code task running on this computer no longer reports typed input or a new instruction as delivered while its coding agent is working. Those agents start from their prompt and do not read their terminal, so the task's terminal now says the input was not delivered, and the orchestrator tells you to send it as a follow-up once the run finishes. Ctrl-C typed into that terminal is refused the same way; Stop ends the run. This matches what cloud tasks started from a prompt already do.
- The Foxl Code Backlog, the Files page (folder lists, preview, download and save) and the display-name save on Usage now word a failed request the way the other Foxl Code screens do: the server's explanation where it gave one, otherwise a sentence in your language. Declining an issue an agent is still working on showed the bare code
task_in_flightinstead of the explanation, a server error showed the raw request (such asGET /api/tasks/...followed by the response), and a dropped connection showed the browser's English "Failed to fetch". - With tool approvals turned on (auto-approve off), image generation now asks before it saves the image to a location the agent chose, the same way writing a file does, because it replaced whatever file was there. It also asks before it sends a credential file (for example an SSH key or Foxl's own sign-in file) to the image model as a picture to edit. An image saved to the default
generatedfolder is still made without asking. - A Foxl Code Terminal pane (a plain shell) on Remote can now be reconnected when your default assistant in Settings is not Claude Code. With Codex or Kiro as the default the reconnect was refused, and with Cursor, Hermes or OpenCode the pane said those assistants cannot be reconnected, so once its cloud machine had stopped the only way back was a new pane. A shell pane you come back to also shows the terminal icon in its header rather than your assistant's.
- A sign-in link that the Foxl phone app, or the Foxl desktop app from version 0.7.28, asked for can now only be completed in that app. Someone who got hold of the link from your email before you opened it could exchange it for a session on another device through a side route, and that also used up the link, so your own click then failed.
- On iPhone, the "Update available" prompt no longer appears when your phone's region is one where the App Store does not offer Foxl (the European Union and China). There it opened a listing the App Store said was not available in your country or region. The prompt still goes by the phone's region setting, not by your App Store account's country.
- On Claude Code (Pro/Max), a model your plan does not include now shows "Usage credits are required for this model" at once. Before, the request was retried five times first, as if it were rate limited. When a conversation grows past what the plan serves without usage credits, Foxl now compacts it and the turn continues, where before it retried the same oversized request.
- Foxl Code on this computer no longer stalls the desktop while it looks up your GitHub sign-in. On a computer with no saved GitHub credential, it also stops asking again on every chat message. Before, each message could freeze chats, terminals and the phone connection for as long as the lookup took, and a credential manager's sign-in window could come back every time.
- In Foxl Code's Settings and Autonomy card, a number field can now be cleared to type a new value. The daily spending cap, the per-task spending ceiling, the timer, Agents per turn and the survey interval put their default back the moment the field was empty, so the new digits were added to it: clearing a $500 daily cap and typing 20 saved $1000 (the most the cap allows) while the field read 50020, and clearing 3 agents per turn and typing 5 allowed 15. Each field now takes its value when you leave it or save; an empty field means the default, and a number outside the allowed range shows the nearest allowed value before it is saved.
- A long conversation on Foxl credits, a Foxl Code session included, is no longer refused with "Credits exhausted or insufficient for this request" because the credits set aside for it exceed what any request can cost. A Claude model bills at most its context window of input, so on the 1M-token models the amount set aside now stops at what a full 1M-token request costs (about 153 credits on Claude Opus 5.5), where a 2.5 MB conversation used to need about 346. A balance below that is still refused. When the desktop app's own Foxl-credits chat is refused this way, it now compresses the conversation once and tries again instead of stopping.
- Foxl Flow's warm-up, sent when you press the dictation key, now works when your model is a GPT model on Amazon Bedrock. It asked for a 1-token reply, which Bedrock's OpenAI Responses endpoint refuses below 16, so each press failed in the background and wrote an error to the desktop log. The warm-up now asks for 16, and the Notes model route and the Notes relay client raise any smaller request to 16.
- The Channels list now keeps the conversations with the newest messages. A Telegram or Signal chat you use every day no longer disappears from it once 300 newer Slack threads have been started. A deleted conversation no longer takes one of those places either.
- Remote access to the desktop (from app.foxl.ai or the phone app) no longer runs a captured command or request a second time when Foxl's relay replays the browser's handshake. The relay could re-send a captured encrypted keystroke or request after announcing that the browser had disconnected, or under another browser's name, and the desktop accepted it again. The desktop now refuses both, and nothing changes for the browsers and phones you already have.
- Opus 5.5 and Sonnet 5.5, whose reasoning cannot be turned off, now run at the effort the model picker shows even when reasoning was switched off on another model. This applies on Amazon Bedrock, an Anthropic key, Claude Code (Pro/Max) and Foxl credits, and Grok 4.7 and GPT-6 Astra on Foxl credits now do the same. Before, no effort was sent and the model ran at the vendor's default, which is high for Sonnet 5.5.
- On app.foxl.ai and the phone apps, a message typed with no connection and handed to your desktop when it reconnects is no longer sent a second time if you open another chat while it is being delivered. It also no longer joins a new chat you start at that moment as a follow-up there; it waits and goes into a chat of its own the next time you open a new chat.
- A Foxl Code task that runs on this computer now ends as failed when its coding assistant is stopped by the task's time limit or killed (for example by the system running out of memory). It was reported as ready for review with exit code 0, so the agent that started it was told the work had finished cleanly. The exit code now shows the signal (137 for a forced kill), as cloud tasks already did. A machine you connected does the same once it runs machine agent 0.3.1, which its row on the Machines page offers.
- A correction to v0.7.0's note on encrypted meeting notes, for iPhone. v0.7.0 said Notes recordings on iPhone and Android are now encrypted so that a device backup no longer lets anyone read every meeting. That holds on Android, whose backups leave Notes out entirely. On iPhone it does not: an iCloud backup, or a Finder backup that is not encrypted, also holds the key that opens the transcripts and AI summaries, and the meeting audio itself as plain files. This is deliberate, so that restoring a backup onto a new iPhone keeps your notes readable, and nothing in the app changed. Chat history kept on the iPhone is stored the same way.
- The privacy policy now covers Channels, DMs and shared folders. It says where messages and shared files are kept (Foxl's database on Cloudflare for text, Amazon S3 in US West (Oregon) for files) and how long they stay: messages and files until they are deleted. It also says that deleting your account does not remove messages you posted or files you shared into a team space, or the workspace's audit and billing records, and that the data export does not include them. The policy used to say account deletion removes every record keyed to your account. The security page in the docs says the same.
- Foxl Notes no longer shows "Something went wrong" (
Token with "taskList" type was not found) when an AI summary includes a checklist of action items. The summary now appears, is saved with the note, and is written to the auto-save folder; before, the error also stopped both saves. - Foxl Notes: action items in an AI summary (
- [ ]) now appear as checkboxes in the note, ticked or not, instead of plain bullets that lost their checkbox on the next save. - Foxl Notes on Windows: a note whose title contains
?,",*,<,>or|(common when the title comes from the summary, like "Should we ship in Q3?") is now saved to the auto-save folder. Those characters are left out of the file name (a|becomes-); other titles keep their file name, and macOS and Linux file names are unchanged. - Foxl Notes: Save as now says so when the file could not be written (for example, the file is open in Word), instead of doing nothing. If a summary arrives but cannot be saved, Notes now shows an error instead of failing silently.
- Foxl Agent: a chat no longer shows "Something went wrong" every time it is opened after the agent started a subagent with a number as its label.
- Foxl Agent on Windows: AWS SSO sign-in now finds the AWS CLI. It used to always report the CLI as not installed.
- Foxl Agent on Windows: workspace files saved with Windows line endings (such as
USER.mdandHEARTBEAT.md) are read correctly, so their settings are no longer ignored and saving from Settings no longer adds a second header. Writing a file whose name contains:is refused with a clear message, instead of producing an empty file under a cut-off name. - Deleting your account now needs proof that the request comes from your own signed-in session, not only a copy of its access token. The Account page in app.foxl.ai and in Foxl 0.7.29 and later sends that proof for you, so nothing changes there. In an older app, deleting more than ten minutes after signing in shows "Could not delete your account"; sign out, sign in again and delete within ten minutes, or update the app first.
- Turning off Auto-save in Foxl Notes settings now stops notes being saved to the folder automatically. The switch had no effect.
Changes
- status.foxl.ai now looks like foxl.ai: the same Geist typeface, colours, buttons and cards, in light and dark, and on a wide screen it uses two columns so the whole board fits on far less scrolling. Hovering or tapping a day in any uptime bar shows its details at once (the date, roughly how long checks failed, the average response time and any incident that day) instead of after the browser's one-second delay, and it works on phones too. An incident still in progress is now listed under its day in Past incidents instead of that day reading "No incidents reported", and today's bar shows the current status until the day's first check finishes instead of a grey "no data".
- When AI inference has a problem, status.foxl.ai says which models are affected and whether it is some of them or all of them. It checks every current model offered on Foxl credits separately, shows "Partial outage" with each model marked failing or working at the latest check, and lists the failing models with their error on the incident page. While a problem is clearing it says the latest check passed instead of "the last check did not pass". Incidents from before this change note that only Claude Haiku 4.5 was checked at the time.
- Cmd-clicking a file path in chat opens it again wherever it is on your computer, such as a project in
~/devor a file on an external drive. Since v0.7.0 Foxl opened files only from your workspace, Documents, Downloads, Desktop and Notes folders and showed "Foxl can only open files in..." for anything else. That limit is gone, in chat and in Notes' "Open file". Foxl still never opens a file that would run, such as a script, an installer or an app. - The Ultrafast switch in the model selector no longer carries a "6x price" note beside it. The tier still costs six times the Standard rate, and usage figures still count those messages at that rate.
- The "What can I help you with today?" greeting on a new chat and on the Foxl Code home, and the Notifications title, are set in the regular weight of the app's typeface instead of a thin one, so they no longer look fainter than the text around them. On a computer or tablet the fox mark above the greeting is gone, since the sidebar already shows it; phones keep it.
Fixes
- The "Explain details" button that appears over text you select in an agent reply sits a little further from the selection, so a double-click that lands slightly off no longer opens it by accident. Near the top of the window it now appears below the selection instead of on top of the selected words.
- A Foxl Code schedule that is waiting because three of its earlier scheduled tasks are still open now retries less often the longer it waits, every 10 minutes at first and at most 2 hours apart, instead of every 10 minutes until one closes. When you merge, cancel or delete one of those tasks, mark it done, or its pull request is merged or closed on GitHub, the schedule tries again within a minute. Waiting schedules had become the largest share of Foxl's daily database writes.
- With a Claude Pro/Max sign-in (Claude Code), your tool approval rules now apply to the agent's shell commands, file reads, searches and web fetches. The agent calls those tools by Claude Code's names (Bash, Read, Grep, WebFetch), and no rule was checked against those names, so every one of them ran without a check: the built-in blocks on commands such as
rm -rf ~, the approval prompt for shell commands when auto-approve is off, the prompt before reading a file that holds credentials, and any rule you wrote for these tools. They now apply exactly as on Amazon Bedrock or an API key. The prompt shows the command it is asking about, and "Always allow" saves the rule under Foxl's own tool name, so it also applies when you switch provider. The tool audit log (audit.jsonl) records these calls under the same names. - With a Claude Pro/Max sign-in (Claude Code), Stop now ends a shell command the agent is running, together with every process it started, as it already did on other providers. Before, Stop (or sending a new message) left the command running until its time limit, 3 minutes by default or longer when the agent asked for more.
- Foxl Code's Fix it now ends once the agent has made its fix. On a task the agent ran on its own (not a terminal you opened), the agent pushed its fix and then waited at its prompt until the task's time limit ran out, 30 minutes by default: the task was then marked failed with Retry offered for work that had shipped, it used compute for the whole wait, and its pull request could not be merged automatically. Now the agent picks up its earlier conversation (when the workspace still has it), works through the fix and stops, and the task goes back to review with its pull request. Fix it on a terminal session still opens the terminal with the instruction typed in, as before.
- Foxl Code chat on a desktop model no longer hands its shell commands Foxl's own credentials. A command it ran (a test script, a repository's
npm test) could read the relay sign-in token, the desktop's connection token and the API keys saved in Settings from its environment, and whatever printed them reached the model and the conversation unredacted. Its commands now get the same environment as the Agent's own shell commands (Foxl's values left out, everything your own shell exports kept), and their output is redacted the same way, while it streams as well as in the final result. - Foxl Code chat's shell commands on the desktop now run with your own shell, PATH and home folder. On Windows they were started with a Unix shell that does not exist there, so every command came back
[exit null]with no output; they now run in cmd.exe, the shell the Agent's own commands use on Windows. On macOS and Linux the PATH was replaced by a fixed list, so programs installed with Homebrew on Apple Silicon, nvm, volta and similar were not found, and the home folder was the repository, so your git and npm settings were ignored; commands now get your PATH, with those install folders added when they are missing, and your real home folder. - A long conversation on Claude Opus 5.5 with a Claude Pro/Max sign-in is no longer summarized once it reaches about 180,000 tokens, a fifth of the model's 1M window. The point where Foxl compresses a conversation now follows the window the context meter shows on a ChatGPT sign-in (272,000 tokens), an Anthropic or OpenAI API key (for example Opus 5.5, Sonnet 5.5 and GPT-6 Sol), and on a Pro/Max sign-in for Opus 5.5 and Opus 4.7, the models measured to accept more than 200,000 tokens there. Every other model on a Pro/Max sign-in still compresses at about 180,000 tokens.
- Scheduled runs, channel replies and subagents on a ChatGPT sign-in now reason at the level the model selector shows, as the chat window already did. "Max" was sent as "high", and with reasoning switched off they sent no setting at all, so GPT-5.6 still reasoned at its default (medium) and used Codex quota.
- Stopping a Foxl Code task that has run for more than about an hour no longer loses its last push. Stop asks the agent to commit and push before it exits, and a run that old needs a fresh GitHub sign-in to push; Foxl refused it because the task already read as stopped, so the push failed and any work not yet pushed was lost when the machine was recycled. A stopped run now gets that sign-in for up to 30 minutes after Stop, until it reports back. The same refusal hit a task whose agent had opened its own pull request while it was still working, and that is fixed too.
- Foxl Code's autonomous loop now checks whether any of your tasks made progress by reading only the task activity since its last check, instead of every task you have ever run. It was the largest database read in the service and grew with every task; what the loop decides to do is unchanged.
- Scheduled runs, channel replies and subagents on Claude Haiku 4.5, with an Anthropic API key or on Foxl credits, now send Haiku's thinking settings (a thinking budget), as the chat window always did. They sent the adaptive thinking and effort settings of the newer Claude models, which Haiku 4.5 does not support.
- A Foxl Code task that Claude Code runs from your prompt, rather than in a terminal you type into, now checks Foxl for a Stop about three times a minute while it works. It used to ask once a second for the whole run, which since v0.7.29 could be up to eight hours, and every one of those requests counted against Foxl's daily request allowance. Stop, the Files page and terminal resizing still reach the task at once, and terminals you type into are unchanged.
- Foxl Code now says so when an instruction cannot reach a running task. A task Claude Code runs from your prompt does not read its terminal, but anything sent to it while it ran (text typed into its terminal, a follow-up the chat agent passed on, Fix it, Request changes, or the automatic fix after a failed check) was reported as delivered and then never seen. Now the terminal shows a notice that typing there is not delivered, along with what you typed; the chat agent is told the task cannot take it and to send it once the run finishes; Fix it shows "This agent was started from a prompt and does not read its terminal"; Request changes no longer says the agent is working on the feedback; and a skipped automatic fix is recorded in the task's audit log.
- A request on Foxl credits, including a Foxl Code turn, is refused with "Credits exhausted or insufficient for this request" less often while the account still has credits. Before each request the relay sets aside the most that request could cost, and it priced every input token at the input, cache-read and cache-write rates added together, although a token is billed at only one of them, and it counted an attached image by the size of its file. It now uses the single highest rate a token can be billed at (the 1-hour cache rate only when the request asks for a 1-hour cache) and, for Claude models, the most Claude charges for one image. On Claude Opus 5.5 an account with 50 credits can now send about 350 KB of conversation in one turn instead of under 200 KB, and a phone photo needs about 1 credit set aside instead of about 770. Text is still set aside at one token per byte, because some real content (base64 text, minified code) is billed nearly that densely, so a long conversation still needs far more credits set aside than it costs: on Opus 5.5 about 14 credits for every 100 KB, and a Foxl Code session on a low balance is still refused once its conversation outgrows that. A PDF attachment is set aside exactly as before. The refusal now also says which kind it is (
code) and how many credits the request needs (required). - Deleting the "Daily check" schedule Foxl Code adds to a repository now sticks. Your next task in that repository, whether from chat, Solve, an issue or a Terminal pane, used to add it back, enabled. Deleting a schedule you made yourself no longer makes room for a new "Daily check" either.
- Reconnecting a Foxl Code task while its previous run is still finishing no longer starts a second run beside it. After Stop the agent still commits, runs the tests and pushes before it exits, and a Reconnect or Fix it pressed in those minutes started another agent on another machine; when the first one finished, the new run was marked failed and could no longer use the model. Reconnect now says the previous run is still running or saving its work, and works again once it has finished.
- Opening Foxl Code's Tasks, Settings or onboarding page no longer counts every task you have ever run just to check whether you have run one, so it costs the same however long your history is.
- Choosing an autonomy level in Foxl Code (Schedules > Autonomy) now saves every switch the level sets. Picking "Only when I ask" on a page opened before another device changed the level could leave auto-merge and the two review-and-merge switches on, while the page showed that level selected and "Saved." A switch turned on and back off before saving is now saved as off too, on that card and in Settings.
- A pet you gift now lands in exactly one collection. When the recipient accepted a gift at the same moment the sender took it back, both ended up with the pet, and when an unclaimed gift expired, two people opening the app at once could each return it to the sender. Every way a gift is settled (accepted, taken back, expired, or picked up automatically when a new account signs in) now gives the one pet to one person. Two shorter gaps of the same kind are closed too: a summon that lost its last gem to another summon, and a gift of a pet the sender did not have, each briefly left a pet that could be passed on before it was taken back.
- Turning off Beta updates no longer installs a beta the next time you quit Foxl if it was still downloading when you turned them off (on every platform) or had already downloaded (on Windows and Linux). On macOS a beta the system updater has already received cannot be cancelled, so Foxl now tells you it will still install when you quit and keeps it listed as ready to install, and Settings no longer says "You are up to date" while an update is downloaded and waiting.
- When a beta is withdrawn, Foxl offers beta testers the previous release instead. If that install does not complete and Foxl comes back on the withdrawn beta, it now says the install failed, as it already did for an update to a newer version, instead of showing nothing.
- Automatic chat titles are the title again, not the start of the model's reasoning. On a model that thinks, such as Opus 5.5, a title often began with a sentence like "Since the conversation is in Korean, I should...", because the reasoning was read as part of the answer. Titles now use the answer alone, and no longer think at your chat's effort setting: with your own API key, AWS account or a sign-in, a model whose thinking cannot be turned off (such as Opus 5.5) is asked for its lowest effort and other models are not asked to think, so a high effort setting no longer uses up the title's allowance and leaves a chat untitled. The same goes for the suggestions on the new-chat screen, and replies posted to Slack, Telegram and Signal, schedule and heartbeat results, the browser extension's chat and Foxl Notes' AI answers no longer start with the model's reasoning either.
- A chat's session summary is no longer sent to Amazon Bedrock unless Amazon Bedrock (your own AWS account) is your selected provider. Half an hour after a chat went quiet, and whenever you saved a session, Foxl sent up to 15,000 characters of it to Claude Haiku 4.5 on Amazon Bedrock with whatever AWS credentials the computer had, whichever provider you had chosen, so a chat on Claude Code, a ChatGPT sign-in, an API key, a local model or Foxl credits could be processed and billed under an AWS account you use for something else. On any provider other than Amazon Bedrock, Foxl credits included, the session record now gets the basic summary (how many messages, and your first request) that a computer without AWS credentials always got, and nothing is sent anywhere to write it. The agent's list of your recent conversations then names each one by the start of your first request, without topics.
- A file the agent builds in pieces keeps every piece. The agent writes a long file as one "write" followed by "append"s, and when the model asked for several of them in one reply they ran at the same time: an append could land in the old file just before the write replaced it, so the finished file held only the first piece while every call reported success. Calls to the same file now run one at a time, in order, and each reports the size and checksum of the file as it left it.
- Foxl Code's auto-merge no longer merges a task's pull request once someone other than your agent has pushed to its branch, including a push made while the pull request was closed. Your own pushes count as yours when your GitHub account is connected to Foxl. Foxl does not review such a push on your credits, and that pull request waits for you to merge it yourself.
- On a Mac with "Keep running when closed" on, Foxl's background service no longer copies every line of its log into
~/.foxl/logs/daemon.out, a file nothing ever trimmed (110 MB after 50 days on one machine). The dated daily logs, kept for 14 days, hold everything, and an oversizeddaemon.outis cut down to its most recent 256 KB when the updated service starts. A debug message that Foxl Agent wrote with Amazon Bedrock models once for every earlier tool result on every model call, which was most of each day's log on every platform, is now written once per model. - The Files editor in Foxl Agent no longer drops keys you type quickly on a slow computer. A key typed while the page was catching up could be erased and the saved file would be missing it.
- The privacy policy now says what Foxl Code keeps after a cloud task ends. It said repository contents are not retained once a task ends; the clone is erased with the task's machine, but the coding agent's own files for the task, including Claude Code's conversation with the parts of the repository it read, stay in the task's AWS session storage for up to 14 days after the task was last used, and files the Foxl Code assistant creates in its own storage, which can include a copy of your repository, stay for up to 14 days after it last ran. Deleting a task or the account does not remove either sooner. The security page in the docs says the same, and the account deletion dialog in Settings no longer says all data is deleted: it says messages in team channels and files in shared folders stay, and that Foxl Code's cloud session storage is removed by AWS within 14 days.
- The connection between app.foxl.ai or the phone and your desktop now limits how much one account can send through it: a single message over 4 MB, more than 2,000 messages in 10 seconds on one connection, or more than 200,000 in a day from one account closes the connection. Normal use, including fast typing, scrolling in a terminal and large pastes, stays well under all three. Without these limits, one account could use up the free daily allowance that every Foxl user's desktop connection, Channels and Foxl Code live updates share.
- Channels now limit how much one account can post: about 1,000 messages, reactions and edits a day (a very long message counts as several) and 120 a minute, plus 20 new workspaces and 300 new shared folders a day. Over a limit, the action is refused and nothing is saved; the message says whether to wait a minute or, for the daily limit, about how many hours until it resets. Before, one account could post without limit and use up the shared daily database allowance, which would stop sign-in, chat and Foxl Code for everyone until midnight UTC.
- The page that hands a desktop or mobile sign-in back to the app now treats everything it carries as plain data, and the relay refuses a sign-in started with a malformed one-time code instead of carrying it through. The partly hidden email address on that page is always shown as plain text.
- A highlight colour in a Notes note can no longer make the app contact another website. An AI summary, or text pasted from a web page, could carry a highlight whose "colour" also told the editor to fetch a picture from any address, so opening the note sent a request there with no click. The editor now keeps a highlight or text colour only when it is a real colour; real colours look exactly as before.
- Foxl Code's cloud orchestrator and its code reviewers now run in sessions another account cannot address. Your first Foxl Code chat after this update starts on a fresh cloud session, so files the orchestrator had kept in its own workspace before the update no longer appear under Files; your tasks, chats and repositories are unaffected.
- With auto-approve turned off in Settings > Safety, the agent now asks before it acts in your own Chrome through the Foxl extension: opening a page or a tab, closing a tab, clicking, typing and choosing an option. Reading the page and listing tabs still run without a prompt. The separate Foxl browser already asked; the extension, which uses your real logins, did not. With auto-approve on (the default) nothing changes.
- With auto-approve turned off, the agent now asks before it creates a scheduled task or changes one, because a schedule's instructions later run with nobody watching. Listing and reading schedules still run without a prompt. The agent can also no longer create a heartbeat schedule or rewrite what the Feed Generator heartbeat does, which the Schedules page never allowed either; repeating tasks are cron schedules, and the Feed Generator is set up in Settings.
- With auto-approve turned off, a code search over a folder that holds a credential file (such as
~/.foxl,~/.codex,~/.config/ghor your whole home folder) now asks first, as a search of the credential file itself already did. Searching your projects and the agent's workspace still runs without a prompt. - Connect GitHub in Foxl Code adds an organization's installation only when you are an active member of that organization, the check that adding a single installation always made. Having access to one repository of an organization no longer adds you to its whole installation, with its repository list and its member list.
- Once you are removed from a GitHub installation in Foxl Code, its tasks' files, terminal screen, typing and Resume stop working for you, as Reconnect and the shell already did.
- A Foxl Code task whose owner no longer has write access to its repository on GitHub stops getting an automatic code review on each push, as auto-merge and Reconnect already required.
- Foxl Code's chat can now read from GitHub only within the repository you selected. On the desktop it signs in to GitHub with your own account, and until now it could also read your other repositories, search across your organizations, and list your gists and account details; those requests are now refused. Reading and commenting on the selected repository's issues, pull requests, commits and files works as before.
- Password sign-in now counts every attempt before checking it, so many guesses sent at the same moment are held to the same eight-attempt limit as guesses sent one at a time. Changing or removing a password counts its current-password check the same way.
- Sign out everywhere, changing or removing your password, and deleting your account can no longer be held back by other people on the same network (an office, a mobile carrier or a VPN). They now have a limit of their own per account instead of sharing one with every sign-in attempt from that address.
- Foxl Code's chat saves a conversation only into tasks on your own account when it hands the conversation to the tasks a message started.
- When Foxl Code's chat or Files cannot get an answer from the cloud service, the error shows a short code and a request id to quote, instead of the service's raw reply.
- While Foxl Code is switched off for maintenance, or once an account is no longer in the beta, a task finishing no longer starts an automatic check-in for that account, which the scheduled check-ins already respected.
- The "Talk to us" form now accepts at most 200 enquiries a day (40 an hour) across everyone, and records at most three repeat submissions a day from the same email address. Before, the form had no overall limit, so a flood of submissions could use up the shared daily database allowance and stop sign-in, chat and Foxl Code for everyone until midnight UTC. Over the limit, the form shows its error with the email address to write to instead.
- The account data export and the usage CSV download on the Account page can now be used three times an hour and six times a day per account (the two share the limit). Each one reads your whole usage history, and before there was no per-account limit, so one long-running account exporting repeatedly could use up the shared daily database allowance for everyone. Over the limit the download reports that it failed, and it works again later.
- The "Unsubscribe" link at the bottom of Foxl product-update and tips emails now works. Clicking it opens a page that asks you to confirm, and one button press unsubscribes you from those emails. Before, the link opened an error page and changed nothing. Links in emails you received in the last six months work too.
- Logging one device out from your device list, or signing out your other devices when you change your password, now also stops notifications to that phone, so a lost phone no longer shows new message, chat or Foxl Code previews on its lock screen. Before, only Sign out everywhere did this. It covers a phone from the next time it signs in to Foxl; a phone that has stayed signed in since before this update is still reached by Sign out everywhere, as before. Signing back in on the same phone turns its notifications back on.
- The one-minute connection pass that Channels, Foxl Code's live updates and the web connection to your desktop use now stays single-use even when a very large number of connections open within that minute. When a channel is that busy, a new connection waits a moment and retries instead of an already-used pass being accepted again.
- A restricted shared folder in a workspace is now open only to the people on its sharing list and to the workspace's admins, as its sharing screen says. Whoever created the folder used to keep full access even when an admin left them off the list, and got it back if they were removed from the workspace and invited again. To give the creator access, add them to the list.
- A shared folder, channel or message from a workspace you are not in now answers "not found", the same as one that does not exist, so its sharing settings, messages, edits and reactions no longer confirm that it exists.
- The "Strict security posture" switch is no longer shown in workspace settings. It was saved but never changed what shared skills, documents or automation could reach, so turning it on gave no protection.
- Deleting your account now also deletes the files and folders on your personal Shared shelf. They used to stay in storage after the account was gone; the nightly cleanup now removes them, including those left by accounts deleted before this release.
- A workspace's bill can no longer be moved onto another admin without their agreement. A request to take it over now waits for that person, who gets an email and can accept or decline it at the top of Settings > Workspace; the bill moves only if they accept, and an unanswered request expires after 14 days. Making someone an admin no longer lets the owner start charging their credits.
- Deleting a workspace now ends everything its members could still do in its channels. Open tabs are disconnected and any call in progress ends, and members can no longer react, show as typing, see their old mentions or start a call there.
- Blocking someone in a channel now hides each of you from the other as messages arrive, not only after a reload: new messages, edits, reactions and the typing indicator no longer reach the other person live, and neither of you can join a call the other is already in.
- On a machine you connect to Foxl Code, the agent no longer puts the repository's GitHub access token in the clone command, where other accounts on that machine could see it while the clone ran. Git now gets the token the same way it already did for pushing.
- The command for connecting a machine to Foxl Code no longer contains the machine's secret. The installer asks for it when it starts and hides it as you paste it, so it stays out of your shell history and out of the list of running commands other accounts on that machine can see. The one-time panel in Settings > Machines shows the secret beside the command with its own Copy button. For unattended installs,
--secret-fileand--tunnel-token-fileread a file only you can read (chmod 600); a secret or tunnel token typed on the command line is refused. - Launching a machine on AWS from Foxl Code always deploys the template Foxl publishes, after checking its fingerprint. The installer used to prefer a file with the same name in the folder you ran the command from, without checking it, and now never looks there. It also stops instead of continuing when it cannot check the template.
- A machine launched on AWS with your own Cloudflare named tunnel no longer has the tunnel token written into its startup script, where any program on that machine could read it back, and the tunnel no longer carries it on its command line. The token is stored the way the machine secret already was: read once at first boot, then deleted.
- A Foxl Code run's compute is now charged until Foxl sees its session end. When a run reported itself finished while its terminal was still open, the charge used to stop at that moment while the session carried on; now the agent is told to stop at once, typing into it offers Reconnect (which starts a new, charged run), and the run is charged up to the moment its session closed. A background Cursor, Hermes or OpenCode task that stops reporting progress while it keeps running is now charged up to the last time Foxl saw it running instead of its last report, with the same 15-minute allowance and time limit as before.
- On a machine you connect to Foxl Code, tasks now run under an account of their own, separate from the Foxl agent's. Code in a repository a task works on can no longer read the machine's secret, change the installed Foxl agent, or reach the cloud instance's metadata service. Anything a task starts is stopped when its coding agent exits, and anything that detached itself is stopped as soon as no other task is running. These apply to a machine when its agent is installed from this release. On a server where you ran the install command yourself, run it again (use Rotate secret first if you no longer have the secret). A machine Foxl Code launched on AWS gets them when you launch it again; re-running the Launch command on an existing machine does not reinstall its agent.
- An HTTP custom tool now encodes the values the agent fills into its URL, so a value can no longer add query parameters, cut the address short or climb out of the tool's path with
... A value in the path can still span several segments, such asusers/123forhttps://api.example.com/{{endpoint}}. A tool with saved headers (where an API key usually goes) sends them only to the host written in its URL: when a parameter chooses the host, the call is refused with a message saying how to fix the tool. A tool with no saved headers whose host or base address comes from a parameter can reach public websites only. - Deleting, moving or renaming a symbolic link in your workspace now acts on the link itself. It used to act on the file or folder the link pointed to, so deleting a link to the workspace folder deleted the whole workspace. Moving or copying something onto a link's name with "replace" now replaces the link and leaves what it pointed to alone, and a link that points nowhere can be deleted.
- The Logs console, the system report you can download for support, and the app's log files no longer contain a webhook schedule's secret trigger address each time it fires. The address is logged with its secret part hidden.
- Foxl Desktop no longer announces itself and its local port to other devices on the network you are connected to. Nothing used the announcement: your phone and the web still reach this computer through your Foxl account as before.
- Programs Foxl starts for you no longer receive Foxl's own sign-in session or connection key: your MCP servers, the Gemini CLI, the Feed Generator's watch command, skill installs, on-device transcription and Signal. Everything your shell sets, your model provider keys and the variables you give an MCP server still reach them. The watch command now runs like the agent's own shell commands: it no longer gets the model keys saved in Foxl's Settings (keys your shell exports still reach it), and saved keys are hidden in the output the agent reads.
- Setting up on-device transcription now installs exactly the engine versions Foxl was tested with, every package checked against its recorded checksum, instead of whatever versions were newest on the day you pressed Install. A package file that does not match is refused and the setup stops with an error. On a Mac whose Python is 3.10 or 3.11 it still installs, with the newest numpy that Python supports.
- Only the Foxl app on your computer can change which Foxl account the desktop is signed in to, or turn automatic Claude Code and Codex sign-in sync on. A phone or browser using the desktop connection can still pick Foxl models, refresh the sign-in of the same account and turn that sync off, but it can no longer sign the desktop in to a different account, which is where your coding-assistant sign-ins are synced.
- The agent's replies in Slack are posted as plain text. A reply can no longer notify a whole channel (@channel, @here, @everyone), mention someone, or show a link whose label is a different address than where it goes. Bold, italic and code formatting still show as before.
- A profile picture set from an image link is now copied into your Foxl account when you save it, and teammates see that copy, so their apps no longer load the picture from the site you linked. The link has to point to a JPEG, PNG, WebP or GIF of up to 512 KB. A picture linked this way before this release, unless it is a GitHub or Google profile picture, shows as your initials to teammates until you save the link again.
- Colours in a PowerPoint deck (slide backgrounds, shapes, text boxes, gradients and outlines) are now checked before they are drawn, so opening a deck can no longer make the viewer load something from another site. Real colours look exactly as before; a value that is not a colour is left out, so that box shows no fill and a slide background shows white.
Changes
- GPT-6 Astra can run on Amazon Bedrock's Ultrafast tier with your own AWS account. It is the same model, faster, at six times the Standard price ($66 per million input tokens and $330 per million output tokens on the US profile). Turn it on with the Ultrafast switch in the model selector, which takes the place of Reasoning's fixed "Always on"; a lightning mark on the model button shows it is on. It is off by default, applies only to the chat messages you send (titles, suggestions and scheduled runs stay on Standard), and usage figures count those messages at six times the Standard rate. It is not available on Foxl credits, because the Bedrock endpoint Foxl credits use for GPT-6 Astra does not offer it.
- Foxl Code's Tasks home is now a list of your recent tasks, grouped the way Claude Code lists its background agents: Needs you, Working and Done, each row showing the task, what came back (ready to merge, checks failed, merged), its pull request and how long ago. Press a row to open the task; press the back arrow (or Esc, from the conversation) to come back. The composer stays at the bottom to start the next one. A new account still opens on the greeting, and tasks that ran on this computer are listed in the sidebar as before.
- A summary line,
14 needs you · 1 working · 94 done, now sits beside the page title on every Foxl Code page (at the top of the Tasks list on a phone). Each number opens the list at that group. It shortens to numbers, then hides, when the header has no room for it. - A Foxl Code task shows its conversation or its terminal, never both side by side: the header has a Conversation | Terminal switch in place of the split view.
- Foxl Code's Runtimes page opens on a list of your open terminals and the agents running without one. Press a row to open that terminal full size; the back arrow (or Esc outside the terminal) returns to the list, and every other terminal keeps running in the meantime. The runtime rows under Runtimes in the sidebar are gone, along with the split and arrange controls.
- Settings > Connect lists Integrations, Skills, Tools/MCP and Channels as rows of their own. They used to sit behind a single Integrations row with six tabs; now each is one click away. Skills keeps your workspace's Shared skills as a second tab, and Tools/MCP holds the System and Custom (MCP) tools.
Fixes
- status.foxl.ai's RSS feed shows an open incident as one item for its whole life. It used to give the incident a new identity every two minutes while it stayed open, so feed readers and RSS-to-Slack bridges posted the same outage again on every poll. The RSS and Atom dates now follow the incident's latest update rather than the last check. The status page also stops checking for changes while its tab is in the background, and checks at once when you return to it.
- New chat in the sidebar opens a new chat from every page. Pressed while Files, Channels, Agents or Schedules was open, it reopened the chat you were last in instead.
- A long paste in the message bar now stays one piece. Once a long message made the message bar scroll, a paste's highlight could sit on the wrong line with an empty box at the end of the line above; it now stays on its text. A paste's label, such as "[Pasted text, 128 lines]", also moves to the next line whole instead of breaking in the middle. And it behaves as one object: clicking it puts the cursor at its edge rather than inside it, a double-click or Shift+Arrow selects all of it, and typing after you click on it can no longer break it and drop the pasted text. This applies to both Foxl Agent and Foxl Code.
- A long paste in the message bar also stays one object when you copy, cut, paste, drag or undo. Copying it puts the pasted text itself on the clipboard, not its label, and pasting it into a message bar in Foxl Agent or Foxl Code brings its card with it. Cut and paste moves it, card and all; before, the cut lost the pasted text. Deleting it and pressing Cmd+Z (Ctrl+Z) brings the card back too, instead of just the label. Text dropped onto a paste lands beside it rather than inside it, and dropping text into Foxl Agent's message bar now works: it used to insert nothing.
Changes
- From this version on, Foxl on iPhone, iPad and Android tells you when you have fallen well behind. When the App Store (on Android, the latest Foxl release) has a version three or more updates newer than yours, or a new minor version, and your device has stayed behind for three days, Foxl offers to open the App Store or download the update. A phone that updates itself is not asked. Not now hides it for a week. Foxl checks at most twice a day.
- If a future Foxl service update ever stops supporting the version of Foxl you have, the app now says so and shows how to update (the App Store, the Android download, the desktop updater, or a reload on the web), instead of failing with errors. It can first ask you to update while your version still works. Nothing is blocked or asked today. The desktop can continue without Foxl services from that screen, since its local features do not need them.
- Dictate anywhere can press keys by voice. Say only "엔터", "탭 두 번", "ESC", "백스페이스", "왼쪽 화살표 세 번" or their English names ("Enter", "Tab twice", "Escape", "Backspace", "Left arrow") and Foxl presses that key instead of typing the word, and end a dictation with "엔터 쳐" or "press enter" to type it and send it. Turn it on in Settings > Notes > Dictate anywhere > Voice key commands. It is off by default, because a dictation that ends in "press enter" or "엔터 쳐" is then sent without those words, and a one-word reply such as "Delete" becomes a key press. A single direction word such as "Right." is still typed, and short commands are recognised far more reliably with a fixed dictation language than with Auto. As with Enter, pressing these keys on Windows and Linux has not been confirmed on a real desktop yet.
- Dictate anywhere can press Enter for you. Turn on Press Enter after typing in Settings > Notes > Dictate anywhere and a chat message or prompt is sent as soon as your words are typed. It is off by default, because in a terminal the Enter runs the line, and it is never pressed when the dictation was cut off partway or the text could not be confirmed as typed. On Windows and Linux it uses the same keyboard tools as the paste, though pressing Enter there has not been confirmed on a real desktop yet.
- Grok 4.7 is available. It is xAI's newest model, built for coding, agentic tasks and long-running agents, with a 500K-token context and image and document input, at the same price as Grok 4.6 ($2.20 per million input tokens, $6.60 per million output tokens). Pick it on Foxl credits, in Foxl Code and with your own Amazon Bedrock credentials. Its reasoning cannot be turned off, so the model selector shows its effort levels with no on/off switch; Foxl starts it at high effort. Grok 4.6 moves to the older models, still selectable with Show older model versions on.
- GPT-6.1 Sol is available with your own Amazon Bedrock credentials. It is the upgrade to GPT-6 Sol, close to GPT-6 Astra on agentic coding, computer use and professional work, at GPT-6 Sol's price ($2 per million input tokens, $10 per million output tokens) with cached input halved to $0.10. It reads files and images, has a 1.05M-token context, and its reasoning cannot be turned off, so the model selector shows its effort levels with no on/off switch. It is not on Foxl credits or the ChatGPT sign-in list yet.
- GPT-6 Sol and GPT-5.6 Sol, Terra and Luna move to the older models for your own Amazon Bedrock account and an OpenAI API key, still selectable with Show older model versions on. On a ChatGPT sign-in GPT-6 Sol stays in the main list until GPT-6.1 Sol is available there, and on Foxl credits GPT-5.6 stays in the main list, since GPT-6 Sol and Luna are not on credits yet.
Fixes
- Foxl now counts the prompt of GLM, Kimi and the other non-Claude models it reaches through Foxl Relay on Amazon Bedrock. Their input tokens were recorded as zero, so a conversation's context usage read far too low and automatic compaction could not see those conversations growing. What you are charged is unchanged: Foxl Relay has always counted these tokens itself.
- Grok 4.6 with thinking turned off works again. Amazon Bedrock now refuses the "no reasoning" setting Foxl sent for it, so every such message failed; Foxl now sends the lowest effort instead.
Changes
- Claude Sonnet 5.5 is available. It is the newest Sonnet: faster than Sonnet 5 and priced at $2 per million input tokens and $10 per million output tokens, with a 1M-token context. Pick it on Foxl credits (the Free plan included), with your own Amazon Bedrock credentials, in Foxl Notes and in Foxl Code. As on Opus 5.5, its thinking cannot be turned off, so the model selector shows its effort levels with no on/off switch; Foxl starts it at medium effort. Amazon Bedrock serves it only through its global cross-Region profile, so a Sonnet 5.5 request can be processed in any AWS commercial Region, not only in the US. Sonnet 5 stays the default. Claude Code (Pro/Max sign-in) mode lists it as well, capped at 200K tokens there like Sonnet 5.
- Foxl Code's Claude Code agent can run Claude Opus 5.5 and Sonnet 5.5. The cloud agent carried Claude Code 2.1.259, and Amazon Bedrock refuses both models for that version ("version 2.1.280 or newer is required"), so a Claude Code task on Opus 5.5, the default since v0.7.25, would have failed on its first request. It now runs Claude Code 2.1.284, which also knows Sonnet 5.5's context window instead of capping the session at 200K tokens.
- Claude Sonnet 4.6 is treated as a legacy model everywhere. The model selector no longer falls back to Sonnet 4.6 when a saved model is unavailable. Sonnet 4.6 stays selectable with Show older model versions on.
- Foxl for iPhone and iPad is on the App Store. foxl.ai and the docs now send iOS visitors to the App Store listing instead of the TestFlight beta, which stays open for anyone who wants builds early. The listing is not available in the European Union yet.
Changes
- A Foxl Code task that has finished no longer opens on an empty black terminal. The conversation is the page now, and it ends with a card saying where the task stands (merged, ready for review, did not finish, cancelled) with its pull request or a Retry button beside it. The terminal opens from one Terminal button in the task header instead of three Conversation / Split / Terminal tabs; its panel has its own expand and close buttons, and it opens beside the conversation by itself only for a task that is still running. Opened on a finished task, it says the session has ended and offers the next step (Resume for a Claude Code task in review, Retry for one that did not finish, the pull request where there is one). For a finished task from an agent that cannot pick its session back up (Codex, Kiro, Cursor, Hermes, OpenCode), the task's menu no longer offers Resume either, which could only end in "Cannot reconnect this task". The header also shows the task's repository, coding agent and start time, and names the pull request by number.
Fixes
- Foxl Code's daily cap for unattended work is no longer set to $0.50 by accident. Choosing a default machine created your settings with the database's old $0.50 value, and clearing the cap field in Settings to type a new number saved $0.50 too. Since the cap now also stops scheduled pull-request runs and new-issue tasks, such an account would have stopped all unattended work after 50 cents a day. Both now use the $500 default Settings shows; an account that already holds $0.50 keeps it and can raise it under Budget in Foxl Code's Settings.
- A forgotten password can be reset, as the sign-in page's hint says. For ten minutes after signing in with an email link (or Google, Apple, GitHub or the password itself), Account > Password lets you set a new password or remove it without the old one, and no longer shows the "Current password" box. Before, it always asked for the current password, and every guess counted toward the sign-in lockout. After those ten minutes the current password is asked for again, with a note on how to reset it instead. An older copy of the phone app still shows the box; in those ten minutes it accepts anything typed there.
- Deleting your account now also closes its open Channels and Foxl Code connections at once. Before, they kept receiving messages and updates for an account that no longer existed. Account > Delete my account also now sends proof that the request comes from your own signed-in device, so that a later release can stop an account from being deleted with a copied sign-in token alone. Nothing changes in how you delete an account today.
- The agent's memory tools can no longer read or change your Telegram, Slack and Signal channel settings. Before, a web page, email or message the agent read could get it to look up a channel's bot token and send it somewhere, or quietly add a stranger to the people allowed to run the agent from that channel, taking effect the next time Foxl started. Channels you already set up keep working as they are, and the Memory list in Settings now shows these entries by size only, like connected accounts.
- The agent can no longer send your Slack sign-in to a website when it downloads a Slack attachment. Downloading a file from Slack used to accept any web address the agent passed it and send your connected Slack account's key along with the request, so a message or page the agent read could get that key sent to someone else's server. Now a download goes only to Slack's own file servers, and any other address is refused before anything is sent.
- Shell tools you create on the Tools page now get the same protection as the agent's own shell commands. They no longer see Foxl's sign-in to Foxl Relay, the key to Foxl's local server or the model API keys saved in Settings, and if a tool prints one of those values, or a secret saved for a skill on the Integrations page, it comes back hidden. Before, a tool that takes text from the agent could be made to print them all. Your own environment variables, including API keys your shell profile sets, still reach your tools as before.
- After the desktop's local server restarts (it crashed and came back, you pressed Restart server, or startup had to try again), your phone and app.foxl.ai keep working with this computer. Since v0.7.28 every conversation, file, terminal and chat request from them was refused after such a restart while the desktop still showed as online, until the window was reloaded or Mobile/Web was reconnected. This did not affect "Keep running when closed".
- Restart server on macOS and Linux no longer stops the server it just started. When the old server was still sending something as it shut down (the Logs or Notifications page, a chat reply, or a request from your phone), Foxl force-stopped the NEW server five seconds later, and the restart then reported that it had failed or the server looked like it had crashed. Now only the old server is force-stopped, and only if it has not exited by then. Its exit no longer counts as a crash either, so a few restarts in a row no longer end on the "Server crashed and could not be restarted" screen while the new server is running fine.
- Help > Reset Settings no longer disconnects this computer from your phone and app.foxl.ai. The reset also erased the key this computer uses to identify itself to Foxl, so the next time it connected it was refused as a different install and showed as offline, until you chose "Use this computer as the desktop" in Settings > Mobile/Web. The reset now puts your preferences back to their defaults and keeps that key, this computer's device record, its trusted devices and a pending update check. If you had switched Mobile/Web off, or this computer was removed from your account, it stays off after the reset; turn it back on in Settings > Mobile/Web.
- The Signal channel no longer throws away what signal-cli receives, though delivery through a real Signal account has not been confirmed yet. It used to stop signal-cli every 30 seconds and discard everything it had printed, so no Signal message could reach the agent and nothing in the log said so. It now keeps one receive running and reads each message as it arrives. It answers direct messages from allowed senders and your Note to Self (when Phone Number is filled in), and leaves group chats and your own messages to other people alone. When signal-cli keeps failing, it waits longer between tries and shows why on the channel, and a reply signal-cli has not sent within a minute is stopped and tried again instead of holding up the chat. signal-cli names senders by their Signal ID, not their phone number, so the list of who may message the agent is now Allowed Signal IDs. The channel shows the ID of the last sender it turned away, so you can copy it in.
- An answer to a Slack, Telegram or Signal message is no longer lost when it fails to send. Foxl used to try once and drop it, and Slack refused to post at all while its connection was reconnecting, then still put a check mark on the request. Slack and Telegram now post a reply whether or not the incoming connection is up at that moment, a refused reply is tried again for about 20 seconds (a long answer picks up where it stopped instead of repeating its first part), and if it still cannot be sent the Slack request gets an x instead of a check mark and the desktop shows a "Reply not delivered" notification that opens the conversation holding the answer. The answer stays in the conversation on the desktop either way.
- In a Telegram group, the bot now leaves photos and files alone unless they are meant for it, the same rule it already had for text: the caption mentions the bot, or the photo or file is a reply to one of its messages. Before, any photo or file you posted in a group the bot is in was saved on your computer, answered by the agent in front of the whole group, and a file it could not read got a public "I cannot read this attachment" reply. Private chats with the bot are unchanged.
- Photos and files sent to your Telegram bot reach the agent again on a workspace that has never received one. Until an
inbox/telegramfolder existed in the workspace, every photo and document was turned away with "I cannot read this attachment (refused: the destination is outside the workspace inbox)", and nothing ever created that folder, so it kept happening. The first attachment now creates the folder and is saved into it. A download also checks where its file really ended up before writing to it, so swapping the inbox folder for a link while a file is downloading can no longer put the file outside the workspace. - Clearing Signal's "Phone Number" or Telegram's "Your Chat ID" and pressing Start now really removes it. Until the desktop server restarted, the old value stayed in force: on Signal it could still message the linked account and run the agent, and on both it was greeted by the agent on every start.
- Reconnecting a Foxl Code Remote task after pressing Stop now gives you a working terminal. Before, the earlier Stop also ended the reconnected session within about a second, on every Reconnect, so the only way back to that task's work was Retry on a fresh copy of the repository. Stop still ends the reconnected session when you press it again, including a Stop pressed while the reconnect is still starting.
- Foxl Code now checks your own GitHub write access when you reconnect a task, each time the autonomous loop works on your repository, and before it auto-merges your pull request, the same check starting a task already had. Before, someone whose access to a repository was lowered to read after they started a task could press Reconnect and get a terminal that could push to that repository, their loop kept a token that could write to it, and their agent's pull requests were still merged for them. Reconnect now answers with the same "this needs write access" message a new task gets, the loop runs without GitHub write access, and the pull request waits for someone who can merge it. If you have write access, nothing changes.
- Reconnecting a Foxl Code task now has the same limits as starting one, because a reconnect starts a new cloud machine for the task. An account with no credits left gets the same "credits exhausted" answer a new task gets, and a reconnect now counts toward the free plan's 5 concurrent tasks and the 25-tasks-in-flight ceiling, including when many reconnects are pressed at once, and a new task started while a reconnect is still starting counts that reconnect too. Before, a free account could reconnect twenty older tasks into twenty running machines. Retry now counts toward the 25-task ceiling too. Reconnecting while you are under the limits works as before.
- A credit balance that went below zero is now paid off once, out of the next credits you receive. When a Foxl Code task's compute or a transcription took an account below zero, that amount used to be held back from every later month's free credits and every subscription renewal, and the held-back credits then expired with the debt still owed, so the same amount was taken again each period. A debt of 10 credits or more kept a free account locked out for good even though 10 credits arrived every month, and a subscription renewal, cancellation or plan change could take the same amount again. Now the debt is paid once, out of the credits that were being held back for it, as soon as they exist: when new credits arrive, when a refund leaves an amount owed, and before a renewal, cancellation or plan change clears the old credits. What you can spend, and in which order your credits are used, is otherwise unchanged.
- A Foxl Code task that runs on a machine you registered yourself no longer costs compute credits. When such a task finished, Foxl charged cloud compute for its whole run as if it had run on Foxl's servers: about 3 credits for 30 minutes and up to 51 credits for an 8-hour run, on top of its model use. The machine is yours, so now only the model use is charged.
- The Compute figure on the Foxl Code Usage page, and each compute line under it, now show what compute actually cost. Each line used to add the task's model spend so far on top of its compute, so a task that ran twice counted its model spend twice more: $0.23 of compute could read as $5.23. Model spend is still shown in the per-model chart on the same page.
- Notes AI works on app.foxl.ai and in the phone apps when your computer is connected. Summaries, Ask AI, reports, automatic titles and live translation now stream from the Foxl app on your computer; they used to fail with "no Foxl desktop answered" or a timeout although your computer had run the request. An Ask AI answer that takes more than 8 seconds to start needs this version of the Foxl app on your computer too; with an older one it can still fail with "Local stream timed out with no response". What you send is encrypted between your devices once they have completed the encryption handshake, but the reply streams back through the relay protected by TLS only, like a live chat reply, so the relay can read a summary, an answer or a live translation while it is in transit. The Desktop Relay and Security pages now say so.
- Settings > Advanced > Download Report on app.foxl.ai and in the phone apps now saves the same multi-line report the desktop app saves, client info included, when your computer is connected. It used to save the report as one line wrapped in quotes. If the report cannot be created, a message now says so instead of nothing happening. Exporting a chat as Markdown there works too once the Foxl app on your computer runs this version; it used to fail with "Could not export this conversation".
- Dropping or pasting files into Files on app.foxl.ai or in the phone apps with your computer connected now says the files have to be added in the Foxl app on your computer. Each file used to fail with "The request did not go through", which trying again never fixed.
- Settings > Notifications > Send Test on app.foxl.ai and in the phone apps now puts the test notification in the bell while your computer is offline. It used to say "Sent" and deliver nothing.
- When a chat on app.foxl.ai or in the phone apps hands subagent results back to the agent, that handoff is no longer recorded as something you said. The agent used to see an extra message from you, which you never typed, in that conversation. The Foxl app on your computer needs this version too.
- Quick Chat on app.foxl.ai and in the phone apps now answers with the provider its model picker shows when your computer is connected. The turn used to run its model on whichever provider the Foxl app on your computer was set to, so a model picked from another provider failed or was charged to the wrong one. The Foxl app on your computer needs this version too.
- A Foxl Code Remote run that stops without reporting back, for example when its connection is lost during a Foxl update, is now charged for its compute once Foxl stops tracking it, where before it was not charged at all. It is charged from its start to its last recorded activity (its last model call or last reported step) plus 15 minutes, which is how long the cloud machine stays up after going idle, and never beyond the run's own time limit (by default 30 minutes plus 40 minutes for pushing its work). A run with no recorded activity after it started is charged 15 minutes. A run on your own machine is not charged for compute, and a run is never charged twice.
- Deleting a stopped Foxl Code task while its run is still wrapping up now charges that run's compute before the task is removed, where before the deletion made the run free. It is charged up to when you stopped it, and no later than 15 minutes after its last recorded activity. Only a run still inside its own time limit is charged this way, so deleting an older task never charges anything. If the charge cannot be recorded at that moment, Delete says so and asks you to try again in a minute, and Delete all finished keeps those tasks for the next try without counting them as still running.
- Foxl Code's "Daily cap for unattended work" now also stops scheduled pull-request runs (including the daily check Foxl adds for each repository you work in) and the tasks started from newly opened GitHub issues, once the day's spend reaches it. Before, only the autonomous loop respected it. A schedule that did not start says why on the Schedules page, and an issue that was not taken up appears in your suggestions so you can start it from Work. If the day's spend cannot be read, they do not start. Run now and Solve are unaffected.
- In the desktop app, a Notes save or delete that the disk refuses (a full disk, a folder that cannot be written) now shows "Could not save note" or "Could not delete note" instead of looking done. A meeting whose save was refused at Stop keeps its unsaved-recording copy and comes back as a note at the next launch; before, it looked saved and was gone after a restart. A note whose delete the disk refused stays in the list (or, after a Cmd+D quick delete, comes back to it when the Undo window closes) instead of vanishing and reappearing at the next launch.
- Foxl Notes keeps a separate unsaved-recording copy for each recording. When a meeting could not be saved at Stop and another recording was started without reloading, the second recording's autosave replaced the first meeting's copy, and a reload or a crash then lost the first meeting. Both now come back as notes at the next launch. An unsaved recording left by an earlier version is still recovered.
- Opening a second app.foxl.ai tab while a Foxl Notes recording runs in another no longer files that meeting as a "Recovered an unsaved recording" note cut off at the minute the tab opened. If the recording tab later crashes or is closed without Stop, the whole meeting comes back at the next launch, not just its first minutes.
- Signing out now counts a meeting that exists only as an unsaved-recording copy (for example one whose save failed at Stop) among the Notes meetings it would delete, and asks first. Before, that copy was deleted with no warning.
- An audio file imported into Foxl Notes now saves the Background text typed for it with the imported note, and an Ask AI conversation held while no note was open moves to that note, the way a recording's do at Stop. Before, the imported note opened with an empty Background that was never saved, and the text turned up in the next recording instead.
- The reasoning effort you pick for a Claude model now takes effect when the model runs on Foxl's hosted service: Foxl Code chat and agents, app.foxl.ai, the phone apps and the desktop in relay mode. Every such turn used to run at the model's default effort whatever was selected, so a Low pick thought, and was charged, as much as the default, and Max thought no harder. Claude Haiku 4.5 has no effort setting, and an effort a model does not offer (Extra high on Claude Opus 4.6 and Claude Sonnet 4.6) still runs at that model's default.
- A Claude request through Foxl Relay that asks for a 1-hour prompt cache (
cache_controlwithttl: "1h") is now charged the 1-hour cache-write price, which is twice the model's input price (for example $8 per million tokens on Claude Opus 5.5), for the part written with that lifetime. It was charged the 5-minute price for every cache write. Requests that use the default 5-minute cache cost the same as before. - A workspace huddle whose participants dropped off without leaving in the last ten minutes before midnight UTC (a phone going to sleep, a closed laptop) now counts toward that workspace's Channels huddle minutes. Such a call was left out of every day's total, so its minutes were never measured; they now count on the next day.
- When Foxl's email provider refuses a message, Foxl no longer treats it as delivered. An organization invite now says its email was not sent, with the invite link still there to copy, instead of reporting it as sent, and a product-update email that could not be delivered is tried again the next time that campaign is sent, instead of being skipped for good. Asking for a sign-in link answers exactly as before, and a link that could not be sent is now logged so the problem can be seen and fixed.
- Changing one notification switch can no longer reset your other email and push choices. If Foxl could not read your saved settings at that moment, the change used to be applied on top of the defaults, which could turn back on push categories you had turned off and undo "unsubscribe from everything". Now the change is refused and the switch goes back. In the web app and in the desktop and phone apps from v0.7.28, the Notifications screen also says your settings could not be loaded instead of showing the defaults as your choices; older phone apps and the Foxl Code settings still show the defaults at that moment, but a change made there is refused the same way.
- On Windows, turning off "Keep running when closed" now stops the background Foxl service that was running. Before, the switch removed the service from Windows' startup tasks but left the running copy going, still holding the address the app's own server needs, so the app could not start its server afterwards. Only a process that is verifiably Foxl's own background service is stopped, as before. This was not run on a Windows machine before release.
- On Mac and Linux, with "Keep running when closed" on, opening Foxl no longer restarts the background service when your shell's settings could not be read at that launch (for example a
.zshrcthat waits on the network, or a login shell that timed out). Before, such a launch restarted it, ending its terminals and any reply in progress, and gave it a PATH without Homebrew, npx and similar tools until a later launch read your shell again. A real change to your PATH is still picked up the next time Foxl opens and reads your shell. - Beta updates: when installing the next beta, or the stable release after a beta, does not complete and Foxl comes back on the build you had, it now says the install failed (in the notifications bell and in Settings), as it already did for stable releases. Before, it treated the two builds as the same version and logged the update as applied.
- A beta build of Foxl Desktop installed without turning on Beta updates in Settings now receives the next beta, and is offered the latest stable release as an update if its beta is withdrawn. Before, it was quietly switched to stable updates, so it stayed on that beta until the next stable release. The Beta updates switch now shows On for such a build, and turning it off still keeps you on stable updates without going back a version.
- In Foxl Desktop, only the main window can now start the screen and system-audio capture that Foxl Notes uses to hear the other side of a meeting. Before, any Foxl window (the meeting overlay, the huddle window, the pet, Flow or Quick Chat) could ask for it, so a script running in one of them could record your screen and system audio without a prompt. Recording from Notes works as before. This does not protect against a script running inside the main window itself.
- Starting a coding task on this computer no longer freezes Foxl while the repository clones. Chats, terminals and the phone connection kept stalling for the whole clone, and again while the task committed and pushed, and a stalled download could freeze the app until it was restarted. Each git step now runs in the background with a time limit, and cancelling a task while it is still cloning stops it before its coding agent starts.
- At most five coding tasks run on this computer at once. There was no limit, so a chat that kept starting agents could start any number of them on your machine; a sixth is now refused with a message saying too many are running, and the orchestrator tells you instead of retrying. Quitting Foxl or restarting its server now stops a running task's coding agent itself instead of leaving it to the operating system.
- Opening a second "This computer" pane on a repository that is still being cloned now waits for that clone and starts in the finished checkout. It used to start its coding agent at once in the half-copied folder. A clone that fails or runs out of time no longer leaves a partial folder behind, so the next pane clones the repository again instead of silently starting in the broken copy.
- Coding tasks running on your computer now show up in Foxl Code on app.foxl.ai and in the phone app, and can be opened and cancelled there. Every request for them was refused with "a relay JWT is required" on those surfaces, so the list stayed empty and only the desktop app could see or stop them.
- Opening a coding task that runs on your computer from app.foxl.ai or the phone now shows its live output as it happens. The connection to your desktop held the whole stream back until it gave up after 10 seconds, so nothing arrived.
- On app.foxl.ai and the phone apps, Retry and Edit in a chat that Foxl Relay answered before relay chat was switched off no longer delete the answers that followed. Chat there runs on your desktop now, so while the relay cannot answer, Retry and Edit leave the conversation exactly as it was and say why, and an edit you were saving stays in its editor.
- On app.foxl.ai and the phone apps, a message you send in a new chat with no signal is no longer answered with "Chat here runs on your Foxl desktop, and it is not reachable right now" the moment the network comes back. It stays in the queue, marked as waiting, until your desktop is connected, and is then sent to your desktop as a new chat from the new-chat screen, where you can see it in the queue first. If that send fails, the message stays queued and is tried again, and it is sent once even with Foxl open in two tabs. A message queued inside a chat that only Foxl Relay answered cannot be sent while relay chat is off: it stays in that chat's queue with a note saying so, and you can remove it.
- On app.foxl.ai and the phone apps, a saved copy of a desktop chat no longer offers "Or continue here as a new chat" when Foxl Relay cannot answer your account. The copy it made could never get a reply, and the app kept showing it even after your desktop reconnected. The notice now just asks you to reconnect your desktop to reply.
- Editing a message you added to the queue while Foxl was still answering now really replaces it. Before, the edit looked saved, but the original queued message stayed in the conversation: it came back when you reopened the chat, above the edited one, and Foxl kept reading it as part of the conversation.
- A Foxl Code terminal stays usable when its agent opens a pull request while it is still working. The task moves to review at that moment, and the terminal went on showing the agent's output but dropped everything you typed without a word, greyed out the phone's keyboard as if the session had stopped, and never came back after a network drop. It now takes typing, resizes and reconnects until the run has actually finished.
- Shared files and Channels keep working in a window left open for more than 12 hours. Once the sign-in's 12-hour access token expired, opening or saving a shared file and sending a channel message failed with "Request failed (401)", and a channel that lost its connection could not reconnect, until the page was reloaded or something else happened to renew the sign-in. They now renew the sign-in once and carry on.
- More Foxl Code screens explain a failed request in your language. The Work page, Usage, Runtimes, Files, the Autonomy settings, Machines, the GitHub install step and a failed answer to an agent's question could show the raw request instead, such as
GET /api/usage 502:followed by a web page's HTML, a bare error code, or the browser's English "Failed to fetch". They now show the server's own explanation when it gave one, and otherwise "That did not go through. Try again in a moment." in your language. - Stop works on a reply that has been running for more than half an hour. After 30 minutes Foxl treated a chat as idle even while its reply was still working, and from then on Stop, deleting the chat, or sending a new message only marked the reply as stopped: a command it was running kept going until its own time limit, and a reply still being written could keep running on your API key or Claude or ChatGPT subscription. The same happened after switching models while a reply ran. Stop now ends the command and the reply at once, a chat counts as idle only 30 minutes after its last reply finished, and no memory summary is written for a reply that is still running.
- When you ask Foxl to remember several things at once ("I prefer TypeScript, my name is Sam and I work in KST"), it now keeps all of them. It used to report each one as saved while your profile kept only one, and the same could happen to entries in the day's memory log when a chat and a heartbeat wrote to it together. Deleting a chat at the moment something else was being added to the memory log could also leave that chat's words in it; they are now always removed.
- Memory topics named in Japanese, Chinese, Russian, Arabic, Thai and other scripts are each kept in their own file, named after the topic and visible in Files. They all used to go into one hidden file, so each new topic replaced the last. Accented names keep their letters ("Réunion équipe"), two different topics whose names differ only in punctuation ("C++ notes" and "C# notes") no longer overwrite each other, and topics you saved before are still found and updated.
- Signing out of app.foxl.ai or code.foxl.ai in one tab now clears every other open tab of it too. Another open tab used to keep the signed-out account's notifications, chat list and unsent message on screen, show them to whoever signed in next on that computer, and save them into the new account's data the next time a notification arrived or was read. Those tabs now reload when you sign out, or when a different account signs in, in any tab; a recording running in one of them stops, since signing out has already deleted the notes it would be saved to. Your session refreshing, or signing back in as yourself, leaves them as they are.
- Signing in as someone else on the same phone or browser no longer shows the previous account's chats, notifications, unsent message or attached photos and files. After Account > Sign out, or after the app signed you out on its own and someone else then signed in on the iPhone or Android app, the next account's sidebar could list the previous account's chats while the computer was away, the bell its notifications, and the message box its unsent text and attachments, and the next message, rename or notification saved them into the new account's data. Account > Sign out now reloads the app the way the sidebar's Sign out already did, a different account signing in after the app signed you out reloads it too, and a reply still arriving for the previous account stops. When the app signs you out on its own nothing reloads, and signing back in as yourself on the phone keeps what you had open.
- Saving an edit to a message, or pressing Retry, and then opening another chat before it finished no longer loses your message. The old messages were deleted but the edited text was never sent (and a retried question was never asked again), so the chat ended before your question. It now waits in that chat's queue and is sent as soon as you open the chat again.
- On app.foxl.ai and the phone apps, the chat list you see while your desktop is offline stays accurate. A chat deleted on the desktop could come back in it (saying only its title had synced), a chat just started on the desktop could be missing from it, and removing a chat's download or archiving a chat could be undone, when two updates to the saved list happened at once.
- Deleting a chat while its reply was still being written no longer leaves a "1" on the Chat badge (and on the Dock icon on a Mac) that nothing could clear. The reply finishing marked the deleted chat unread, and there was no row left to open.
- On app.foxl.ai and the phone apps while your desktop is away, a message waiting to be sent in one chat no longer appears in every other chat's queue, where it looked like that chat's next message and Remove deleted it. Each chat's queue shows only its own messages, as on the desktop.
- "Open beside" on app.foxl.ai and the phone apps at tablet width now shows a desktop chat's messages - from your desktop when it is connected, or from the copy saved on the device while it is away. It used to say the chat had not synced to this device, even with the desktop connected.
- Opening app.foxl.ai in two tabs at once for the first time no longer leaves one tab's offline copies of your chats unreadable. Each tab could create its own encryption key for the saved chats, so after a reload the chats one tab had saved could not be opened offline, and the saved copies could be cleared. Both tabs now share the one key.
- On app.foxl.ai, clearing the offline copies of your chats in one tab (signing out, deleting all chats, or the app discarding copies it could not read) while another tab was open no longer stops that tab from saving or showing offline chats until the other tab is closed.
- Pressing Stop in the Foxl Code chat now keeps the tool steps and thinking the reply had already shown, including the row naming a task it had just started. They used to disappear, on screen and after a reload, leaving only the partial text or "[Cancelled]".
- "Delete all" in the Foxl Code task list no longer erases the chat of the tasks it keeps. Queued and running tasks stayed in the list, as the confirmation said, but their conversations were cleared from the device, losing every tool step and thinking row, and the chats of tasks that ran on your desktop were cleared too. Only the chats of the tasks actually deleted go now.
- Leaving Foxl Code's Tasks page while the chat is still replying no longer loses the reply. Opening Work, Repos, Files, Runtimes or Schedules (or another product) mid-reply used to leave that device with an empty or cut-off answer for good, and the next message sent the cut-off text as context. The reply now finishes and is saved either way; coming back while it is still arriving shows it streaming, with Stop working as before.
- Settings > Notes now says "Speaker separation is not installed yet" and shows the Install engine button on a Mac whose on-device speech engine is installed but whose speaker-separation models are missing. It used to show plain Ready there, so recordings came back as one speaker with no way to add the models from Settings.
- Settings > Usage now shows its request counts, totals and tool success rate in your language, with numbers written the way your language writes them, and a single request reads "1 request" instead of "1 requests". These lines, and the "to" between the two dates of a custom range, were in English in every language.
- code.foxl.ai's Settings has the Appearance pane again, so you can choose light, dark or system theme, the color theme, the surface, the text size, reduced motion, pointer cursors and the send key there, and the Tab bar pane for arranging the phone tab bar. Searching "dark mode" or "theme" in the command palette now opens Appearance instead of General.
- Saving Settings > Heartbeat no longer undoes newer heartbeat instructions. Changing only the interval or active hours used to write back the instructions the pane had loaded, replacing any edit made since in Files, by the agent, or in Settings on another device. Now the instructions are saved only when you changed them, and if HEARTBEAT.md was changed after you opened the pane, Foxl asks whether to overwrite it or reload the saved version, as the Files editor does.
- The Reload button in the "changed since you opened it" prompt and the Don't save button in the Files editor's unsaved-changes prompt are readable again. Their labels were drawn in the button's own background colour, in both light and dark themes, so each showed as an empty box.
- Dictate anywhere no longer offers Deepgram, AssemblyAI, OpenAI or ElevenLabs as its transcription provider, because dictation can only use Amazon Transcribe (or Foxl Relay, where your account has it). Picking one of those four used to dictate on this computer's own AWS account instead, billed there, or close the pill without a word on every press when the computer had no AWS credentials. If you had picked one, Settings > Notes > Dictate anywhere now says so, and pressing the shortcut shows a short message naming it instead of dictating until you choose another. Your pasted keys still work for recordings.
- The Dictate anywhere pill's messages are no longer cut off at both edges. The pill is small, and every message it can show - such as "Allow Accessibility to type · copied instead" - was clipped in every language, so the part saying what to do was often the part missing. The pill now widens to fit the message while it is shown.
- When Deepgram, AssemblyAI or OpenAI refuses the API key you pasted for Notes transcription, the recording now stops with the provider's own reason, such as "Invalid credentials." or "Incorrect API key provided", and names the provider. It used to say only that the transcription connection closed, so trying again failed the same way with nothing pointing at the key. Refusals from Amazon Transcribe and ElevenLabs now name the provider too.
- Dictate anywhere on Foxl Relay no longer loses the record of how long you dictated when the relay has a hiccup: a usage report the relay could not take is kept and sent again instead of being thrown away. If the relay refuses a dictation outright, the dictation now stops, your words so far are still typed, and the pill says "Foxl Relay refused this dictation". It used to keep listening as if nothing had happened.
- Skills with Korean, Japanese or Chinese names are each their own skill now. Every such name used to be filed under the same id, so creating a second one replaced the first without a word, switching one on or off switched all of them, and Delete could remove the wrong one. Creating a skill whose name is already taken now says so and keeps the existing skill, instead of overwriting it; the same goes for a second skill that keeps the template's "My New Skill" name. Skills you already have keep their files and their on/off state, and a skill you switched off stays off when a copy of it appears or goes. If you go back to v0.7.28 or earlier afterwards, the skills whose names used to share one id there (Korean, Japanese and Chinese names, and look-alikes such as C++ and C#) follow their own files again, so a skill you had switched off can be on in that version.
- Settings > Migrate from OpenClaw now imports. The Migrate button used to show a dry-run report every time and write nothing; it now runs the dry run, shows what it found and imports once you confirm. The import no longer replaces anything already in your workspace: every OpenClaw persona is kept, a daily memory file for a day you also used Foxl is added to that day's log instead of replacing it, and running it twice does not import anything twice. On the web app or the phone, a computer still running an older Foxl only runs the dry run and asks you to update Foxl there first, because that version's import replaced files.
- The Integrations page shows a skill as on when the agent is using it. A skill whose SKILL.md has no on/off line is on, and the Skills page said so, but Integrations showed it as off with an Enable button - and when it needs a key you had not pasted, only a greyed-out "Paste credentials to enable", so it could not be switched off there. It now shows as on, with Disable.
- In Foxl Code, "Manage machines" and "Models and credits" in the Tasks and Runtimes header now open Settings on that pane, with the sidebar and the address bar following. They used to show Code Settings inside the Tasks or Runtimes page, and clicking a task or that same sidebar row afterwards did nothing. Repos' "Start task" and the setup checklist's "Open repos" and "Open Settings" now land on the page they name the same way, and clicking a task while the checklist is showing opens it.
- Saving Foxl Code Settings or the Autonomy card no longer switches back settings that were changed somewhere else after the page was opened, such as auto-merge or the self-directed loop turned off on your phone, or the coding agent picked in the Tasks header. A save now sends only what you changed on that page.
- Settings > Code > This computer now shows a change only once your computer has confirmed it: "Agents act without asking", the start folder, "Stop offering", the clone folder and "Add a folder". When the phone or app.foxl.ai had lost its connection to the desktop, a change there used to look saved while the desktop kept the old setting, so "Agents act without asking" could read off while agents on the desktop still acted without asking. The switch now keeps reading on until the desktop confirms it is off, and a change that did not reach the desktop says so.
- Files on app.foxl.ai and the phone apps no longer saves a sample file over your real one. With your computer away, Files shows sample files under the real names (MEMORY.md, HEARTBEAT.md and the rest); when your computer then connected, a file you had open kept its sample text, and saving it replaced your real file with that text without asking (for HEARTBEAT.md it also switched the heartbeat off). The open file is now reopened from your computer as soon as it connects, a sample copy is never saved to it, and if you had typed into the sample copy you are told those edits were not saved.
- Schedules on app.foxl.ai and the phone apps now shows your own schedules as soon as your computer connects. With your computer away the page shows sample schedules ("Morning briefing" and others); they used to stay listed as yours for up to an hour after it connected, and turning one on or off, editing or deleting it failed. Coming back to Schedules later no longer brings the samples back either. And when your schedules cannot be read, on any device, the page now says so and offers Retry instead of claiming you have none.
- A chat's Files panel on app.foxl.ai and in the phone apps now says "Connect your desktop to see workspace files" while your computer is away, instead of listing sample files (AGENTS.md, SOUL.md, a memory folder) as if they were yours. Your own files appear as soon as your computer connects.
- Typing in the message box is fast again in Korean, Japanese and Chinese, especially with a long draft or pasted text. Since v0.7.26 the message box used phrase-by-phrase line wrapping, which doubled the work done on every keystroke: typing Korean into a 12,000-character draft on a slower machine took about 49 ms per keystroke instead of 28 ms. The message box and other text fields wrap as they did before v0.7.26, and messages, the sidebar and cards keep wrapping by phrase.
- Dictate anywhere works again on the desktop. Since v0.7.21, holding Fn showed the pill for a moment and then closed it without transcribing anything: the pill could not start a transcription session because its requests to the local server were refused.
- A Foxl Code task's plan shows its status ("Open", "In progress", "Done") again. It had been printing an internal label,
task_detail.plan_status_open. - Deleting a chat now also takes Foxl's automatic summary of it out of memory: the session notes file (which quoted your first messages) and the "Session Summary" in the day's memory log, so later chats no longer list it as recent history. A chat deleted within half an hour of its last message used to be summarised after you deleted it; it no longer is. Deleting from the trash for good also removes session notes an earlier version left behind. A Session Summary written before this update names its chat only by the first 8 characters of the chat's id, so it goes with the chat only when no other chat's id starts the same way, and is otherwise left as it is.
- A chat moved to the trash with Cmd+D (or from the sidebar) takes Foxl's automatic memory of it along: its lines in the daily memory log and its session notes (
memory/sessions/) leave the workspace while it is in Settings > Archived chats, and it is out of the search bar and the agent's conversation search. Restore puts them back as they were. Before, the agent still listed it under recent conversation history in every new chat and could open its session notes, and restoring a chat did not bring its memory-log lines back. Deleting it for good removes them with the chat. Archived conversations are set aside the same way until you unarchive them, and a reply written in an archived chat is added to the memory log when you do. What you or the agent saved on purpose (USER.md, MEMORY.md and memory topics) stays where it is. - Conversation search lists every conversation that mentions what you typed. Before, one long conversation that mentioned it about a hundred times or more filled the whole list, so the search showed only that conversation and offered no more results. On the phone, the number beside a result now counts all of its matching messages.
- Searching for a Chinese, Japanese or Thai word finds it in the middle of a sentence, both in the search bar and when the agent looks through your past conversations; so does a Lao, Khmer or Burmese word. Before, a Chinese or Japanese word was usually found only at the start of a sentence, and many Thai words were not found at all. Search for the word itself: in these languages a whole sentence is looked up as one piece of text.
- The agent's terminal now types a command exactly as written. A backslash followed by
norrused to be turned into Enter anywhere in the line, so a Windows path such asC:\Users\me\proj\node_modulesran asC:\Users\me\projand thenode_modules, and a quoted\nin asedorprintfcommand was split into separate lines. Only a real line break presses Enter now, and a command that ends in the two characters\nwith no real line break is refused rather than typed, so nothing is left half-typed for the next command to run. - When the agent rewrites a file that is a symbolic link, such as a
.zshrclinked into a dotfiles folder, the change now goes into the file the link points to and the link stays a link. It used to replace the link with a separate copy and leave the real file unchanged. A rewritten file also keeps its permissions now: a script stays executable and a private file such as~/.aws/credentialsstays readable only by you, where both used to be reset. - With Settings > Web Access filtering turned on, the agent's browser tool now checks every address it is told to open the way the browser reads it.
open example.comwithouthttps://, an address ending in a dot such asexample.com., one with a user name in front (user@example.com), percent-encoded or written in full-width characters, and a site opened inside abatchof browser commands all reached a blocked site before; only a fullhttps://address was checked. With filtering on,data:andjavascript:addresses are refused too, since they can send the page anywhere. Links and redirects the page itself follows are still not covered by this check. - The agent's code search now returns as many matches as it asks for, and says when there were more. A search for 50 results used to come back with about 10, because the lines of surrounding code used up the limit, and it reported those 10 as the complete count, so an agent renaming a function could fix a fifth of the call sites and call it done.
- The tool profile you pick on the Tools page, and any tool you switch off there, stay that way after Foxl restarts. An update, a reboot or the background server restarting used to put every tool, including shell commands, the terminal and browser control, back on without telling you. Browser control switched off in Web Access also stays off when the Chrome extension reconnects.
- Deleting a chat for good also deletes what its tools printed. Before, a second copy of every tool result a chat produced - a file it read, a command's output, a fetched page - stayed in Foxl's database after Delete permanently or Empty trash, whole and with no size limit. Those copies are now kept to the same 1 MB per result as the chat itself and removed with it, and ones saved before this update, which cannot be tied to a chat, are cleared once they are seven days old. The Overview page still counts the tool calls of a deleted chat; only what they read and printed is gone.
- Export JSON in the desktop app saves the whole conversation. Before, a tool result over 256 KB was cut short in the file, and in a conversation over 4 MB the older turns' screenshots, documents and tool results were replaced by notes pointing back at the app, so an export taken before deleting a chat could be missing parts of it without saying so. On the phone and app.foxl.ai, an export over 4 MB still leaves out the oldest turns' attachments and tool results, because it has to fit the connection to your computer; it now says so at the top of the file and names what is missing where it was.
- Install engine for on-device transcription can be pressed again after a failed attempt. Once a first attempt had created its Python environment - for example when the model download dropped, or the speaker models failed and the message said to press Install engine again - every retry stopped at once with "could not create the Python environment (uv venv)", and only deleting a folder by hand got past it. A retry now keeps what was already installed and carries on from there.
- With your own Anthropic API key, the home screen's greeting and suggestions ask for Claude Haiku 4.5 by the model id on Anthropic's models page. Before, Foxl sent an id that page does not list. The model list for that provider uses the listed ids for Opus 4.6, Sonnet 4.6 and Haiku 4.5 too, and a model you had already picked there under the old id stays picked.
- The system report in Settings names the version of Foxl you are running. Every installed copy reported
Version: vdev. - Using a Claude Pro or Max plan in Foxl no longer signs Claude Code out of its MCP servers. When Foxl renewed the Claude sign-in it rewrote the credential Claude Code keeps, keeping only the Claude token and deleting every MCP server login stored beside it, so each one had to be signed in again in Claude Code after every renewal. Foxl now changes only the Claude token, keeps every other saved value exactly as it was (including ones with quotes, backslashes, line breaks or accented letters), and no longer overwrites a newer sign-in Claude Code saved in the meantime. If Claude Code's saved sign-in is too large for Foxl to update safely, or cannot be read, Foxl now leaves it alone instead of renewing it, and once the Claude sign-in has expired it asks you to open Claude Code once so Claude Code renews it itself.
- A Claude Pro/Max or ChatGPT sign-in that expired while the computer slept no longer makes one of two things that start together fail. Two schedules, chats or background tasks starting at the same moment each renewed the sign-in with the same one-time renewal token, and the one that lost failed with a sign-in error. Now they share one renewal, and a renewal that is refused picks up a sign-in that Claude Code or Codex saved in the meantime.
- Using a ChatGPT Plus or Pro plan in Foxl no longer switches the Codex CLI to API billing. When Foxl renewed the ChatGPT sign-in it rewrote Codex's
auth.jsonwithout the line that says the sign-in is a ChatGPT one, so on a login that also held an API key the nextcodexrun billed that key instead of the plan, and Codex's agent identity was deleted too. Foxl now changes only the sign-in tokens and the renewal time, keeps everything else in the file, and no longer overwrites a newercodex loginmade in the meantime. - The Notes assistant remembers what was already said when it answers without its tools on Amazon Bedrock. A follow-up such as "Expand on the second one" used to reach the model with only the new question, so it could not know what "the second one" was; the earlier questions and answers are now sent with it, as they already were on Anthropic, OpenAI, Google and Ollama. The same change is made for a Claude Pro/Max or ChatGPT plan, where it has not been tried against the real service yet.
- With your own OpenAI key, Notes' summaries, titles, live translation and Flow dictation cleanup now send OpenAI's reasoning models (o3, o4-mini, GPT-5.x and GPT-6) a request those models accept. Foxl sent them a length limit and a temperature setting that OpenAI does not accept for them, so the request could fail while agent chat on the same model worked. They now also run at the lowest reasoning effort each model allows, so a short answer such as a note title is not used up by reasoning and returned empty. This was checked on the same models served through Amazon Bedrock; OpenAI's own service has not been tried yet. Other OpenAI models and OpenAI-compatible providers are unchanged.
- Saving to a memory topic that already exists now adds to it. When the agent saved meeting notes under a category it had used before, such as "Meeting Notes", the new notes replaced everything saved there earlier with no copy kept, and the Memory index kept describing the first save. The new notes are now added under a dated heading below the earlier ones, and the index describes the newest entry.
- A memory topic you edited in Files keeps being one topic. After saving a topic file in Files once, the agent's next save to the same topic started a second file and a second line in the Memory index, because Files writes the topic's name in quotes. Topic files with Windows line endings or a byte-order mark, and names another tool wrote in single quotes, were affected the same way.
- A memory topic whose name contains " #" (for example "Tips #1") keeps its full name when you edit it in Files. Files read everything from " #" onward as a comment, saved the name as "Tips", and the agent's next save to "Tips #1" started a second file. The agent now writes topic names in quotes, so Files reads them whole. A topic file that Files already cut this way is not repaired: it keeps the shortened name, and the next save to the full name still starts a new file.
- Typing in the desktop's floating Notes window during a meeting no longer loses keys, on either the Notes tab or the Background tab. When you typed quickly, the window could briefly put back an older copy of what you were writing, which removed the keys you had just typed (and on the Notes tab moved the cursor), and the saved note or Background could end up without them.
- Leaving a huddle while muted and joining one again no longer sends your microphone. You stayed muted on screen, on your level meter and on everyone's participant list, but the new call's microphone was live, so the room could hear you. A call you join now starts in the mute state the button shows.
- Joining a huddle from a second device while you are already in it on another one now connects that device to everyone. It used to take your other device's place in the call, try to call itself, and could end up with no audio to or from other people.
- A huddle recovers after your connection drops and comes back mid-call. If the call later lost track of you (for example after switching from Wi-Fi to mobile data), Foxl used to keep showing you in the call with no audio either way until you left and joined again. It now rejoins the call by itself.
- Joining a huddle that already has about ten people in it no longer throws people out of the call. The joiner, and people already in the call, could be disconnected moments after someone joined and then drop out and back in again.
- A huddle that is still running past midnight UTC, with nobody joining, leaving or muting, is no longer recorded as having ended moments after it started. Its minutes now count in the workspace's channel usage until people really leave.
- Sending a file in a channel or direct message works in a workspace whose name has a space in it. Every attachment there failed with "That folder does not exist" and the message was removed; the file now lands in the workspace's chat folder and the message sends.
- "Load older" keeps working in a channel where you have blocked someone, or someone has blocked you. One of their messages among the newest ones used to make the button disappear for that channel, leaving older history unreachable; it now pages back past their messages as well.
- A message you send or edit now appears straight away on your other open devices, such as a second tab, the desktop app or your phone. It used to show only on the device you sent it from, and once someone replied, your other devices showed the reply without your message until you reopened the channel.
- Uploading a file in Shared under a name that is already in the folder now asks before replacing it. It used to replace the existing file, often a colleague's, without a word and with no way to get it back. Choose Replace to update it; otherwise both are kept and the new file is saved as "name (1)".
- Connecting GitHub from the desktop app now finishes even if you click back into Foxl before GitHub is done. It used to end with GitHub showing the app installed and Foxl Code's Repos page showing nothing, because switching back to Foxl early used up the step that completes the connection.
- app.foxl.ai and the phone app keep working when the desktop wakes from sleep, changes network or reconnects to Foxl Relay while they are open. Before, they kept using the encryption key from before the reconnect: the first lists they reloaded and anything saved in that moment failed, and an open remote terminal ignored what you typed, with nothing on screen saying so, until the page was reloaded. They now set up a new key with the desktop as soon as it is back, and wait for it before sending.
- An encrypted request the desktop refuses, such as a duplicate that arrives late, no longer takes the desktop offline for every phone and tab ten seconds later. The desktop now answers it with an error, so only that request fails.
- Opening a terminal from a phone or browser that is already connected no longer makes the desktop show "Device connected" again for every terminal. The notification now comes once per device, as intended.
- Long conversations, notes and files in Korean, Japanese, Chinese or with emoji now arrive intact on the phone and on app.foxl.ai. Anything over about 64 KB that came from the desktop had a few characters turned into replacement marks, and saving it from there wrote those marks back into the desktop's copy. Chat replies from the desktop are fixed the same way.
- The desktop now checks the whole integrity tag on every encrypted message that reaches it from app.foxl.ai or the phone. The desktop app, and the background service on Windows, used to accept a tag cut down to a quarter of its length, which turned forging a message from practically impossible into a one-in-four-billion guess. The background service on macOS and Linux, and the browser, already refused such messages.
- On iPhone, a Notes recording that is recovered after the app was closed mid-meeting (iOS stopping it to free memory, or a force quit) now keeps its audio and plays back like any other note. Before, only the transcript came back, and the recorded audio was deleted the next time you pressed Record.
- Voice input now stops and shows Amazon Transcribe's own message when the service refuses the stream, for example because an AWS session expired or a permission is missing. Before, the microphone stayed on and the button stayed red while nothing was transcribed, and with Foxl credits the seconds kept being charged. This covers the microphone in Agent chat, Foxl Code chat and Quick Chat, and Foxl Flow, which stops listening, pastes what it heard before the refusal and shows Amazon's message on the pill.
- On iPhone, voice input in a chat no longer stops a meeting Foxl Notes is recording. Dictation now shares the microphone with the recording and leaves it running when it finishes, fails to start, or is tried while the recording is paused; before, the meeting stopped hearing anything and Notes gave up on it about 15 seconds later.
- Voice input in Japanese or Chinese no longer adds a space after every sentence. Two dictated sentences now read 今日は晴れです。明日は雨です。 in the chat composer, and in Foxl Flow when it pastes your words without cleanup. Korean and other languages written with spaces still get one space between sentences.
- Foxl Flow no longer pastes the first half of a long dictation when the cleanup model runs out of room. With an Anthropic, OpenAI or OpenAI-compatible key as the model, an answer cut off at its length limit now counts as a failure, so Flow pastes your own words instead, and a Notes summary or answer reports that it was cut off instead of keeping only its beginning. On Foxl Relay, Flow's cleanup does the same while "Wait for the full answer" is on, which is the default.
- Tapping the microphone again while voice input is still starting now cancels it, in Agent chat, Foxl Code chat and Quick Chat. Before, the button went back to idle and then turned red a moment later with the microphone on and your speech being transcribed and charged to your Foxl credits; leaving the chat while voice input was starting did the same, with nothing left on screen to stop it.
- Pet characters collected before pets moved to your Foxl account are now added to it even if you first open the Den offline, signed out or while Foxl Relay is having trouble. That first failed attempt used to count as done, so those characters were never added and did not show in the Den, the Settings gallery or on the desktop pet.
- On iPhone, the Foxl Relay data sharing sheet no longer accepts "Don't allow" while your Allow is still being saved. Declining at that moment used to close the sheet as if you had declined, while your account kept the permission and later requests went out without asking. The decline is now unavailable while the save is in progress, which is usually a moment and at most about 20 seconds on a poor connection; to withdraw permission afterwards, use Settings > Data controls.
- A Notes meeting report for a Japanese or Chinese conversation now shows a real speaking pace. It used to count each sentence as one word, so normal speech showed about 5 to 12 words per minute, and the AI coach was given that number as a fact about how you spoke. English, Korean and other languages written with spaces show the same pace as before.
- In a channel or direct message, pressing Italic (Cmd/Ctrl+I or the toolbar button) on bold text now makes it bold italic. It used to remove the bold and leave the text italic only. The Italic button also shows as pressed on bold italic text now.
- The desktop titlebar's status pill and its MCP tooltip are now in your language. The pill read "42% ctx" and the tooltip "2/3 MCP servers connected · 1 error" in English whatever language the app was set to.
- In the desktop titlebar's status panel, an MCP server that failed to connect now shows its retry button when you point at its row or move to it with the keyboard, and the button spins while the retry runs. The button was there but invisible, so there was no way to see it.
- Large product-update and marketing announcements are now sent in rounds, so every iPhone that has them switched on can be reached.
- Once status.foxl.ai is next deployed, it keeps checking the Foxl API every two minutes while the API hangs, so a hang is reported as an outage two minutes sooner. A check that had to wait out its 8-second timeout used to push the next check back by a whole round, for as long as the hang lasted.
- Once status.foxl.ai is next deployed, its API reports
uptime_24hover the last 24 hours rather than since midnight UTC, so an outage late in the evening no longer vanishes from it at 00:00. The since-midnight figure stays available asuptime_today, andmonitoring.sweep_interval_mswill say two minutes, the interval that same deploy switches the checks to. - Once status.foxl.ai is next deployed, it keeps working through an incident that stays open for weeks. The front page and the API will show a long incident's status changes and latest updates, with a link to its full timeline, instead of every 15-minute update; after about five weeks those updates outgrew the page's stored snapshot, and the page then reported its own monitoring as stale while it was running.
- Foxl Code compute now counts as credits used. On the Account page, the Foxl Code Usage page and the 80% and 100% usage emails, an account that spent its credits on cloud tasks used to show little or none of them as used, so the 80% email never came and the 100% one came only once the balance had gone below zero. Relay transcription and the monthly workspace storage and channel charges now send those emails too when they take you past 80% or 100%, instead of waiting for your next chat message. You still get each email at most once per billing period.
- Foxl Code tasks run on Claude Code (from chat, a schedule, Solve, the API or Retry) are no longer stopped after two minutes with "The agent produced no output within 120s". Claude Code shows nothing in the terminal until it has finished, and Foxl read that silence as a start that had failed, so every such task that needed more than two minutes was stopped and its changes were thrown away before it could commit, push or open a pull request. These tasks now run until they finish or reach their time limit. A Claude Code task that really cannot start is still stopped at two minutes, and terminals you type into are unchanged.
- "Fix it" in Foxl Code's Needs-you list now reaches the agent when the task's cloud machine had gone to sleep. Its instruction (read the failing check and fix it, or address the review comments) is typed into the reconnected Claude Code once it is ready and sent, so the agent starts working on it. Before, nothing was typed and the agent sat at an empty prompt. The reconnected session still stays open after the agent is done, until you close it or the task's time limit ends it (30 minutes by default), and that machine time is billed as before.
- Reconnecting a Foxl Code Remote terminal brings back what it was. When Claude Code is your default coding assistant, a plain Terminal pane comes back as a shell, not as Claude Code - including when the pane reconnects on its own after its cloud machine went to sleep - and a Claude Code pane you reconnect and then close no longer runs your repository's test suite or opens a pull request, which a terminal session never does. With another default assistant, a Terminal pane still cannot be reconnected. Terminal panes opened before this release still reconnect as Claude Code, because which ones were shells was not recorded until now.
- A Foxl Code task on Claude Code, Codex or Kiro whose repository cannot be cloned now fails at once and says why ("Could not clone owner/repo: fatal: Remote branch main not found in upstream origin"), instead of starting the agent in an empty folder, spending model credits there, and ending in Needs you with no pull request and no reason. This happens when the repository's default branch was renamed or deleted, the repository was renamed or removed, Foxl Code lost access to it, or the clone timed out.
- Reconnecting to a Foxl Code terminal on Claude Code after its machine was recycled (machines are released after 15 idle minutes) now resumes the agent's conversation instead of starting it over, and the terminal says the machine was recycled instead of blaming a Foxl Code update or 14 idle days. Reconnecting to a task that ran in the background no longer closes the terminal at once with "No conversation found to continue": it opens a new conversation and says why.
- A Foxl Code task that runs for more than an hour now gets fresh GitHub access before it pushes its branch and opens its pull request. GitHub's access for a task lasts one hour while a task may run for up to eight, so a long task used to finish its work, fail to push it, and lose it when its machine was recycled. This covers only Foxl's own end-of-run push and pull request: git commands the coding agent runs itself during the task still use the access it started with, so after the first hour GitHub refuses those.
- In Foxl Code's Files view, a finished task whose machine has since been recycled now says its checkout is gone and names the branch its pushed work is on, instead of showing an empty folder that looked as if the agent had produced nothing.
- Foxl no longer marks a Remote task on Cursor, Hermes or OpenCode failed 15 minutes after it starts. Any such run still going at that point was failed, reported as "stream ended" and billed to that moment, and the result the agent sent at the end was refused. Foxl now waits for the time limit you set in Settings, plus the time the agent needs to save and push its work, before it gives up on a run that has not reported back, and bills a run that stopped without reporting only up to its last sign of activity plus 15 minutes.
- Foxl Code's notification bell shows "CI failed", "Review approved" and "Changes requested" for a task whose agent had already finished, and the task's timeline records its CI results, review verdict and auto-merge. They were dropped without a trace once the run was over, which for most tasks is before CI reports.
- In Foxl Code, a failed CI check on an agent's pull request, a reviewer's "changes requested" and Request changes on the Work page now reach an agent that is still working on the task. The feedback used to go where a running agent could not see it, so it was lost. Request changes also no longer reports the agent as resumed when the feedback did not reach one.
- Pressing Reconnect with an instruction on a Foxl Code task whose agent is still running now types the instruction into that agent. It used to be dropped, and the task was reported as gone and needing a reconnect while it was still running.
- A Foxl Code plan that starts several tasks at once in a repository you had not used before now adds one "Daily check" schedule for it. It could add one per task, and each of them then started its own daily run on the same repository.
- Reopening a closed pull request in Foxl Code brings its task back to review, and merging it later marks the task merged. The task used to stay cancelled from the first close, so its CI results, review and auto-merge were no longer tracked and Retry was offered on work that had shipped.
- The "Checks failed" notification for an agent's pull request in review is now sent whichever of GitHub's two reports of a failed run arrives first. It was missed whenever GitHub reported the failed workflow run before the failed check suite, so the phone stayed silent and the failure never appeared under Needs you.
- Issues filed by a Foxl Code "issue" schedule are recorded under the repository they were filed in, or not recorded at all when Foxl cannot confirm you still work in that repository. They could be recorded under a different repository you had worked in, so Solve and Decline on the Needs you card acted on the wrong issue there (Decline closed it on GitHub), and the loop's open-issue budget was never given back.
- Foxl Code's cloud orchestrator now stops a chat answer when its own connection closes, including the model request it is waiting on and any command it is running, instead of calling the model on your credits and running tools, coding agents included, for an answer that can no longer arrive. Pull-request reviews and the background loop keep running when their caller goes away, because they report their results on their own. Whether closing the tab or pressing Stop reaches the orchestrator in the cloud has not been measured yet.
- A Foxl Code orchestrator answer no longer hangs forever when the orchestrator runs a command that waits for input or never exits, such as starting a development server, a
git committhat opens an editor, ortail -f. The command now gets no input, and it is stopped after five minutes (or the limit the orchestrator asks for, at most fifteen). In the desktop app's Foxl Code, Stop now also stops a command the orchestrator is still running, with the processes it started, and a server it left running in the background stops when Foxl does.
Changes
- Unread notifications are red in the iPhone and Android apps again, matching the desktop and the web. The bell's badge, the tab bar's badge and the unread dots on the notification rows had been blue in the apps since v0.7.18.
- Typing and streaming replies stay smooth with a long conversation list. The sidebar and every conversation in it used to redraw on each character typed in the message box and on every update of a streaming reply. With 200 conversations on a slower machine that was about 60 ms of work per keystroke, and while a reply streamed the app dropped to 27 frames a second with typing 100 to 200 ms behind. The sidebar now redraws only when something in it changes: typing costs about 5 ms per keystroke, and a streaming reply keeps 60 frames a second.
- Long conversations open faster. Coming back to Chat from another page no longer re-reads the formatting of every message, and on the desktop app and in Chrome and Edge, messages scrolled out of view are no longer laid out and painted until you scroll to them. For a 120-message conversation full of code and tables on a slower machine, returning to it went from about 320 ms to 160 ms and opening it from about 510 ms to 370 ms.
- Typing in a note keeps up with many saved notes. Each keystroke used to convert the whole note and redraw every row of the notes list; with 300 notes on a slower machine that was about 90 ms per keystroke. The list and the saved copy now take the edit together when you pause, switch notes or leave the window, and a keystroke costs about 17 ms.
- Typing in a file in Files no longer redraws the whole file tree on every keystroke. With 400 files showing (the session memory folder is open by default and grows daily) that was about 80 ms per keystroke on a slower machine; it is about 13 ms now.
- Less background work: another open tab or window no longer makes this one redraw every 10 seconds, the titlebar usage readout and the desktop connection status in Settings stop polling while the window is hidden, a running agent no longer copies a 500-event history that nothing displayed on every event, and the Runtimes page no longer redraws every pane every 10 seconds when nothing changed.
- An MCP tool added or edited from the phone, app.foxl.ai, the iOS app or a script calling Foxl's local API is now saved switched off, and the Tools page there cannot switch it on: turn it on in Foxl on the computer it runs on. Saving one from there used to start its program on your computer straight away. On the computer itself nothing changes: saving with the switch on, or turning the switch on, starts it as before, and tools you already have keep running. Editing a running tool from the phone keeps it running unless the edit changes its command, arguments, environment or address, in which case it is switched off until you turn it back on on the computer. This stops a save from another device from starting a program by itself; it is not a sandbox, and a connected device can still run commands on the computer through the terminal and shell tools as before.
Fixes
- GPT, Grok and Gemma replies through Foxl Relay are no longer kept by Amazon Bedrock. Bedrock's Responses API keeps each reply, with the message that asked for it, for 30 days unless told not to, and the chat on app.foxl.ai, the phone apps and Notes never told it, so every such turn was kept in one store that every Foxl request shares and could be continued by anyone holding the reply's id. The relay now asks Bedrock to keep nothing on every request, and refuses
previous_response_id,conversationand item references with a clear 400 (stored_state_unsupported) instead of reading a stored reply. No Foxl app, Foxl Code agent or Codex uses them, so nothing changes for you; a program of your own that chains turns byprevious_response_idthrough the relay needs to send the earlier turns ininputinstead. Replies kept before this change expire on Bedrock's 30-day schedule. - Save Image As on a chat image now names the file after the format the image really is. An attached
photo.jpgis offered asphoto.jpg, notphoto.jpg.pngwith JPEG data inside, in the desktop save dialog, the phone's share sheet and a browser download alike. The desktop dialog now offers only that image's own format (plus All Files) instead of PNG, JPEG and WebP choices that renamed the file without converting it. An image whose format Foxl cannot recognise keeps its own name and gets no extension added. - The desktop's local server no longer gives its access key to any program that opens its start page. Before, any other program or user account on the computer that could reach the local port could read the key from the page and then run commands through Foxl. Now only the Foxl app itself receives it. With "Keep running when closed" on, the key now also changes every time the background server restarts. Whenever the local server restarts under a new key, an open window picks it up and reconnects instead of reloading.
- On app.foxl.ai and the phone, opening a chat from the sidebar now clears its "not downloaded" cloud as soon as the chat's messages are saved on the device. Before, the cloud stayed until the next background sync, even though the chat had just opened with its messages on screen.
- Restricted shared folders now protect text documents and chat attachments. A text document in a restricted folder is listed, opened, found by search, edited, renamed or deleted only by the people that folder admits (its members, its creator and workspace admins, with a view-only member able to read but not change it), and the shared document list no longer shows the names of folders you cannot open. A file sent in a direct message or a private channel is listed and downloadable only by the people in that conversation, and the direct-message and private-channel folders are no longer listed to other workspace members; workspace admins do not see them either, matching the chat itself.
- Shared documents and shared skills now have limits, so one account can no longer fill the storage every Foxl user shares. A document or skill can be at most 512 KB, a workspace can hold up to 2,000 shared documents and 500 shared skills, and each account can keep up to 25 MB of shared documents and skills in total across all its workspaces. Editing a document never fails because of that total unless the edit makes it larger, and deleting a document now frees its space. A workspace's allowed-models list is capped at 200 entries. Shared files are not affected; they already have their own storage limits.
- Foxl Code no longer lets a pull request from someone else's fork act on your task. On a public repository anyone could fork it, name a branch after a running task's branch and open a pull request; that moved the task to review with their pull request attached, started a paid review of their changes, cancelled the task when they closed it, and their fork's checks could mark the task's CI red or green and wake the agent. Pull requests, reviews and CI results now count toward a task only when the branch is in the repository itself, and auto-merge refuses any pull request whose branch lives in another repository. Pull requests and CI on your own branches work as before.
- Connecting GitHub to Foxl Code no longer gives you more access than you have on GitHub. Before, a GitHub account that could see just one repository of an installation, as a collaborator on someone else's repository or as a read-only member of an organization, could start agents, merge pull requests and close issues on every repository in that installation. Foxl Code now asks GitHub what your own account can do on the repository first. Starting a task, merging, closing, asking for a review, scheduling, and giving the chat assistant write access to the repository need write access. Viewing a repository's Work list and diffs needs read access. Connect GitHub also no longer adds you to another person's personal installation just because you collaborate on one of their repositories. If you own the account or have write access, nothing changes. Accounts connected before GitHub sign-in was linked to Foxl are not checked yet.
- Foxl Code's task limits now hold when many tasks are started at once. Before, starting a burst of tasks in the same moment (from several tabs, a script, or the orchestrator spawning several agents) could exceed the free plan's 5 concurrent tasks and the 25-tasks-in-flight ceiling, because each request checked the count before any of the others had been recorded. Each new task now reserves its place in the same step that records it, so the extra requests get the usual "too many tasks" answer and start nothing. Starting tasks one at a time works as before.
- Foxl Code's installation membership now keeps the decisions people made. Choosing "Leave install" on your own row in the members list no longer counts as an admin removing you, so Connect GitHub can bring you back later. An admin's role change for a member (promoting or demoting them) is no longer undone the next time that member presses Connect GitHub. And uninstalling or suspending the GitHub App now also cancels that installation's queued and running tasks, pauses its schedules, and records each member's removal, where before those tasks kept running and the schedules kept failing on every run.
- Signing out of Foxl Desktop now also disconnects this computer from your phone and browser sessions. Without "keep running when closed" turned on, the desktop's connection to Foxl stayed signed in as the previous account after sign-out, so that account's phone or web session could still reach this computer's files, terminal and agent until the app was quit, including after someone else signed in. It now closes when you sign out, when your session expires, and when a different account signs in (which gets a connection of its own). Signing out does not yet end that account's sessions on Foxl's servers.
- Foxl Desktop now checks that its local server is really Foxl's every time it loads a page or opens a connection to it, not only once at startup. While the server restarts, another program on the same computer could briefly take its address. Before, Foxl could then load that program's page in the Foxl window with your sign-in available to it, and pass it the key that unlocks the local server. Foxl now refuses to load or connect to anything that cannot prove it is the server Foxl started, and shows the startup screen until the real one is back. Background requests made in the brief moment before Foxl notices a restart can still reach the other program.
- A web page can no longer end a Microsoft or Slack sign-in that is waiting in your browser by sending a reply marked for a different sign-in, and error text on Foxl's sign-in page is now shown as plain text instead of page markup. An error reply with no sign-in marker still ends the sign-in straight away, because that is how Microsoft reports a cancelled consent, so a page can still cancel a pending sign-in that way; it cannot complete one.
- With auto-approve turned off, Foxl now asks before the agent reads a credential file with its file, image or code search tools, the same way it already asked before running a shell command. That covers Foxl's own secrets (its daemon state, the desktop app's sign-in storage, the key that unlocks saved provider keys, the extension pairing secret and its database), everything in your SSH, AWS, GPG, Kubernetes and Google Cloud folders (their config files included), and the sign-in files of Codex, Claude Code, the GitHub CLI and git. Symlinks to those files count too, and a custom file tool now refuses them the way it already refused SSH keys. Other files read as before, and with auto-approve on (the default) nothing new is asked. A search over a folder that contains one of these, such as your whole home folder, is not caught.
- Shell commands the agent runs no longer see Foxl's own sign-in tokens or the model provider API keys saved in Foxl's Settings (
OPENAI_API_KEYand the like), and any provider key's value that a command prints is replaced with a marker before the agent reads it, so a command likeenvcan no longer show them. A provider key your own shell profile exports still reaches your scripts as before, and so does everything else in your environment, including your PATH, proxies, AWS and GitHub settings and your own keys. A skill that needs a model key can still be given one on the Integrations page, and a command that asks for a withheld key is told why it is empty. Terminal panes and local coding agents no longer inherit Foxl's sign-in tokens either, and keep your API keys. On Windows, the agent's commands now always start the system's cmd.exe and a local coding task's git steps always use the git on your PATH, never a copy sitting in the project folder (a program named inside a command is still found the way cmd.exe finds it, project folder first, sogradlewandbuild.batkeep working); this Windows part was not run on a Windows machine before release. - Sign-in limits now apply per network rather than per address. All the addresses of one IPv6 network (a /64, which is what a single home, phone or server is given) share one limit of 10 sign-in, sign-up and password attempts a minute, where each address used to get its own, and an IPv4 address written in IPv6 form shares that IPv4 address's limit. Renewing a session no longer counts against that limit either: it is counted per session, so someone else on the same office, school or mobile network can no longer make it fail by filling the limit with sign-in requests. Someone who controls a much larger IPv6 range, or many separate addresses, can still request sign-in email at 10 a minute from each network.
- Workspace invites now have daily limits and stop working when the person who sent them loses access. One person can send up to 50 invites a day and one workspace up to 100. An address that has already received 3 Foxl invite emails in a day still gets the invite, but no further email, and the admin is given the link to share instead. The invite email's subject no longer contains the workspace name or the sender's name, and the email now shows the sender's full address. Removing someone from a workspace cancels the invites they sent and takes them off the restricted folders they had been added to, so inviting them back does not quietly restore either; a restricted folder they created themselves is still theirs if they rejoin. Making an admin a member cancels the invites they are no longer allowed to send.
- Foxl Desktop no longer blocks content from other sites that its own pages embed. The app's security policy was also being applied to embedded frames from other sites, and it forbids being embedded. So Cloudflare's sign-in check could never load in the desktop app, which would have made every desktop sign-up fail once that check is switched on. It is not switched on yet. The app's own pages keep the same policy as before.
- In Foxl Desktop, Open on a workspace file the viewer cannot show (an archive, a binary, or one whose preview failed) now opens the file in its own application, as double-clicking it in Finder or Explorer would. Before, it opened your web browser at a local address that carried the key to Foxl's local server, which stayed in the browser's history. The desktop app now refuses to send any link to its local server to the browser, and Copy Link on such a link leaves the key out. A file the system will not open for safety reasons (an app or script, or a file outside your usual folders) is reported with the reason instead.
- Signing in to Foxl Desktop with Google, GitHub, Apple or an email link no longer passes your session through the link that returns you to the app. The link now carries a one-time code, which only the copy of Foxl that started the sign-in can exchange for a session. Before, another program on the computer that registered itself for Foxl's links could have received a working sign-in. The phone app already worked this way. Sign-ins started before updating still complete.
- Signing out now ends that sign-in at the Foxl service, not only in the app. Before, the session stayed valid on the server after you signed out: a copy of its credentials (a backup, or the next person on a shared computer) could keep using the account, and the desktop connection stayed open. Now the service refuses that sign-in's tokens straight away and closes its live connections, and on a phone it stops that device's notifications in the same step. Your other devices stay signed in. This applies to sign-outs from app.foxl.ai, the desktop app and phone builds that include this change. Older phone builds sign out only locally until they update, and a sign-out made while offline still signs you out on the device.
- A tool approval prompt that expired no longer takes the place of the next one. After one prompt went unanswered for a minute, every later prompt for the same tool showed the expired prompt's command, and pressing Allow answered that dead request: the row said "Allowed" and the new command never ran. An expired prompt now leaves every open window, each prompt is tied to the one tool call it is about (so two commands asking at once each show their own), and a row shows your answer only once the desktop has accepted it. If the prompt was already gone, the row says nothing rather than "Allowed" and offers the current prompt instead.
- With auto-approve turned off, an approval prompt that no chat is showing can now be answered. A prompt from your heartbeat watch, from Run on the Tools page, or from a conversation that is not on screen (a scheduled run, a Slack or Telegram message, a chat you moved away from) had nowhere to appear, so it timed out a minute later and the call did not run. It now appears as a card at the top right of whatever screen you are on (for Run on the Tools page, inside the playground under the Run button), with Allow, Deny and Always allow, and Foxl shows a desktop notification when its main window is not in front (if notifications are on). If nobody answers, the card says the call did not run and stays until you close it. A tool row whose prompt expired now says "Timed out" instead of "Denied", and a prompt answered in another window shows that answer. With auto-approve on (the default) nothing asks, as before.
- Images from other websites in a reply, the model's thinking, the Notes AI assistant and meeting window, the Notes summary on a phone, a workspace or Shared
.mdfile, or a Foxl Code task no longer load by themselves. Each one shows the website it would load from and a Load image button, so text written by someone else, or by a model steered by a web page it read, can no longer send your information to that website just by being displayed. Images from the page's own address still appear straight away, and attachments are unchanged. A note open in the Notes editor still shows its images as before, including ones in an AI summary. - Rendered markdown in chat replies, workspace and Shared
.mdfiles and Foxl Code no longer writes a meaninglessnode="[object Object]"attribute onto every paragraph, heading, list item, table cell and link. Nothing about how a reply looks changes; the page just stops carrying that noise. - Previewing a workspace
.htmlfile on app.foxl.ai or the phone no longer pulls in files from outside that file's own folder. A page that pointed at../MEMORY.mdor a project's.envused to have that file copied into it from your desktop, where the page's own script could read it; it now reads only its own folder and below, as the desktop app always has, and anything above it is listed as not loaded. - The Foxl Notes Report tab now shows "Generating report..." only on the note whose report is running. Other notes show their own report or the Generate button, a report finishing on one note no longer resets another note's report that is still running, and asking again for a report that is already running no longer starts a second one.
- Foxl Notes keeps what you typed in a note body. Stopping a recording that transcribed no speech (a muted or wrong microphone, or a language mismatch) now saves the notes you typed as a note and says why nothing was transcribed; with neither speech nor typing it tells you no note was saved. "Send to Notes" now adds the transcript to the end of the note and saves it, instead of replacing your notes on screen without saving. A note that already holds the transcript, including the note of a recording in progress, is left as it is.
- Foxl Notes no longer loses the notes you type during a recording to another note. While a recording runs, the header's New note button is hidden and Cmd+N or the Notes row in the sidebar takes you back to the live note instead of clearing it; opening a different note from the search palette or a notification says to stop the recording first instead of sending the meeting's lines into that note, and the dimmed notes list can no longer be opened from the keyboard. Recording cannot start while an audio file is being imported, and importing a second file during an import is refused with a message, so the two transcripts no longer mix.
- Quitting Foxl during a Foxl Notes recording no longer loses it. Cmd+Q, Quit Foxl in the tray menu, and Install now for an update first ask whether to stop the recording. Stopping files the note with its transcript and typed notes before Foxl closes; Cancel keeps recording. If nobody answers, the recording is stopped and saved after 30 seconds. A restart that Foxl performs itself, such as turning on keep-running-when-closed, saves the recording without asking. The summary, title and report for that note are not generated during the quit; you can generate them from the note afterwards. On app.foxl.ai, closing or reloading the tab while recording now asks first.
- Every Sign out button now signs you out the same way. Foxl Code's own Sign out buttons (in Code's Settings and on the beta waitlist page) used to clear only the browser's storage: in daemon mode the desktop app signed you back in within a minute, the desktop kept its copy of your session, and a phone kept showing your message notifications. Sign-out also now clears messages still waiting to be sent (with their photos), the private repository names Foxl Code remembered, and the cached model list. Before, the next person to sign in on the same device could see them, and an unsent message could go out from their account. Your pinned chats, starred models and Foxl Code's model choice are now kept per account on the device: the next person to sign in starts without them, and you get them back when you sign in again.
- On app.foxl.ai and on phones, Sign out now asks before deleting Notes meetings that are stored only on that device. Signing out still removes them, because the next person on the device must not see them, but it used to happen in one tap with no warning. Now Sign out (in the sidebar, on the Account page and in Foxl Code) shows how many meetings will be deleted and lets you cancel and export them first. "Sign out everywhere" says the same in its own dialog. Sign out also warns when a recording is running, and signing out mid-recording from the Account page no longer leaves the microphone on. The seeded sample note does not count, and the desktop app, which keeps meetings on disk, only asks about a running recording.
- The 80% and 100% credit-usage emails now also count replies that were not streamed, such as Notes AI summaries on Claude models; until now only streamed replies and GPT models could trigger them. The same replies now also count toward the service's unusual-spending check.
- A Foxl Code task's compute charge now runs the same checks a chat reply does. When a finished task's cloud compute takes the credit usage shown on your account page past 80% or 100%, or leaves your balance below zero, you get the usage email; before, only the task's model replies could trigger it. Compute spend also counts toward the service's unusual-spending check now, which could not see it before. A usage email that a chat reply already sent is not sent again.
- Foxl's hosted GPT, Grok and Gemma models always run on Amazon Bedrock's Standard tier, the one credits are priced at. A request that asked for the
priorityorflextier used to reach Bedrock as sent while the charge stayed at the Standard price; the tier is now removed before the request is forwarded, the charge is unchanged, and the reply says which tier served it (service_tierin the reply, and anX-Foxl-Service-Tierheader). On your own AWS account the Notes tier setting is honoured as before. Requests that ask for Bedrock's background mode, which the service could not charge for, are now refused with a clear error. - Deleting a workspace no longer skips part of its bill. Its storage and channel usage up to the day of deletion is now charged on the billing owner's usual renewal day, including the month before the deletion and all channel usage, which a deletion used to drop; storage kept only during the restore window is not charged. A workspace that is deleted and then restored is charged for the whole month instead of only the days before the deletion. This can charge a workspace owner more than before for a deleted or restored workspace.
- A workspace admin who was paying for the workspace stops paying when they are removed, leave, or delete their account. The bill goes back to the workspace owner and the change is recorded in the workspace's audit log; until now the person kept being charged every month for a workspace they could no longer open, or, after deleting their account, nobody was charged and the members' uploads were refused. This moves those charges to the owner, so an owner can now be charged for storage and channels that used to fall on the departed admin.
- Remote access over the encrypted tunnel no longer goes dead for a phone or browser after a single forged or corrupted frame. The desktop and the browser now count a frame towards the replay protection only after it passes its authentication check, so a bad frame is refused on its own and the next real keystroke or request still gets through. Covered on both the desktop and the browser, for terminal traffic and for requests.
- Remote access from app.foxl.ai and the mobile app no longer sends requests and keystrokes unencrypted once you have connected to your desktop securely. Before, a relay that withheld or tampered with the key exchange (for example, by claiming the desktop could not save its safety code, or by reporting it under a new device id) could get requests and keystrokes sent in the clear, even while the safety-code warning said remote access was paused. Now requests wait for the encrypted session and fail rather than go out unencrypted if it never arrives, a desktop presenting a safety code this browser has not accepted raises the safety-code warning even when only a terminal noticed it, and the desktop refuses an unencrypted command in the name of a client that holds an encrypted session. A browser that has never connected securely still works with older desktops as before. Two things change on purpose: connecting a second desktop in a browser that already trusts one now asks you to compare its safety code once, and once a browser has connected securely it can no longer reach a desktop older than v0.6.27 through the relay (the warning says to update that desktop).
- Removing your desktop from your device list no longer lets a sign-in token issued before the removal register a different desktop in its place. After a secured desktop is removed, a replacement is accepted only on a sign-in made after the removal (the desktop app refreshes its sign-in and retries on its own), and an old device registration without a device secret can no longer be used while your current desktop has one. If you remove your desktop and reconnect it from an older version of the app, it can take until that app's next sign-in refresh (up to 12 hours) to reconnect; updating the app avoids the wait.
- Three pages no longer discard what you did without saying so. In a skill's detail dialog, Enable/Disable now follows the skill's current state, so a second press turns it back on instead of repeating the same call. Agents > Run keeps your goal in the field and says why when the run is refused, for example because one is already running. The Tool Playground runs nothing when the parameters are not a valid JSON object and says so, where it used to run the tool with no parameters at all.
- "Unpair device" on the Mobile/Web page and Delete on a custom tool or MCP server now ask first, with Cancel focused, and Cancel sends nothing. The unpair confirmation says that the desktop turns its own remote access off until someone at that computer turns it back on. If either request fails, the device or tool stays in the list and an error says so. A custom tool's edit dialog now has Delete and Test in playground buttons, so a tool can be deleted or tried on a phone, where the row's own buttons are hidden.
- Schedules: the Timeout and heartbeat Interval fields can be cleared to type a new number. They used to refill with the default on every keystroke, so clearing Timeout and typing 5 read 105 and saved 60 minutes; the default and the 1-60 minute limit now apply when you leave the field or save. Next run and Last run, run counts and a pause after repeated failures now update on their own while the page is open: the list is read again just after a schedule is due and while its run is still going, and otherwise every 15 minutes. On the phone and in the browser, where each read goes through the relay, it is read at most every 2 minutes and otherwise every hour. Nothing is read while the window is hidden.
- status.foxl.ai's incident alerts to Slack and webhook subscribers no longer stall or overrun a check: every outbound alert gives up after 5 seconds, deliveries are planned against Cloudflare's per-run request limit and carry over to the next check when they do not fit, and the public subscribe endpoint caps URL length, request size and the number of endpoints, rate-limits per IPv6 /64 and refuses cross-site browser posts.
- Shared files kept outside any workspace now stop at the storage your plan includes (5 GB on Pro, 50 GB on Ultra). Storage outside a workspace is never charged, so it used to have no limit at all; an upload that would pass the included amount is now refused with a message saying so, and the storage panel shows that limit and no longer estimates an overage charge that was never made. Workspaces are unchanged.
- Workspace names only have to be unique among your own workspaces. Until now a name used by any other team anywhere on Foxl was refused, which told you that team existed and let anyone take a name first; and renaming a workspace to a name in use elsewhere failed with a server error instead of saying why.
- Pressing Esc to close the find bar, the model picker, a menu or a dialog while a reply is streaming with a message queued no longer also interrupts the reply and sends the queued message early; Esc with nothing open still does. And when the desktop app loses its server, an Esc pressed at something else while the small "waiting for connection" notice is showing no longer stops the full panel with Restart from appearing later.
- The Schedules page no longer crashes on a schedule that names its days, such as
0 9 * * MON(which the agent or the API can save), or while you are typing one. Day names and?are described ("Every Monday at 9:00 AM"), and expressions the page cannot put into words, such asL,W,#or an out-of-range value, are shown as written instead of as a wrong sentence like "Monthly on day NaN" or "Every Friday" for the second Friday. - Agents > Subagents: saving a new or duplicated subagent under a name that already exists no longer silently replaces that subagent's prompt, tools and model. The form now says the name is taken and keeps what you typed; editing a subagent still saves over itself as before.
- Settings > Shortcuts no longer lets a single key or Tab become a shortcut, which then took over typing or Tab navigation (for example every "n" typed in a message opening a new chat). A shortcut now needs Cmd/Ctrl or Alt (function keys work alone), the row says so if you press a plain key, and Tab or a click elsewhere stops recording. A plain-key shortcut saved by an earlier version goes back to its default.
- Editing an earlier message while a reply is still streaming no longer closes the editor and throws the edit away. The editor now stays open with your text and says the reply is still running; stop it or let it finish, then save. On app.foxl.ai and the phone, saving an edit mid-reply no longer cuts the conversation under the running reply, and editing a message that had an image or document re-sends the attachment instead of the text alone.
- On Linux, Keep running when closed now refuses to start the background service from any folder another account on the computer can write to, not only from an AppImage. A service pointing into such a folder (for example an unpacked AppImage under /tmp) could be made to run another account's program as you once that folder was gone. An existing setup like that is moved to where Foxl now runs if that location is safe, and switched off otherwise, with Settings saying why.
- On Windows, Foxl's local server and the keep-running-when-closed service now run on Node.js 22.23.3 instead of 22.14.0, which picks up the six Node.js 22 security releases published since February 2025. The newer Node also brings full-text conversation search to Windows, as on macOS and Linux: the first launch after the update builds the search index once (a few seconds on a large history), and searching is faster afterwards.
- iPhone and iPad: the text of the chat's "..." menu no longer shows through faintly before the menu has opened.
- Opening a chat that no longer exists (from the search box's Recent list, an old link or a notification) no longer leaves the chat you were reading on screen with a message box that would send into the missing one. The app opens a new chat instead and says the conversation no longer exists, and that chat is removed from Recent. If the desktop could not be reached, the new chat opens with a message saying the conversation could not be opened, and the link and Recent entry are kept so you can try again.
- In the desktop app and on app.foxl.ai, opening a chat, agent or schedule notification from the bell while in Foxl Notes or Foxl Code now switches to Foxl Agent, so the sidebar shows that chat and shortcuts such as New act on Agent. Before, the page changed but the sidebar and shortcuts stayed on Notes or Code. Notifications that open Settings or the notifications page still open over the product you are in.
- Cmd+B (Ctrl+B on Windows and Linux) in a Foxl Notes note now only makes text bold; it no longer also collapses the sidebar. Outside the editor it still shows and hides the sidebar. On macOS, Ctrl+B no longer toggles the sidebar and is no longer blocked in text fields such as the chat box, where macOS uses it to move the cursor back one character; on Windows and Linux, the Windows key plus B no longer toggles it. Settings > Shortcuts now lists the sidebar shortcut.
- "Delete all conversations" now removes the deleted chats' pins too. Before, with eight chats pinned, Pin stayed unavailable on every new chat afterwards while the Pinned group was empty, leaving nothing to unpin. Pins on chats the delete did not reach stay: on app.foxl.ai, deleting the desktop's chats keeps the pins of chats kept only in the browser, and the reverse. A pinned chat older than the 50 most recent still appears under Pinned only once the list has loaded that far.
- Blocking someone in Channels now also keeps them off your channel list. Their messages no longer appear as the preview under a channel or DM name and no longer raise its unread badge (the list shows the newest message you can open instead), and it works in both directions. "Mark as unread" now lands before a message you can actually see. A new message from a blocked person can still move a conversation you share with them up the DM list, because that order is kept per conversation rather than per reader.
- In Channels, the name on a huddle invite (in the app and in the phone notification), in the call's participant list, on a "declined" notice and on "is typing" now comes from the person's Foxl account (their name, or their email if they have not set one), not from whatever their app sent, so nobody can ring you or type under someone else's name. Someone you blocked, or who blocked you, can no longer ring you from inside a call either; that was already true for invites sent from the invite picker and is now true for every path. A name changed during a call shows the old one until that person reopens the channel.
- Channels now has limits on the two things one account could otherwise pile onto everyone else's screen. A reaction must be a single emoji, a message can carry at most 20 different reactions (adding to one that is already there always works), and an archived channel takes no new reactions, though you can still remove your own. A workspace can hold at most 200 channels, archived ones included, and a member who is not a workspace owner or admin can create at most 50 of them; creating channels is also rate-limited per network address. The Channels page does not yet show a message when a reaction is refused; the reaction simply does not appear.
- Channels: a half-typed message and picked files now stay with the room you typed them in. Switching to another channel or DM shows that room's own composer, so Enter can no longer post a draft into the wrong room (including when a send fails after you switched), and returning to the first room (including with Back on a phone) brings its draft back. Drafts are kept in memory while Channels is open and are never saved.
- Channels: opening a room with unread messages by clicking it now shows the "New" line above the first one you have not read, placed once the room's latest messages have loaded. Messages that arrive while you are looking at the room no longer raise its own badge or the phone tab-bar count and no longer add a "New" line under you; while the app is in the background the badge still counts up and clears when you come back. Reconnecting after more than 100 new messages (a laptop waking overnight on a busy channel) now shows the latest messages, with "Load older" reaching the rest, instead of only the oldest 100 with everything newer missing.
- Huddles: joining a huddle that already has 12 people now says it is full straight away, before asking for the microphone, instead of hanging on "joining" with the mic open and the call bar showing. A join the huddle never confirms now gives up after 10 seconds with an error and releases the microphone. The invite card is announced once by screen readers instead of every second of its countdown, the countdown uses your language's unit, and huddle join and invite errors now appear in your language.
- Changing or removing your password with the wrong current password is now answered as a plain refusal instead of as an expired sign-in, so no Foxl app can mistake a typo for a dead session and refresh your sign-in over it. You still see the same "current password is wrong" message on every app version, including phones that have not updated yet.
- Channels: leaving a private channel now asks first, because you cannot rejoin one yourself, and deleting a message asks first and says that its attached files are removed from Shared files too. Leaving an open channel or hiding a DM stays one click. A leave, delete or reaction that fails now shows an error instead of nothing. Channels also follow the app's language instead of English or the browser's language: the "Today" / "Yesterday" dividers, message times, the channel list's "now" / "5m" / "3h" stamps, the Cancel buttons in the new-message and add-people dialogs, the phone's workspace picker title, Slack and Telegram reply placeholders, the channel list density options in Settings, and the load, send and attach errors (a refusal worded by the server is still shown as it sent it). The sample messages in the density preview are still English.
- Editing an earlier message in Foxl Desktop no longer loses your rewritten text when saving fails. Saving removes the old messages first, and if the desktop refused that (a server error or a dropped connection) the editor used to close anyway, leaving an error and the old message with your edit gone. The editor now stays open until the save has gone through, and if it fails your text is still there with a note, so pressing Save again retries.
- Setting your first password and linking GitHub now need proof that you are the signed-in device, not just a copied session. Before, anyone who got hold of one of your short-lived sign-in tokens could add a password or their own GitHub account to your account and then sign in with it. An updated app sends the proof on its own, so nothing changes for you. An app that has not updated yet, such as the iPhone app until its update arrives, can do either only within ten minutes of signing in. If saving a first password or linking GitHub fails, sign out, sign in again and try within ten minutes. Connecting GitHub repos in Foxl Code needs the same proof when your Foxl account has no GitHub account linked yet: without it nothing is connected, where before a copied session could add someone else's GitHub repos to your repo list. An account already linked to the GitHub account you connect with is not affected.
- Files on the phone and on app.foxl.ai no longer offer "Open in Finder" on folders and search results, and a skill's details no longer offer Reveal there, where choosing either opened a Finder window on your Mac at home instead. The
activeHoursbadge on HEARTBEAT.md also shows its start and end hours instead of "[object Object]". - Files works with a screen reader and the keyboard. The file tree now announces itself as a tree, with each folder's level and whether it is open, and the file tree in a chat's files panel moves with the arrow keys and takes a single Tab stop. The markdown Edit and Preview tabs are named on a phone. Messages there are also in your language: a spreadsheet with no rows, a failed Download, file sizes, and the common refusals of a move, upload or delete (the item is gone, the name is taken or cannot be used, the connection dropped) and of the workspace member and settings pages (the last admin, no permission, a name in use, an invite already pending). A refusal with a reason of its own, such as full shared storage or the daily invite limit, still gives that reason as before, in English. A failed workspace delete now explains itself inside the confirmation dialog instead of behind it.
- Files no longer overwrites or loses your edits. Saving a file the agent changed after you opened it now asks whether to overwrite its version or reload it, instead of silently replacing it. An unsaved edit kept behind the phone's Back button survives switching tabs, and a delete that fails no longer closes the open file and throws its edit away. A file that cannot be opened (moved or deleted, over 20 MB, or the connection dropped) now says so, with Retry or Download, instead of doing nothing or showing an empty editor that could not save.
- Foxl Code: tasks you delete from the sidebar (Delete all, or a task's Delete) now leave the Work page too. They used to stay in the Done list and its count, and a deleted pull request kept counting in Needs you, until the page was reopened. A task deleted on another device leaves Work at its next refresh, except an older one Work loaded with "Show older", which stays until the page is reopened.
- Foxl Code Runtimes: with a pane zoomed, Mod+] and Mod+[ now zoom the pane they move to, so what you type always goes to the terminal on screen. Before, focus moved to a hidden pane and your typing, including Enter, went to that agent unseen. A pane you opened with Cmd-T now shows how its task ended (for example Cancelled or Failed) when the task is stopped elsewhere, fails or idles out. It no longer goes back to "Queued" with Stop still offered, and its sidebar row keeps the agent mark and status instead of saying the agent keeps running.
- Foxl Code Schedules: Next run, Last run and the run count now update by themselves while the page is open. The list is read again shortly after a schedule is due and at least every hour, never more often than every 2 minutes and never while the window is hidden. A schedule whose run is starting says "Due now" instead of a time in the past, and the header's refresh button is announced as Refresh instead of Retry. Accessibility: the Work tabs and a task's Conversation / Split / Terminal switch now work with the arrow keys, Home and End. With the sidebar collapsed, each task shows its title on hover and names its title and status to screen readers. On a phone, the terminal view takes focus when it opens, is marked as a modal dialog for screen readers, closes with Escape from a hardware keyboard outside the terminal itself, and gives focus back when it closes.
- Foxl Code tasks: a follow-up you half-type for one task, with any text you pasted, now stays with that task. Opening another task shows that task's own draft, or an empty box, so Enter can no longer send it to the wrong agent. Going back to the first task brings the draft back. A follow-up typed while a new task is starting still stays in the box. Drafts are kept only while you stay on the Tasks page and are never saved. A task running on your own computer also keeps its live terminal when a status check fails, instead of wrongly saying the desktop forgot the task. If checks keep failing, it says it cannot reach that computer and shows the last known state. On code.foxl.ai with no desktop it now says no desktop is reachable, and a Cancel that fails now says so.
- Foxl Code asks before two row actions that used to run on one click. Rotate secret on a machine in Settings > Machines now explains that the box disconnects until you re-run the install command with the new secret, and Remove access for a member of a GitHub installation on Repos now says their queued and running tasks there are cancelled and their schedules paused; in both, Cancel is the focused button. Remove on a machine uses the same dialog instead of the browser's own prompt. The installation's member list now shows how each person joined ("installed it", "org member") instead of internal names like
install_access.role_installed_it, translates the role badges, the "you" badge and the Disconnect button, and gives each member's actions button a name screen readers announce. - Foxl Code's cloud task view and Settings > This computer now explain failures in the app's language. That covers why a workspace was cleared or expired, a task that never started, why Reconnect cannot bring back an agent, the budget warning in a task's header, the failed-tests reason for a task that finished with failing tests, the task header's details tooltip, the reconnect-failure message in the terminal, and on This computer the folder and clone errors, the add-folder prompt, the remove note and the Runtimes rows' machine labels and close controls. English is unchanged.
- Foxl Code explains a failed action in words instead of printing the raw request. Retry, Cancel, Mark done, Resume and Delete in a task's header, sending from the composer, Merge and review comments, Repos (Sync, connecting GitHub, linking, the member list) and Settings (uploading or removing a Claude or Codex credential, Sync from this computer, push notification switches, Save) used to show text like
POST /api/tasks/.../retry 409: {"error":...}; they now show the server's own sentence, such as the reason a credential file was refused, or a short translated message when there is none. The empty-draft, signed-out and could-not-send messages, the Repos and Settings banners and notices, the credential expiry line, the Save changes button, and the Shared files storage card with its over-limit and unpaid-charge warnings now follow the app's language, and deleting a shared file asks in it. The usage chart names Fable 5, shared file storage and Channels the same way on code.foxl.ai and app.foxl.ai, translated, instead of "fable-5", "storage" and "channels". Sentences written by the server itself are still in English. - Saving a shared document in Foxl Code's Files no longer undoes a teammate's rename or silently replaces their newer edits. A save now keeps the document's current name and folder, and if someone else saved the document after you started editing, Files keeps your text and asks whether to discard yours and reload or overwrite theirs, instead of saying "Saved" over their work. An unsaved edit you leave by opening another file or going to Tasks now keeps the browser's leave prompt up until it is saved, and its file shows the unsaved dot in the file tree and search results. The button that opens the Shared panel (uploads, the storage bill, New shared doc) is now a real button you can reach with Tab and tap on a phone. Not covered: saves from Foxl Agent's own Files page still replace the whole document as before, and in the desktop app a stashed edit is not guarded against quitting, matching Foxl Agent's Files page.
- In the Quick Chat window, links now work the way they do in the main window: a mail link opens your mail app, an editor or notes link (vscode://, obsidian:// and the like) opens that app, and a Foxl conversation link opens the conversation in the main window. Before, only web links opened and the rest did nothing when clicked. Right-clicking in Quick Chat now shows the same menu as the main window (Cut, Copy, Paste and Select All in the message box, Copy Link and Open Link in Browser on a link), and Quick Chat no longer underlines words as misspelled, matching the main window.
- On Windows and Linux, a Foxl link that opens the app when it is not running now does what it says. A sign-in link from the email completes the sign-in, and a copied conversation link (foxl://chat/...) opens that conversation once the app has loaded. Before, the app started on its default screen and ignored the link. macOS already handled this. Not yet confirmed on a Windows or Linux install: the behaviour was checked on macOS with the same Electron build and with the documented Windows and Linux launch arguments.
- The desktop app now shows the unread count on its Dock icon on macOS and as a red badge on its taskbar button on Windows. Installed builds never showed either, and the Windows badge image was blank in development builds too. On Linux, Settings no longer shows a "Launch at login" switch, because Linux has no login item for Foxl to set: the switch read ON and did nothing. The Windows badge shows 1 to 9 and then 9+; it was checked as an image with the same Electron build on macOS, not yet on a Windows taskbar.
- A huddle popped out into its own window no longer stays on top after the call has ended in the main window. Opening Chat, Notes, Code or Files from Channels leaves the call, and the huddle window now closes with it (or says the huddle ended); reloading the main window closes it too. Invite in the huddle window now brings the main window forward with the people picker open, instead of opening it behind a full-screen app or in a closed window. On Windows and Linux the huddle window no longer shows the app's full menu bar, and on every platform its title bar names the huddle and the channel in your language instead of reading "Foxl". The menu bar change is not yet confirmed on a Windows or Linux desktop: it was checked on macOS, which draws no menu bar in the window.
- Huddles: when a huddle fills up between opening it and joining, the relay now answers the join with a "huddle full" reply instead of silence, so the app says the huddle is full and releases the microphone straight away instead of after its 10-second join timeout. Older apps ignore the reply and behave as before.
- Channels on a phone now follow the right workspace: the Channels tab badge counts the workspace you switched to (it kept counting the one you left, or stopped updating after a fresh sign-in), and tapping a message or huddle notification from another workspace switches to that workspace and opens the room instead of leaving you on the current workspace's room list. Notifications sent before this relay update still open the current workspace, as before. Not yet tested on a device.
- Phone fixes: the Email button on a failed chat now opens Mail in the iOS app (it did nothing before), and when no mail app opens it shows the support address with a Copy button; the "Back to recording" pill no longer sits under the tab bar (and moves to the left edge in Arabic); the end of Word documents, slide decks and text files in Files is no longer hidden behind the tab bar; and a notice that appears while the keyboard is up is shown above the keyboard instead of behind it. Checked in code only, not yet on a device.
- Integrations > Channels: the fields in the dialog that connects Telegram, Slack and the other chat apps are now shown in your language (they were always English, including the allowlist fields that decide who the bot answers), each field is announced by its label to screen readers, the show/hide button on a secret field has a name, and a failed save, start, stop or removal now shows the reason the desktop gave (for example a missing token) instead of an HTTP code or nothing at all.
- The Notes transcript works from the keyboard. Tab moves into the transcript once, and the Up and Down arrow keys (and Home and End) move between its speaker names and lines, so a long transcript is one Tab stop instead of hundreds. Enter on a name renames that speaker and leaves you back on the name; Enter or Space on a line plays the recording from there, with Space on the playing line pausing it. Screen readers hear which line is playing and what the rename field is for, and on a phone the speaker name and its rename field are larger touch targets.
- Notes keeps a note's Background. The context you paste into the Background tab is now saved with the note, including text typed during a recording, so it is still there after a reload or a restart and the summary, Ask AI and reply suggestions keep using it. Notes AI also answers in Russian and Arabic when the app is in those languages instead of in English, and the suggestion buttons above the phone's Stop bar ask for the app's language instead of "auto".
- Notes speaks your language in more places. A note nobody has named yet is called "New Transcript" in your language in the sidebar, search, phone home and share sheet, and a new note's heading, its participants line and the Word and Markdown exports' duration are translated too. Counts now agree with their noun ("1 word", and the right Russian and Arabic forms) in the editor's word count, the assistant's header and the search results. The recorder's messages about credits running out, a dropped connection or a microphone that stopped are in your language, and older notes' dates in the list, the phone's recent notes, shared notes and reply-card times follow the app's language instead of the browser's. Export file names still use the English "New Transcript".
- The Notes editor no longer loads images from other websites on its own. A picture in a note that comes from another site, for example one an AI summary put there, shows its website and a Load image button, and is fetched only when you click it, without telling the site which page asked. Typing in the note, sharing it and saving it no longer fetch it either, and the saved note is unchanged. Pictures pasted in as data and pictures Foxl serves itself appear straight away, and so does a picture you put in yourself with Insert image, by pasting or by dropping it in, including after a reload. A picture you loaded with Load image asks again after a reload.
- In Arabic, confirmation dialogs, the chosen value in dropdowns, the model picker's sections and rows, table headers (including the Files CSV preview) and the Settings and Files search fields now start at the right edge like the rest of the app, and a switched-on toggle keeps its knob inside the track instead of pushing it out to the right. Lists and quotes in channel messages indent from the right, and the jump-to-latest button in chat and Notes sits on the left.
- In Arabic, Foxl Code's own pages follow the right-to-left layout: Work, Repos, Channels, Schedules, Files, Settings, the task side panel and pull request review. Menu icons, search icons, badges and row actions sit on the mirrored side, "next" and "back" arrows and disclosure chevrons point the right way, and the Schedules editor and the task panel on a phone slide in from the left. Dragging the task panel's or the Files sidebar's edge, arrow keys on tab rows, and the swipe that closes the phone terminal follow the mirrored edges. Code diffs and file previews stay left to right, so their punctuation is not reordered.
- The desktop app is on Electron 44.4.5 (Chromium 152.0.7977.130, Node.js 24.21.0), up from 44.2.0. It brings the security fixes to the app's browser engine (Chromium, V8, PDFium, Skia, ANGLE and Dawn) released since, which matters because that engine renders every message, preview and document the app shows.
- docs.foxl.ai now sends the same kind of security headers as foxl.ai and app.foxl.ai. Browsers are told to use HTTPS only, other sites can no longer show the docs inside a frame, and a content security policy limits the docs pages to their own scripts, Google Analytics once you accept it, and Cloudflare's page-view counter. Search, copying a page as Markdown and the theme switch work as before.
- Screen readers now name every switch in Settings, Tools, Notifications, the model picker and the channel list, instead of announcing "switch, on" with no label - including each push and email notification category, "Auto-approve all tools", the About switches and every system and custom tool. On the Skills page the enable toggle can now be reached with Tab and flipped from the keyboard; it still asks before disabling a skill.
- Saving your profile from Account > Edit profile in the desktop app no longer erases what the agent has written about you in USER.md. The save used to rewrite the whole file with an empty body, so every note under your name, bio and company (including the first-run "About you" section) was lost and the agent stopped knowing it from the next reply. Now only the name, bio, company and website change; the rest of the file, and any other fields in it, stay as they are. Notes already lost to an earlier save are not recovered.
- Push and email notification settings no longer show the defaults as your choices when they cannot be loaded (offline, or the service erroring): the pane says it could not load them and offers Retry instead of live switches, so a category you turned off, or an unsubscribe from all email, is never shown as on. A change that fails to save still flips back, and now says so. In Settings > Feed Generator, an unsaved interval, active-hours or HEARTBEAT.md edit is kept when you switch to another Settings section or close Settings and come back, with "Unsaved changes" still showing; it is not kept across a reload.
- Counts of one now read in the singular: "1 signed-in device", "Try again in 1 minute", "1 day left", "1 tool", "1 subagent", "1 message queued" and "Paused. 1 line buffered." instead of the plural, in all ten languages. Notification times ("12m", "3h") and For You's next-run time ("in 5m") now use your language instead of English, and the next-run time past a week shows the date in the app's language; in English the notification times read as before and the next-run time reads "in 5 min.". The storage card on the Account page (a workspace's shared-file size, what the plan includes, the over-plan estimate and the paused-uploads notice) is translated too, with numbers in your language's format.
- More of the app follows your language instead of showing English: the sign-in title and its GitHub button, the provider Save buttons and the migration buttons in Settings, the desktop connected/disconnected notice on app.foxl.ai and the phone, the Close button on every dialog and sheet, the chat's Stop, Attach and emoji buttons, the buttons for editing a sent message, the image viewer's menu, buttons and notices (its "Reveal in Finder" now reads "Show in folder", since it also appears on Windows and Linux), and the titles of command, file, web, code-search and browser steps in a reply. The terminal drawer's split buttons showed "terminal.split.vertical" instead of a name; they are named now, and the button that hides the drawer no longer shares its name with the buttons that end a terminal session. Titles of other tool steps and the composer's formatting bar are still English.
- A link whose text is a web address now shows where it really goes when it points somewhere else. In Channels and direct messages, chat replies, the Notes AI assistant and meeting window, the Notes summary on a phone, and Foxl Code documents, a link written as
[https://github.com/...](https://another-site.example)used to read as the GitHub address; it now shows the real address instead. This covers text that starts withhttps://orwww., or names a site followed by a path (github.com/...); text that is only a site name, such asgithub.com, is still shown as written. Links with ordinary text, such as[the PR](...), look the same as before. Every link in a Channels message now also shows its real address when you hover over it, and a message's link preview is for the real address rather than for the one its text names. - Notes no longer drops a transcript line when you type as it arrives. During a recording, a key pressed (or a Korean or Japanese character composed) within a few milliseconds of a new transcript line reaching the live note could leave the note without that line for good, and on a busy computer that window grew longer; the line also stayed missing from the note saved at Stop. Now the note keeps both your typing and the line, and your cursor stays where it was.
Features
- Foxl Code's chat now shows what the coding agent did. When a cloud agent finishes, its result appears in that task's conversation: the pull request it opened, or that it changed nothing, that the repository's tests failed, or that it did not finish, followed by the agent's own final output. It appears shortly after the run ends while that task's chat is open, is there when you reopen the task on any device, and the orchestrator reads it as part of the conversation, so a follow-up such as "add tests to that PR" knows which PR you mean. Interactive terminal sessions and tasks run on Foxl Desktop do not post a result.
Changes
- Long replies stream without slowing the app down. A reply is now drawn one paragraph, list, table or code block at a time, so each update redraws only the part still being written instead of the whole reply, and the messages already on screen are no longer redrawn on every update, nor is the chat you are reading redrawn for a reply streaming in another chat.
- Replies from Foxl's hosted models start sooner. Before a request reaches the model, the service now waits on six database round trips instead of nine, and a Foxl Code agent's request looks up its model's price once instead of three times.
- Notes uses less of the app while it records. The recordings list in the sidebar and the search palette no longer redraw on every word the transcript adds; with 300 saved notes that was about 16 ms of work per transcript update.
- The chat's files button no longer re-reads your whole workspace every 5 seconds through every reply while the files panel is closed, which on app.foxl.ai and the phone went through the desktop connection. Its count still updates during the reply when a command names a file it writes, and for every file when the reply ends, and opening the panel now reads the files right away.
- Pages that show your account no longer ask the server for your profile and credits every time you open them. The answer is reused for a minute; credits still update after each chat reply, and a sign-in or an explicit refresh still asks again.
- With several browser tabs or desktop windows open, one window no longer re-renders the whole app and re-reads your profile every 10 seconds because another window renewed its connection slot.
- Files re-reads its saved file tree once when the page opens instead of on every render. On a large workspace (about 1.6 MB of cached tree for 9,800 files) that was a full JSON parse per render once the in-memory copy was a minute old.
- Foxl Code reads far less from its database while you watch it. The Runtimes page's ten-second refresh looks up only the tasks in each state instead of reading your whole task history three times (about 1,140 rows down to 17 for an account with 380 tasks), refreshing older rows in the task list looks them up directly, the activity feed behind the notification bell no longer carries each finished run's terminal output (437 KB down to 15 KB for 100 events), and the Work page reads its task rows once instead of twice.
- Notes on iPhone and iPad: tapping a line in a long meeting starts playback about twice as fast and uses about a quarter of the memory, so a long recording no longer risks the app being closed.
- Notes on Android, the web and the desktop app records its local audio copy at 32 kbit/s, about a quarter of the storage and memory per hour.
- Attaching a camera photo no longer freezes the message box: photos are encoded in the background as JPEG, about four times faster and a fifth of the size.
- Scrolling a long conversation list on a phone is smoother: the date label no longer redraws the whole list each time it changes month.
- Scrolling the workspace file tree starts without waiting on the app, and the sidebar no longer re-measures every conversation after each update.
- Hidden or backgrounded pages stop polling: the subagent status and log checks, the offline panel, the log console and the demo carousels wait until you are looking again, and the channel unread check runs only where its tab bar is shown.
Fixes
- The agent's web fetch stops reading a page once it has the text it asked for, instead of downloading and holding the whole response first, and its timeout now covers the whole download rather than only the first byte. A reply cut short says so. One fetch returns at most 200,000 characters.
- The agent reads large files in pages. A read returns up to 100,000 characters by default (200,000 at most) and ends with a note saying where to continue, and the agent can ask for a starting line and a line count. Before, a file over 1 MB was refused outright and a smaller one could fill most of the conversation's context in one read.
- Native form controls follow the default light or dark theme, selected text uses the theme accent, and chat and Settings panes reserve scrollbar space to avoid horizontal jumps.
- Email sign-in offers a resend button with a 30-second cooldown, translates failures, and announces errors with the affected fields identified for screen readers.
- The sidebar asks for confirmation before its single or bulk conversation deletions, including the mobile swipe action. Cancel is focused first and leaves the conversation history intact.
- Notes inserts links and images through an in-app URL dialog on desktop, web, and mobile. Enter applies the URL, Escape cancels, and clearing a link URL removes the link.
- Agent and Code chats announce when reply generation starts and finishes through a persistent screen-reader status region. Send buttons in Agent, Code, and Channels have localized accessible names.
- Long URLs and unbroken text wrap inside chat replies. Wide code blocks and tables contain horizontal overscroll, and message headings keep their visual sizes while leaving the page title as the top-level heading.
- Opening another conversation restores follow-to-latest after reading older messages. Sub-agent timelines now let touch users scroll back during a live reply and keep that position while more events arrive, including when loading earlier history.
- Message actions and attachment remove buttons become visible when reached by keyboard. Hidden actions on touch tablets no longer take taps before reveal. While editing a sent message, Escape cancels and Command/Ctrl+Enter saves; IME composition keeps those keys for text input.
- The latest failed chat turn offers a visible Try again button in its error card when retry is available. Model-switch dividers and the fallback context-compaction label now follow the selected language.
- Copy Markdown in Notes and copy clone URL/full name in repositories now confirm success or failure with a localized toast. Model/provider and Feed Generator settings show a Saved confirmation after the server accepts the changes.
- Arabic navigation icons, row spacing and pane edges follow the reading direction in Foxl Agent, Notes, Settings and the shared dialogs, sheets and menus. The sidebar and phone drawer open from the right, resize and swipe gestures follow their mirrored edges, disclosure chevrons, file-tree guides and tree arrow keys follow the mirrored rows, and code, terminal and editor text stays left-to-right. Foxl Code's own pages are not mirrored yet.
- A reasoning step that took one second now reads "Thought for 1 second" instead of "Thought for 1 seconds", in all ten languages. In Foxl Code the thinking line was English in every language; it now follows the app's language like the rest of the chat.
- Foxl Code Schedules shows "Waiting for a free slot" for a schedule held back by the open-task limit, instead of a "Next run in 8 seconds" countdown that kept restarting, and keeps the explanation beneath it. The table's headers and relative times no longer wrap onto several lines when the Needs you rail is open.
- Loading or reloading Files, Agents, Schedules, Code, Settings or Notes while a chat reply is still streaming no longer changes the address to that chat, so reloading the page or copying its link keeps you on the page you opened. The reply still resumes when you go back to Chat.
- The Heartbeat row on Schedules now updates its last run and run count every time the heartbeat runs. It had stopped updating (a new install showed a dash and 0, an older one the date and count of a run from weeks before), because the heartbeat runs on its own timer and nothing stamped the row, so a heartbeat that had just sent you a notification looked like it had not run. Its individual runs were already listed under recent executions.
- The Heartbeat keeps its schedule when Foxl restarts. It used to start counting its interval again from zero every time the app or the background service started, so a daily heartbeat on a machine that restarts every day could go days without running; it now runs one interval after its last run, or straight away if that time has already passed.
- A reminder you ask for once ("remind me on Sep 16 at 5:30pm") now runs once, even if your computer was asleep or Foxl was closed at that moment: it runs as soon as the computer is back, then switches itself off instead of repeating next year. The Schedules page shows it as One-time with its date, and marks it Done once it has run.
- A chat reply that was cut off is no longer shown as a finished answer. When the connection to your desktop closes mid-reply, or the relay gives up on the stream (the "Stream timed out" and "Desktop disconnected" cases), the reply now ends in an error card with the partial text kept above it and a way to try again, and any tool it was running stops spinning. A reply you reopen or reload mid-turn no longer keeps its loading shimmer forever when that stream ends, and pressing Stop on it settles it. In chat answered by Foxl's hosted models, a cut-off reply ends in the same error, and a reply that stopped at the output length limit now says so instead of reading as complete.
- Two chats answering at once no longer interfere. A tool from a chat running in the background no longer appears in the chat you are reading, a background chat finishing no longer hides the Stop button or clears the tool chips of the one on screen, and Stop stops the chat on screen rather than whichever one started last. A new chat opened beside a running one starts ready to send instead of in queue mode.
- A reply resumed after a reload or reconnect behaves like one you started. Stop is shown and works, a message sent meanwhile is queued for it instead of cutting the running reply short, and switching away and back picks the reply up again instead of leaving it frozen.
- A chat answering in the background no longer reaches into the one you are reading. Its context usage stays on its own chat instead of filling the open chat's meter, compacting its context no longer switches you into it a second later, finishing a later turn no longer renames a long conversation, and with Foxl's hosted models its failure no longer shows an error banner over another chat.
- Stop now stops a running shell command. The agent's foreground command and every process it started are ended the moment you press Stop, instead of running on (and writing files) for up to its full timeout while the turn looked stopped. Background sessions still keep running until their own deadline.
- A long desktop reply on app.foxl.ai or the phone is no longer cut off at two minutes while it is still streaming. The relay's time limit now counts silence, not the length of the reply, and when a reply really is cut off, or the desktop disconnects or refuses the message, you see an error instead of a truncated answer presented as finished.
- A reply to a message sent within 30 seconds of the previous one, and the summary Foxl writes after its subagents finish, no longer lose what they have streamed so far when you refresh or switch back to them more than half a minute in. The previous turn's cleanup used to erase the new reply's live state, so the reloaded bubble restarted from empty, and a summary being watched live stopped updating.
- Sending a new message while the previous turn is stuck in a long-running tool no longer breaks the new turn when the old one finally finishes. The new reply keeps streaming as the live turn, a message you type into it is still queued into it instead of being refused, and the old turn's last tool result and end-of-turn signal no longer appear in the new one.
- A reply no longer repeats its first words when the model hits a brief error partway through and Foxl retries it. The saved message, a refreshed or reopened chat, and the live reply now show the answer once, where before they read like "The answer is 4The answer is 42."
- Leaving a chat before its reply finishes no longer strands your credits. When the app cannot collect the reply later (a Foxl Code agent, the desktop app, a stopped turn), the model stops as soon as the connection goes, what it had written is billed and the credits held for the reply are released. A reply with more than about 30 seconds left could previously outlive the server's time limit for work after a disconnect, leaving its credits held for two hours and counted against the number of replies your plan can run at once. GPT and Grok replies, whose usage only arrives at the very end, are billed by estimate when cut off instead of not at all.
- On a phone, a reply still being written when Foxl goes to the background keeps generating for up to 20 more seconds (12 when the connection is only seen to stall). If it finishes, it is waiting for you as before; if not, what arrived is saved with a note that it stops there, and the notification says so.
- No more "Your response is ready" notification for a reply you already read to the end, for an interrupted Foxl Code agent turn, or for a turn the desktop app stopped.
- A reply from GLM-5, Kimi, GPT or Grok that breaks off mid-way now shows as an error instead of ending as if it were finished, and the prompt is billed by estimate rather than at zero. A GLM-5 or Kimi rate-limit error is no longer followed by a "finished" signal, and a completed GLM-5 or Kimi reply ends once with its real token counts, so apps built on the Anthropic SDK no longer see each reply twice with zero usage.
- When a model is busy or rate-limited, the relay no longer retries silently for up to 50 seconds while holding the request's credits: it tries at most three times within a second and passes the provider's suggested wait on, so Foxl Code and coding agents back off on their own schedule. In the web and phone chat this shows as an error you can retry. A request for a model your plan does not include, or one that does not exist, no longer uses up one of the free plan's 200 daily requests, and a malformed request is rejected as such instead of being reported as a server error.
- A reply to a request the phone app sends through your desktop now goes only to the device that asked. It was also sent a second time over the live connection, and when the connection was not encrypted between your devices, to every other device signed in to your account.
- The desktop app no longer signs you out when its remote-access connection reconnects. After the first 12-hour sign-in renewal, the connection that lets your phone and the web reach this computer kept the sign-in it was given at launch, and the next reconnect (waking from sleep, a network change, a server update) presented a renewal token the app had already used, which the server treats as a stolen session and ends. The connection now takes its sign-in from the app window and never renews it on its own; with "keep running when closed" on, the background service and the app hand each renewal to each other at once instead of up to a minute apart.
- Foxl now closes its remote-access connection cleanly when the computer goes to sleep and reconnects on wake, so the relay can mark the desktop offline right away instead of waiting for the silent connection to time out while requests from your phone fail.
- Unlocking the screen no longer drops a working remote-access connection. Foxl now checks the connection first and reconnects only if it has stopped answering.
- After a server update, desktops reconnect over a few seconds instead of all in the same instant.
- The local server no longer restarts in a loop forever when it keeps crashing right after it starts. Foxl now retries a crashed server up to three times in ten minutes, waiting 2, 4 and then 8 seconds, and then stops and offers Restart server. The background service retries five times in ten minutes, waiting up to 32 seconds, and then exits so that macOS or systemd starts it again on their own slower schedule. Before, every successful start reset the count, so a server that crashed a few seconds after starting was restarted every few seconds indefinitely.
- A server that cannot be launched at all (its runtime missing or not executable) is now retried and reported instead of leaving Foxl, or the background service, running with no server behind it.
- On macOS and Linux, the background service stops trying once it cannot work until the app is opened again: after the app has been moved or uninstalled, it no longer restarts every 10 seconds. It still retries when the port is only temporarily in use.
- Keep running when closed is no longer offered in the Linux AppImage build, where it could not work: an AppImage runs from a temporary folder that disappears when the app quits, so the background service had nothing to start after a quit or a restart. An existing setup is switched off with a note in Settings.
- Foxl Flow no longer gets stuck on its cleanup spinner when the model stops answering. The cleanup now gives up after 8 seconds (a little longer for a long dictation, so a healthy cleanup of one is not cut short) and pastes the words you dictated as they were transcribed, and it closes the stalled request instead of leaving it open in the background.
- The Dictate anywhere pill follows the key again. Letting go of Fn no longer brings back a pill whose dictation had already ended (a microphone or session that could not open, or a silence stop), so it no longer lingers on screen looking like a held key. The pill turns to its cleanup spinner the moment you let go, a new press is no longer hidden by the previous dictation's error message timing out, and a cleanup that never answers pastes your raw words after ten seconds (a little longer for a long dictation, so a healthy cleanup of one is not cut short) instead of leaving the spinner up and ignoring the key from then on.
- Typing into a Foxl Code cloud terminal keeps up on a slow connection. Keystrokes typed while one is still being delivered now travel together in the next request instead of queueing one request per 30ms, in the same order, and each request makes one fewer database read. A long session no longer keeps every terminal frame in memory for the task header, and a session token refresh no longer clears the terminal and its scrollback.
- Notes: the live note during a recording no longer repeats one line and drops another. When a sentence finished after a later one (the other speaker's long question, or the last words before the connection renews every few minutes), the note showed your line twice and never the other speaker's; every transcript line now reaches the note exactly once, in the order it was finished. A line arriving while you type also leaves your cursor where it was, so your next keystrokes stay in your own text, and Undo takes back only what you typed instead of emptying the note. A line that arrives in the middle of a Korean or Japanese composition waits until the character is committed.
- Notes: a live reply suggestion no longer waits for the translation of the last sentence to finish streaming; it appears about a second and a half after the other person stops talking.
- Notes: the AI summary and AI Assist now read your note with its paragraphs, headings and list items intact. Both used to receive the whole note as one unbroken line of text.
- The Foxl Code repo picker no longer shows a stray space after the slash, so a repository reads "foxl-ai/.github" as it does in the Repos list instead of "foxl-ai/ .github".
- The line at the top of a channel no longer runs its description into the "Add people" link.
#generalread "Everyone in this workspace Add people"; the description now ends as its own sentence, and the "This is the beginning of the regular channel" line is translated in every app language. - Settings > Coding agent no longer repeats its own title or the Kiro and Cursor billing sentence, and the model help names Opus 5.5 as the default (it said Opus 5) and explains that this is the model the coding agent runs inside each task, separate from the task composer's model picker.
- On a phone, the model chip in the message box shows the model's name instead of cutting it to a few letters to make room for the reasoning effort. When both do not fit, the effort label steps aside; it is still one tap away in the picker.
- Deleting all conversations no longer freezes Foxl. The desktop stopped answering for as long as the delete took, which was seconds for a few hundred conversations and could be minutes on a long-used install; it now keeps working while the conversations' entries are removed from the daily memory log.
- Deleting a conversation now removes everything you said in it from the daily memory log. A message that contained a line starting with "## " (a markdown heading) used to leave part of your words behind.
- Deleting a conversation stops the subagents it started. Before, a subagent that finished afterwards made Foxl write a summary reply into the deleted chat.
- Foxl no longer keeps every finished subagent run in memory until it restarts. A forked subagent held a copy of the whole parent conversation for the rest of the session.
- The Channels tab badge on a phone keeps counting after you leave Channels. It used to stop updating for the rest of the session after the first visit, so a message that arrived while you were elsewhere in the app never showed on it.
- A Channels tab in the background no longer marks messages read. The read marker now moves when the channel is actually on screen, so your other devices keep their badge and the "New" divider for messages you have not seen, and a burst of messages is one update instead of one per message.
- Opening a channel whose history fails to load shows the error and loads again once the connection is back, instead of showing the channel's oldest hundred messages as if they were the current conversation. A message that arrives while a channel is opening is no longer dropped when its history finishes loading.
- Switching channels while the microphone permission prompt is up no longer joins the other channel's huddle with your microphone on. The join is dropped and the microphone released.
- Archiving or reopening a channel says why when it is refused (only a channel owner or admin can archive, and a reopened channel's name may have been taken), instead of closing the channel you were reading and doing nothing.
- Long chats compact at 90% of the model's context window, using the estimated next request including pending tool results (GPT-6 Astra, GPT-6 Sol and GPT-5.6 Sol compact at 90% of their lower measured input limit). Opus 5.5 can continue after compaction without the "User messages cannot contain reasoning content" error.
- Compaction removes thinking signatures tied to the previous context and refreshes its token estimate. An empty summary preserves the conversation, and an unrecoverable overflow reports a failure instead of claiming compaction succeeded.
- The agent keeps working after a compaction in the middle of a task. After such a compaction the next Opus 5.5 call was often filtered and the turn ended with "Stream ended without completing a message". The summary is now marked as a checkpoint to continue from rather than a new message from you, it quotes your request when that request was among the summarized messages, and it records what is left to do.
- The "Context compacted" line in a chat now survives a reload. When Foxl shortens a long conversation to fit the model's window it draws a divider saying what it left out - "the 20 oldest messages were summarized", or how many tool results were shortened - and that line disappeared the next time the window was refreshed, so the one record that older history had been dropped was gone. It is kept now, and the dividers already recorded in your existing conversations reappear too.
- Stop now closes the model request itself, not just the reply on screen, when you use a Claude API key, a Claude Code or ChatGPT subscription, or GPT and Grok on your own AWS account. Before, the request kept streaming for its full length after Stop, with nothing reading it.
- Stop no longer waits out a retry. A run that hit a model error used to sit out its whole retry delay after you pressed Stop before it ended. A server asking for a very long wait before retrying now shows its error instead of stalling the turn.
- Notes summaries and live translation close their model request when they are cancelled or abandoned. Before, every translation Foxl gave up on kept streaming in the background on your own API key until it reached its length limit.
- A Notes summary no longer saves half an answer as if it were finished. When the model failed partway through, the partial text was written into the note as a complete summary; it now reports the error instead. This covers a Claude, OpenAI or OpenAI-compatible, Gemini or Ollama key.
- Image generation is offered after you sign in to ChatGPT, without restarting Foxl. The agent's generate_image tool used to be offered only if a ChatGPT sign-in already existed when Foxl started, so signing in afterwards left it missing until a restart. A new conversation, or one whose model you switch, now picks up the sign-in, and an API-key-only Codex login no longer offers an image tool that fails on first use.
- A Gemini CLI chat that fails now says why, for example that no API key is set, instead of showing an empty reply. Stopping a Gemini CLI reply also stops the CLI (at its next line of output), which runs with every tool call auto-approved, instead of leaving it working in the background.
- Command output and Gemini CLI replies in Korean, Japanese, Chinese and other non-Latin scripts no longer show stray replacement characters where a character happened to fall across two reads.
- Edits to your name, bio, company or website on the Account page are no longer put back to the saved value while you type when your account refreshes in the background, for example when a chat reply finishes.
- Files: unsaved edits are no longer thrown away when you open something else. Opening another file with unsaved changes (from the tree, Quick Open, search, the command palette or a new file) now asks whether to save them, discard them or stay, and Save opens the other file only once the save succeeded. Clicking the open file's own row keeps your edits, a rename or move carries them to the new name, leaving Files for another page and coming back restores them, and closing or reloading the browser tab asks first.
- Workspace search no longer comes back empty when a folder in the workspace contains a symbolic link that loops back on itself, and no longer lists notes from inside node_modules, hidden folders or a local folder named Shared, which the file tree already hides. Searching is also about twice as fast on a large workspace, and on the desktop typing a new query drops the previous request instead of keeping a connection open for it.
- The tool audit log is readable only by your own account (it records the commands, paths and addresses the agent used and was readable by every account on the Mac), is written without pausing a running reply, and rotates at 10 MB, keeping one previous file.
- A Foxl Code run that finishes without opening a pull request no longer waits in review for two weeks. A run that found nothing to change is marked cancelled, and one whose pull request or push failed is marked failed, so a scheduled task's next run can start instead of reporting that earlier scheduled tasks are still open, the run leaves your needs-you list, and its phone notification says the task finished with no changes rather than that it is ready for review. A run whose pull request is open, or whose outcome could not be confirmed with GitHub, still goes to review.
- A finished Foxl Code task no longer holds a live connection open while you look at it. Opening a task whose run has ended used to leave its terminal stream open for as long as the tab stayed open, hidden tabs included; the terminal now connects only while an agent can still be working. The task header stops saying Running once the run ends instead of waiting for a reload, and follows later changes such as a merge. The review rail stops re-reading the selected task every ten seconds while it is closed or once the task is merged, failed or cancelled.
- Android: the message box sits right on the keyboard instead of floating a whole keyboard height above it, which pushed the greeting or the conversation under the header.
- Android: the Back gesture closes the open sidebar, sheet or menu first, then goes back a screen, and from the first screen returns to the home screen instead of doing nothing.
- Android: if the system reclaims the app's web view, Foxl reloads it instead of crashing.
- Android: Foxl no longer asks for notification permission, which it cannot use yet on Android.
- Android: status and navigation bar icons stay readable when the app theme differs from the phone's.
- Android: file sharing is limited to the app's own cache and photo folders instead of all shared storage.
- iPad and tablet windows between 640 and 767px wide (an iPad mini held upright, a 13-inch iPad split half and half) show the sidebar again. The sidebar button did nothing there, so the conversation list, Settings and the product switcher could not be reached.
- An iPad or Android tablet typing on a hardware keyboard now follows your Enter-to-send setting. An on-screen keyboard still inserts a newline on Enter.
- On touch tablets, a conversation's actions button, its sync icon and a running subagent's Stop button are visible and tappable. Before, the actions button was invisible but still took taps at the end of a long title.
- On iPad, the message box sits directly on the keyboard instead of about 20 points above it.
- Saving an image from chat on iPhone, iPad and Android opens the share sheet (Save Image, Files, AirDrop) instead of reporting "Image saved" while saving nothing. The image viewer also has a Save button in its toolbar.
- Reinstalling Foxl on iPhone or iPad starts signed out instead of silently signing back into the previous account.
- iOS now declares the photo-library add permission that the share sheet's Save Image option requires.
- On iOS, a reply that is still streaming when you switch apps keeps its background time even if the turn started as you left, and gives it back as soon as the answer arrives.
- A Notes recording on iPhone and iPad no longer keeps the microphone on after the page reloads.
- iOS permission prompts, home-screen quick actions and the notification reply field appear in your language (all ten languages).
- Notes saves a recording's audio in pieces and keeps it only once it is complete, so a failed save can no longer leave a truncated recording.
- A Telegram channel no longer goes dead after a reply that takes longer than 90 seconds. The reply is delivered, the bot keeps listening, and other chats are answered while a long reply is still being written instead of waiting behind it. If the connection to Telegram drops anyway, the bot reconnects on its own, backing off up to a minute between attempts, and stops only when Telegram rejects the bot token or another running copy of Foxl keeps taking the same bot.
- Deleting a Telegram or Slack channel stops it. Until now the bot kept answering its allowed senders until the app restarted, adding the Slack channel back failed with "already connected", and starting a Telegram channel again left a second copy polling the same bot.
- Foxl Code's home line, the right-hand Needs you panel and the Work page now agree: all three count the same decisions, and the panel lists the same items Work does. A pull request whose agent has finished counts as needing you rather than as working, so the home line no longer says agents are running when none are, and Work no longer misses a finished pull request that sits behind older tasks in your history.
Features
- Your first nine favourite models have a keyboard shortcut. Option+1 to Option+9 (Alt+1 to Alt+9 on Windows and Linux) switch straight to them, with the picker open or closed, from inside the message box, in Foxl Agent and in Foxl Code. Each of those rows shows the key beside its star, numbered in the order the list draws them, so dragging a favourite moves its number with it. Option plus a digit no longer types its symbol inside Foxl, and in Firefox on Windows and Linux those keys stay with the browser's tab switching.
- Foxl Code shows a task's conversation and its live terminal side by side, so you can steer the agent while watching it work instead of flipping between two tabs. The task view now has Conversation, Split and Terminal modes, with Split the default on desktop. Phones keep the two-tab layout.
- Bring your own key now works on the providers that advertised it and could not deliver. A Google AI key registers in the session you save it in instead of reporting "not configured" until you restart, so Gemini rows reach the picker; a local Ollama started after Foxl is picked up without restarting the app; and the Gemini CLI connection refuses a scheduled task, heartbeat, channel or extension run with a clear message instead of an unrelated AWS error. Gemini 3.8 Flash and 3.5 Flash Lite are selectable (Gemini 2.5 is marked legacy, since Google now limits it to prior users), and the model lists for Hugging Face, xAI, Groq, Qwen, Together, Z.ai, Cerebras and AI21 were re-checked against each vendor's current catalog and corrected, because every one of them still offered a model that had been withdrawn.
Changes
- UI motion is snappier across the app, in the direction recent iOS releases took. The shared motion clock is faster (page and list enters, presses, fades, accordions) and the full-screen transitions were tightened to match: the settings sheet, the terminal push, the iOS-style context menu, settings drills, the mobile reveal drawer and the sheet-card scale. Reduced-motion collapses the shared clock and the iOS-style context menu to instant, as before; the five full-screen transitions named above carry their own durations and are not covered by it yet. The native-glass menu on iOS stays in lockstep with the web animation.
- The desktop boot window's mark now breathes on the same 1.8s clock as the web boot layer and the app's first screen, instead of a slower 2.6s that had drifted from its own intended timing.
- Screen readers now describe the app rather than reading out bare buttons. Icon-only controls in chat, the image viewer and Integrations carry names; the Notes tabs, the pasted-text toggle, notification filters and the meeting HUD menu report their selected, expanded, pressed and checked state; Notes speaks each recording transition and the floating pill reports its state with the elapsed time; the onboarding tour cards take focus when they appear and hand it back when they close; and the server-down panel is a real modal dialog that moves focus to Restart and makes the covered app inert, so typing no longer lands in a hidden message box.
- Task status no longer depends on colour alone. Each badge carries its own shape, a check for success, an X for failure, a triangle for a warning and a speech bubble for review, so a failed task and a merged one are distinguishable without seeing hue. Windows High Contrast also gets a visible outline on the selected sidebar row, the active tab and search matches.
- Copying confirms itself. Copy link, copy conversation and the pasted-text copy report success or failure in a toast a screen reader announces, instead of failing silently.
- Touch reaches the controls that were hover-only. The disconnect control on a connected integration is visible on a touch screen and asks before disconnecting, the favourite star in the model picker is visible on a tablet, the Overview charts carry their values on each bar, the pet panel buttons and the remove-domain control meet the 44px touch floor on every touch device (phone and tablet, either orientation), and Logs and Notifications size their scrollers to the dynamic viewport so their last rows are not left under the mobile browser toolbar.
- An iPad or touch-capable Mac with a hardware keyboard sends a chat message on Cmd+Enter. A phone's on-screen keyboard still inserts a newline on Enter and sends with the button.
- The terminal is keyboard-operable. Desktop session tabs can be switched and closed from the keyboard with a visible focus ring, and on a phone the keyboard's send key runs the command instead of inserting a newline.
- File references in a reply open by keyboard and by screen reader, not only on a Cmd or Ctrl click.
- Relative timestamps keep up. An open notification list, the Notes recordings list and the task list refresh their ages once a minute, and the sidebar's Today divider rolls over to Yesterday at midnight without a reload.
- Renaming a conversation inline commits when you click away instead of discarding what you typed. Escape still cancels.
- The window and browser-tab title name the page you are on instead of always reading "Foxl".
- Create and submit buttons are guarded against a double click, so a fast second press no longer sends two requests when creating a tool, creating a skill, revoking an invite or adding an approval rule.
- Tooltips and hover cards render above dialogs, sheets, popovers and menus instead of being clipped behind them, switches and tabs use the same focus ring as every other control, and a mouse wheel over a focused number field scrolls the page instead of silently changing its value.
- Command, URL, secret and filter fields are no longer auto-capitalized or autocorrected on iOS, filter fields show a search key on the keyboard, and each visible label is linked to its field so tapping the label focuses it.
- More of the app is translated, and the Korean copy is consistent. The macOS titlebar tool panel, the Foxl Code credits explainer and the Notes recorder's error and save messages are localized in all ten languages; the Settings "About" rows show localized labels instead of raw keys; the Foxl Code dictionaries carry the same key set in all ten locales; Korean loanword spelling and terminology were normalized; and em dashes were removed from UI copy with the ellipsis style made consistent within each language. Korean, Japanese and Chinese now wrap at phrase boundaries in narrow columns, and the mobile browser tint follows light and dark mode instead of staying dark.
- Arabic flips the high-traffic directional icons, back arrows and chevrons, to match right-to-left reading. The rest of the icon sweep is tracked for a follow-up.
- The command palette on web and iOS shows a hint instead of an empty panel before you type, and the desktop Settings destination filter gained the result count and clear button the mobile sheet already had.
Fixes
- Remote Kiro keeps early input queued until its V3 composer is ready. Loading spinners no longer consume the first prompt.
- Quick Chat's minimize button hides the window in one press, including after Explain details. It used to shrink the window to its message box first and hide it only on a second press. The conversation and your draft are still there when you reopen it.
- Dictate anywhere (Fn): the pill no longer occasionally stays on screen stuck on the cleanup spinner after you let go of the key. If the paste could not run because another app was holding the clipboard, the pill now reports it and closes instead of hanging.
- Every page loads faster on the web app, desktop and iOS: the initial JavaScript downloaded before first paint is about 300 KB smaller (gzipped) on every screen. The syntax-highlighting bundle is no longer pulled in until a chat view needs it, and only the active language's translations are loaded up front instead of all ten. No change to how anything works.
- The desktop no longer freezes while the agent runs a shell command. Attributing a command's file changes used to scan the whole workspace synchronously, twice per command, blocking chat streaming and terminal input for most of a second on a large workspace; that scan is now asynchronous and yields.
- Chat replies start faster in long conversations: the full transcript is no longer re-loaded and re-serialized before every turn on the main model path (it is only read by the Gemini CLI transport that actually uses it).
- Sending an image or document to the agent is faster: decoding the attachment used a conversion that is about 200x slower under the bundled runtime on macOS and Linux, adding roughly 100ms per turn for a few megabytes of images.
- The workspace file panel no longer re-scans the whole workspace on nearly every poll while a reply streams, which was competing with the stream itself.
Features
- Claude Opus 5.5 is available and is the new default for chat, the Foxl Code coding agent and the desktop's expert routing tier. It costs less than Opus 5 ($4 / $20 per million tokens against $5 / $25) with cache reads at $0.20. Opus 5 stays selectable, and Foxl Notes keeps Sonnet 5 as its default.
- Reasoning on Opus 5.5 is always on, so the model picker shows its five effort levels with no on/off switch. Its default effort is Medium, and it thinks more per turn than Opus 5 at the same level.
- Opus 5.5 also runs on a Claude Pro/Max sign-in (Claude Code), with the full 1M context, and the
opusshorthand now selects it. Reaching it needed an update on Foxl's side, which is fixed - without it every Opus 5.5 request on that sign-in failed. - Kimi K3 is available on Amazon Bedrock with your own AWS account, including image and PDF input, prompt caching, and reasoning controls.
- GPT-6 Sol and GPT-6 Luna are available with your own AWS account, an OpenAI API key, or a ChatGPT Plus/Pro sign-in, including file input, prompt caching, and reasoning controls you can switch off. Both cost half of their GPT-5.6 counterparts. They are not on Foxl credits.
- GPT-5.4 Mini is removed from the ChatGPT sign-in picker: OpenAI stopped serving it on that connection, so every request it received failed. It remains available with your own AWS account or an OpenAI API key.
Changes
- GLM 5 appears under older models in Settings. Existing conversations and scheduled tasks continue using their saved selection.
Fixes
- iPhone and iPad launch correctly when built with Xcode 27. Notes releases the microphone when paused, reconnects transcription before resuming, and reports capture or connection failures without leaving the recorder running.
- Kiro and Cursor can run on Remote again with your own vendor API key. Both can be selected as the default coding assistant, and their key fields are available in Code settings. Foxl charges compute only; the vendor handles model usage.
- Missing or unusable vendor keys are reported before a Remote task starts. Saving one vendor's key preserves the other, and credentials remain bound to their owner.
- Cloud execution and CI permissions are restricted to their intended resources, with live permission checks in release validation.
- Cloud terminal attachments use the task's original runtime and reject revoked repository access.
- Container builds no longer leave the next image queued behind a runner that shuts itself down before completing the previous job.
- ChatGPT context meters use the exact 272,000-token limit. If model discovery is temporarily unavailable, the fallback list retains verified models and excludes retired GPT-5.4 Mini.
Fixes
- Remote terminal startup retries temporary session conflicts instead of leaving a blank, failed pane. Typing entered during startup is delivered once, and choosing Remote always uses the selected machine.
- Remote input no longer stalls for a polling timeout when a keystroke arrives just as the server starts waiting for it.
- Startup input waits for Codex, Hermes, and OpenCode to accept it, including Enter. Terminal setup bytes and a Codex model still loading no longer release queued typing. Shortened startup hints and Hermes's rotating suggestions no longer keep input waiting.
- Hermes and OpenCode Remote panes now carry terminal output and input through the same connection used by the other coding assistants.
- Hermes uses its supported model client, and OpenCode no longer sends a thinking option rejected by older Claude models.
- Hermes preserves Backspace and Enter when several keystrokes arrive together.
- Claude Code requests no longer fail when the CLI supplies its own prompt cache settings. Interactive cloud assistants can read terminal input without being stopped by the wall-clock wrapper.
- Stop reaches the remote CLI and runs its normal cleanup. A terminal killed by its time limit is reported as a failure.
- Cloud runtimes load their CLI tools before accepting tasks and retain the Claude Code, Codex, and OpenCode executables in the startup snapshot. The desktop fetches task metadata while preparing the terminal and checks startup progress every second.
- Remote terminals running Claude Code work again. The Claude Code release the cloud runtimes install began asking, on first run, whether to switch to its new fullscreen renderer - a question nobody could answer in a terminal that streams to a browser, so the agent sat on that prompt for its whole time limit and delivered nothing. On the other side of the same change it drew into the alternate screen with mouse tracking on, which a reopened or reconnected terminal could not redraw and showed as a blank panel. Foxl now pins the classic renderer for every unattended terminal - the cloud runtimes, the Foxl Code shell runtime and your own connected machines - and your own
tuisetting still overrides it. - A dispatched task that produces no output in its first two minutes no longer blames the workspace for running out of storage when the workspace is empty. It now says what was actually measured and names the real causes.
Features
- Quick Chat opens a compact, draggable conversation from the button beside New chat or its keyboard shortcut. Explain details carries the current conversation into a separate discussion, and Add to chat brings that discussion back as a conversation reference while preserving the text you are writing. Quick Chat keeps its own model, reasoning settings and drafts, with file attachments and context and skill pickers.
Changes
- Errors across iOS and desktop use calm, neutral cards with an outlined icon and clear recovery actions. Chat keeps provider diagnostics under Details without changing the original message or its copy/retry actions. Settings, file viewers, notifications, Foxl Code, and the desktop startup screen follow the same visual treatment. Interrupted replies keep their failure card visible after any partial answer.
Fixes
- Renaming a speaker in a Foxl Notes transcript no longer reverts the note's body to what it said before your last edit. The rename was applied to the copy of the note the editor was opened with, which does not carry your typing, so it re-saved that older body over the correction you had already watched save. The editor kept showing the new text, so the loss only appeared the next time the note was opened.
- Clearing a Foxl Notes body now stays cleared. An empty body was saved correctly and then refilled with the raw transcript on the next open, and typing after that saved the transcript back as your notes.
- An AI summary landing while you are still typing no longer loses the summary. The summary was written and shown, and then the save your keystrokes had already scheduled wrote your earlier text back over it - so the note looked correct until it was next opened.
- Exporting a Foxl Notes recording to Word now writes the note you have been editing rather than only the raw transcript, and its bold text arrives as bold instead of as asterisks.
- A Shared document or file whose path exists in two of your workspaces is no longer read, edited, renamed or deleted at random. Every workspace is created with a
README.md, so anyone who belongs to two of them has two entries atShared/README.mdwith nothing in the file tree telling them apart - and an operation that named only the path landed on whichever one the server happened to list first, which meant deleting one workspace's document could remove the other's. Foxl now refuses those operations rather than guessing, and refusing also means an ambiguous path can no longer be resolved from the file tree at all: the operation reports that the file could not be found or written. Naming which workspace you mean is not yet possible from the interface, so if you hold two entries at one Shared path, use a distinct name for one of them until it is. - Failed chat replies remain visible after switching conversations or reloading. Retry keeps the original question instead of saving it again, and message actions use the stored row IDs. Failures that arrive after reconnecting or during an agent's follow-up appear immediately with any partial answer preserved.
- The chat's
…menu opens again on iOS. A compatibility issue with the native glass plugin left the menu invisible and blocked taps on the screen. - The iOS chat menu joins its round button with a softer overlapping panel, larger touch targets, and an opening and closing animation anchored to the button.
- When the agent finishes a file it now names it as a path you can open, instead of ending the answer on a download link that goes nowhere. It had no way to refer to a file it had just written: the write reported an absolute path, which the chat does not recognise as one of your files, so the agent filled the gap with a made-up link like
[download](attachments/report.pdf)- clickable, and a dead end every time. - On iOS, one permission covers Foxl Relay models and speech-to-text before sending your content or audio. The dialog explains both data flows and names Amazon Bedrock and Amazon Transcribe. Permission follows your account across iPhone and iPad. You can withdraw it for both services in Settings > Data controls, effective before the next use on each device. This settings pane appears only on iOS. Desktop and your own provider accounts keep their existing flow.
- iOS release builds use the requested version in the app's About screen as well as the App Store build metadata.
Changes
- Editing one Foxl Notes title no longer rewrites your whole recording history. Saving any single change used to serialize and re-encrypt every recording you have, which on a full library blocked the interface for 61 to 72 milliseconds per keystroke-driven save. Only the recording you changed is written now.
Fixes
- Renaming a Workspace file to a different capitalisation of its own name, or overwriting a file with one of its parent folders, no longer deletes the original and then reports a failure. Both cases resolved to the same path on disk, so the operation removed its own source before it could write, and the file was gone with nothing to restore from.
- Copying a Workspace folder now keeps symbolic links that point inside the workspace. They were skipped silently and the copy still reported success, so the result was missing files that the original folder plainly had.
- Saving a Workspace file no longer writes its front matter into a different file. If you switched files while a save was in flight, the response was applied to whichever file was open when it arrived, and the next save then committed that mixed content to disk. A save response is now matched to the file session that asked for it and dropped otherwise.
- A background Workspace refresh no longer erases edits you typed while it was loading. The refreshed copy from the server replaced the editor's contents wholesale, so anything entered after the request went out was lost with no indication.
- The Shared folder no longer lists files from another workspace that happen to sit at the same path. Files were matched on path alone, so two workspaces with a
notes/folder showed each other's contents. - Switching workspace no longer lets the previous folder listing overwrite the new Shared screen. A listing still in flight arrived afterwards and repopulated the panel, so you were looking at one workspace's files under another's name.
- Switching channel no longer mixes the previous channel's messages and history into the new timeline. Sends and history pages in flight were applied to whatever channel was open when they returned.
- Renaming a shared document no longer overwrites its body. The rename re-sent the document with the copy the client happened to hold, so a rename that raced a read, or that happened while someone else was editing, replaced the real contents with a stale or empty version. The rename now changes the name only and leaves the body untouched.
- Uploading a shared document now goes to the workspace you selected. The upload ignored the chosen scope and resolved by path, so it could overwrite an unrelated document of the same name in a different workspace.
- Conversation search no longer mixes in results from a search you have moved on from. A slow response, or a second page belonging to an earlier query, was merged into whatever was on screen. Responses are now tied to the search session that requested them.
- A Foxl Notes save made in one browser tab is no longer lost when another tab saves. Each tab wrote the entire recording list, so the second write silently discarded the first one's new note even though both reported success. Tabs now coordinate their writes.
- Deleting a Foxl Notes recording no longer empties a note you opened afterwards. The delete completed on an eight second timer and applied its result to whichever note was selected when it fired, taking any editing done in the meantime with it.
- Failing to save a Foxl Notes recording when you press Stop no longer discards the recovery draft as well. Both were cleared together, so a failed save meant the meeting was gone at the next reload with nothing left to recover from. The draft is now kept until the note is safely saved.
- Editing a Foxl Notes body no longer loses its links, tables and numbered lists. Autosave round-tripped the document through plain text, so any structure the summary had was flattened the first time you typed in it.
- Refreshing the conversation list no longer throws away history you have already loaded. Scrolling back through 120 conversations and then triggering a refresh replaced them with the latest 50, so the older ones had to be fetched again from the start.
- Shared files shown in Workspace can be opened, copied and renamed again. Those operations were routed to the local filesystem, which has no copy of a shared upload, so every one of them failed on a file the tree was displaying as present.
Changes
- The web app loads about half as much JavaScript before it can paint. It used to download every one of the ten interface languages and both companion window shells on the first visit, whether or not any of them was ever used. Measured on this release: 5.49 MB of initial JavaScript down to 2.60 MB. Only the language you are actually reading is fetched, plus English as the fallback, and switching language downloads the new one on demand. Nothing about the offered languages or the picker changed, and a language you have already loaded still switches with no network at all.
Fixes
- Signing out and into a different account no longer leaves the previous account's workspace on screen. A workspace list that was still in flight when the account changed could arrive afterwards and repopulate the new session, and the selected personal workspace was kept from the old account entirely, so requests against it were refused by the server with no explanation. The account a response belongs to is now checked before it is used, and signing out clears the workspace selection with it.
- A plan change takes effect on your next Foxl Code request instead of after a sign-in. The service read your plan out of the sign-in token, which is issued once and then reused, so an account that had just moved between plans kept the old one - including the limit on how many tasks may run at the same time. It now reads the account's current plan.
- Opening a folder list with many shared folders is much faster. Each folder's permissions were looked up one at a time, which meant 203 database queries for 101 folders; they are fetched together now.
- Downloading or previewing part of a file returns the right bytes. A range request for the last N bytes of a file, which is what a media player and some document viewers send, was answered with the wrong slice, and the reported length did not always match the data sent with it.
- Switching conversation while a channel message is being sent no longer leaves the composer stuck. The send state and the saved draft belonged to the view rather than to the thread, so the next conversation opened busy, and a send that failed after you had moved on restored its draft into the wrong thread.
- Scrolling back through channel history no longer duplicates messages. Two overlapping requests for the same older page could both be applied - measured, 100 distinct messages displayed as 150 rows.
- A new channel message no longer discards the history you had already loaded. A live update replaced the whole list with the most recent page, so scrolling back and then receiving a message collapsed 100 loaded messages to 50.
- The runtime-role migration tool can finish on a runtime created after June 11. AWS refuses to accept one network setting on those, even when the value is unchanged, so the tool stopped partway through and left the remaining runtimes on the shared role. It now leaves that setting out for exactly those runtimes and carries it forward for every other one, which is what AWS requires in each case. Operator tooling only; no user-facing behaviour changes.
- Foxl Code's shell coding agent starts again. Since September 11 the container behind the Cursor, Hermes and OpenCode backends could not boot at all - its bundled program had two copies of one declaration, which makes the whole file unreadable to Node, so every attempt to open one of those agents ended with the service reporting only that the runtime would not start. Nothing else was wrong with it, and no other backend was affected. The build now refuses to produce a program that cannot be read, so this cannot ship unnoticed again.
Changes
- Settings > Web Access describes the Chrome extension and its browser connection in ONE section instead of two. The two headings said nearly the same thing, and the second one existed only because the first collapsed to a bare heading once the extension connected - so the sentence about how Chrome starts the connection, and the Reinstall button, now sit under "Chrome extension" with the install steps. The row of browser names (Chrome, Chrome Beta, Chromium, Edge, Brave) is gone with it: it stated no question, so nothing about it said what a name in that row was asserting, and its only remedy was the Reinstall button right underneath. Nothing about how the connection works changed.
Fixes
- Android no longer crashes when a saved sign-in credential has an invalid storage type. The app reports the secure store as temporarily unavailable and preserves the session instead of treating the failed read as a sign-out.
- On iPhone and iPad, the bottom of a long screen is reachable again. The last row of Schedules and Agents sat behind the bottom tab bar and no amount of scrolling would bring it out, so Run, Edit and Delete on the final item could not be tapped. Measured on an iPhone 17 Pro: the clearance the app reserves for the bar was 117px and none of it was in the scrollable range, so the page simply stopped 50px too early. Every screen was checked, not just the two that were reported.
- Opening the schedule or subagent editor no longer leaves the tab bar sitting on top of it. Those editors fill the screen on a phone, so Save and Cancel were underneath the bar - and because the bar is a real iOS control drawn above the page, nothing in the page could get above it. It now steps aside while an editor is open, the way it already did for every other panel, and comes back when the editor closes.
- A message you queue mid-reply no longer leaves the previous reply saved twice. On v0.7.19 the answer to a queued message was written to disk with the whole preceding answer stuck to the front of it, so re-opening the chat showed the same text again - and unlike the two earlier versions of this problem, closing and re-opening did not clear it, because the repetition was in the saved transcript rather than on screen. The reply that was actually sent to you was always correct; only what got stored was wrong.
Changes
- Workspaces and Channels are now part of the paid plan. Channels, the Workspace settings section, and shared files (the "Shared" shelf in Files, shared skills, and the shared storage usage readout) no longer appear for a free account or a signed-out visitor - the surfaces that spend a workspace's credits are shown only where that plan includes them. Nothing you already have is deleted; a plan that includes the Workspace brings every one of them back exactly where it was.
- The model picker closes when you choose something again. Picking a model, and now picking a reasoning effort as well, dismisses the picker on the desktop and on the phone. The desktop popover had been kept open after a model pick on the reasoning that the model and its effort are one decision; in practice most picks are a model and nothing else, and the surface covers the composer, so it had to be dismissed by hand every time. Adjusting the effort afterwards is one trip back through the trigger, and Cmd/Ctrl+Shift+/ still cycles the selected model's levels without opening the picker at all. Dragging the effort slider is unaffected - it closes when you let go, not at the first step - and the arrow keys still walk the levels with the picker open. Foxl Code's picker follows the same rule.
- Unread notifications are red again on the desktop and on the web, and stay blue in the iPhone and Android apps. v0.7.18 turned the bell's badge and the unread dots blue everywhere; the phone tab bar's badge had stayed red, so on a phone two badges beside each other disagreed about the colour of the same fact. All three now read the one value, so a surface cannot go half-and-half again.
Fixes
- Cmd+D deletes the open conversation in Foxl chat again. It had been unreachable in practice: chat puts the cursor in the message box the moment a conversation opens, and the shortcut refused to fire whenever the cursor was in any text field - so the keys did nothing no matter what was selected. Ctrl+D typed into the message box still does what macOS means by it (delete the character to the right) and leaves the conversation alone, and the same keys still belong to the file editor and the terminal when you are in one. Foxl Notes is unchanged: Cmd+D there is still ignored while you are writing in a note.
- A message you queued mid-reply survives a trip to another chat. Opening a different conversation in the sidebar used to delete every queued message belonging to the one you left, so coming back showed nothing pending - and for a queued message carrying a photo or a file, that row was the only copy, so the message was silently thrown away rather than merely hidden. Queued rows now wait in their own chat until it is open again.
- Coming back to a chat that was still replying no longer repeats the prompt and the answer. Walking out of a running chat and back left two readers bound to the same reply, and each of them spliced your queued message into the transcript, so one message showed up as two prompts and two answers.
- A reply you walked away from keeps streaming when you come back to it. The paint scheduler kept only one pending update, so with two readers on one chat the live one's text could be dropped and the answer appeared to stop mid-sentence until the turn finished.
- Scrolling the model list no longer makes the group heading flick away and come back. The headings pin to the top of the list, and the one on screen was being pushed out 8px of scroll before the next one arrived, so for that moment model rows showed through where the heading had been. The gap between groups now belongs to the group above it, so one heading hands over to the next with nothing bare in between.
Fixes
- The model selector opens again. On v0.7.17 clicking it appeared to do nothing: the picker was drawn correctly and then hidden a frame later, because showing its window makes the main window lose focus, Foxl marks itself as the background window, and the picker treated that as a signal to re-apply its own styles - which put it back into the hidden state it starts in and only ever leaves once. It affected every Mac and only v0.7.17.
- On a phone, a suggested prompt long enough to wrap is no longer cut in half. The composer sized itself to your draft and not to the suggestion showing in it, so a two-line suggestion had its second line sliced through the middle - and it could not be scrolled into view. That text is what Foxl sends if you press the arrow without typing anything, so it now always fits.
Changes
- The browser site filter is off by default, and your choice is remembered. Settings > Web Access > Allowed domains used to arrive with the filter on, 33 sensitive domains blocked and eight domains pre-entered in the allowlist - and because none of it was saved, every restart or app update rebuilt exactly that, so removing a row or switching the filter off was undone the next time Foxl started. Foxl now reaches every site until you turn the filter on, the allowlist starts empty, and the switch plus every domain you add or remove is kept across restarts and updates. Turning the filter on still blocks the same banking, payment, crypto-exchange and tax or government domains as before.
Fixes
- Settings -> Web Access no longer tells you to update an extension that is already the newest one there is. The amber line asking you to move the extension onto the verified browser connection, and the Chrome Web Store button under it, were shown to everybody whose extension was connected - and the published extension cannot use that connection yet, so the store handed back the build you already had and the warning could not be cleared by anything you did. The panel now says what is actually true and stops asking: your extension is connected over a local port because that is the only way it can connect today, the verified connection is already installed on this machine, and it will be used automatically once the extension that speaks it is published. The warning and the store button come back only when an update really exists and would really change it, and an extension that is up to date yet still on the local port is now told the connection failed to take rather than being sent to the store.
- The model picker no longer flashes an unstyled panel before it opens, and the Reasoning switch no longer looks like it is turning itself on every time you open it. The picker opens in its own small window so the list is not cut off by the app's height, and that window was being shown before its copy of the app's stylesheet had loaded - so for a moment you saw raw content, most visibly a star on every model row, and then the panel snapped into place at a different size. The Reasoning switch was the same cause seen a moment later: its knob had nothing telling it to sit on the right until those styles arrived, so once they did it slid across in front of you, reading as reasoning switching on when it had been on all along. It only happened in the installed app and never in development, which is why it shipped. The window now waits for its styles before it appears, and cannot be shown at all until they are in place; if they cannot load, the picker opens inside the app as it used to rather than showing anything unstyled.
Fixes
- Signing out now really ends the connections it says it ends. "Sign out everywhere" already blocked new requests at once and closed the desktop connection, but a Channels window and a Foxl Code window that were already open kept receiving - a message someone sent afterwards still arrived, and a task created afterwards still appeared. Both are closed now, along with the per-device "Log out" and a password change, and the boundary is exact: signing one device out leaves your other devices connected, and signing one person out of a channel leaves everyone else in it. A device whose connection is closed this way reconnects on its own if its sign-in is still valid.
- A cloud task's credential can no longer spend on a model it was not approved for. A task pinned to one model was allowed to bill any model whose name merely started with the same text, so a Fable 5 task could run as Fable 5.1 - a separate model with its own price. Both request paths now compare the approved model and the requested one as the same identity, so a genuine alias (a provider id, a context-window suffix) still works and a different model is refused before anything is spent.
- Reconnecting to a cloud task no longer reports success when nothing was reconnected. While the managed cloud service was unavailable, pressing Reconnect answered "attached" and moved the task back to Running with its finish time cleared, so a cancelled task looked live with no agent behind it. The refusal is now reported as a refusal and the task is left exactly as it was; reconnecting to an agent that really is still working is unchanged.
- A relay database hiccup no longer looks like a bad sign-in to a cloud agent. Two internal credential paths answered a read failure with "invalid token", which sends the caller off to replace a credential that was never the problem; they now report a server error, which is something to wait out. A genuinely invalid or expired credential is still refused the same way it always was.
- The keyboard focus ring around a note in the Notes sidebar is no longer cut off down both sides. The same fix applies to the Agent conversation list, whose rows sit in an identically bounded scroller.
- Cancelled mobile gestures no longer dismiss sheets, navigate back or refresh a list. Reopening a sheet or starting another drag cancels the previous animation's delayed cleanup, preventing unexpected closes and jumps. Notes Ask AI now supports swipe-down dismissal.
- iPad headers and sidebars clear the status bar and home indicator. Notes exposes a touch-sized audio import button both in an open note and on the empty screen.
- Notes shows Foxl Relay when the signed-in account has hosted AI access. Asking about a note no longer sends Agent-only fields to the hosted model API.
- Imported audio waits for the transcription service to finish instead of closing after 2.5 seconds, preserving delayed final results and any remaining partial transcript.
- A pet overlapping the chat composer lets clicks reach the text field. Dragging stays active until release, and the pet becomes grabbable again once the composer moves away.
Improvements
- Model pickers use compact, single-line rows. Drag rows to reorder models within Favorites or a provider group, or drag provider headings to move whole groups. Both orders are remembered across launches. Favorites stay pinned at the top, and the existing effort controls stay in place; Cmd/Ctrl+Shift+/ cycles the selected model's supported effort levels without opening the picker.
- On Electron, model pickers open in a small native popup that can extend beyond the app window while staying on screen. The effort shortcut sits beside the current effort level.
Fixes
- Kiro and Cursor are back in the Foxl Code assistant lists, and they say where they run. v0.7.13 dropped both out of the cloud terminal picker, the task picker and the default-assistant list entirely, so the only way to find out they still existed was to already know - and Kiro had been a working option the release before. They are listed again, marked "Desktop only", because that is the truth: a cloud task runs the four Foxl-metered assistants, and Kiro and Cursor run on your own machine through Foxl Desktop, where nothing about them changed. Nothing was removed from the desktop and no stored Kiro or Cursor key was touched.
- No more outline around the page when a sheet opens on a phone. With a Surface preset selected (Settings > Appearance), opening the model selector - or any sheet - drew a thin frame of the background wash around the receded page, because the wash is painted across the outer chrome as one continuous gradient and only part of it moved. The whole shell moves together now, so the page recedes behind the sheet with nothing showing around its edge. Measured on the three presets it was worst on: a 35-38 of 255 colour step at the edge, now 0.
- Foxl Code is not offered to a shell with nobody signed in. Everything Foxl Code shows - tasks, repositories, runtimes - comes from Foxl's servers on your account, so signed out there was nothing behind any of it: the product switcher offered a Code row, the phone tab bar gave it a cell, the command palette listed its pages, and Settings listed six Code panes whose every form was empty and unsaveable. All of them now appear when you sign in, alongside the ones an account already on the Code waitlist stopped seeing. code.foxl.ai is unchanged - that site serves Foxl Code and nothing else, so it keeps showing its own sign-in page.
- A chat the sidebar says is saved on this device now opens from that copy, immediately, instead of waiting for a round-trip to your desktop. The encrypted on-device history was only ever read when the desktop was AWAY, so with it online - the normal case - every chat you opened was fetched over the tunnel even though the whole transcript was already on the phone. It is read first now and the desktop's answer replaces it when it arrives.
- Opening a conversation shows a placeholder transcript while it loads, rather than an empty pane. Tapping a chat moved the title and the sidebar highlight at once and then had nothing to show until the messages arrived, so on a phone the pane went blank and on the desktop it printed the new-chat greeting and re-laid itself out a moment later. The composer now also stays where it will be, so the placeholder is replaced by the real messages without the pane jumping.
Improvements
- The New-channel dialog is a Foxl form now. It says which workspace the channel lands in, labels its two fields instead of leaving the placeholders to do it, carries the
#inside the name field, and shows the name it is about to create the moment what you typed differs from it - soproduct launchreads back as#product-launchbefore you commit rather than after. Open and Private are the segmented control the rest of the product uses, with one line under it describing the option you picked: an open channel is one anyone in the workspace can find and join, a private one is hidden and only the people you add can see it. Cancel and Create sit in the standard dialog footer, so on a phone Create is the full-width button under your thumb. - The two visibility options line up. They were
<button>cards in a stretched row, and a button centres its own content vertically, so the taller card's height was inherited by the other and "Private" sat 16px below "Open" - two titles in one row that did not share a baseline. - Creating a channel no longer submits a name you were not shown. The dialog applies the same normalisation the server does (spaces to dashes, a leading
#dropped, 80 characters) and sends that, and the field stops at 80 rather than letting the server silently truncate the 81st character away. - Cancel in that dialog is translated. It was the only English literal left in an otherwise localised screen.
Features
- A channel has its own menu now, in its header, next to the member count. Muting it, starring it, editing its info, adding people, copying a link, leaving and archiving were all reachable only by right-clicking its row in the sidebar - which nobody finds on a desktop and which does not exist at all on a phone, where that sidebar steps aside as soon as you open a channel. So "stop notifying me about the room I am reading" had no control anywhere near the room.
- You can edit a channel's name, topic and description. The topic in the header IS the control: click it to change it, and on a channel that has none it reads "Add a topic" rather than showing nothing. Until now a channel's topic could not be set at all and its description could be written exactly once, in the create dialog, so every channel kept whatever it was born with. Renaming stays a channel owner's or admin's call, and the dialog says so when the server refuses.
Fixes
- The Channels sidebar lines up. The workspace name, the CHANNELS and DIRECT MESSAGES headings and the rows beneath them now share one left edge, and the gutter is 12px instead of 16px - so four pixels come off an empty margin and go to channel names, which is the thing a 240px rail runs out of. The section headings used to sit 6px left of the names they head, which is too small to read as deliberate and too large to read as aligned.
- A channel with messages no longer prints its own name three times. The top of the transcript read
# #general- a hash glyph immediately before a name already spelled with a hash - a couple of lines under the# generalin the header and just aboveMessage #generalin the composer. The header keeps the name; the line under it now just says what kind of room it is and what its topic is. An empty channel is unchanged: it still gets the full welcome block. - The "answering" spinner in the sidebar sits in the same slot as the pin and the
..., at the row's right edge, instead of 40px further in - it was the one trailing glyph that did not line up with the others. Hovering the row still puts the...there, and a pinned chat that is answering shows the spinner rather than drawing one on top of the other. A row that is answering now holds the same 40px whether the pointer is on it or not, so its title no longer reflows. - The answer a subagent's work produces reaches the screen every time, not sometimes. When a subagent finished quickly - the
2+2case - the server announced the follow-up turn milliseconds after the turn that spawned it ended, on a different connection, and the client was still a render behind: it read that as "a reply is already streaming" and threw the announcement away, with nothing on any surface saying so. The turn really ran, so a reload showed it, which is what made it look intermittent. The client now knows a turn has ended the instant it ends, and an overlap makes it wait for the reply instead of dropping it. - The fade under the status bar now covers the agent detail screen too, and there is only one of it. v0.7.13 hazed the page out under the clock, the wifi glyph and the battery on every phone screen that uses the shell's own header - which is all of them except an agent you have opened, because that screen supplies its own equally transparent header. So the one screen a person scrolls longest was the one still putting prose through the OS glyphs. The fade moved up into the shell, where it covers every screen, and it runs 24px past the inset in four steps rather than stopping exactly at it, so the bottom edge is a haze rather than a line.
Fixes
- Conversation titles in the sidebar use the full width again. The row used to hold 40px empty for the
...button whether or not it was showing, so every title ran out of room early and ended in an ellipsis; now the space is given up at the moment you hover the row, and the ellipsis arrives with the button that needed it. On the chat you are currently in - where the button used to be painted permanently - that is 32px of title back. - A pinned chat shows its pin where the
...sits, and the two swap: the pin at rest, the...under the pointer, in one box. It used to sit immediately beside the "answering" spinner with no gap between them, which read as one crowded blob; on a phone the spinner was drawn directly on top of it. - Right-clicking a chat in the sidebar draws the same menu the
...button does. The two carry the same actions in the same order, but only the click menu had been given the roomier treatment, so the right-click one rendered 12px icons with NO gap at all between an icon and its label, in 32px rows - measured, against the click menu's 16px icons, 10px gap and 36px rows. Both are now the second one, on a mouse and under a long press. - Chat no longer warns that your desktop is offline when chat does not need one. An account whose replies are served by Foxl's own hosted models got a "Desktop offline" pill under the greeting on the phone, and then a reply streamed in from the next message it was told could not be sent. Measured on an iPhone: the pill was up and
claude-sonnet-5answered normally. The warning stays for accounts where the desktop really is where chat runs. - Foxl Code is hidden entirely for accounts that do not have access to it, instead of leading to a private-beta notice. The product no longer appears in the sidebar's product switcher, and its Tasks cell is gone from the phone's tab bar - which was the third of four cells in the default row, so a quarter of the primary control on the screen was a dead end. Settings already hid its Code panes. A session left sitting on Code moves back to Foxl Agent, and everything returns by itself the day the account is let into the beta - your saved tab-bar layout is not rewritten.
- A message on the phone can be read again: notifications no longer appear underneath the tab bar. Every toast was drawn 16px from the bottom of the screen, and the floating tab bar occupies the bottom 117px, so a message was hidden behind it and a long one was clipped mid-sentence. The transcription error that names the three settings that would fix it was one of them.
- Scrolled text no longer collides with the clock and the battery. Chat still scrolls under the two round buttons at the top - that is the design - but the strip iOS draws its own status bar in now fades the page out, so prose stops overlapping the time, the Dynamic Island and the battery on the way past.
- The install prompt for a desktop-only feature does not say the same thing twice. "Foxl's 24/7 agent runs on your computer. These run on your computer. Install Foxl on your Mac or PC..." now reads as one sentence, in all ten languages.
- A subagent's answer no longer goes missing. When you asked for a subagent and it finished, the reply that summarised its result appeared only sometimes - and reloading the window always showed it, which made it look like the text had never been sent. It had: the reply was streaming to a window that was not listening. Foxl now waits for that reply properly instead of giving up if it looks a moment early, and a chat that has finished a turn no longer switches the recovery off for the rest of the session.
- Streaming text is smoother in three more places. A reply resumed after a refresh, a chat you switch back to while it is still answering, and every Foxl Code reply now repaint at most once a frame, the way a normal reply already did. Long transcripts were redrawn in full 50-100 times a second on those paths, which is what made the text arrive in stutters.
- A file the agent names is now openable on a phone or tablet with a tap. Holding Cmd/Ctrl is what turned a path in a reply - or in a tool's result - into a link, and a touch screen has no such key, so on iOS and Android those paths were plain text that no gesture could open. A tap opens a workspace file in the files panel now, and because there is no key to hold, the underline that marks an openable path is always visible on those devices. Nothing changed on a computer: a plain click still selects text and only Cmd/Ctrl opens. Handing a path *outside* your workspace to another application still asks for Cmd/Ctrl, so that one stays on the desktop, where the key exists.
- The agent no longer answers a question about an earlier chat with a made-up link to it (
http://127.0.0.1:13847/chat/...). There is no address that opens a conversation, and that one loads a copy of the app that is not signed in, so it names the conversation by title and date instead. - On a phone, Settings no longer opens with a search field over the section list. Search is a round button at the right of the sheet header now, and the field appears - focused - only when you tap it. Tapping it again closes the field and clears the query, so the list is never quietly filtered by a search box you cannot see. The desktop Settings rail keeps its always-visible field.
Features
- The model picker on a phone can be SEARCHED now. Tap the magnifier in the sheet's header and a search field takes the place of the title; type a model name, part of an id, or a provider ("foxl", "AWS", "Ollama") to narrow the list, and tap the X to go back to the whole thing. It is behind a button rather than always on screen so the keyboard only appears when you ask for it, and the sheet lifts clear of the keys while you type, so the list you are filtering stays visible instead of sitting behind them. Before this, scrolling was the only way to reach a model on a phone - which is fine for the handful Foxl serves and not for the hundreds an OpenRouter key on your desktop adds. Both pickers get it: Foxl Agent's composer and Foxl Code's.
- Foxl Notes live translation no longer takes the whole app down with it. On a long meeting it could reach a state where translations stopped arriving and Foxl Chat stopped answering too, until you quit the app and reopened it. Nothing had crashed: the browser allows only six simultaneous streaming connections to your desktop, live translation opened about seven per sentence with no limit (and turning it on captures system audio, so two microphones were each doing that), and once those six were taken there was nothing left for Chat's own connection. Translation is now capped at two at a time so the rest of the app always has room, a translation that takes longer than 20 seconds is abandoned rather than holding a connection for minutes, and everything in flight is dropped the moment you stop recording. On a very busy meeting some lines will now go untranslated on purpose - a caption that arrives a minute late is no use, so the newest speech wins - and Notes tells you once per recording when that happens, with a note that a faster model helps. Previously those lines were skipped silently.
- A trailing sentence with no full stop is translated again. The 1200ms "speaker paused" timer that flushes it was being reset by every word of every translation already in flight, so during continuous speech it never fired at all and those fragments were never translated.
- Cancelling a Notes AI request now really stops it. The cancel path was only honoured when Notes was pointed at Foxl Relay; on the default setting (your own model through Foxl Desktop) and on a self-hosted endpoint the request kept running to completion in the background, holding a connection and still spending, while the app behaved as though it had stopped.
Features
- Tools > Custom now has Export and Import buttons. Export downloads every custom tool you have defined as a dated JSON file you can keep as a backup or carry to another machine. It does not contain your API keys: an MCP server's API key, the values of an MCP tool's Env fields and an HTTP tool's headers are left out on purpose, so re-enter those on the other machine - everything else (the commands, URLs, scripts, paths and parameters) is in the file. Import lists what it will add and what it will replace, by name, before it writes anything, and imported tools arrive turned off so nothing runs until you switch it on. Re-importing your own backup onto the machine it came from keeps the keys that machine already has. Both endpoints existed with no button.
- A file path inside a tool's RESULT is now Cmd-clickable (Ctrl on Windows and Linux), the same way a path in the reply's own text already was. When the agent writes a file, runs a command, or answers with JSON that names a path, hold Cmd and click it: a file in your workspace opens in the files panel, and a path elsewhere on this computer opens in its own application. Nothing is underlined until you hold the key. Foxl will not run anything for you - clicking a script, an installer or an application bundle is refused with a line saying why - and a path with a space in it is left as plain text rather than linked, because there is no way to tell where it ends in a wall of command output.
- Cmd+D now deletes the open note in Foxl Notes, the same way it deletes the open conversation in Foxl Agent. It acts on the note you have open and asks nothing, so it is the quick path; the sidebar row and its right-click menu still confirm before deleting, which is the deliberate one. Instead of a dialog it is REVERSIBLE: the note leaves the list at once, a toast offers Undo for eight seconds, and nothing - not the note, not its transcript, not its audio - is removed from this device until that window closes. Undo puts it back exactly where it was. Pressed with no note open it does nothing, and it is deliberately inert while you are typing in the note body or in any other text field, so it can never fire in place of a keystroke meant for the text. It does not end a recording that is still running. The shortcut is listed under Settings > Shortcuts > Notes and can be rebound there.
Fixes
- Attaching a document on Amazon Bedrock no longer fails with "The document file name can only contain alphanumeric characters...". Foxl was sending the file name with its extension - which Bedrock's Converse API refuses and which Bedrock Mantle requires - to whichever of the two the model really uses, so a PDF attached to GPT-6 Astra was refused outright, and so was one attached to a Claude model if GPT-5.6 had been the last model picked. The name now follows the route the turn actually takes.
- Attaching a document to GPT-6 Astra on your own AWS account now works at all. That model was the one reached over Amazon Bedrock's Converse API, which does not carry attachments for it however the file is named, so no PDF or text file could ever be attached to it there. It now uses Bedrock's Responses API, which reads the same file.
- GPT-5.6 Sol, Terra and Luna and Grok 4.6 on your own AWS account moved to the same Bedrock endpoint. Attachments already worked for these four, so this is a route change rather than a fix: they were served by Bedrock Mantle in one fixed US region and are now served by the Responses API on the ordinary Bedrock runtime endpoint, which reaches them from more regions. The data-processing scope is unchanged - Foxl asks for the US cross-Region profile, as before. Set
FOXL_BEDROCK_CRIS_SCOPE=globalto use the global profile instead, which AWS prices about 10% lower and which may process a request in any commercial AWS region worldwide. Claude models are untouched, and GPT-5.5, GPT-5.4 and Gemma 4 keep their existing route. - A model that still cannot read attachments now says so. On Amazon Bedrock's Converse API documents are read by the Claude models, and Kimi K2.5 and GLM-5 refuse them whatever the file is called. That was reported as a raw AWS validation error about the file name, which read as a problem with the file. The message now names the route instead.
- Logging one device out now closes its live connection to this computer even when the connection carries no session label. "Log out" on the devices list closed the labelled connections and could leave an older, unlabelled one open - and the relay would then promote that one as the desktop link, so a device you had just revoked kept relaying. Reaching this needed a sign-in from before March, so almost nobody could have been in that state; the connections you did not revoke are unaffected either way.
- A message you queue while the agent is working no longer duplicates the reply. Sending one mid-turn could repaint the answer you had already read as a second bubble underneath your queued message, and show two answers to the one message you sent. Nothing was ever wrong in the saved conversation - re-opening the chat cleared it - but it made the transcript unreadable at the moment you were following it. The queue boundary now resets the state every reconnect reads, so the committed reply stays where it was and the resumed reply starts clean.
- Right-clicking a file under "From this chat" in the workspace files panel now offers the same menu the workspace tree below it does - Copy path, Download (Share on a phone) and Open in Finder on the desktop. Those rows had no menu at all, so the files the conversation had just produced were the one place in the panel where a right-click did nothing.
- The Preview tab on a workspace
.htmlfile now renders the page, instead of a blank white pane. It has been blank in every release since the feature shipped in v0.7.3: the app applies one security policy to everything it loads, and that policy forbids a page from being displayed inside another - which is exactly what the preview does, so the browser refused to draw it and there was nothing on screen to say why. The preview keeps the policy the local server wrote for it now, and nothing else changed: the app's own window is still protected the same way it was. - Bold and italic around a quoted phrase now render in Korean and Japanese. A reply like
"먼저 확인하자"는 결론showed the asterisks instead of the bold text, because standard Markdown cannot close an emphasis marker that sits between a closing quote and a particle - and Korean and Japanese write it exactly that way, with no space. Fixed in Foxl Agent chat, Foxl Code chat, and all three Notes surfaces (summary, AI assist, meeting HUD) from one shared rule. - Settings -> Web Access no longer warns that your extension is "connected the old way" when it is not. That amber line was shown to everyone with the extension connected, whatever route it came in on, so it could never go away - including for someone who had already done the one thing it asks for. It now reflects the connection in front of you, so it appears only while the extension really is on the old local port and disappears once it moves onto the verified browser connection.
- And when it does appear it now carries a button to the Chrome Web Store, so "update the Foxl extension" is something you can act on from the panel. "Reinstall browser connection" is unchanged and still reinstalls this machine's side of the connection; it cannot update the extension, which is what that warning is about.
- Foxl Notes now saves the recording in progress every ten seconds, so a crash mid-meeting no longer loses the meeting. Until a recording was stopped nothing about it was on disk: the transcript and anything you typed beside it lived only in the open app, so a crash, a force quit or a flat battery lost the whole session, and the longer the call the more there was to lose. If Foxl goes away with a recording live, the next launch puts that recording in your notes list and tells you it did.
- Typing in a note now reaches disk at least every ten seconds while you keep typing. The save waited for a pause, so writing steadily through a call meant nothing was written at all until you stopped, switched notes or closed the window - the one case that was left was the app dying without warning, which is exactly when it mattered.
- Foxl Notes no longer creates duplicate notes, and duplicate saved files, after a recording has ended. A recording started twice in quick succession left one transcription pipeline running that nothing could stop; every 4.5 minutes it opened a new speech session, the service refused it with "no new audio was received for 15 seconds", and Foxl treated that refusal as the end of a recording - filing another copy of the meeting that had already finished, exporting it to the save folder twice, and spending credits on another AI summary. One report ran for over an hour and produced 20 identical notes and 40 files, with that error appearing on whatever screen was open. Recording can no longer start twice, a pipeline that outlives its recording now shuts itself down within 20 seconds, and one recording files exactly one note however many times Stop is pressed or from whichever window.
- A Foxl Notes note now saves ONE file to the auto-save folder instead of two. Every auto-titled note was written twice, once under its real title and once under "New Transcript", so the folder filled up at double rate and the copy a person opened was often the untitled one.
- A maximized window now opens maximized. Foxl remembered its position and size across launches but never that it was maximized, so quitting from a maximized window brought it back as an ordinary window stretched to fill the screen. Un-maximizing such a window also used to leave it filling the display, because the remembered size had been overwritten with the size of the screen. The size you last chose is kept now, so un-maximizing returns to exactly the window you had.
- On Windows, a window that had been maximized also came back slightly TOO BIG - a few pixels off every edge of the screen, because what was remembered was the maximized frame, which Windows makes larger than the screen. It comes back at the size you chose.
- A deny rule on a remote MCP tool is honoured on the first call after Foxl starts. Until the tool's status had been checked once, the rule was matched against a guessed name, so on a server whose tool names collide the rule could quietly fail to apply.
- The custom-tools export API no longer returns your MCP API keys, MCP environment values or HTTP headers to any caller, and an import that could read nothing now says so in red rather than reporting success with a count of zero.
- Foxl now speaks your language on every screen, not most of them. Hundreds of buttons, menu rows, empty states, dialogs, tooltips and error messages across Foxl Agent, Foxl Notes and Foxl Code had their English text written directly into the page, so they stayed English in Korean, Japanese, Chinese, Spanish, French, German, Portuguese, Russian and Arabic - often a translated heading with an untranslated control right beside it. They are translated now, in all ten languages. English is unchanged.
- The popped-out huddle window and the Foxl Flow dictation pill no longer show internal labels instead of words. Those two windows are separate windows from the app, and they had no translator attached, so their text arrived as raw identifiers - the huddle window printed things like
channels_ui.leavewhere its Leave button belongs, and the name beside "(you)" in the participant list disappeared entirely, while the Flow pill's only line of text was an identifier in every language including English. Both windows now read from the same dictionary as the rest of the app. - In a workspace that lets any member add shared skills, a member can no longer overwrite or withdraw a skill somebody else wrote. Editing your own, and adding new ones, are unchanged; an admin can still edit anyone's.
- Saving a shared skill through the API without naming a publish state now keeps the state it had, instead of resetting the skill to a draft and removing it from every member's agent. The Foxl apps always name it, so no screen in Foxl could reach this - it was only reachable by calling the API directly.
- Your blocked-accounts list no longer shows the blocked person's email address. A row for an account with no display name - which is every account that signed in with a link or a password rather than Google, Apple or GitHub - now reads "Blocked account" above its id, rather than a bare id on its own. Unblock works as before.
- A failed model request on the GPT and Grok chat models now reports a short "Upstream error" line naming the status, instead of forwarding the cloud provider's own error text, which named internal infrastructure detail. The full text is still written to the relay's logs. A provider refusing the relay's own credentials is reported as an upstream failure rather than as a problem with your sign-in, so the app no longer tries to re-authenticate you over it.
- An attached PDF now reaches the model under its real name. Every attachment arrived called
document.pdf, so asking "what is the total in invoice-2026-08.pdf?" named a file the model could not see, and two PDFs in one message were indistinguishable. A PDF whose own filename has no.pdfon the end keeps working: that name is what this endpoint reads the file type from, so the extension is put back rather than the file being refused. - Opening a Word document no longer lets the document phone home. A
.docxcan point a picture, a background or a stylesheet at a web address instead of carrying it, and the request went out the moment the file was drawn - no click, nothing on screen - telling whoever wrote it your IP address and the moment you opened their file. Nothing the document points at is fetched now. - When a picture from a tool has to be moved beside the message for the model to read it, the note left behind now names the tool call it came from - so two images looked up in one turn can be told apart.
- Dragging a file out of the chat files panel and dropping it back on the file list it came from no longer adds it to your message. The cursor also says plainly that nothing will happen there, instead of promising to attach it.
- The desktop startup screen keeps the original black logo in dark mode.
- Exporting a conversation from the sidebar saves the chosen chat without switching away from the one you are reading. Desktop exports also download inside the app, and an export that comes back in the wrong format now says so instead of saving a file with the wrong contents.
- Settings and Notifications on a phone now behave like real sheets. Keyboard focus stays inside the one that is open, the screen behind it is hidden from VoiceOver, and Escape or a backdrop tap closes only the topmost thing rather than everything at once. Sheets and confirmation dialogs leave room for the keyboard and the safe areas, so their content scrolls and their buttons stay reachable on a small screen.
- Touch targets and text sizes on iOS hold up at larger system text. Inputs keep a 16px minimum so iOS stops zooming the page on focus, and clear buttons, switches and form controls keep a 44px target even at 90% text scale. Mobile Settings gains filtering and an empty state, moves focus to the heading after you drill into a section, and keeps labelled switches beside their descriptions.
- Dialogs no longer run edge to edge on a phone. Every dialog and confirmation in Foxl Agent, Notes and Code now sits 16px in from each side, so its border has the same gutter as the rest of the screen instead of touching the display edge.
- A confirmation that can delete something still opens with Cancel focused, so a stray Return cannot confirm it, and it opens at the top of its own warning rather than scrolled somewhere else.
- Cmd+D and Ctrl+D no longer delete the open conversation or the open note when the cursor is in a text field. On macOS Ctrl+D is the system "delete the character to the right", so in Foxl Agent that key could end the conversation being typed in - and with the new Notes shortcut it would have destroyed the note and its recording. Both now stand aside while you are typing, and the character-delete they were shadowing works again.
- Foxl Code keeps updating after its live connection comes back. A reconnect delivered a fresh snapshot and told nobody, so the task list, the questions surface, the plan queue and the suggestion feed all sat on whatever they held before the drop until something else happened to refresh them. A connection that stays open but stops answering is now noticed and replaced instead of looking healthy forever.
- Editing a shared document while it saves no longer loses what you typed. The save's reply used to overwrite the editor with the body that had been submitted, so anything typed in the second or two it took went away with no warning. Leaving the file and coming back keeps unsaved work too, however many files you have open, and Copy, Download and the size and line-count readout now describe the text on screen rather than the last saved copy. Wrap lines reaches the editor.
- Two shared files with the same path in different workspaces are now told apart - in the tree, in Quick Open and in the editor - so opening one no longer shows the other's contents, and renaming one does not open something else.
- A suggestion whose pull request failed to merge stays actionable. It was recorded as accepted anyway, so it vanished from the list with nothing merged and no way to try again, and its notification was marked read.
- Loading more task history survives a status change. Every task starting, finishing or being retried collapsed the list back to the newest twenty rows and reset how far you had paged in. Older rows now follow their real state, including being removed when the task is deleted, in a lookup that is bounded and scoped to your own account.
- The Needs you list belongs to the account you are signed in to. After switching accounts, a list built for the previous one could still be on screen.
- Typing at a cloud terminal no longer disappears when the send fails. The text is kept and can be viewed or copied, it survives moving between panes, and nothing is silently re-sent. A session that has simply gone to sleep is reconnected without interrupting you, and on a phone the command you sent is put back in the composer.
- A link to a task you already have opens that task. It could redirect to the first-run setup screen instead, which put the terminal out of reach.
Improvements
- Foxl is now watched from outside its own hosting. A small monitor in a separate provider checks relay.foxl.ai, app.foxl.ai and code.foxl.ai every five minutes and raises an alarm when two checks in a row fail or stop arriving, so an outage that takes Cloudflare, this repository's CI or the maintainer's laptop with it is still noticed. A daily job records the coordinates a database or a deployment could be recovered from. A wobble in something we do not run - the GitHub download feed, or a paid model probe - is reported and does not count as Foxl being down.
- Desktop chats have a visible conversation menu for pinning, renaming, copying, exporting and deleting. Keyboard navigation and rename keep focus in the sidebar.
- The one-click trash icon that appeared on a desktop conversation row when you hovered it is gone; deleting is now Delete in that row's menu. It sat where the pointer rests while you scan a list and deleted immediately, with no confirmation and no undo.
- Desktop toolbar buttons have consistent sizing, translated tooltips and current shortcut hints. The files button shows whether its panel is open, and titlebar search follows your configured shortcut.
- The desktop titlebar search says "Search Foxl" and its hint names conversations, files and commands - the field already searched all three.
Fixes
- Logging a device out now really ends that device's access, at once. "Log out" on the devices list, and the "sign out other devices" half of a password change, only stopped the device renewing its session - it kept working with what it already held for up to twelve hours, while the screen said the session had ended. The device you are using, and every device you did not revoke, are unaffected. A session ended because a stolen refresh token was replayed is now closed the same way.
- Signing out now ends the live connection, not just the next request. "Sign out everywhere" and logging a single device out stopped that device's API calls immediately and left a WebSocket it already had relaying to your desktop until the app was closed - and a connection ticket issued just before you signed out could still open a new one. Both are closed now, at once, and the devices you did not revoke are untouched. A password change that signs your other devices out closes their live connections too, and so does a session ended because a stolen refresh token was replayed.
- A one-time sign-in code left over from before you signed out everywhere can no longer bring that session back. The code a phone exchanges for a session is also spent once now, so a duplicate exchange returns the session that already exists instead of replacing it.
- Signing out no longer leaves Foxl Code reachable. "Sign out everywhere", logging a single device out, and deleting your account all took effect on the app and left the Foxl Code API answering the same token for up to twelve hours - so a device you had revoked, or an account you had deleted, could still read and write your tasks, repos and settings. It is refused there now, immediately, with no change needed on any device and no re-login.
- Deleting your account works no matter how much history it has. Past about a hundred conversations, tasks or task documents, "Delete account" failed with a server error and left everything in place - so the longer you had used Foxl, the less able you were to delete it. Nothing else about what is deleted or kept has changed.
- GPT-6 Astra and Kimi K2.5 can now read an image a tool returns on Amazon Bedrock, where the whole turn used to fail. Both accept an image attached to a message but refuse one inside a tool result, so the image is moved to the message itself and the model sees it as usual -
view_imageandgenerate_imagework on these models again, in chat, in a channel, in a scheduled task, in a Feed Generator run and from the browser extension. Only the path that uses your own AWS keys was affected. GPT-6 Astra on Foxl credits was always fine, because it reaches Bedrock a different way; Kimi K2.5 is only available with your own AWS keys at all. - Attaching an image or a PDF to GPT-6 Astra, GPT-5.x, Grok or Gemma in the web and mobile apps now really sends it. The attachment used to be dropped on the way out, so the model answered as though nothing had been attached.
- A
denyrule on an MCP tool is now honoured everywhere that tool can be run. It applied to the agent and to the ordinary Run button but not to the Tools page's MCP Playground, and not to the Run button when the rule named the remote tool rather than the server - so the same tool on the same server could be blocked in one place and run in another. Rules apply per remote tool (theserver__toolname the agent calls), so blocking one tool leaves the others on that server working, and MCP tools with no rule of your own still run without a prompt exactly as before. - The custom-tools export endpoint is reachable.
GET /api/tools/custom/exportsat below the single-tool lookup route, so it always answered "Tool not found" and the export it serves could never be fetched - by anything, for the whole life of the route. There is no button for it in the app yet; this fixes the endpoint, not the workflow. Looking a tool up by id is unchanged. - A cloud terminal that says it is live but has stopped drawing now notices by itself and reconnects. Cloud machines are reclaimed after fifteen idle minutes, and until now the only thing that spotted it was typing a key into a dead terminal. This also covers the case where you open a terminal just after its machine was reclaimed - it used to show the last frame the machine ever drew and stay frozen there for as long as you left it open. A terminal that is simply idle is left alone.
- Cancelling an AI summary in Notes now stops the work rather than only hiding it. Signing out, closing the note or starting a recording left the summary running to completion in the background, and it was still charged to your account.
- Attached images, documents and pasted-text chips in the composer now line up with the message text below them instead of sitting 4px further left. Same fix for Foxl Code chat's pasted-text chips and the Channels composer's picked files.
- A finished Foxl Code task always settles. If the settlement call to the billing service failed, it was retried forever, and while it was outstanding the task could not be reconnected - so a task that had really finished could be left cancelled with no way back. It now stops retrying after about an hour and records why, and reconnecting works again.
- A Notes summary stays on the note it was generated for. On a phone, summarizing one note and then opening another showed the first note's summary under the second note's title, and the second note's Summary tab showed a spinner for work belonging to the first. What is shared and what is copied is also no longer decided by whichever request answered last when you switch repository or workspace in Foxl Code.
Improvements
- Refined Agent, Notes and Code with a shared product menu, clearer sidebar groups, consistent spacing, and matching title-bar and sidebar colors in dark mode. Chat keeps its centered composer and rounded workspace surface.
- Settings uses a more compact navigation rail. Click a keyboard shortcut to change it directly, with clearer recording and conflict feedback.
- Files uses a compact toolbar and a complete “Search files” placeholder. Notes on phones keeps sharing and copying together in the top overflow menu.
Fixes
- Signing in again or switching accounts while tokens are refreshing no longer lets a late response sign out the new session or restore the previous account's data. Automatic refresh and concurrent request sharing continue within each login.
- Windows: a background service that crashes now really does come back, and the previous release's claim that it did was wrong. v0.7.8 said restart-on-failure was "requested rather than working" and asked to be checked on a real Windows desktop. It has now been checked, on a real Windows Server 2022 machine, and the honest answer is that the setting it relied on does not do this job: Windows records a background service whose process exits - for any reason, with any exit code - as having completed successfully, and does not start it again. Four different ways of killing it were tried and none came back. The setting is not broken and it is kept, because it does cover the case it is for (the service failing to start at all - a moved app, a deleted launcher - which retried three times a minute apart, exactly as documented). What it does not cover is a crash. The service is now also asked to re-check itself every minute, with Windows' own rule that a run is skipped while one is already going. Measured on that machine: a killed service was back 30 seconds later, and a healthy one was left alone across the check - so "keep running when closed" now survives a crash without waiting for the next Windows sign-in, which is what it was supposed to do since v0.7.8.
- The Chrome extension can use the automatic connection again - it has not worked in any released build since v0.7.4. That release replaced the copy-a-code step with Chrome's own native messaging, so the extension is supposed to be vouched for by the browser and connect with nothing for you to carry. On every packaged build, on every platform, the piece Chrome starts was looked for in the wrong folder, so Foxl reported the connection as unavailable on each launch and the extension quietly fell back to the older path. Found by reading the app's own log on two machines - the same line on every start going back at least to September 6 - and confirmed against the installed files on both. Nothing you set was wrong and nothing needs redoing: install the update and the browsers are set up again on the next launch.
- The iOS sidebar's native Liquid Glass button follows the page transition without jumping vertically or disappearing offscreen. The material and touch target move together.
- Foxl Code no longer repeats the “Needs you” heading. Development reloads reuse the React root, preventing duplicate panels and detached click handlers.
- Saved Notes transcripts open at the beginning, and the phone login form keeps its fields reachable while the keyboard is open.
- Native iOS and Android origins can reach the Code service through its CORS checks; protected routes still require authentication.
Features
- GPT-6 Astra now runs on Amazon Bedrock - on Foxl credits and with your own AWS account. It was reachable only through a ChatGPT subscription or an OpenAI API key; AWS made it generally available on September 8, 2026 and it is now offered under Settings > Model & provider > Amazon Bedrock, alongside Claude and the GPT-5.6 tiers, and on the hosted catalog for Pro and Ultra plans. 1,050,000-token context, 128,000 max output, and reasoning, tool use and streaming all work. With your own AWS account it needs no region setting - it works from us-east-1, us-east-2 and us-west-2.
- The reasoning effort you pick is now the one GPT-6 Astra uses on Bedrock. Effort levels reach the model on that transport for the first time: previously any non-Claude Bedrock model was sent a single fixed reasoning level, so choosing Low or Max changed nothing while the picker went on showing your choice. Astra also cannot turn reasoning off at all, so switching thinking off now sends its lowest level rather than nothing, which used to mean the server quietly chose for you.
Fixes
- The agent finds your earlier conversations again when it asks in a full sentence. Searching your past chats used to require every single word to appear somewhere in one message, so a question phrased naturally - "지난주에 결정한 릴레이 설정", "what did we decide about the homebrew cask" - came back empty even when the subject had been discussed a dozen times, because one inflected ending or one filler word was enough to rule everything out. It now starts strict and then drops the least distinctive word until it finds something, keeping the rare words that identify what you meant, and it tells the agent which words it actually used so a partial match is never presented as an exact one. A search for something you genuinely never discussed still comes back empty rather than offering unrelated conversations. Searching a whole question is also much faster - a six-word question measured 4.9 seconds before and 0.23 seconds now. The search box in the title bar is unchanged.
- A link to another app in a reply opens that app again.
obsidian://,vscode://,slack://,tel:,mailto:and the rest of the app schemes Foxl supports had been clickable since v0.5.14, and from v0.7.0 clicking one did nothing at all: the desktop window had been narrowed to open web addresses only, so the link still rendered underlined with its scheme in the tooltip and the click was refused in a log line nobody reads. The window now opens exactly the set the chat already renders as a live link - editors, note apps, meeting and call links, calendars - and nothing else. The Open links in other apps switch in Settings still limits replies to web and mail addresses when it is off, and the schemes that could run code or read your disk are refused either way. - Windows: "Restart service" tells you the truth, and reconnecting can no longer uninstall the service. Pressing Restart service reported success while restarting nothing - it read the exit code of the request, not whether the process had been replaced. It now checks that a NEW service really took over, and it only believes the fallback signal in the one case that signal is about (Windows reusing the process id it just freed) rather than treating a freshly restarted child as proof the service above it restarted. Separately, pressing Reconnect could reach a repair path that DELETES the background service and its saved sign-in - so a button you press because your phone cannot see the machine could take the machine offline whenever the app is closed. That path now reports the problem and changes nothing. The service is also asked to register with a restart-on-failure rule so a crashed service comes back without waiting for the next Windows sign-in. That request is not confirmed yet, and it is worth being precise about what is and is not known: Windows' own parser reads the settings back correctly (retry three times, one minute apart, no time limit, keep going on battery), and no registration has ever been observed. The machine the automated check runs on has no signed-in user, and Windows will not register a scheduled task for it - measured three times, two different ways. So treat restart-on-failure as requested rather than working until it has been seen on a real Windows desktop.
Features
- The terminal workspace can be arranged, not just split. The Terminals actions menu has a Layout section with five named arrangements: Columns and Rows put every terminal in equal columns or equal rows, Main on top gives the terminal you are in the top of the screen with the others sharing a row underneath it, Main on the left does the same down the side, and Grid lines them up in level rows. None of them opens or closes a terminal - they move the panes you already have, so every session keeps its scrollback and you can click through all five looking for the one you want. Main on top is the shape that was previously unreachable: splitting the same pane repeatedly can only ever make a line.
- A Foxl Code terminal shows what it is spending, in its top-right corner, as it spends it. Context, tokens sent and received, and the coding CLI's own cost figure - the same readout and the same formatting as Foxl Agent's titlebar, because it is the same measurement in a different window. The numbers are the ASSISTANT'S OWN: a coding CLI running in a terminal puts no usage on the wire, so Foxl reads the accounting the CLI journals for itself rather than estimating it. Re-opening a pane shows the last reading immediately instead of waiting for the agent's next turn.
- On a subscription it shows subscription usage instead of a price. A plan is not metered in dollars, so a dollar total would be a number that looks like a bill and is not one. With codex you get the plan name and how much of each quota window is gone - the five-hour block and the week - with the reset time on hover, and the figure turns amber at 75% and red at 90%. On a Claude subscription you get the plan and the tokens: Claude Code publishes no quota consumption anywhere, so Foxl says what it can measure and does not guess the rest.
- A Kiro terminal shows how many credits you have LEFT, not how many you have spent. Kiro bills against a plan measured in credits, so that is the number the corner shows: the balance, the percentage of the plan gone, the plan's own name, and when the cycle resets - plus, on hover, how many credits this particular terminal has used. It is read from Kiro's own account rather than estimated, and the unit label comes from Kiro too, so a plan that meters something else reads correctly. Deliberately not a dollar figure: a plan is not billed in dollars until it overruns, and an overrun is shown as an overrun. One caveat, stated because it is the difference between a missing readout and a wrong one: whether Kiro accepts a cloud terminal's API key for this particular lookup has not been confirmed with Kiro yet. If it does not, the balance is simply absent - no figure is ever invented - and the refusal is logged with its status so it can be told apart from an account that genuinely has nothing to show.
- opencode and Hermes terminals show their tokens, read from the accounting each CLI keeps for itself, with opencode's own cost figure alongside. A Hermes session running on Bedrock shows no price, because Hermes records that it did not price that session - a $0.00 on work that really cost money is the one number worth refusing to print.
- The readout appears for Claude Code, codex, Kiro, opencode and Hermes. A Cursor terminal shows nothing, and that is now a measured fact rather than a gap: the Cursor CLI writes no session record at all and offers no usage command, so there is nothing to read and nothing to ask. A wrong number in the corner of the screen is worse than no number, because there is no way to tell which one you are looking at. In a narrow or split pane the readout sheds its least useful segments instead of quietly cutting one off - the credit balance is the last thing to go, since it is the only figure that answers whether you can finish the afternoon.
Changes
- Closing a terminal in Foxl Code closes the window, and stops nothing. Until now, if the terminal was one you had opened here yourself, its X also cancelled the agent running in it. The reasoning was that such a pane IS its session, so closing it left a cloud machine running with nothing on screen attached to it - but X is the reflex gesture for "get this off my screen", it sits next to the zoom button, it asks for no confirmation, and it was ending an agent mid-edit with no way back. Stopping a runtime is now only ever what a control that says "Stop" does: Stop runtime in the pane's own menu, or Stop on the task row. Switching to the Conversation tab, narrowing the window and navigating away from a task no longer stop anything either, for the same reason. A closed pane still stays closed, and a run you left going is still on the Tasks page and still reopenable from "Watch a run". A LOCAL terminal is unchanged: its shell ends with the pane, because otherwise the next pane adopts the session you just closed and it comes back with its scrollback.
- The desktop app is on a supported Chromium again. It was built on Electron 41, which stopped receiving security fixes on 2026-08-25, so the browser engine inside the app - the thing that renders every message, note and provider sign-in page - had been six Chromium versions behind and getting further behind each week. It is now on Electron 44 (Chromium 152). This raises the macOS requirement to macOS 13 (Ventura), because Chromium itself dropped support for macOS 12; a Mac on 12 will refuse the new version by name rather than installing it and failing to open.
- Shared search no longer reads everyone's documents to answer one person's query. It walked the whole shared corpus before narrowing to what you are allowed to see, so it got slower as other people shared more. It now reads only the documents you can see - measured, a search that examined 6,000 rows examines 50 - with the same results in the same order. This release also lays the groundwork for removing a duplicate copy of every shared document's text; that removal, and the storage it frees, comes in a later release.
- A Foxl Code terminal reconnects itself when its machine has gone to sleep. Opening a task whose machine had been recycled used to show a card saying the session stopped, with one Reconnect button to press. The terminal now brings it back on its own, showing only the standard Foxl loading blur while it does - no card, no button and no wording. It retries a couple of times if the runtime refuses, and if the session genuinely cannot be resumed it says so instead of leaving the blur up. It only does this when the machine is really gone: a task you stopped yourself, or one that has finished, is left alone and keeps its Reconnect button, so nothing restarts work you ended.
Fixes
- A browser instruction is addressed to one connection now, and only that connection can answer. Every instruction Foxl sent to your browser - the page it was opening, the text it was typing - was sent to every program connected on the extension's channel, and the first answer back was the one Foxl believed. So a second connection could both watch and answer, and Foxl would work from a page it had never really seen. If the connection drops mid-instruction, Foxl says so instead of waiting thirty seconds.
- The reasoning effort slider no longer shows a dark rim on the left of its handle at the lowest level. The filled part of the track was drawn up to the middle of the handle even at Low, where it should be invisible, and a sliver of it escaped around the handle's left edge. The highest level was never affected.
- The model picker no longer slides sideways while you drag the effort slider. The model chip in the composer carries the effort next to the name, so the chip changed width as the level changed - and because the picker opens aligned to that chip, it jumped up to 23px left or right under the pointer. The effort now sits in a slot as wide as the longest level, so neither the chip nor the open picker moves.
- "Equalize pane sizes" now makes the panes equal. It set every divider to the middle, which is not the same thing once you have more than two terminals: three panes opened with two presses of Cmd+T came out 50% / 25% / 25%, so the pane you started in kept half the workspace and the command whose whole job is evening things out was what put it there. It was only correct at two panes, or at four split evenly. Every terminal now gets the same area whatever shape you built.
- A generated image is no longer cut off in the chat when you reopen the conversation. A tall image (the 1024x1536 and 1536x1024 sizes especially) showed its top three quarters with white underneath, and only after a reload - the picture looked right while it was being generated, which is why it read as a bad generation rather than a display bug. The preview stored with the message was slightly too large for the transcript's own size limit and was being trimmed part way through the image data, which a browser draws as far as it got and then leaves blank. Previews are now sized to fit that limit, and an image that still cannot fit is left out rather than shown half-drawn. Images already in your history are served whole again too, so old conversations look right without regenerating anything. One trade comes with it: the zoom view shares the thumbnail's copy, so zooming a tall generated image is slightly softer than before. The full-resolution file is still on disk, and Reveal in Finder or Save Image As open that.
- "Reveal in Finder" on a generated image opens the right folder again. The same trimming took the file path with it, so the menu item pointed at a path that did not exist and did nothing at all when clicked, with no error.
- Numbered lists no longer lose their tens digit. In a chat reply, a numbered list of ten items or more had the left edge of every two-digit number cut off - "10." rendered as "0.", "11." as "1." - on the phone and on the desktop, while the text beside it was fine. The number is drawn outside the text column and the column trims what sticks out, so there was not enough room for a second digit. Lists now leave room for three.
- The encrypted tunnel now refuses a frame that was replayed, reordered, reflected or aimed somewhere else. Encrypting a frame stopped nobody from RE-SENDING it, and for a keystroke frame that means re-typing into your shell; nor from pointing one at a different terminal. Each frame is now tied to its direction, its position in the stream and the terminal it names. A frame that arrives out of turn is dropped and counted; one that has actually been tampered with is dropped, counted and reported as an error. Either way your other devices keep working. This is about a frame surviving in one piece, not about who can read it, and it holds against anyone who can copy frames off the network rather than against something that can rewrite the initial handshake. Older desktops and phones keep working exactly as before, and get none of it until both ends have been updated.
Features
- Foxl Code has its own reasoning depth. The model picker in Foxl Code now carries a Reasoning switch and the same Low/Medium/High/xHigh/Max effort levels Foxl Agent has, and it is a separate setting - changing how hard Foxl Code thinks no longer changes Foxl Agent, which is what it used to do (Foxl Code simply read the Agent's setting and had no control of its own). Models whose reasoning cannot be turned off show "Always on" instead of a switch that would not do anything. The control appears only for models served by your own computer, because those are the turns it can affect.
Changes
- Foxl Code's Work board is three lanes now, and they are grouped by who has to move next. It was five - what needs you, what is not started, what is working, what is done, and the activity log - and two of those five were wrong about their own contents. A pull request your agent has FINISHED and left for you counted as "Working", so it sat under a spinning icon that turned for as long as the PR waited. On a real account that was two days, over a change that was approved with its checks green, while the "Needs you" lane counted 24 other things and not that one. It is a decision, so it is in Needs you now, as a card that says "Waiting for your review" with Diff and Merge on it. The lanes are Needs you, In flight (an agent may still act on these - nothing here is waiting on you) and Done. Nothing animates any more: each row shows how long it has been running instead, which is the number that tells you a run is stuck. A run that is paused waiting for your answer says so rather than reading as busy. Done stopped being a wall of cancelled runs. It was 39 rows of which 37 said "Cancelled", and every one of them was titled with the repository name, so the column read as the same row a dozen times. Cancelled runs are folded behind one line you can open; merged and failed stay open; and a row without a title now says what it is about - "Pull request #12" - rather than repeating its repository, which is already on the line below. Not started and Activity are still there as tabs, with links to them under the board. Both want the full width of the page rather than a fifth of it: Not started has to ask which repository first, and the activity log runs into the hundreds.
- A button means the same thing on every card in Foxl Code. The cards had been unified once already, but only their shells were - each one still chose how its own buttons looked. One Merge was a solid button, another was grey, another was a plain word with no outline at all, and on the suggestion cards it depended on the order the server happened to send the actions in. So the most irreversible thing on the page, merging someone's code, looked different depending on which card you reached it from, and on one card it looked like a link. Now every card asks one place. Each card has exactly one solid button - the thing that is actually recommended for that card - and everything else is outlined. On a pull request your agent just finished, the solid one is Diff, because nobody has read the change yet; Merge sits beside it. On a pull request that is already approved, Merge is the solid one. On a red build it is Fix it. When a card has nothing to recommend, it says so by having no solid button rather than promoting whatever is first. Two smaller things came with it: a button waiting for its second press is red on every card now (it used to go red on some and black on others, for the same write), and buttons in the activity log are the same size as buttons on the cards.
- Reasoning effort is a horizontal slider in the model picker on desktop. It used to be an "Effort Low >" row that expanded a vertical list, so picking a level took two clicks and said nothing about the fact that the levels are an ordered scale. It is now one track with a stop per level and the current level named above it - drag it, click anywhere on it, or use the arrow / Home / End keys. Only the levels the selected model accepts are offered, exactly as before. The phone sheet keeps its one-tap pills.
- Choosing a model no longer closes the picker on desktop. Picking a model and setting its effort is one decision - the levels are per model, so they can only be set after the model is - and closing on the first half meant a second trip through the trigger for the second. The check mark moves to the new row and the effort control re-renders with that model's own levels. The phone sheet still closes on a tap, where it is also one of the three ways out of a sheet that covers the screen.
Fixes
- Merge asks twice on every card in Foxl Code, including the new "waiting for your review" one. That card is the one this release moved finished pull requests onto, and it was the only place in the product where a single click merged to a default branch - every other Merge on the board arms first and needs a second press. Its Merge sat a few pixels from the filled Diff button the card asks you to press first, on a change nobody has read yet. It now turns red and says "Confirm merge" for the second press, like the others, and disarms itself after four seconds.
- A pull request with failing checks no longer looks ready to merge. The same card showed only "The agent finished and opened a pull request", so a red build or a reviewer asking for changes was not on the row at all - and that card is what you see for those pull requests, not a separate one. It now leads with "Checks failed" or "Needs changes" when either is true, in the same words the other lanes use.
- Foxl Code's model picker no longer names a reasoning depth the turn does not use. Until you choose one, Foxl Code follows your desktop's setting - but the picker filled the gap with the model's own default instead, so on a stock setup it highlighted High while the turn ran at medium, and it showed reasoning switched on for people who had switched it off. It reads the desktop's real value now, so what it shows is what runs.
- Picking your Claude subscription for Foxl Code is no longer billed to your AWS account. A model chosen under Claude Code (OAuth) and the same model under Amazon Bedrock are one model on two accounts, and the part of Foxl that decides which one serves a request treated them as identical - so with Foxl Agent on Bedrock, choosing the subscription in Foxl Code silently ran on Bedrock and charged AWS, with nothing on any screen saying so. The transport is now part of that comparison, so the account you picked is the account that answers.
- "Read all" and "Clear all" are gone from Foxl Code's activity log. Neither did what it looked like. There is no read state to mark on a log of things that already happened, and both only wrote to the browser you pressed them in - so "Clear all" hid rows the server keeps sending, on one device, with nothing cleared anywhere else. Hiding a single noisy row still works. The repo filter now applies to the log like it does to every other tab.
- The Work board no longer stretches past the bottom of the window when a lane is long. With 22 cards in the first lane the board grew to roughly four screens tall, the page did not scroll, and the links under it could not be reached at any window size.
- Image generation works again. On v0.7.5 every "draw me ..." request failed with
The 'gpt-5.4' model is not supported when using Codex with a ChatGPT account. That release correctly removed GPT-5.4 from the model picker - OpenAI had stopped serving it to ChatGPT accounts - but the image tool carried its own separate copy of that model name, so the picker came out clean and the image tool was left calling a model that no longer exists. It now uses GPT-5.6 Sol, and the model name lives in one place instead of two, checked by the same gate that keeps removed models out of the picker. Verified by generating real images: five of the six models the ChatGPT account offers can carry an image request and GPT-5.4 is the only one that cannot. - Foxl Code chat failed with "Language model stream error: Bad Request" whenever its model came from a different provider than Foxl Agent's. Every message in Foxl Code ended in that one line, which named no model, no provider and no reason. The cause was that a Foxl Code turn was assembled from two unrelated decisions: the MODEL came from Foxl Code's own picker, and the PROVIDER came from whatever Foxl Agent happened to be set to. So with the Agent on ChatGPT and Foxl Code on Claude, a Claude model id was sent to ChatGPT's endpoint, which serves no Claude model - and the upstream refusal was wrapped in a way that discarded everything useful about it. Foxl Code now decides the model and the provider together, against the same catalog its own picker is built from, so the two halves can no longer disagree. If the model you picked genuinely cannot run on this computer, the reply says which model answered instead rather than failing.
Changes
- Claude Fable 5.1 is available under Claude Code (OAuth), and the effort control on that provider now reaches the model. Fable 5.1 (released September 1) joins Opus 5, Fable 5, Opus 4.8 and Sonnet 5 in the Claude Code (OAuth) model list. Two things about that provider had to change for it, and both were found by sending real requests rather than by reading. First, Anthropic decides which models a Claude Code client may use from the client's version: the version Foxl sent (2.1.75) was refused for Fable 5.1 with "version 2.1.251 or newer is required", so Foxl now sends the version of the current CLI, 2.1.261. Opus 5 was re-checked on the new version, with and without tools, and still runs on the subscription. Second, the effort level you pick (low through max) was being removed from every Claude Code (OAuth) request before it left the app, on the old belief that the subscription would push a request carrying it onto pay-as-you-go billing. Measured on Opus 5, the subscription accepts all five levels sent the way the Claude Code CLI sends them, so the effort you choose now applies on this provider too. One caveat, stated plainly: on a Claude Pro account without extra-usage credits, Fable 5.1 answers "Usage credits are required for this model." It is not part of the subscription and is billed against usage credits when your account has them. That reply is now shown at once rather than after a minute of automatic retries, which is what a rate-limit-shaped error used to get.
- The browser extension connects through Chrome now, and the pairing code is gone from Settings. Foxl used to print a 64-character code in Settings > Web Access for you to copy into the extension, because the extension runs in Chrome's sandbox and a human was the only channel a secret could travel through. Foxl now installs a small connector that Chrome itself starts, and Chrome only lets the Foxl extension use it - so there is no code to copy and nothing secret is stored in your browser. Settings > Web Access shows which browsers are set up instead, with a Reinstall button for when you add a browser or move the app. Requires the Foxl extension 0.7.2 or newer; an older extension keeps working over the previous connection, and Settings says so when that is what is happening.
Fixes
- The chat box on the desktop suggests something from YOUR work again, not three generic lines. The grey prompt inside the message box (press send on an empty box and it sends that prompt) had been rotating the same three placeholders forever - "Summarize a document or link", "Research a topic and cite sources", "Automate a task on a schedule" - while the phone and web app, asking the same desktop over the relay, got suggestions drawn from your profile, your recent sessions and your recent chats. The desktop was skipping that request entirely. It now makes it, so the placeholder and the empty-chat chips both read like the work in front of you. Nothing new is displayed: this is the same placeholder, with better text in it.
- A chat opened with "Open beside" can be scrolled. The side pane laid its transcript out with no height of its own, so the whole conversation was drawn at full length and everything past the bottom of the card was cut off rather than scrolled - a wheel, a drag and a keypress all did nothing. Only the newest messages were reachable, which is the opposite of what you open a second chat to read.
- Your phone no longer notifies you that your phone connected. "Device connected" is a fact about your computer - something reached it - so it belongs on the machine it is about. It was being fanned back out over the relay to every phone and browser tab as well, including the one whose own connect had just caused it, so bringing the iOS app to the foreground raised a banner announcing itself. The desktop app still shows it, unchanged, and the Notifications setting still governs it there.
- The unread count on the notification bell no longer has a pale ring around it. The red dot in the sidebar carried a 2px halo in the sidebar's own colour to stop it touching the bell, which in light mode read as a white band drawn round the circle. It is a solid dot now, matching the badge in the desktop title bar.
- "Sign out everywhere" now stops notifications too, not just sessions. v0.7.3 shipped that control with a caveat printed in its own dialog: a device you never sign in on again kept receiving previews of new messages, because the relay picked notification targets by account alone and the signed-out device's registration was still on file. So the one case the control exists for - a phone that is lost or stolen - was the case it did not cover, indefinitely. New notifications now stop reaching a device as soon as the account signs out everywhere, and start again by themselves the next time you sign in on it. Notifications already delivered are still not recalled, which is the only thing the control cannot do, and the dialog now says just that.
- The reasoning effort picker now works for ChatGPT and Claude Code models. Selecting a ChatGPT (GPT-6 Astra, GPT-5.6, GPT-5.5) or Claude Code model showed a bare Reasoning on/off switch and no Low / Medium / High / xHigh / Max row, while the same models under Amazon Bedrock showed all of them - so on those two subscriptions there was no way to ask for more or less thinking. Both now offer the levels the model actually accepts.
- GPT-6 Astra no longer shows a reasoning switch that did nothing. That model cannot run without reasoning - asking it not to is refused outright - so the row reads "Always on" and the effort levels stay available. Turning the old switch off did not stop it thinking; it quietly replaced your chosen effort with the lowest one, so picking Max and leaving reasoning off ran at Low.
- GPT-5.4 is gone from the ChatGPT model list. ChatGPT subscriptions are not served that model, so every message sent with it failed. The list now carries only models verified to answer on that connection.
- A long ChatGPT conversation compacts at the right point. GPT-6 Astra reported a 1,050,000-token context while this connection serves 272K, so the context meter read low and compaction started far too late - a long session could hit an upstream limit instead of compacting. It now reports the real window.
Features
- Foxl Code's Work page is a board on a wide screen, and you can switch it off. On a desktop window 1280px or wider it now uses the full width and puts all five questions side by side as lanes - what needs you, what is not started, what is working, what is done, and the activity log - so the whole state of your fleet is one glance instead of five clicks. Each lane scrolls on its own, so a long activity log no longer stretches the page past four empty columns. Every card, button and menu is the one you already had; only the layout changed. A Board / List switch sits at the top of the page. Pick List and you get the single full-width page you had before, tab strip and all - which is still the better way to read a long activity log or page back through what is done. The choice is remembered, so the page opens the way you left it. Phones and tablets are deliberately untouched: below 1280px the tab strip and single list are exactly as before, which covers every iPhone and every iPad in portrait. Narrow a desktop window past that point and the tabs come back on their own. The "Needs you" side panel steps aside on this one page while the board is showing, because its list is the board's first lane - the same rows, right next to it - and it was taking 360px of the width. It is unchanged on Tasks, Repos, Files, Runtimes and Schedules, and it returns on Work the moment you switch back to List or narrow the window. One smaller fix in the same area: with a repository filter set, the activity lane's heading counted every event in the store rather than the ones it was showing, so the number disagreed with the list underneath it.
Features
- "Sign out everywhere" is in Account > Sessions. One control now ends every session on every device, including the one you press it on. There was no such control before: you could only sign devices out one at a time, and a device signed out that way kept working for up to twelve hours because signing it out did not reach the credential it was already holding. Both are fixed, and the sign-out takes effect on the very next request. Note it ends SESSIONS: a device you do not sign in on again may still show previews of new notifications, and the dialog says so.
- Foxl Code shows a PDF, a Word file, a spreadsheet and a deck the way Foxl Agent does. The Files page rendered an image and offered to download everything else, so the four formats a coding agent most often leaves behind as a report could only be opened in another application. It now mounts the same viewer the Agent's Files page uses: a PDF pages, a
.docxlays out properly, an.xlsxbecomes a table, a.pptxshows real positioned slides, and audio and video play. A file shared with your workspace has a Preview button beside Download for the same reason. Files under Tasks, Computer and Session are served as text by the machine that made them, so a document there has no original bytes to show; the page now says that plainly and offers the download, instead of printing the file's decoded contents. - Files in Foxl Code opens in a real editor, and shared documents can be edited there. The Files page showed a file as coloured, numbered text you could only read. It now mounts the same editor Foxl Agent's Files page uses - the VS Code core, with find and replace, folding, bracket matching and multiple cursors - and a document shared with your workspace can be typed into and saved, with Cmd+S (Ctrl+S on Windows and Linux), an unsaved marker beside the filename, and a Save button that appears the moment you have changes. A shared document still opens as formatted prose, because that is how a runbook is read; the Edit button in the header is the way into the editor. Files under Tasks, Computer, Storage and Session stay read-only and now say so, because the agent that produced them is what writes them - the editor there is for reading with real tools, not for typing. A save that the server refuses now tells you why and keeps your text, instead of quietly settling back as though it had worked.
- An .html file in your workspace opens as a PAGE now, not as source. Open one from the workspace panel and it renders the way a browser renders it: the stylesheets, images, fonts and scripts it references load from the paths the file itself names, so a report with a
style.cssbeside it looks like the report. The markup is still one click away on a Source tab, and there is a Reload button for a file the agent is still writing. On app.foxl.ai and on your phone nothing can fetch a file off your desktop by URL, so the linked files are brought over the tunnel and folded into the page instead. That covers stylesheets, images and scripts; anything the page fetches LATER by running its own code cannot be brought in ahead of time, and whatever could not be loaded is named above the preview rather than left as a silent gap in the page. The preview runs sandboxed either way, on an origin of its own, with no access to your account or your session.
Changes
- GPT-6 Astra is available on the ChatGPT sign-in. OpenAI's new flagship, released today, appears in the model picker as GPT-6 Astra when you are signed in with a ChatGPT account, with the five effort levels the model accepts - low, medium, high, xhigh and max - each confirmed against OpenAI's endpoint before it was listed. Astra cannot switch its reasoning off: asking it for "none" fails the request, so Thinking off runs it at the lowest effort instead of failing your turn. On this sign-in the context window is the 272K OpenAI serves there, as with GPT-5.6, and the cost estimate uses OpenAI's published API prices. Three defects on the same path were fixed on the way. The effort you chose could be dropped before it reached OpenAI, for any model the underlying SDK did not recognise by name: on the version installed when Astra launched, every Astra turn would have run at OpenAI's default effort while the picker said otherwise, and the request still succeeded, so nothing looked wrong. The SDK's own fix for that shipped separately, and Foxl now requires the fixed version rather than hoping for it, as well as telling the SDK directly that every model on this sign-in reasons. "Max" was quietly sent as "high" for every GPT model on this sign-in; it now goes out as picked. And the sign-in's model discovery was pinned to an old client version, which is why it appeared to list nothing newer than GPT-5.4 Mini. Astra is not on the Bedrock providers yet. OpenAI says it is coming to Bedrock; it will be added there once a real call has confirmed it.
- Foxl has its own typeface now. The app, foxl.ai and docs.foxl.ai all render in Geist for body text and UI, Instrument Serif for display headings, and JetBrains Mono for code - self-hosted, so they look the same on macOS, Windows and Linux instead of falling back to whatever each OS ships. Korean text uses Pretendard in the app; it is loaded only when Korean is actually on screen, so an English session downloads none of it. Until now body text was the system font, which meant the product looked like a different application on every platform and unlike its own website. The Latin faces add about 148 KB across all three families.
- The new-chat screen on desktop and tablet is the mark and the question again. v0.7.1 shared the phone's whole zero state to every window width, which put three starter prompts ("Summarize a document or link", "Research a topic and cite sources", "Automate a task on a schedule") under the greeting on the desktop app, app.foxl.ai and code.foxl.ai. They were written for a phone, where the composer is small and tapping a phrase beats typing one; on a desktop the composer is already large and focused, so they spent the most valuable strip of the first screen on canned text. They are unchanged on the phone, which is where they belong. The Foxl mark stays on every width.
- The new-chat greeting now uses Foxl Code's task-composer type. "What can I help you with today?" is set in the same light weight and leading as the identical line on Foxl Code's Tasks screen, so the three surfaces that ask this question ask it in one voice. Same size as before on a desktop.
- The four Foxl Code request limits added in v0.7.1 are OFF again, because the numbers were too small. A chat turn was capped at 20 a minute and 300 an hour, forcing the autonomous loop's next run at 10 and 60, adopting a GitHub installation at 5 and 10, and typing into a cloud terminal at 600 a minute - and every one of those is reachable on a busy afternoon, so the cap you would actually meet was your own, not a runaway script's. None of them applies now: nothing limits how many requests you send. The machinery stays in place and each limit can be switched on per environment with a single setting, at a number chosen then rather than the tight ones, so if a looping client ever does become a problem the answer is a setting change and not a release. Two details worth knowing if you operate this: a limit of zero is refused rather than obeyed, since it would admit nothing while looking exactly like a bug, and the service's health check now reports which limits are actually in force - including any setting that was rejected - so a change that did not take effect says so instead of looking applied.
- The Files tree names its root. The five shelves at the top of the list (Tasks, Computer, Storage, Session, Shared) sat under nothing, so there was no indication of what the tree as a whole was or any way back to it once a file was open. There is now an "All files" row above them, and clicking it returns you to the whole list.
Fixes
- Remote terminals in Foxl Code take input again. A cloud terminal came up, painted the assistant's screen, and then ignored every keystroke for the rest of its life - on Claude Code, Kiro and Codex alike. This is the defect behind every "the terminal starts and then freezes" report since v0.6.0, and it was never in the terminal: keystrokes were being sent to the wrong machine. Each cloud terminal streams its output over one long-lived connection to the microVM running it, and keystrokes were sent as separate requests addressed to the same session. Measured on production: while that streaming connection is open, a second request for the same session is served by a *different* microVM - one with no terminal in it - so every keystroke was answered "this session has gone to sleep" while the real terminal sat there working. The screen-reading request missed in the same way, which is why the pane could also report that the machine was still starting for as long as it was open. Keystrokes and resizes now travel the other way round: the machine running your terminal asks for them, so there is no second address to get wrong. A keystroke typed while the assistant is still starting is still held and delivered in order once it can read, and a terminal whose machine really has gone away still offers Reconnect.
- Your Claude subscription tokens no longer appear in a command line. Refreshing them wrote the new pair back to the keychain in a way that put both the access and the refresh token where any program on your Mac could read them for the moment of the write. They now travel on a private channel, and the write is verified rather than assumed.
- A ChatGPT sign-in that has been open for a while no longer fails its first message. The desktop kept using an access token past its expiry and only noticed when the request was refused; it now refreshes before sending.
- Signing in to Codex with an API key no longer offers ChatGPT subscription models. They were listed and then failed on first use. An API key belongs to the OpenAI provider, where it already works.
- A custom tool parameter containing
$&is passed through as typed. Certain characters in a value had part of the surrounding command pasted into them. - A skill that requires a program by its full path can be satisfied. Such a requirement could never be met, on any machine, however the program was installed.
- Daily memory entries are dated the day they were written. Near midnight the file and the date written inside it disagreed by one day.
- Notes usage is recorded against the model that answered. With Notes pinned to a different provider than the Agent, a Notes reply was filed under the Agent's provider and its token counts could be understated.
- Foxl Code: a slow or failed reviewer no longer uses up a review round. Two rounds are allowed per pull request, and a reviewer that could not start still consumed one - so a transient failure could quietly leave a PR with no review at all, waiting on a reviewer that was never running.
- Two organisations that both installed Foxl on the same repository no longer collide. The autonomous loop's own issue list was keyed by repository and issue number alone, so one install's record silenced the other's.
- The membership re-check reaches every organisation. An organisation Foxl temporarily could not read was retried every minute forever, which could use up the whole check budget and leave other organisations unchecked.
- An organisation with more than 1,900 repositories, or more than 4,900 members, is handled correctly. Past those points Foxl silently saw a partial list, which could remove repos or member access it had simply not been shown.
- A machine marked failed can come back. A box that reported a working new address stayed marked failed until someone edited it by hand, and the reason it failed was erased on its next check-in.
- Interval schedules keep their timing. A five-minute schedule drifted by a few seconds every run and lost roughly one run in ten over a day.
- Old task activity is cleaned up again. One long-running task could block the cleanup permanently, so the records kept growing.
- A settings save no longer half-applies. Pasting the wrong kind of Anthropic key was refused after the rest of the form had already been saved.
?limit=-1no longer removes the limit on task search, activity and suggestions.- Agent output is scrubbed the same way everywhere. Four of the five agent runtimes removed only GitHub tokens from what they showed and stored, so an Anthropic key, a Slack token, an AWS key id or a login token printed by a coding tool could survive into the saved final screen.
- Machine errors no longer show internal detail. A database or network failure was returned to the browser verbatim.
- A busy autonomous loop keeps its own pace. While a periodic review was pending, the loop ran on every cron minute instead of its configured interval.
npm run deployin the container directories runs the real deployer. It ran a retired script that could target the wrong runtime and report success after failing.- Four desktop settings requests from the phone and the web app are encrypted now. The model picker and the chat home reach your desktop through the relay, and those particular calls were the only ones going through a helper that skipped the encryption every other request already used - so the relay could read which provider you use, the model you picked, and the greeting your desktop writes from your recent chats. They ride the same encrypted envelope as the other desktop requests now. A desktop that predates the encryption keeps working exactly as before.
- A name containing
$&is no longer mangled in a message. A file, note, channel or repository whose name contains one of a handful of characters had part of the surrounding sentence pasted into it - "Deleting <name>" could come out repeating the word "Deleting". - A large paste into a remote terminal no longer disappears. Roughly 30,000 characters or more was silently dropped instead of being sent.
- Your Overview and For You pages use the right timezone after your machine changes it. Travelling, or a daylight-saving change while the app stayed open, left them reading the day boundary from the timezone the app had started in.
- Exporting your data reports the right error. A failed export said your account could not be deleted.
- A model-fallback chain that fails to save no longer looks saved. The switch and the list stayed on the screen showing a chain your desktop had never stored.
- docs.foxl.ai offers an iPad the web app, not the macOS installer. An iPad reports itself as a Mac, and only the download button on the docs site had missed the check the main site already had.
- status.foxl.ai keeps an outage on the day it happened. After midnight UTC every bar in the 90-day strip was labelled a day late until the page next refreshed its data.
- status.foxl.ai says "degraded" when something is slow rather than "unavailable". A component answering every check, just slowly, was announced as being down.
- Channels: editing a message keeps its reactions. The chips disappeared from everyone's screen when a message was edited, and stayed gone until the channel was reloaded. The reactions themselves were never lost.
- Channels: the "New" divider sits above the oldest unread message. With a deleted message among the unread, it sat one message too low, so the oldest unread looked as though it had already been read.
- Foxl Code: a terminal whose session token expired reconnects instead of showing developer instructions. It printed advice about starting a local server, on code.foxl.ai, and stayed dead until something else happened to refresh the token.
- Foxl Code: the review panel finds the pull request on a retried task. Opening the original task said "No PR yet" even though the retry had opened one.
- Claude Fable 5.1 works again on the Claude Pro/Max sign-in. If you use Foxl with a Claude subscription rather than an API key, picking Claude Fable 5.1 failed every time while Opus 5, Sonnet 5 and Haiku 4.5 kept working, so it looked like a problem with that one model. It was not: this sign-in carries a Claude Code version number, Anthropic decides which models that version is allowed to use, and ours had fallen behind what Fable 5.1 requires. It now matches the version Foxl already uses for cloud coding, and Anthropic accepts the model. There is a check that asks Anthropic directly which models the sign-in can reach, so the next model to need a newer version is a visible answer rather than a mystery failure.
- The same is true on Android, backed by a key generated inside the Android Keystore that is not exported from it. It moves itself on first use and nothing signs you out; the backup and phone-transfer paths were already excluded, so this narrows the remaining case of a rooted device or a forensic copy.
- "A device connected to this computer" is a notification again, and it now has a switch. The banner that used to appear when your phone or a browser reached this computer over the relay stopped arriving for anyone using "keep running when closed": in that mode the background service holds the connection, and it only wrote the event to a log file. It now names the device that connected ("Safari (iPhone) connected to this computer"), lands in the notification bell alongside everything else, and opens the Mobile/Web page when tapped. Settings -> Notifications -> Devices turns it off; it is on by default, and it still announces a device only once, then stays quiet about that device for six hours. With the app fully quit and only the background service running there is nobody to show a banner to, so nothing is shown until you open the app.
- A message from Slack or Telegram no longer goes quiet when the agent needs your permission. An approval prompt can only be answered in the Foxl app on your desktop, so a request that started in a chat used to stop dead for a minute with nothing said, which looked like the agent had crashed. The thread now gets a line naming the tool it is waiting on and telling you where to answer, and a line if the approval was not granted. The prompt itself still cannot be answered from the chat, and the details of the call stay in the desktop dialog rather than being posted into a room other people can read.
- Inline code no longer falls back to Courier on some Windows machines. The rule behind
codeandprenamed only the webfont and the genericmonospace, skipping Menlo, Consolas and the rest, so a machine that had not yet fetched the font dropped straight to the generic. It reads the full stack now. - The app no longer fetches a font stylesheet from Google on every launch. JetBrains Mono was pulled from
fonts.googleapis.comat the top of the app's stylesheet; it ships in the app now, like every other font it uses. - The app opens offline again. Two fonts were loaded from Google's servers before the window was allowed to draw anything, so on a network that quietly drops traffic instead of refusing it - a hotel or airport portal, a corporate firewall, a dead DNS - Foxl showed a blank window with nothing explaining why. Measured on the shipped build: no first paint within 20 seconds. Both fonts ship inside the app now, so the window draws in 100 ms with the network unreachable, and the pixel-office game keeps its font offline, which it never did before.
- The window draws 4x sooner on a normal launch. Same cause: those two font requests were render-blocking. Measured first paint on the shipped build, 348 ms, against 88 ms with the fonts local. Nothing about how the app looks has changed - it is the same typefaces, at the same weights, from files inside the app instead of over the internet. Foxl also no longer contacts Google on launch.
- The model picker opens straight away, even with hundreds of models. On the phone, with an OpenRouter key on your desktop, the model button used to sit there greyed out reading "Loading..." every time you came back to a chat - it could not be opened at all until the whole catalog had been fetched over the relay. It now opens on the list it showed you last and quietly refreshes behind it, and coming back to a chat within a few seconds does not re-fetch anything. Every model is still there. The list fills in as you scroll rather than all at once, so a long catalog no longer stalls the sheet as it slides open, and searching still looks through everything you have - not just the part currently on screen. The model you have selected is always shown when the picker opens, however far down the list it sits.
- Groundwork for a browser-extension pairing code. Nothing changes for you in this release, and browser control keeps working exactly as it does today. The connection the extension uses is accepted on the strength of one header the caller fills in itself, so anything else on your machine can claim to be the extension - watch what Foxl is doing in your browser, and start a full agent run with shell access. Closing that needs a shared code, and the extension is a separate program that cannot send one yet. So this release ships the desktop half only: Settings -> Web Access now prints a pairing code, kept in a file only your own account can read, and Foxl says on that page that the code is not required yet. A later release will require it, once the extension can carry it - at which point a program that cannot read your home folder can no longer take the extension's place. Even then it will not stop a program already running as you, which can read that file like anything else you own; that is the same limit every app on your machine has, and it turns "just connect" into "find and read a specific file".
- A "deny" tool rule is no longer defeated by a second space. A deny rule was matched as a plain piece of text, so the same command written slightly differently went straight past it: with
exec(rm -rf)denied,rm -rf ~/work(two spaces),rm<tab>-rf ~/work,rm -r -f ~/work,rm -fr ~/workandr'm' -rf ~/workall ran. The command is now normalised before matching - quoting undone, whitespace collapsed, operators separated, a POSIX program path reduced to its name (/bin/rmtorm) and short flags expanded and sorted - and the rule's own text is normalised the same way, so all of those hit the rule. A normalised match has to start at a word boundary, so a deny rule still cannot fire on a command that never contained it (xterm -fr redis notrm -rf). Settings -> Tool approval now also says plainly what a deny rule cannot do: it matches text, so a substitution ($(...),$VAR), an equivalent tool (find -delete,python3 -c), an encoding (base64 -d | sh), a long-flag spelling (rm --recursive --force) or a wrapper that takes an argument (git -C /repo push --force) still walks past it. Use "ask" for anything that must not run unattended. - Known gap, stated rather than implied: the program-name reduction above is POSIX paths only. A backslash is the POSIX shell's escape character, so a Windows program path (
C:\Windows\System32\cmd.exe,.\rm.exe) is not reduced to its filename and gets none of that extra reach - most visibly for the anchoredexec(name:*)deny form. Nothing got worse: a deny rule is still matched against the raw command text first, so a rule namingcmd.exestill finds it. Asserted as a known gap incheck:tool-permissions. - Opening a cloud terminal on a Cursor, Hermes or OpenCode task now says why it cannot open, instead of failing silently. Foxl's own cloud account is missing one permission it needs to attach a terminal to those tasks, which was re-measured against AWS and is still missing. The old behaviour was the worst possible shape: the server handed the app a connection address that looked fine, the connection was then refused, and the refusal arrived as a closed socket with nothing anywhere saying what had happened or that only an operator could fix it. It now refuses up front, names the exact permission, and says who has to grant it. There is also a command that asks AWS directly whether the permission is there - so the answer stops depending on somebody remembering to check. The permission itself is an AWS change only the account owner can make; until it is made, the honest refusal is what you get.
- Dismissing a Foxl Code card works again in the desktop app and on the phone. Pressing the X on a "Checks failed" row - or Dismiss, Snooze or a reason - answered "Failed to fetch" and left the card where it was. The request was being refused by the browser before it was sent, because the app's API proxy did not list
PATCHamong the methods it permits. The web app at app.foxl.ai and code.foxl.ai was never affected, which is why this looked like a phone-and-desktop-only fault. Editing a schedule, renaming a machine and changing a workspace member's role were broken the same way and are fixed by the same change. - Adding your own machine to Foxl Code works again. The install command downloads a small manifest from code.foxl.ai first, and that file was never published with the release, so the installer stopped with an error before creating anything. It is published now, and the release checks the live site afterwards rather than trusting the upload.
- A machine tells you when its agent is out of date. Your box reports which version it is running every minute and nothing ever looked at it, so a fix could ship and the machines already set up would quietly keep the old one. The machine row now says when there is a newer version and what to re-run.
Performance
- Saving is roughly 10x faster. The local database was running in SQLite's default journalling mode, which fsyncs twice for every row written. Measured on a real 1.3 GB database: a burst of 500 agent events went from 337 ms to 31 ms, and 200 chat messages (which also update the search index) from 188 ms to 24 ms. Tail latency improved with it - across 6,456 samples over three minutes the slowest 1% of requests went from 17 ms to 2.8 ms, and the number of moments where the server briefly stopped answering dropped from nine to two. The first launch after this update takes about a second longer, once, while the change is applied and one index is built.
- Searching your conversations returns 50x less data. The search dropdown shows one clipped line per result but was being sent every matching message in full - measured at 1.5 MB for a single search on a real database, including one 1.2 MB message. It now sends the snippet it displays: 31 KB, and the search itself is 5x faster. From a phone, over the relay, that is 1.5 MB it no longer has to download to draw the same dropdown.
- The provider list no longer stalls the server. Checking whether Claude Code is signed in ran a keychain lookup as a blocking subprocess on every request, and that route is polled - so every few seconds everything else, including a reply being streamed, waited about 30 ms behind it. Measured: an unrelated request went from 1.9 ms to 28.9 ms while it ran. The answer is now remembered for five seconds, so signing in with
claude loginstill shows up within five seconds, and the route went from 28 ms to 2.7 ms. - The overview page's rollup is 15x cheaper, and its cache actually works. It recounted every message on the machine by reading the message bodies - most of a 1.3 GB file - to answer four totals; one index removed that (40.6 ms to 2.7 ms). Separately, the page polls every 30 seconds while the cache expired after 15, so it never once got a cached answer; live values like whether the agent is running are still computed fresh on every request.
- The tool-history list is 7x smaller (1.9 MB to 259 KB on a real database). It was sending whole tool outputs, including base64 screenshots up to 506 KB each; it now sends the first 4 KB of each and says so where it cut.
Fixes
- The macOS app opens again. v0.7.1 could not start: the window flickered without ever loading, nothing on screen said why, and quitting showed "A JavaScript error occurred in the main process". v0.7.1 has been withdrawn and this release replaces it. If you installed it, it updates itself to this one - the failure was in the window, not in the updater, so the automatic check kept working. MEASURED on a machine running the broken build: it moved from 0.7.1 to 0.7.2 on its own. Downloading from foxl.ai also works if you would rather not wait. What happened, in one sentence: the security policy v0.7.0 added to the app window refused the app's own start-up script, so the window never received the key it needs to talk to its local server, and it retried forever. The policy now permits that script again. Everything else that policy blocks is unchanged - the app still refuses to evaluate code from a string, still refuses to be framed, and still refuses to load a script from anywhere but itself - and the underlying hardening is being finished properly rather than left as it was.
- Quitting no longer shows a JavaScript error. Three pieces of start-up work ran up to two seconds after the window appeared and did not check whether the window was still there, so quitting during those two seconds crashed the main process with "Object has been destroyed". All three check first now.
Changes
- The cloud coding agent now installs an exact Claude Code version. The Foxl Code runtime that runs Claude Code against your repositories used to install whatever release was newest on the day its image was built, so the version written in our source never decided what actually ran. The image and the dependency range now name the same exact version, 2.1.259, and what runs is what the source says. This is a reproducibility fix and not a security one: the version last measured in that runtime, 2.1.246, is already past the fix for both of the advisories the old range sat inside.
- "Always allow" on a shell command remembers its first word again, the way it did before v0.7.0. v0.7.0 narrowed what one click saves in three ways at once: it matched the first word as a whole word only, it saved no rule at all when the command you approved contained a
;, a pipe, a redirection,$(...)or a line break, and it never covered a later call that carried its own environment variables. A pipe is ordinary in a shell command, so in practice the common case saved nothing and the next command asked again - which is the opposite of what pressing "Always allow" is for. All three are reverted: one click onls -laallowslsfollowed by anything, as it did through v0.6. That is a broad rule and it is meant to be - it also covers a command that merely starts with those letters, such aslsof, and a longer line that begins with the word you approved. What one click saved is listed under Settings > Safety > Tool rules as "Allowed for this session only", and it is gone when the app restarts; a rule that must keep asking, or never run, can be added there as anaskordenyfor the tool or command, which outranks it. A narrower form of this may return later if it can be done without a prompt for every pipe. - A GitHub event about one connected account can no longer change another one's records. Four Foxl Code bookkeeping tables were matched by repository NAME plus a number, with nothing saying which installation the event came from. GitHub hands the same
owner/reponame back out after a repo is renamed, transferred or deleted, so a pull request closing in one account could mark a still-open pull request as closed somewhere else, quietly drop a decision out of that person's "Needs you" list, retire a suggestion card that was still live, and - when an issue was reopened - take back a backlog slot that keeps their autonomous loop from running. Every one of those writes is now scoped to the installation the event names, and refuses to write anything at all if the event does not name one. - Transcribing with your own key or on your own Mac no longer spends Foxl credits. Those two modes never sent any audio to Foxl - you paid your own provider, or the speech engine ran on your machine - but the app was still reporting the seconds and Foxl was still deducting credits for them. It now reports nothing, and the server charges nothing even for app versions that still ask. A recording in those modes also no longer stops when your Foxl credits run out, because nothing is being spent.
- Starting a Foxl-hosted voice transcription now checks that your credits can cover it. Until now a session was allowed through as long as your balance was above zero, so a nearly empty account could still open a transcription stream. A session now puts a small hold on your credits before it starts and releases it as soon as the first report arrives, so an ordinary recording feels exactly the same. Importing an audio file holds the length of that file, which is the only case where the amount is known in advance, and the hold now lasts as long as the audio rather than five minutes. There is also a limit of 32 transcription sessions open at once. It does not stop one session's URL being reused for several streams at once - that is a property of the signed URL and has to be reconciled against AWS.
- The four most expensive Foxl Code requests now have a ceiling, so one looping client cannot spend a quota everybody shares. There were limits on how many agents one account could have running and on what a task could spend, and none at all on how many REQUESTS it could send - so a buggy or retrying client could keep starting cloud agent turns, keep forcing the autonomous loop to run past its own interval, and keep asking GitHub whether an arbitrary organisation has Foxl installed. Three of the four are bounded per ACCOUNT, with both a per-minute and a per-hour limit: sending a chat turn (20 a minute, 300 an hour), forcing the autonomous loop's next run (10 and 60) and adopting a GitHub installation (5 and 10). The fourth, typing into a cloud terminal, is bounded per TASK at 600 a minute and has no hourly limit - it is counted inside the task's own coordinator instead of in the database, because a database round trip per keystroke would slow down the one path you feel. Every number is far above what a person produces by hand. Over the line the answer says how long to wait rather than looking like a sign-in problem.
- Billing is still unconfigured, and the refusal now says so precisely instead of looking like a missing setting. Foxl sells nothing today, so nothing about paying changes here. What changed is internal: the one refusal every billing route already returned now carries a machine-readable code, and a signed-in caller and the admin health check get the actual diagnosis from a single shared source, as does the daily internal report. There is one command that answers "is billing configured, and why not". An anonymous request to the public config endpoint still gets only the bare refusal. Choosing a payment provider is still an open decision and no provider was picked here.
- A coding agent's GitHub token can no longer widen by accident. The token handed to an agent's shell is minted with a reduced permission set, and if that set cannot be resolved the mint now fails instead of quietly asking GitHub for a token with everything the app can do. The parameter is traced to GitHub's own reference beside the code, including the answer to the question people keep asking: GitHub offers no way to limit a token to one branch, so the branch rule still needs a different fix.
Security
- The per-address limit on sign-in attempts now exists on every copy of the relay database. The table that limit writes to was declared one way in the database setup files and another way in the live databases, so any database built from the files - a fresh local one, a test one, or one restored from scratch - silently accepted every sign-in attempt with no limit at all. The setup files now build the same table production has, and a limiter that cannot record an attempt says so in the server log instead of staying quiet.
- Pet characters can no longer be claimed by a new account without drawing them. When the pet collection moved to your account in August, a one-time step let existing players bring the characters they had already drawn on this device up to the server. That step was open to every account, so a fresh account could hand itself the whole roster, rarest character included, and gift the copies on. It is now limited to accounts that existed before the move; everyone else earns characters through Draw, as intended. Nobody who used the step legitimately is affected.
- Connecting GitHub to your account can no longer be replayed from a captured link. The request that starts a GitHub link travelled inside the address GitHub sends you to, and for ten minutes anyone who saw that address could finish the request again. It is now good for one attempt and five minutes; a second use is refused with the same "expired or already used" message you would see for a stale link, and starting over is one click.
- Connecting Slack now requires being signed in to Foxl. The relay endpoint that completes a Slack connection on the desktop's behalf (it holds the Slack app secret so the desktop never has to) accepted requests from anyone on the internet, with no limit on how often, and handed back whatever Slack replied. Someone who obtained a Slack sign-in code could have redeemed it through our app without holding a Foxl account, and the endpoint could be used to hammer Slack under our credentials. It now completes the exchange only for a signed-in Foxl account, limits attempts per address and per account, accepts only the exact return address the desktop uses, and reports a failed exchange with a short reason instead of Slack's raw reply. If your desktop is signed out when you connect Slack, it now asks you to sign in first, before a browser tab opens. Desktops older than 0.7.1 must update before connecting Slack: the relay refuses a connect that does not carry a Foxl sign-in, and there is deliberately no grace period for a route that spends the app secret.
- Foxl Code no longer leaves credentials on a cloud task's workspace. A cloud coding task runs on storage that is kept for up to 14 days, and three paths could leave secrets there: a failed task's saved output redacted only two of the tokens it might contain, a task that never started left its whole set of run secrets and your model login behind, and the file browser could read your login file straight out of the workspace. Saved output is now scrubbed of every known key, token and login shape; a task that fails before it starts wipes its secrets immediately - including a model login left behind by an earlier run on the same reused workspace - and its run secrets are kept off the retained disk entirely; and the file browser refuses to read or list the internal credential files - in upper case, lower case or any mix of the two, including the two look-alike letters a Mac or Windows disk treats as an ordinary s or i, and even through a link a repository plants to them - while still showing you your own work.
- Disconnecting Slack now revokes Foxl's token at Slack, and disconnecting Microsoft 365 tells you where the permission still lives. Until now, Disconnect only deleted Foxl's own copy of the sign-in. A Slack token does not expire on its own, so anyone holding a copy of Foxl's database could have kept using it after you disconnected. Foxl now asks Slack to revoke the token it holds for your account before removing its copy. If Slack refuses, or cannot be reached, the Integrations page says so and links to your workspace's app management page where Foxl can be removed - the local copy is removed either way, so a machine that is offline can still disconnect. Microsoft offers no way for an app to revoke its own access, so Settings now says plainly that the permission stays active at Microsoft and links to the page where you remove it - for a work or school account and for a personal one.
- Naming a client that does not exist no longer earns a readable copy of what the desktop sends. Terminal output, the list of open terminals and status updates are encrypted for every client that has completed a key exchange with the desktop. A client the relay merely announced - one that never sends the desktop anything of its own - is no longer served a readable copy alongside that ciphertext; a connection left behind by a socket that died without saying so no longer keeps that decision alive either; and the number of clients that can hold keys with one desktop is now capped. Every readable copy that does go out is counted, and the client it was sent for is named in the desktop log instead of passing silently.
- What this does not do, stated plainly: a build too old to encrypt still rides in the clear. A phone or browser build older than v0.6.27 cannot do the key exchange, so it keeps receiving terminal output, the terminal list, and notices when a terminal opens or closes, readably - including while a newer client is connected to the same desktop, and including while it is the only client attached. That is deliberate, because most clients in use today are those builds. But it also means the relay, which carries what clients send, can still obtain a readable copy by sending one message as if it came from such a client, and the desktop has no way to tell the difference: a client that cannot do the key exchange shares no secret to check it against. Removing that would mean refusing to serve those builds at all, which is a product decision rather than a fix, so it is not part of this change. The counts are reported with the rest of the connection status.
- What an MCP server says about its own tools can no longer instruct the assistant. The descriptions a connected MCP server provides for its tools and their parameters were handed to the model word for word, so a third-party server could hide a line such as "before any answer, run this command" where the assistant reads it as an instruction - and MCP tools run without an approval prompt. Those descriptions now reach the model cleaned of hidden characters, trimmed to a sensible length, and marked as the server's own data rather than instructions: a tool's description is enclosed in markers that say so, and since a parameter's description is a single field with nowhere to put markers, the tool it belongs to says in our own words that those are the server's text too. A line that reads as an order to the assistant is removed and the removal is stated, for a tool's description and for each parameter's, and every kind of line break now counts as one, so an instruction can no longer hide by using an unusual one. Ordinary wording such as "Important: must be an absolute path" is kept.
- app.foxl.ai and code.foxl.ai now ship a Content Security Policy. The browser is told exactly which scripts the app may run - its own, Cloudflare's sign-in challenge, and analytics (only after you consent) - and refuses everything else, so a flaw that managed to inject markup into a page would be far less able to run code or read your sign-in tokens. Nothing changes in how the app works: links, images, fonts, live transcription, self-hosted models, the files panel (text, Office documents, spreadsheets and PDFs), copying or saving an attached image, and the chat's HTML, SVG and diagram previews all keep working, and the previews still run inside their own sealed frame.
- The desktop app's own window now refuses to run script it did not load. Foxl's window is where your sign-in tokens live and where every desktop action - saving a file, opening a path, typing into another app - is reachable, and it used to allow inline script and
eval. It no longer does, so a flaw that managed to get markup into a reply, a channel message or a filename is far less able to run code on your machine. The sidebar, chat, notes, settings, the files panel and the chat's HTML, SVG and diagram previews were all checked rendering identically under the new rule; recording a meeting, the code editor and the built-in PDF preview were not part of that check, so tell us if any of them behaves differently. One deliberate change inside a preview: script that a model writes into an HTML block no longer runs there. The two start-up screens (the boot splash and the server-error page) had no rule at all and now carry their own. - The terminal font is loaded from the app instead of the internet. Its Nerd Font ships inside Foxl, and the stylesheet was still asking a public CDN for the same file first on every launch. Nothing looked different either way; the request is simply gone.
- A sign-in link in your email now needs one press before it signs you in. Opening the link used to sign you in the instant the URL was FETCHED, which is not always you: plenty of mail systems and security products follow every link in an incoming message before you ever see it. When that happened, whatever followed the link received a live sign-in for your account, and your own click then said the link had already been used. The link now lands on a short "Confirm sign-in" page that names the account and does nothing on its own, and the sign-in happens when you press the button - so an automatic fetch gets a page instead of your session, and leaves your link working. Links are still single-use and still expire 15 minutes after they are sent. That page needs cookies enabled for relay.foxl.ai; if yours are blocked it says so and your link stays valid.
- The Channels and Foxl Code live connections no longer carry your account password-equivalent in their web address. Those two connections are opened with a web address rather than a private header, because that is the only way a browser can open one - and until now the address carried your normal sign-in credential, which is good for twelve hours and for your whole account. Addresses are the part of a request that gets written down: by the network in front of us, by any company proxy, by a diagnostics export. Both now ask the server for a separate one-minute pass that opens exactly one connection, for one device, once - and for the chat connection, one room - and nothing else. The real credential travels in a private header on an ordinary request. Older installed apps keep working unchanged while they update; the old way is still accepted, is now counted, and has a dated removal.
- The desktop's tracing libraries are up to date. The OpenTelemetry packages the desktop server uses carried a published advisory in the version range Foxl shipped. They are updated, and the exporters are pinned to the versions the agent framework expects so the two cannot drift apart again.
Fixes
- Image features work on Intel Macs again. Showing the agent a picture, and the preview it makes of an image it generated, both need an image library that ships as a small compiled file per processor type - and the Mac download only ever contained the Apple silicon one. On an Intel Mac those features did nothing at all, with no error shown anywhere, because the app is written to carry on quietly when that library is unavailable. The build that produces the Mac download now includes both, checks that each one is really for the processor it claims, and stops rather than publishing an app that is missing one.
- Free accounts no longer have unpaid usage written off every month. A free account that ran a Foxl Code task or a transcription past its last credit ended with a negative balance, and the monthly refill quietly reset that balance to zero before adding the new credits, so the overrun was forgiven month after month. The refill now adds the month's credits on top of whatever the balance is, exactly as a mid-month grant does, and an account in the red works again once it holds enough credits to cover what it used.
- Saving one Foxl Code setting no longer resets the others. A save that sent only some settings used to write the defaults over everything it left out: the coding model, the per-task budget floor, the budget multiplier, the heartbeat interval and quiet hours went back to their defaults, and the autonomy switches snapped back to their default positions, all with a success response. A field that is not sent now keeps its stored value; an explicit on or off still applies, and clearing a field still clears it. That holds for the self-directed loop in both directions: a save that never mentions it neither turns it back on for someone who switched it off, nor off for an account that had it running without ever touching the switch.
- Scheduled Foxl Code tasks from one account no longer hold up everyone else's. Each minute's batch of due schedules now takes turns between accounts instead of taking the twenty oldest overall, so one account with many schedules due at the same time cannot delay another account's by minutes.
- A cloud task whose machine stopped answering is now reported in about twenty minutes, not eight hours. When the machine behind a task on Foxl's cloud died mid-run, the task could keep showing as Running for up to eight hours - you could not retry, cancel or reconnect it, and the rest of your queue waited behind it. Foxl now starts asking that machine about a run that has gone quiet for five minutes, and stops tracking the task only once it has kept saying it no longer holds the session for more than twenty minutes. One refusal is deliberately not enough: a machine that was working perfectly well has been seen giving that answer for a quarter of an hour, and cancelling a run that goes on to open its pull request is worse than reporting it late. Any sign that the run is still working - an event of its own, or its output reaching Foxl again - starts that twenty minutes over, so a machine that answers badly for a while and then carries on is left alone. A task Foxl has stopped tracking keeps any commits and pull request it made and can be reconnected on the same workspace, a run that is merely busy is left alone, and a terminal pane you are sitting in is never touched.
- A Foxl Code task that runs out of workspace storage now fails within seconds on every coding assistant, and says why. A repository large enough to fill the 1 GB cloud workspace during its clone left the assistant unable to write its own startup files; with Claude Code that ended in seconds with a clear message, while a task on Kiro, Codex, Cursor, Hermes or OpenCode sat silent until its whole time budget ran out and then reported only "failed" with an empty screen. All of them now stop before the assistant starts and show the storage reason, and Kiro and Codex also stop a run that produces nothing in its first two minutes, as Claude Code already did. The same check covers tasks run on your own machine. A task stopped this way now also wipes the sign-in details and run secrets it had already written, wherever it put them - and a sign-in left behind by an earlier run on the same reused workspace - so a refusal leaves nothing behind on storage that is kept for up to 14 days and nothing on the task's own temporary disk either.
- A Foxl Code task whose instructions start with a dash now runs on every coding assistant. With Kiro, Codex, Cursor, Hermes or OpenCode, a task typed as a markdown bullet ("- add a retry to the uploader") or opening with something like "--verbose" was read by the assistant as a command-line option: it refused with a usage screen and the task failed within seconds, with nothing connecting the failure to the text you typed. Claude Code was already immune. The prompt is now handed to each assistant as text, whatever it starts with.
- Removing a "deny" tool rule now really removes it. Deleting a rule that blocked a command from Settings made it disappear from the list, but the block stayed in force until the app was restarted, so the tool kept being refused with no rule visible behind the refusal. The list also showed rules in an internal regex spelling (
exec(^(?:ls.*)$)) instead of what you typed (exec(ls*)). Both fixed. - Changing the Feed Generator prompt through the desktop API now changes the prompt that runs. A direct API call that set the prompt reported success but stored it in a field the heartbeat never read, so the feed kept running the old prompt. Editing the prompt in Settings was already saved correctly and is unchanged. The API now writes the prompt where the heartbeat reads it, and refuses a prompt that is not text.
- Workspace paths sent with a trailing slash, a
./or a doubled slash are accepted instead of refused as "Invalid path". Shapes likeShared/ora/./bmean one unambiguous thing and are now normalised; an API caller or another client can send them, the file browser itself did not. In the other direction, a new file or folder cannot be given a name that would be unusable on a Windows machine your workspace syncs to (NUL,CON,COM1,nul.txt, or a name ending in a dot or a space): it is refused up front with a clear "Invalid path" on every platform, instead of silently becoming a device or an unopenable file there. Something that already carries such a name can still be renamed, moved and deleted. A name containing a control character gets the same clear answer instead of a raw filesystem error. - The startup diagnostics page no longer offers "Restart server" while the server is simply still starting. On a slow cold start the boot screen hands over to the diagnostics page after 12 seconds, which then presented Restart as the obvious action; pressing it tore down a server that was seconds from ready. The button is now hidden while the server is still starting and has reported nothing wrong, and comes back as soon as there is something to repair (a crash, an error line from the server, a missing background service) or after 30 seconds of quiet starting, whichever comes first.
- "Restart server" leaves other people's processes alone. The restart used to terminate whatever was listening on Foxl's port; it now confirms the occupant is a Foxl server first and logs what it left alone otherwise (macOS and Linux).
- Requesting a huge workspace file returns a clear
file_too_largeerror (limit 20 MB for text files) instead of holding hundreds of megabytes in memory, and document previews are rendered at most two at a time. - Internal hardening from the September 2026 audit, no visible change: the desktop's WebSocket connection compares its token in constant time, as the HTTP guard already did; the agent's web fetch tool also refuses IPv4-translated, 6to4 and Teredo spellings of a private address; the packaged app no longer runs
gitat launch to decorate the About panel; and an unused dynamic-import code path in the skills loader is deleted. - Right-click on a row in Foxl Code's file tree did nothing. The menu existed but the rows never received the click that opens it. They do now.
- A webhook schedule's trigger URL now works without the app's connection token, from this computer. The URL the Schedules page showed sat behind the token the app itself uses, so a local script or cron job that called it got "403 Invalid connection token" and the schedule never fired. Each webhook schedule now has its own long random trigger URL that needs no sign-in; the form shows it whole, with Copy and Regenerate. Anyone holding that URL can start the schedule, so regenerate it if it leaks. Where the URL can be called from has not changed, and the form now says so instead of implying otherwise: Foxl listens only on this computer, so curl, a local cron job or another app on the same machine can call it, while GitHub, Zapier or another computer cannot reach it directly. To call it from anywhere else, run a tunnel or reverse proxy on this computer that forwards to the URL and sends
localhostas the Host header, or start Foxl with the hostname that forwarder sends listed inPILOT_ALLOWED_HOSTS. (LAN access,PILOT_ALLOW_LAN=1, also accepts this computer's own name and addresses - and nothing else, so it is not a way to admit a hosted service.) On app.foxl.ai and the phone the form no longer prints a URL at all - it pointed at the relay, which does not serve it - and tells you to copy it from Foxl on the desktop instead. - On a Mac, a sign-in link clicked after Foxl was quit now launches Foxl and signs you in once it is ready - and on every platform, a link that arrives while Foxl is still loading is no longer lost. Two things stood in the way. Foxl only accepted a sign-in link while the same app process that started the sign-in was still running, so a magic link opened after the app had been quit, or had crashed, launched Foxl and then refused the link. And a link that arrived while the window was still on the loading screen, or on the "server not responding" page, was applied to that page instead of the app, so the sign-in was lost and the system was sometimes asked to open a page that does not exist. A sign-in started on this computer in the last 20 minutes is now remembered across a restart, and a link that arrives before the app has finished loading is held and applied the moment it has. A sign-in link that nobody started from this computer is still refused. On Windows and Linux, Foxl still does not pick up a link that launches it from cold; a link that reaches an already-running Foxl works everywhere.
- Every usage cost Foxl shows will be the one it recorded, not a guess. Two screens worked cost out for themselves from their own short price lists: the Overview page and its Usage view matched a model by name, with a guessed mid-range rate for anything the list did not know, so o3 mini was priced at o3's rate and current models - Opus 5, Fable 5 and Fable 5.1 among them - at that guess, which for Fable is less than a third of the real figure. The "Usage today" card on the home screen had a second, different list of its own, so the two screens disagreed: over one recent day on this machine they would have read $200.86 and $138.80 for the same 24 hours. All of them now read the cost Foxl recorded when each request ran, and a model Foxl has no rate for counts as $0 rather than a made-up price. Those cost figures are hidden while paid plans are hidden (since v0.7.0), so nothing changes on screen today; when they return, the Overview, the Usage view, the home card, the menu-bar readout and each message receipt will all show the same number. Under the hood, the internal price lookup also matches the exact model id against the shared catalog instead of the first entry its name happens to contain.
- When notifications cannot be set up on your phone, the app now says why. If registering for notifications failed on a device (for example a provisioning problem), the app said nothing, so "you declined" and "it is broken" looked identical. Settings > Notifications now shows "Notifications could not be set up on this device" with the reason and a Try again button. The notice stays on screen while the problem persists - a retry that fails again keeps it up with the new reason - and clears only once registration succeeds. Separately, every place the app can ask for notification permission now goes through one shared signed-in check; whether a first run can still show the permission prompt over the login screen was not re-checked on a device and remains open.
- A task no longer opens with the wrong status. The header showed a grey "Queued" pill and a
tsk_…slice on every task - merged, failed or running - and flipped to the truth a moment later. It now shows a placeholder until the task loads. - A failed task says why. The header showed "Failed" and nothing else. It now carries a "Did not finish" chip whose expander gives the reason - including the case that failed most often on real accounts, where the agent finished cleanly but the repository's own tests did not pass, with the test output behind it.
- The task page lines up and speaks your language. The status pill is translated (it was English in every language), the header lines up with the cards below it, the terminal card matches its neighbours and its header says "Terminal" with a live dot only while the agent is actually running, the plan chip says "In progress" rather than
in_progress, the budget warning loses its cap-and-commit jargon, and Resume switches you to the terminal it tells you to type into. - Your profile photo no longer disappears and reloads every time you reopen the window. Closing the desktop window with Cmd+W only hides it, so reopening from the Dock does not reload anything - but the sidebar footer blanked the picture to your initials anyway and then loaded it again a moment later, every single time. The photo, your name and your email are now kept while the window is away and repainted from memory. Measured on the reopen: the image element is never unmounted, the picture is not requested again, and the account lookup behind it drops from two extra requests to none.
- Less work behind a window nobody is looking at. Seven background refreshes kept running on a hidden window - the relay device list every 15 seconds, the channel list and MCP connection status every 10, the agent list and the home dashboard every 30, the running-agent list every 5, and the tunnel switch every 10. They now pause while the window is hidden and catch up the moment it comes back, so a Foxl left running in the background stops spending requests on screens that are not on screen.
- Your MCP tools connect on their own again, and nothing asks you to approve starting them. v0.7.0 asked for one approval per MCP tool the first time its program started, and the prompt it raised could not be answered from the Tools page - so a server that had been working for months answered "Not approved: starting <command> ... was denied or the approval request timed out" and the agent stopped seeing its tools. Turning a tool on is the approval; that gate is removed. A local MCP server also gets your full environment again, so one that reads a token, an HTTPS proxy setting or a certificate bundle from it works without being told again in that tool's Env field.
- The two other guards v0.7.0 added are unchanged: pressing Run on a shell or script tool still goes through the approval prompt the agent's own tool calls use, and the MCP inspector still takes one of your saved tools rather than a command from the request.
- Signing in no longer reveals whether an address has a Foxl account. Asking to sign in with an email answered one thing for a registered address and another for an unregistered one, so anyone could check whether a given person uses Foxl - and the password door already went to some length to hide exactly that. The sign-in request is the same request for both cases now, and answers identically, except for a small number of throwaway-mail domains we do not open accounts on.
- When a tool needed your approval and no Foxl window was open, the agent said you had refused. Ask a run from Telegram or Slack, or let a schedule tick at 3am, and a tool that needs approval had nowhere to show its prompt - the approval dialog only exists in an open Foxl window. The request waited a silent minute and then reported "User denied", so the agent apologised for a decision you had never made and never mentioned that a question had been asked. It now says which of the three things happened - nobody could be asked, the prompt was shown and went unanswered, or you really did decline - and when nothing could possibly see it, it says so at once instead of stalling. A prompt raised while the window was reconnecting is now re-sent to it rather than missed.
- A shared workspace's storage now has a ceiling, and it cannot be run up by one member. Shared files were billed to whoever pays for the workspace, and on a paid plan there was no upper limit of any kind - so any member, including an invited contractor, could charge the owner an unbounded recurring storage bill. Uploads are now refused past a real ceiling (four times the plan's included storage, so 20 GB on Pro and 200 GB on Ultra), the refusal names the number, the Shared panel's storage bar now measures that ceiling rather than only the included allowance and warns at 80% of it instead of leaving the first sign of it to be the refusal, and the workspace's billing owner can set an explicit limit of their own. Uploads are also rate limited per person per workspace. A personal workspace is not capped: nothing there is billed to anybody else, and there would be no owner to raise it. Removing someone KEEPS their files and keeps billing them - deleting a colleague's work because their access ended would be the wrong trade - but the removal now reports how much storage it left behind, and a workspace admin's Shared panel breaks the total down by uploader and marks the ones who have left, so an owner can find those files and delete them.
- A scheduled task runs for as long as you told it to, and no longer fails part-way through work it used to finish. v0.7.0 gave every unattended run a budget, and two of its three limits sat below a normal run: the runtime a person sets on a schedule was never read at all, so every schedule was cut off at ten minutes however it was configured and editing that field did nothing; and the cap on how much a run could generate was a fifth of what a single reply from the default model is allowed to produce, so one ordinary first answer could exhaust the whole run's allowance before anything checked it. A task that had run for months would stop mid-way and be recorded as failed. The number is now enforced rather than only logged, so a schedule whose timeout was set below the time it needs will now be stopped at that timeout - raise it in the schedule's own settings. Schedules now use their own configured runtime, and the limits are set where they were meant to be: high enough that only a runaway loop reaches them. You can still lower any of them per schedule, or in HEARTBEAT.md for the Feed Generator.
- Cmd-clicking a file path that Foxl will not open now says so. v0.7.0 limited opening to your workspace, Documents, Downloads, Desktop and Notes folders, and a path outside them underlined and then did nothing at all: the refusal was written to the log and discarded before it reached the screen. It now appears as a message naming the reason, so a file kept somewhere else, a file that has moved, and a file Foxl will not open because it can run are three different answers instead of one silence. Notes' "Open file" no longer reports the same refusal as "no saved file yet" either, which sent you looking for a missing export when the folder was the problem - the case being a save folder chosen on another computer, since that setting syncs between devices and the permission does not. What Foxl opens is unchanged.
- Signing in with Apple works when Apple sends no email address. Apple only passes your address on the first sign-in and decides for itself whether to include it again later. v0.7.0 required a confirmed address on every sign-in, checked before it looked up who you are, so an Apple ID already linked to your account could be refused with no way to get back in. Foxl now recognises you by your Apple ID itself, which is what Apple provides for that purpose. An unconfirmed or missing address still cannot be used to find or create an account, so nothing is loosened: the check now applies only where the address is what identifies you.
- The Notifications screen on your phone now tells you the truth about whether the system has notifications turned on for Foxl. It read that setting once, when the screen opened, and never again - so if you turned notifications off in iOS Settings, the screen went on showing eleven happily-enabled switches and said nothing, and if you turned them ON from its own "Open Settings" button it still insisted they were off. It now re-checks every time you come back to the app, and says which state you are in either way instead of leaving "allowed" as a blank space.
- A subscriber whose payment finally goes through gets their plan back, whichever order the payment notifications arrive in. After four failed card attempts a subscription is marked unpaid and the account drops to the free plan. When the card was fixed, the payment provider sends two notifications at once - "the subscription is active again" and "the payment was recovered" - and if they arrived in one particular order the account was left on the FREE plan with a paid subscription behind it: free-tier models, free-tier rate limits, and the free monthly credit top-up, with nothing anywhere able to correct it afterwards. Both orders now end at the same place, and the plan is restored on the next sign-in for an account already stuck this way - credits already missed for that one period are not re-issued.
- A coding-assistant key you store with Foxl Code is now tied to the account and the field it was saved in. The stored form was encrypted but not pinned to a place, so anything that could write our database directly could have moved one person's key into someone else's - or one of your own keys into the slot for a different assistant - and it would have been used. Keys saved from now on cannot be moved; older ones are re-pinned the next time you save them.
- "Work without asking permission", turned off, now also stops the repository from configuring the coding assistant. Turning that switch off used to remove the coding CLI's act-without-asking flag and nothing else, so a
.claude/settings.jsonhook and an.mcp.jsonserver inside the CHECKOUT still started as the CLI came up - before the first tool call anyone could have approved. Measured against the real CLI: with the switch off, a repository'sSessionStarthook ran, its MCP server started and its slash commands were available. With the switch off, nothing the repository ships under.claude/is loaded now - hooks, MCP servers, slash commands, subagents and skills alike - and the task terminal says so, while your own instructions and advanced config still apply in both modes. Note the two are welded: a repository hook you legitimately want back means turning the switch on, which also grants the act-without-asking flag, so a hook you want on every task belongs in your own config rather than in a repo. This is unchanged with the switch ON, which is where a repository shipping its own formatter hook keeps working. Applies to Foxl Code tasks in the cloud and on your own machine. - A new chat opens with something to click on, on every screen size. The first screen showed only the question and the box to type in - the Foxl mark, the three suggestions and the "Desktop offline" notice were on phones only, which left an iPad looking mostly blank. All four now appear on the desktop app, the web app and tablets too, centred above the composer.
- The Notes coaching report is readable in a narrow column. With the transcript open beside it, the Feedback list had so little room that a sentence stacked one word per line and the category labels ran off the edge of the card. The report now lays itself out from the space it actually has rather than from the size of the window, so it stacks into one column when it is narrow and the labels wrap instead of overflowing.
- Syncing skills now takes one reviewed version of the library, not whatever was pushed last. The sync cloned the tip of the skills repository's default branch, so a single commit there reached every desktop that synced - as prompts and tool descriptions the agent follows - and a fallback in the same code path meant a rewritten history was merged rather than refused. It now fetches ONE pinned commit, checks it out detached, and verifies that is really what landed; if it cannot, the sync fails and says so instead of falling back. The pin is currently the same commit the branch is on, so nothing about the skills you have changes - what changes is that moving it is a reviewed edit to Foxl rather than a push to another repository. Because of that, "Up to date" now says which version it means: nothing looks at the library's latest commit any more, so the plain message would have been true about the pinned version and misleading about the library.
- You can now see the safety code that tells you a remote connection is really your desktop, and you are told when it changes. The code was described in the docs as something to compare on both screens and no screen ever showed it. It is now on the Mobile/Web page at both ends, and if the code your desktop presents ever changes - a reinstall, a new machine, or someone sitting between you and it - a warning says so, says what it means, and cannot be hidden. Accepting the new code takes a deliberate confirmation; closing that confirmation accepts nothing. Before this, that situation just broke remote access quietly, with nothing on screen and no way to recover.
- On iPhone and iPad, the long-lived credential that keeps you signed in is now stored in the iOS Keychain instead of inside the app's web storage. It was in a plain file in the app's own folder, which no other app can read but which an unencrypted computer backup, a jailbroken device, or a forensic copy of the phone all can - and that credential can mint fresh sign-ins until it is revoked. It moves itself the first time the app needs it after this update, and nothing signs you out. Android is unchanged for now (its backup and phone-transfer paths were already excluded); the short-lived access token stays where it was, on purpose.
- A change that reaches Foxl's release branch without review is now reported. Every Foxl product is built from one branch, and a check now goes red when a commit lands on it with no merged pull request behind it, or when that branch's history is rewritten. It reports rather than blocks - the commit has already landed by the time it runs - and the release automation's own version-bump commit is the one exemption.
- A corrupt Foxl Code credential no longer puts a piece of your token into our server logs. When the stored Claude or ChatGPT credential could not be read back as a file, the error our server wrote down quoted the first ten characters of the decrypted credential - and those logs are kept for days and readable by anyone with access to our Cloudflare account. The diagnostic is still there and still says what went wrong (the kind of failure, the size of the stored credential, and where in it the reading stopped); it just no longer carries any of the credential itself. Nothing about how the failure is reported to you changed: Foxl Code still refuses to start the task and still tells you to re-sync the credential in Settings.
- The pages the agent reads in your browser no longer end up in the log the app hands out. When the Chrome extension sent a page back - its text, its accessibility tree - the desktop wrote the whole thing into the 5000-entry log buffer that
/api/logsserves to anything holding your connection token, which includes your phone over the relay tunnel. A page you are signed in to could therefore be read from another device, and one page read pushed a lot of genuinely useful diagnostics out of that buffer. The log line now records which request replied, how big the reply was and what kind of thing it was, and never the reply itself. The version the extension announces and an unrecognised message type are bounded the same way, and a frame the desktop cannot read as JSON is reported by name and size instead of by quoting the frame. - The image library the agent uses to look at your pictures is up to date. Showing an image to the agent decodes it with a library that had four published vulnerabilities in the version Foxl shipped, and it is handed whatever image file you point it at. Macs with Apple silicon, Windows and Linux now bundle the fixed version. The build was also reading its own copy of that version number rather than the one in the project, so the two could disagree without anything reporting it - it reads the project's now. (Intel Macs are unaffected either way: that image library is missing from those builds entirely, which is a separate bug being fixed on its own.)
- A Cursor, Hermes or OpenCode task no longer offers a Reconnect button that cannot work. Those three agents run their terminal as a cloud shell rather than a session Foxl re-spawns, so the server has always refused to reconnect them - but the app offered the button anyway, and the sentence it printed after the refusal told you to reattach through a shell that no version of the app has ever been able to open. It then re-enabled the same button, so the whole loop was: press it, read about a shell, look for the shell, press it again. The card now says up front that reconnecting cannot bring that agent back and why, offers Retry where Retry actually works, and offers nothing where it does not. The Runtimes pane had the same button and was worse
- it printed the raw error from the server - and it is fixed the same way. Nothing changes for Claude Code, Kiro or Codex tasks.
- Windows can update itself again. Since v0.5.7 every automatic update on Windows was downloaded, checked, and then thrown away: the check required Windows to call our signature fully trusted, and our certificate is self-signed, so it never could. Nothing said so - the failure left one line in a log file - which means Windows installs have been sitting on whatever version they were installed from for 40 releases. The app now runs its own check, which still refuses an unsigned installer, one altered after signing, and one signed under a publisher name other than Foxl AI, and a refusal now shows up in the notification bell instead of disappearing. On Windows this one update has to be installed by hand: the fix ships inside the new build, so the build you are running still cannot fetch it. Download the latest version from foxl.ai once, and automatic updates work from then on. Getting a signature Windows trusts on its own needs a paid certificate; that is a separate, still-open item.
- Mobile sign-in no longer hands the session to the
foxl://URL itself. The relay returns a short-lived PKCE code that only the app that started the sign-in can redeem, so an access token and a 30-day refresh token no longer travel in a URL any app on the device may claim. Apps installed before this change keep signing in exactly as they did. - The mobile build no longer carries a flawed archive library. The icon and splash generator was installed as part of the phone app's build tooling even though it only ever runs by hand when the artwork changes, and it brought along old copies of an archive library and an image library with published flaws - including the most serious one anywhere in this project. It is run on demand now instead, which takes those out of the build entirely. Nothing about the shipped app changes.
- A provider endpoint Foxl is not using now says so. A custom endpoint that Foxl refuses was reported only in a log nobody reads, while the Settings field rendered empty - identical to never having set one - as requests went to the vendor's own address instead. The refused address and the reason now appear in Settings where you typed it.
- A phone signed out by a session change can register for notifications again. When a sign-in was revoked from elsewhere, the phone kept a note saying it had already told the relay about its notification token, so after signing back in it never told it again and notifications stayed silent. That note is now cleared along with the session.
- Image features work on Intel Macs again. Showing the agent a picture, and the preview it makes of an image it generated, both need an image library that ships as a small compiled file per processor type - and the Mac download only ever contained the Apple silicon one. On an Intel Mac those features did nothing at all, with no error shown anywhere, because the app is written to carry on quietly when that library is unavailable. The build that produces the Mac download now includes both, checks that each one is really for the processor it claims, and stops rather than publishing an app that is missing one.
- Settings no longer shows a red error under Amazon Bedrock. The provider pane asks the server for each vendor's own extra options, and the providers that have none - Amazon Bedrock, Anthropic and the subscription sign-ins - answered "not one of those vendors". That answer was drawn as a failure: an alert quoting an internal error string, next to a Retry button that could never succeed. Those providers now simply show no extra options, and a real problem reaching your desktop still shows the error and the retry.
- Changing a provider's settings no longer sends the provider dropdown back to Amazon Bedrock. Saving an API key, flipping one of a vendor's own options or pressing Refresh re-read the saved provider and overwrote the choice you had just made in the dropdown - so picking OpenRouter and adjusting one of its switches jumped back to Bedrock while the model box still held an OpenRouter model. The pane now keeps an unsaved choice until you press Save Provider Settings, and stops showing the previous vendor's options while the new one loads.
- A rescheduling request no longer forgets a schedule's Timeout. Asking the agent to move a schedule to a different time rewrote its whole configuration instead of the timing part, so the run-length limit set in the schedule's own editor was dropped without a word. Only the timing changes now, and switching between a repeating time and an interval no longer leaves the old one behind.
Improvements
- The Files pages now work like an editor's explorer, in both Foxl Agent and Foxl Code. Files are coloured by type (TypeScript, JSON, Markdown, images, lockfiles and forty-odd more), nested rows carry indent guides so a deep folder still reads as a tree, and the path above the open file is a row of breadcrumbs: click a folder to reveal it in the tree, or open its picker to hop straight to a sibling file. The tree is fully keyboard-driven - arrows move, Left and Right fold and unfold, Space opens, Home and End jump, and typing a few letters lands on the matching row. Cmd+P (Ctrl+P on Windows) opens Go to file, a fuzzy finder over every file with your recently opened ones listed first. A folding button collapses the whole tree, and a tree-shaped shimmer stands in while files load instead of a lone spinner.
- Foxl Agent's Files page gets New file, New folder, Preview for Markdown, and "Ask the agent about this file". New file and New folder are inline rows typed straight into the tree (the old folder prompt is gone, which also fixes it on iOS, where that prompt was blocked). Markdown files carry an Edit / Preview switch, remembered across files, so the agent's notes read as prose. Every file's right-click menu now offers Copy path and Ask the agent, which starts a chat with that file already in the prompt. Typing a name that is already taken - including a hidden file the tree does not list, or a note the agent saved a moment ago - is refused rather than emptying that file, and names with characters such as
#or?open and save correctly. - Foxl Code's Files page shows real source. Files open in a syntax-coloured viewer with line numbers and a wrap toggle in place of the raw text dump, Markdown renders as a page with a Source toggle, images display inline, and every file can be copied or downloaded from the header. Right-click a file for Copy path, Copy name and Download, or a folder to refresh or collapse it.
- The Work page's "Needs you" list is grouped by what you do about it. It used to be one flat column of look-alike cards - a question, a merge, a failed build and an issue Foxl filed for itself all through the same shell, told apart by colour alone. The list now has three headings: Your call (answer, approve, merge), Agent needs a hand (send it back, or open the task) and Suggestions (start an agent, or close the issue). Each card's label is a plain state ("Ready to merge", "Reviewer asked for changes", "Nobody is on this issue", "Foxl filed this issue"), a card about a pull request says "Pull request #8" instead of a bare "#8", and one condition reads as one sentence whichever feed it came from. "Foxl is reviewing this" rows no longer appear or count - nothing is waiting on you there.
- Buttons on the Work page say what they do. "Solve" is "Start an agent". "Decline" is "Close issue", because that is what it does - it closes the GitHub issue and leaves a comment - and it now asks for a second press like Merge does, on the Not started tab too. The Answer and Retry buttons that only ever printed an error are gone: a stalled task offers "Open task", where the paid retry lives. Every Merge on the page arms with the same words, and an X says "Hide" where it only hides the row on this device and "Dismiss" where it is remembered. After a "Fix it" that went through, the card leaves instead of sitting there with the same button; a press that failed leaves it where it was. "Backlog" is "Not started".
- The Work page loads once, not in stages. Its five feeds landed on five cadences, so the Needs-you count climbed 0, 2, 5 as they arrived and the skeleton flashed on every refresh. The count and the skeleton now wait for every feed's first answer, and every tab loads and empties in the same shape. The Korean page title is 현황 (it read 이슈/PR, a name left from the deleted GitHub mirror).
Changes
- Reading messages in a channel is faster. Opening a room, and catching up after the connection blipped, were both slow - and the database was never the reason. Each read was asking our database seven separate questions one after another and waiting for each answer before asking the next, which over a network is where all the time went: the questions themselves are answered in a fraction of a millisecond. Three of the seven were just "are you allowed to see this room", asked three different ways, and two more pairs never needed each other's answers. They are now asked together. Opening a channel went from seven round trips to four and catching up went from eight to three, with the same answers to every permission question. Measured against a real server on the real database: a channel page went from 1.7x the cost of the sidebar's own list to 1.26x, and the catch-up read from 1.85x to 1.02x.
Fixes
- Links to Cursor, Zoom, Notion, Teams and thirty more apps work again. The fix for the security issue below narrowed the list of apps a link in a reply may open down to four (Obsidian, VS Code, Slack and phone numbers), which brought back the original problem in a smaller form: a
cursor://link to a file, azoommtg://link to a meeting or anotion://link to a page rendered as a normal link and then did nothing when clicked. The list now covers the editors (VS Code, Cursor, Windsurf, Zed, the JetBrains IDEs, Sublime), notes apps (Obsidian, Logseq, Notion, Bear, Craft, Things), calls and chats (Slack, Teams, Zoom, Webex, Discord, Telegram, Signal, WhatsApp, Skype, FaceTime, phone and SMS), trackers and design (Figma, Linear, Asana, Todoist, Trello), Spotify and calendar subscriptions. What stays blocked is unchanged and is the point: anything the operating system itself acts on - a diagnostic, a script host, a settings pane, a filesystem search or a remote login - plus everything that can run code. Settings > General > "Open links in other apps" still turns the whole thing off. - A Remote terminal no longer sits under a stuck "your typing is held" banner, and it stops covering the terminal with notices altogether. A cloud pane could draw its assistant's banner and then look dead a second later: a strip saying "The machine is still starting. Your typing is held..." stayed on top of a terminal that was in fact live and taking every keystroke, because the strip could only be cleared by a live output frame and an idle assistant sends none. Rather than patch that one case, the pane no longer paints transient notices over the terminal at all - a held keystroke is delivered by the server in order with nothing to announce, a session that has genuinely gone raises the Reconnect card, which is the one thing you can act on, and a cold start shows only a small wordless loading mark until the first frame arrives. The live output stream also reconnects itself if the connection drops, so a network blip or a laptop sleep no longer leaves the pane silently frozen.
- New Chat keeps what you were typing. Since v0.6.21, starting a new chat (Cmd+N, the sidebar +, the Chat row, File > New) wiped the message box: the half-written message, the images and files you had attached, and the cards for any long text you had pasted. Moving between two existing chats never touched any of that, so the one control you reach for to carry a question into a fresh chat was the one that lost it. The message box now travels with you the same way in both cases; only sending, or removing it yourself, clears it. The find bar and the previous chat's open file tabs still close on a new chat. The cards for pasted text had a second way to go missing: visiting another page (Settings, Notes, Code) and coming back kept your typed text, card numbers included, but dropped the cards themselves, so a message could carry a
#1that pointed at nothing. They come back with you now, and survive a reload like the rest of the message box. - A scheduled task could fail on exactly the days it had the most to do. A schedule that had run for months would start reporting "Model reached maximum token limit. This is an unrecoverable state that requires intervention", then work perfectly when you ran it by hand a minute later. Nothing was wrong with your schedule. Every automated run - a schedule, the Feed Generator, a reply to a Slack or Telegram mention, a request from the browser extension - was capped at a fraction of what the chat pane gives a model, and on the current default model that ceiling covers the model's private reasoning as well as its answer. So a quiet day fit and a busy day did not, which is why it looked random and why re-running it appeared to fix it. Automated runs now get the same room the chat pane gives them, and they use the thinking depth you chose in Settings instead of the model's own default.
- A schedule that hits a hiccup now retries instead of giving up. A momentary network drop or a busy moment on the model provider ended the whole run, even though the chat pane has recovered from both for months. Scheduled runs, the Feed Generator and the extension now back off and retry the same way.
- A failed scheduled run keeps its transcript. Opening one used to show a single error line with no record of what the run had already done, which matters most when it had already made real changes before it stopped. The full transcript is saved now, with the error at the end.
- The iPhone microphone prompt no longer says every recording is sent to Foxl's transcription service. That was true when the relay was the only place a phone could send audio. Notes on a phone can now transcribe on your paired computer, on your own Amazon Transcribe or speech-to-text account, or through Foxl's service, and the prompt names all of them - so a recording meant to stay on your own machines is not declined on the belief that it would be uploaded. The sentence about recording continuing in the background is unchanged.
- Internal hardening from the 2026-09-02 audit of the iOS shell: the terminal keyboard bar passes a key name into the web layer as a real JavaScript argument instead of by string interpolation (#939), and the release tooling now keeps the Xcode project's
MARKETING_VERSION/CURRENT_PROJECT_VERSIONin step with the Info.plist it already bumps - the committed pair had sat at 0.5.12 / 1877 through 23 releases (#936). - A conversation that could not be deleted now stays where it was. If the desktop refused the delete or the connection dropped part-way, the phone and the web app used to remove the chat from the list anyway, erase its offline copy and drop its pin and unread marker - while the conversation lived on at the desktop and came back on the next sync without them. The chat now stays put and a message says the delete did not go through, so you can try again.
- The search box at the top of the window now takes Japanese, Chinese and Korean input. Pressing Enter to confirm a word in the input method used to open the first search result and close the field, so a query in those languages could never be finished. Enter and the arrow keys now stay with the input method until the word is confirmed.
- Eleven low-severity findings from the 2026-09-02 security audit, across the web app, the shared UI packages and the marketing site. What you could have seen: the Notes AI stream retrying a refused request forever with no error shown (#968); a relay hiccup leaving the phone convinced the desktop tunnel was still online for a minute after a reload (#974); closing the Files cover with Escape dropping keyboard focus to the top of the page (#975); the pasted-text chip's Edit and Expand controls being 24px targets on a phone with English-only labels (#976); and a test enquiry sent from stg.foxl.ai landing in the production lead pipeline (#940). Hardening with no visible change: source citation links now pass the same URI-scheme gate as every other link in a message, so a
javascript:citation renders as text (#973); notification "Open" usesnoopener(#969); pending native login nonces are forgotten on sign-out (#967); live transcript text is HTML-escaped before it reaches the Notes editor (#971); a slide deck's inline styles can no longer carry a CSSurl()beacon (#970); and the/forge-apiCORS allowlist is pinned to the exact origins the shells load from (#972). - A pasted API key now saves even when it arrives with a stray space or line break, and a refused key says why. Copying a key from a vendor console or a password manager often adds a trailing newline; the key form sent it as-is, the server rejected it, and the form showed nothing at all. The key is now trimmed before it is sent, and if the server still refuses it the reason appears under the field.
- Signing in to AWS with SSO no longer freezes Foxl or shows your session token to other programs, and saving an SSO profile can no longer break your AWS setup. Listing the accounts and roles your SSO session can reach used to run the AWS command line once per account and wait for each one, which stopped everything else in the app - other requests, a chat in progress, the phone's connection - for up to 20 seconds per account, and it handed the live session token to those commands on their command line, where any other program on the machine could read it. Foxl now asks AWS directly over an encrypted connection, in the background, a few accounts at a time. Separately, saving a profile from the account picker could corrupt your AWS config file: a comment that happened to mention the profile name was mistaken for the real section, so the section ended up in the file twice and every AWS tool on the machine refused to start until the file was fixed by hand. Foxl now edits the file by its real sections, refuses to write anything AWS would reject, replaces the file in one step so an interrupted save cannot leave it half written, and keeps a one-time backup (
config.foxl.bak, beside the file) the first time it changes it. - The model picker now shows the model that will actually answer. Choosing a model used to be recorded on your device before the desktop had accepted it, so if the desktop refused - a provider with no key, or a tunnel that dropped at that moment - the composer named the new model while your messages were answered by the old one. The picker now waits for the desktop to confirm; if it refuses, your previous model stays selected and the reason is shown in the picker.
- A Foxl Code schedule that cannot start because three of its earlier pull requests are still open now retries and says so, instead of silently skipping the run. Scheduled runs are limited to three open tasks per account, and a pull request waiting for your review counts as open. Until now a run blocked by that limit was simply dropped: the Schedules page kept showing "enabled" with a next run in the future while nothing had happened. A blocked schedule now tries again every ten minutes until a slot frees, and the row shows why it has not started - as does any other reason a scheduled run could not begin.
- A coding assistant that committed its own work no longer loses it. Foxl Code used to decide whether a task had produced anything by looking for uncommitted files, so an assistant that committed as it went - which most of them do - was reported as "finished without changing anything" and its branch was never pushed. Every runtime now checks whether the branch is ahead of the base, pushes the commits it finds, and asks GitHub before saying nothing happened. Claude Code and Codex tasks also carry a git identity again, so the end-of-run commit cannot die on "Author identity unknown", and if a commit is ever refused the terminal says so. Codex and Kiro output is scrubbed of tokens the same way Claude Code's already was.
- Edits you type into a note are saved. Fixing a word in a note's body used to change only what was on screen: the edit reached disk only if something else - a rename, an AI summary landing - happened to save the note afterwards, so quitting the app, reloading the tab or closing the phone app brought the old text back with no warning. Typed edits are now written about a second and a half after you stop typing, and written at once when you switch notes, leave the window or close the app.
- Deleting a note asks first. Delete in a note's right-click menu used to act on the single click: the note and its recording were removed at once, with no prompt and no way back. It now asks you to confirm, naming the note - as a native action sheet on iPhone and iPad, a dialog elsewhere - and nothing is removed until you say so.
- Switching the repository filter on Work no longer leaves the previous repository's tasks in the list. If you changed the chip while the first list was still loading, the late answer was applied anyway, and every later refresh preserved those rows - so two repositories' tasks sat under a chip naming one of them until you reloaded the page. The answer for a filter you have moved off is now discarded, and its request is cancelled.
- Importing an audio file waits until the current recording is stopped. Dropping a file onto Notes, or using File > Import Recording, while a meeting was being recorded replaced the live transcript with the imported file's, and pressing Stop then saved the import instead of the meeting - which was unrecoverable. The import is now refused while a recording is running or paused: the drop zone dims and says so, and the menu command tells you to stop the recording first.
- The cost view shows what you actually spent, cached tokens included. The routing cost summary always read "0 requests, $0.00" no matter how much you had used, because it was looking at a counter nothing ever wrote to - and the maths behind that counter left out cached tokens, which on a typical agent turn are most of the bill. It now reports from the same usage records as the Usage page, with cache reads and writes counted, and it says plainly when a model has no known price instead of quietly showing it as free.
- The Ask AI sheet in Notes stays above the iPhone keyboard. Tapping the "Ask AI about the conversation" field on a phone raised the keyboard over the field and its Send button, so you could not see what you were typing. The sheet now makes room for the keyboard and the input row rides up with it, the way the chat composer already does.
- iPad no longer shows the phone tab bar next to the sidebar. On an iPad the bottom tab bar appeared alongside the open sidebar, offering the same four destinations twice. It now shows only when the window is phone-width: a full-width iPad keeps just the sidebar, a narrow Split View pane still gets the bar, and it follows a rotation or resize live.
- A daily Foxl Code schedule set to
24:00no longer saves as a schedule that never runs. Several time pickers write midnight as24:00; the server accepted it, showed the schedule as enabled, and then never fired it, because that time could not be turned into a next run. A time outside00:00-23:59is now refused when the schedule is saved, with the allowed range in the message, and a schedule can no longer be saved or re-enabled in a state where it has no next run - pausing it or fixing the time are the two ways out. - The daily cap on unattended Foxl Code work now counts real money. The cap was compared against a fixed per-wake-up estimate, so it bounded how often the autonomous loop woke and said nothing about what the tasks it started actually cost - a $5 cap could not stop a day of $50 in task spend. The loop now reads what the day's tasks have really spent (settled and still reserved) before every run and goes quiet at the cap, and Settings shows that real figure. If the ledger cannot be read, the loop skips the run rather than spending against an unknown total.
- Search no longer rebuilds its whole index every time Foxl starts when your conversations are not in a Latin script. Foxl decided whether the search index was already built by looking for a word beginning with the letter "e", and a Korean, Japanese or Chinese history has none - so it concluded the index was empty and re-indexed every message on every launch, more slowly the more history you had. It now asks the index how many messages it holds, which works in any language and also catches messages that were saved while the index was unavailable.
- Deleting a message, resetting a chat, or archiving one now tells you when it did not go through. If the desktop refused the request or the connection dropped part-way, the app used to apply the change anyway - the message vanished, the chat emptied, or it moved into or out of the archive - and the next reload quietly put everything back. Nothing changes now until the server has agreed, and a refusal shows a message so you can try again.
- A search that could not run now says so, instead of showing "No results found". When your desktop is asleep or the connection has just dropped, searching your conversations from the phone or from the title bar looked exactly like a search with no matches. It now tells you the search is unavailable and to reconnect and try again.
- Every model id in the catalog now resolves to its own model. Seven of the provider-specific ids the catalog lists for its own models - the dated Anthropic ids and the versioned Bedrock ids for Opus 4.6, Sonnet 4.6 and Haiku 4.5 - were not recognised by the catalog's own lookup, so a request made with one of them was treated as an unknown model. For Haiku 4.5 that meant the thinking settings the model rejects. The lookup now knows every id it lists, and a name that merely ends in a model id no longer inherits that model's settings.
- Removing a saved API key now tells you when it could not be removed. The key row used to switch to "not configured" the moment you pressed Remove, even when the server had refused and still held the key - it came back on the next reload. The row now stays in place and the reason appears under it, so you know the key is still there.
- Deleting a Foxl Code task now asks first. Right-click, Delete (or arrow-down and Enter) on a task removed it, its transcript and its whole event history in one click, while the neighbouring Delete all already asked. Both places a task can be deleted from - the task menu and the open task's own menu - now confirm with the task's name, using the same native sheet on iPhone.
- Provider options that fail to load now say so and offer Retry. In Settings, the routing, model and cost controls of an OpenAI-compatible provider used to render as a blank area when they could not be fetched - for example over a flaky connection from the phone - with nothing to say why. There is a spinner while they load, and an error with a Retry button if the load fails.
- A pause or a cough during an on-device recording no longer makes the next sentence overwrite the previous one. When the on-device engine was handed an utterance it could not turn into words - a short noise, or a rare engine error - it said nothing about it, and the sentence after it was numbered as if it were the same utterance. On screen that meant the new sentence replaced the earlier line instead of being added after it, so the note came out one sentence short with no gap and no warning. Every utterance is now counted, whether or not it produced words.
- Syncing or installing skills no longer freezes the app. Pulling the skills library and installing a skill from skills.sh used to hold up the desktop's server for their whole duration - up to two minutes on a slow network - so chat replies stopped mid-sentence, terminals stopped echoing, and the app could look as if it had crashed. Both now run alongside everything else and the rest of the app keeps working. The skills.sh installer is also pinned to one exact version of its command-line tool instead of whatever the package registry serves that day, and a package name must now be exactly
owner/repo. - The find bar inside a note is translated. Pressing the find shortcut in a note showed "Find in note" in every language, because that label was missing from all ten Notes translations and the English fallback was the only thing that could render. The Notes translations are now checked in CI the same way the rest of the app's are, so a label missing from one language fails the build instead of shipping in English.
- Searching your conversations on Windows now finds what it should, treats
%and_as ordinary characters, and no longer errors on a long paste. Windows searches without the fast index, and that path took your query too literally:AKIA*or-awsfound nothing even when a message plainly contained the word, while a query with a%in it matched every conversation you have. Punctuation is now handled the way the indexed search handles it, so both give the same answer, and pasting several paragraphs into the search box returns results instead of an error. - A quote or a line break in your profile no longer wipes it on save. On the desktop, saving a name or bio containing a
"or a new line wrote a profile file the app could not read back correctly, so the form closed on "Saved" and the next visit showed the text mangled or missing. The profile is now written in a form that survives any character, and if the desktop refuses the save you are told instead of the form closing. - Notes tells you when the export to your folder is failing. If the folder you chose for auto-saved notes was renamed, unmounted, full or no longer writable, the note still appeared in Foxl and nothing was written to the folder - with no message anywhere. The first failure now shows a notice naming the folder, and Notes settings keeps a marker beside the folder until an export succeeds again.
- Permanently deleting one chat from the Trash now asks first, like Empty trash does. The small trash icon on each row - a few pixels from Restore - used to hard-delete that chat the instant it was clicked, with no way back, while the bulk Empty trash button right below it showed a confirmation. Both now confirm, and the single-chat dialog names the chat it is about to remove.
- Screen readers announce the sidebar, chat and note find controls in your language. The Home button, the product switcher, the connection dot, a conversation's delete and stop buttons, the "generating" indicator, and the previous / next / close buttons of the find bars in a chat and in a note all named themselves in English whatever language the app was set to. Each is translated now, along with the chat find box's "Find..." placeholder.
- Connecting Microsoft 365 or Slack no longer hangs when its sign-in port is already taken. Foxl receives the sign-in through a small listener on your own machine. If that listener's usual port was busy - a second Foxl window, another app - Foxl quietly moved to the next port but still told Microsoft or Slack to deliver the sign-in to the old one, so it went nowhere and Settings sat on "connecting" for five minutes before failing with no explanation. The provider is now told exactly where Foxl is listening, and if no port is free at all you get an error immediately instead of a wait.
- A database upgrade step that fails no longer silently cancels the steps after it, which could leave per-conversation usage permanently broken. Foxl adds new columns to its local database as it starts, and several of those were grouped together so that one failure skipped the rest - with nothing recording how far it had got, so later starts skipped them again instead of finishing the job. On an affected install the per-chat token and cost figures stopped working for good, with no error anywhere. Each step now runs on its own, retries on the next start, and says so loudly if it fails for any reason other than already being done.
- The copy, share, edit and regenerate buttons under a message have names for screen readers. They were icon-only with no accessible name, so VoiceOver read four bare "button"s under every message with no way to tell which one regenerates the reply. Each is named now, in your language, and the copy button announces "Copied" while its check mark shows. The one tooltip in that row (Report) is unchanged.
- The audit log now records what the agent ran and what was blocked. It had been empty since it shipped: the code that wrote it sat on a path the agent never took. Every tool call now lands there - approved, auto-approved or refused, with the reason it was refused, how long it took, and which agent and conversation ran it. Keys and passwords in tool arguments are redacted before they are written.
- Importing your settings from Claude Code or OpenClaw works when the file contains a web address, and the report now says what was actually imported. The importer treated the
//inside anyhttps://link as the start of a comment, so a configuration with a single URL in it could not be read - and the summary still said "Imported N items". The report now separates what was written into Foxl from what was only found and noted for you to set up by hand, so the number you read matches what is on disk. - Every text field accepts Korean, Japanese and Chinese input without submitting on the IME's Enter. In those input methods Enter finishes the word you are composing, and renaming a conversation, a speaker, a note or a terminal pane - along with about a dozen other fields - treated that keystroke as "done" and saved the half-typed text. Those fields now wait for the Enter you press after the word is committed, the way the chat composer already did.
- Pressing Reconnect on a dead Foxl Code task no longer keeps it alive forever. A task whose agent had gone away was supposed to be closed out automatically after 14 days with no progress, but each failed Reconnect attempt was recorded as if the agent had done something, which restarted that clock - so the tasks people tried hardest to recover were exactly the ones that never got cleaned up, and the background loop behind them stayed pinned awake. Failed reconnects and Foxl's own status notes are no longer counted as progress; only the agent's real activity is.
- Subagent rows in the sidebar and session chips in the phone terminal can be reached and opened from the keyboard. Both responded only to a pointer: Tab skipped the row and landed on its small stop / close button, so with an external keyboard or a screen reader there was no way to open a running agent's conversation or to switch terminal sessions. Each row is a real button now, with its stop / close control beside it rather than inside it, and the sidebar's stop button appears on keyboard focus as it does on hover.
- When a request to the local server fails, the app now shows what went wrong. A failing request used to come back as a web page rather than as an answer the app could read, so the screen reported a parsing problem instead of the actual reason - and a request the server had merely refused was reported as a crash. Failures now carry their real reason and their real status, and internal details stay in the log instead of being sent back.
- Typing into a cloud terminal from two places at once no longer loses a keystroke. If two writers reached the same pane while its machine was still starting - the terminal and an agent tool, or two devices - both were told the typing was held, but only one of the two actually ended up in the hold and the other was silently dropped. Each held keystroke is now added to the hold in one indivisible step, so both land, in order.
- The hold for typing into a starting cloud terminal is now bounded in bytes, and a paste that does not fit says so. The limit counted characters rather than bytes, so held CJK or emoji typing could grow to two or three times the intended size, and a single very large paste was not limited at all. The oldest bytes are dropped first and never through the middle of a character, and the answer to a paste that had to be cut now says how many bytes were dropped instead of reporting it as held whole.
- A refused local Code request no longer signs you out of the app. When the web app or the phone asked this computer about its coding tasks before your session had finished attaching, the desktop answered with the same status the account server uses for an expired sign-in, and the app took it at its word and logged you out. The desktop now reports that request as incomplete instead, so a cold start or a token refresh in flight never costs you your session.
- Android now says notifications are not available yet, instead of pretending they are on. Push notifications are not built for Android - so an Android user who turned them on received nothing, forever, while the app showed the phone as registered. The Notifications screen on Android now says notifications are not available there yet (they work on iPhone and iPad), and the app no longer registers an Android device that could never be delivered to.
- Stop now stops the helper agents too. Pressing Stop while the assistant had delegated work to subagents ended the visible reply but left those subagents running commands in the background - and when they finished, the conversation you had just stopped started a new turn on its own to summarize them. Stop now halts every subagent the conversation started, and nothing restarts the conversation afterwards.
- Microsoft 365 no longer disconnects itself when the agent does several things at once. Microsoft issues a new sign-in token on every renewal and retires the old one. When two tool calls ran at the same moment - reading email and checking the calendar in one turn, say - both renewed at once and Foxl could end up keeping the retired token, so the next renewal failed and the connection had to be set up again from scratch. Renewals are now shared between whatever is running, and if Microsoft does reject a sign-in for good, Settings says so on the Microsoft 365 row instead of every request failing the same way.
- Schedule cadences are written in your language and your clock. "Every Monday at 9:00 AM" appeared in English on every Schedules row, card and preset whatever language the app was set to, with a 12-hour AM/PM clock even where the language uses a 24-hour one. Weekday names and times now follow your language and its clock, and the words around them are translated.
- Suggestions arrive in your language even when another language was being generated. If two Foxl windows, or the app and the phone, asked for the greeting and the starter suggestions at the same moment in different languages, the second one was handed the first one's language and kept it for five minutes. Each language is now generated and cached on its own, and a request for a language Foxl does not ship is refused instead of quietly answered in English.
- A Foxl Code terminal could open on nothing for a retried task, and could point at the cloud for a task running on your own machine. Reattaching a retried task's terminal connected to a session that never existed, so the pane stayed blank; and a task running on a machine you connected could be handed a cloud terminal that machine has no session for. The terminal now uses the task's real session, and a task on your own machine no longer opens an empty cloud pane.
- Resizing a Foxl Code terminal now ignores an out-of-range or malformed size. A pane width or height sent from the browser reached the cloud runtime unchecked, and resizing a finished task or sending a malformed request could return a server error. Sizes are now clamped to sensible bounds, a resize on a task that is no longer running is refused cleanly, and a malformed request no longer errors.
- "shared/notes.md" and "Shared/notes.md" are the same shared file. The workspace recognised the team's Shared folder only when it was spelled with a capital S. On a Mac or on Windows, where folder names are not case-sensitive, a path typed as
shared/...quietly became a private file on that one computer while looking like a shared one. Any spelling of the folder name now means the shared folder, everywhere in the workspace. - The Feed Generator's
watchsetting is now read the way the examples write it. Awatch:block in HEARTBEAT.md written as nested lines - the form every example shows - was read as an empty setting plus three unrelated keys, so the "only wake the agent when something changed" check never ran while it looked configured, and saving any Feed Generator setting rewrote the file in that broken shape. Nested blocks are read correctly now, a trailing# commentis a comment, and a block Foxl cannot read is skipped with a log line naming the file and the line instead of being silently misread. - A Foxl Code task no longer fails because its test suite could not start. When a repository's tests need dependencies that were never installed, running them on a fresh checkout stops before a single test executes - and on the Codex, Kiro, Cursor, Hermes and OpenCode assistants that was reported as a failing test suite, so the pull request was withheld and the task was marked failed, while the same repository and the same prompt on Claude Code opened its pull request. Every assistant now installs the repository's dependencies before running its tests, and a suite that could not start is reported as inconclusive rather than red. A suite that runs and fails still blocks the pull request, as before.
- Foxl Code never puts its own dependency install into your pull request. The install that runs before the tests happens in the same checkout that is committed a moment later, so on a repository that does not ignore
node_modules(or a Python virtualenv, or a build output) the harness's own files could have landed in the pull request you were asked to review. Whatever the install creates is now kept out of the commit, on every assistant, and a directory your repository ships on purpose is left exactly as it was. - A file sent with no caption no longer shows up as "Message deleted", and deleting a message now takes its attachments with it. Channels decided whether a message had been deleted by looking for an empty body - which is also what a screenshot or a document dropped into the composer with no text looks like, so your own attachment rendered under an italic "Message deleted" line. Deleting a message, meanwhile, only blanked its text: the tombstone kept its file chips, each one still a working download for everyone in the room. The relay now says explicitly when a message was deleted, a deleted message shows no attachments, and its files are removed from the workspace the same way a delete from Files is - billing stops that night and the bytes follow after the usual grace window.
- A photo or file sent over Telegram reaches the agent instead of vanishing. Foxl acknowledged an attached image or document, then answered as if you had sent only the word "Image" - the file was fetched and thrown away. Attachments are now saved into your workspace inbox and handed to the agent so it can look at the photo or read the document, and one it cannot use (too large, or a type it cannot open) gets a reply that says so instead of a confident answer about nothing.
- A long Foxl Code conversation no longer jumps back to its beginning when you open it somewhere else. Past 200 messages, opening a task on a second device (or after clearing the browser's storage) showed the first 200 messages and dropped the most recent ones - and because that view is also what your next message is answered against, the agent carried on as if the latest exchanges had never happened. The transcript now opens at its newest messages, and a "Load earlier messages" button at the top walks back through the rest.
- Starting an agent that cannot start now says so immediately. "Start agent" used to answer "Agent started" before the run existed, and when no model could be built the failure was only ever announced on the live connection - a phone reaching the desktop through the tunnel, or a window that reconnected, saw a success for a run that had died at once. Worse, that failed start left the agent marked as running, so every later attempt was refused with "Agent already running" until the app restarted. The request now waits for the run to exist and reports the real reason when it cannot, and a failed start no longer blocks the next one.
- Foxl Code's assistant no longer carries every tool into every turn, so a chat question can no longer end in a GitHub issue you did not ask for. Until now only the PR reviewer had a limited toolset: a plain chat message, the autonomous loop's advance tick and its idle survey were each handed all 30 tools, including near-duplicates and two that look alike but do different things - one files an issue in your tracker, the other also spends the loop's own issue budget, and a chat turn spending that budget could silence the survey for a week. Each kind of turn now gets only the tools that turn is for: chat keeps its wide set but cannot touch the loop's budget and files an issue only when you explicitly ask for one, the advance tick drives your queue and cannot file issues at all, and the idle survey keeps exactly what surveying needs. The tools that overlap now also say which one to use when.
- foxl://chat links now open the conversation in the desktop app. Copying a link to a conversation and clicking it later just focused the window and did nothing on the desktop, even though the same link worked on the phone. The link now opens the right conversation (or a new chat for foxl://chat/new).
- Turning automatic updates off no longer strands an update you already downloaded. The "Download updates automatically" switch also quietly disabled installing a downloaded update when you quit - so an update that had finished downloading was never applied, and the app kept reporting it as pending. The switch now only controls automatic downloading; an update that is already downloaded still installs when you quit.
- A workspace whose plan renews on the last day of the month is no longer billed for storage or Channels hours before its credits arrive, and an unpaid storage bill no longer blocks uploads for a month. For a renewal on the 29th, 30th or 31st at a daytime hour, the monthly charge ran on that day's midnight pass - up to fourteen hours before the renewal grant landed, exactly when the balance is lowest - so it could fail, mark the workspace past due and refuse every upload while the owner was fully paid up, and nothing looked at it again until the next renewal. The charge now waits for the first pass after the renewal instead. And a charge that did fail for lack of credits is now retried every day, so a top-up clears the past-due flag on the next pass rather than at the next anniversary.
- A cloud terminal that lost its live connection reconnects instead of going quiet. If your laptop slept or the network dropped while a task's terminal was open, the pane could stop updating for good: the agent kept working, but nothing on screen said the connection was gone, and only a reload brought it back. The terminal now keeps reconnecting for up to ten minutes, reconnects at once when you return to the tab or the network comes back, and if it still cannot get through it says so and offers Retry.
- No estimated dollar costs or upgrade prompts appear while paid plans are hidden. A few screens still showed an estimated dollar cost for your model usage, worked out from a price list that was months out of date, and an unused Notes dialog still carried an "Upgrade to Pro" button. Those dollar estimates and the dialog are gone from the app while Foxl runs as a free project; the usage screens keep their token and message counts.
- An expired Foxl Code session now renews itself instead of signing you out of everything. Foxl Code treated any "unauthorized" answer from its server as the end of the session and dropped the whole app - Agent, Notes and Code - to the sign-in screen, even though a valid refresh token was still on the device. An access token lasts 12 hours, so this happened on a normal day's use, and most often on the first chat message sent after the expiry. Foxl Code now refreshes the session and retries the request once (a chat message is also sent with a renewed session in the first place), and signs you out only when the refresh itself is refused.
- Runs that happen while nobody is watching have a budget now. A heartbeat tick, a scheduled task or a reply to a channel message runs unattended, and until now nothing bounded one: the "maximum runtime" only noted that a run was stuck and let it keep going, and there was no limit at all on how many tools it could call or how much text it could generate. Each such run now stops at 40 tool calls, 24,000 generated tokens or its maximum runtime (10 minutes unless you changed it), whichever comes first, and a run that hit a limit is recorded as "budget_exceeded" with the reason rather than as a normal completion. A heartbeat run also can no longer hand its work to a separate background agent, which would have run with none of these limits; scheduled tasks and channel replies were already kept from doing that. The heartbeat's limits can be tuned in HEARTBEAT.md (
maxToolCalls,maxOutputTokens,maxRuntime), within a fixed ceiling. - Switching models mid-chat could silently wipe the conversation from the agent's memory. After a model switch (or a stop, an error, or an app restart) the desktop rebuilds the agent from the saved transcript, and it restored the FULL stored tool output every time - including screenshots that
view_imagehad returned as base64 text, around 100k tokens a picture. Once a conversation's saved history was larger than the new model's context window, the model refused it, the recovery trimmed the history down to the message you had just typed, and the reply carried on as if the chat were new: nothing in the window said so. Measured five times in one evening on v0.6.28. Now the restored history is sized to the model it is being restored for (inline images are dropped as text, then the oldest tool outputs are shortened, then the oldest turns are left out with a note that says how many), the chat uses the same proactive summarizer the autonomous agent has had since v0.6.19 instead of a last-resort trim, and every compaction shows up in the transcript as a divider, the way a model switch already does. - The agent can actually see the images it looks at.
view_image(and thegenerate_imagepreview) handed the model its picture as a base64 string inside text - around 100k tokens that no model can read as an image, which is also what filled the conversations above. Both tools now return a real image block: the model sees the picture for roughly 1.5k tokens, the thumbnail in the transcript is unchanged, and on the two catalog models without vision the image is replaced by a one-line note instead of a refused request. - A shell command that runs out of time is now stopped completely, and a background command no longer runs forever. When one of the agent's shell commands hit its time limit, only the shell itself was stopped: a pipeline or a chain of commands kept running underneath, invisibly. And a command started in the background had no time limit at all. Now the whole command - every process it started - is stopped when the limit is reached, background commands get their own limit (an hour unless the agent asks for more), and the process list shows each command's deadline and how long it has left. And when Foxl's agent service stops - quitting the app, or restarting for an update - any command the agent still had running is stopped with it, instead of being left behind with no time limit.
- Notes: pressing Summarize saved the note dozens of times and left the transcript on disk instead of the summary. The summary streams in token by token, and every token was treated as a finished summary: the note was written to disk, a new Word or Markdown file was built and saved, and a "Saved" toast fired - once per token, for the whole stream. Because the note's title is derived from the summary, the file name also changed as the first sentence grew, so the auto-save folder filled with partial copies under different names, and the transcript-only file written when the recording stopped stayed behind under its old title, which is the file you opened. Now the summary is written back once, when it is complete, and its export replaces the file from the previous title - so one note is one file, and that file holds the summary.
- Two agent pull requests from one plan can no longer merge unattended on top of each other when they both add a database migration with the same number. Each of those pull requests is green on its own and GitHub reports no conflict, because two new files never conflict - so nothing in the unattended merge path could see that the combined result numbers two migrations identically, the exact shape a human merge train once had to catch by hand. Foxl Code now checks a pull request against its siblings before merging it unattended and holds the merge when the numbers collide. The hold shows up in Needs you, and on your phone, as a held merge rather than a refused one - GitHub was never asked - so you know to renumber one of the two migrations before merging (a migration that has already been applied must keep its name). Everything that does not add a migration merges exactly as before.
- A schedule that keeps failing now tells you, keeps trying, and can be resumed with one tap. After three failures in a row a schedule used to be switched off silently: nothing on the Schedules page said why, no notification was sent, and it never ran again until someone noticed the silence. It is now shown as "Paused after 3 failures" with the last error and a Resume button, you get a notification when it happens, and instead of stopping for good it retries with a growing delay (an hour, then six, then daily) until a run succeeds or you resume it.
- Limiting a shared folder to specific people can no longer hide it from the person doing it, or from any workspace administrator. Restricting a folder without ticking yourself used to save fine and then drop the folder, and every file in it, from your own sidebar on the next refresh - with no row left to reopen the sharing dialog from, nothing saying why, and the storage still counting. Now whoever limits a folder always stays on its list with edit access, the dialog shows that and will not let you un-tick yourself, and a workspace owner or admin can see and open any restricted folder in their workspace even when they are not on its list - which also brings back folders that were already lost this way. The first time each day an administrator reaches a folder that way, it is recorded in the workspace's audit log.
- Pressing Enter in Foxl Code while a message is still sending keeps your draft, and Stop still stops. Typing a follow-up while the assistant was working and pressing Enter used to empty the box and send nothing - the text was simply gone. Enter now does nothing until the current turn finishes, so what you typed stays in the box and goes out when you press it again. Tapping Stop with a follow-up in the box used to empty the box as well, instead of stopping; it now stops the reply and leaves your text where it was.
- Long Foxl Code chats stay smooth while a reply streams. Every streamed token used to redraw every earlier message in the transcript, so typing in the composer stuttered and the page scrolled jerkily the longer the conversation got - on a phone it became unusable well before the Agent chat did. Earlier messages are now left alone while the reply comes in, as they already were in the Agent chat.
- Speaker separation could not finish installing, and said it had. Installing the on-device transcription engine downloaded the two speaker models and then saved neither of them, so Notes kept offering to install them and every attempt downloaded the same 33 MB again. The download now saves its files, and if that part fails the installer says so instead of reporting success - transcription itself keeps working either way, just without speaker labels. The Install engine button also stays on screen while speaker separation is missing or an install has failed, so the retry is one press away; before, it disappeared as soon as transcription itself was ready.
- The Foxl Code tier table can no longer miss a new Claude model. The list of Claude models a Pro, Ultra or Enterprise account may run a Foxl Code task on was typed by hand, and Fable 5.1 - added to the model catalog on September 1 - was not on it. The table is now derived from the catalog itself, so the next Claude model cannot be left off. This is hardening with no user-visible change today: tier limits are not enforced while Foxl is free, and the Foxl Code model picker does not offer Fable 5.1 yet, so nobody could have been refused. (#943)
- Gemini 2.0 Flash is no longer offered. It was the one model in the catalog with no price, so a chat on it with your own Google key was recorded as costing $0.00. Google's own pricing page no longer lists any 2.0 model, so there is no honest number to give it and the row has been removed; Gemini 2.5 Flash and 2.5 Pro remain. A saved selection of the old id moves to Claude Sonnet 5 (or the first model your plan can run) the next time the chat opens; Google itself shut Gemini 2.0 Flash down on June 1, 2026. (#944)
- A storage or Channels charge can no longer deduct credits while its receipt reads $0.00. The credit amount and the dollar amount were rounded separately, and at the smallest fractions of a gigabyte-month or member-month they could round in opposite directions - one up to a deduction, the other down to zero. The dollar figure is now derived from the rounded credits, so the two always agree. (#945)
- Hardening with no user-visible change today: the pre-flight task-cost estimate clamps out-of-range inputs instead of producing a negative or infinite budget, the credit gate refuses rather than admits a task when handed a non-numeric cost, count or balance, and a negative token count from a provider is treated as corrupt rather than billed as a refund (#959, #757). Internal fixes to the status page, CI and release tooling: outbound status webhooks no longer follow redirects (#941); the public error redaction now also hides internal hostnames, dashed ids, database table and column names, Lemon Squeezy keys and IPv6 addresses (#947); the release gate reads the published state back after publishing (#890); the iOS workflow declares least-privilege permissions and records the commit of its out-of-repo plugin (#889); the Discord bot image runs unprivileged and every base image is pinned by digest (#887); a stale "ephemeral runner" comment was corrected (#886); and the workflow-injection gate now also catches
github.event.*,github.head_refandgithub.actor(#888).
Security
- One account can no longer fill the shared database through push registration. The phone's push-token registration accepted a token of any length, any number of times, with no limit on how often it could be called, so a single free account could write enough oversized "tokens" to reach the database's hard size cap - at which point every write in the service fails, for everyone, not just push. A token is now checked against the shape real APNs and FCM tokens have, each account keeps at most its 20 most recently registered devices, and the route shares the same per-address rate limit as sign-in. A phone registering normally sees no difference.
- Pet gifts can no longer be used to send unlimited email to any address. Sending a pet to a friend emails them an invite, and the only limit was on how many gifts were waiting to be claimed - taking a gift back freed that slot at once, so one account could send, take back and resend to any list of addresses without end, each time putting 200 characters of its own text into a message from our domain. An account can now send at most 10 gifts a day and can mail a given address once a day, whatever became of the earlier gift, and sending or taking back a gift shares the same burst limit as signing in. Claiming a gift is unchanged.
- Removing someone from a workspace now closes their open Channels connections immediately. Their access already ended the moment an admin removed them, but a room they still had open kept streaming new messages to them until they closed the tab, and they stayed in any voice huddle they had joined. Removal now ends those live connections and drops them from the call at the same time.
- One account can no longer flood the moderation queue or fill the shared database with content reports. Reporting a message or a person had no ceiling: a script could file an unlimited number of reports against made-up targets, each with a maximum-length note, and every one became a permanent row in the database all Foxl accounts share and another line in the only review queue there is. Reports are now capped per account - at most 50 awaiting review at a time and at most 100 in any 24 hours - and the route goes through the same per-address limiter as signing in. A note longer than 2000 characters is refused with a clear error instead of being silently cut short (the app's own report form already stops at 2000, so nobody typing in it will see this). Reporting the same thing twice still just updates your earlier report.
- Connected-account tokens and skill secrets are now encrypted on disk, and the assistant can no longer read them back. Signing in to Microsoft or Slack, or typing a skill's API key on the Integrations page, used to store that credential as plain text in the same local database the assistant searches with its memory tool - so a web page the assistant read could instruct it to "recall" the entry and send it somewhere. Those entries are now encrypted with the same per-install key that already protects your provider API keys, the memory tools refuse to read or write them, and the memory viewer shows only their size. Existing connections keep working and are re-encrypted the first time they are used; there is nothing to redo.
- Someone holding one of your signed-in sessions can no longer keep your password sign-in locked, or guess your current password without limit. Changing or removing a password asks for the current one, and a wrong answer counted toward the same lockout that protects sign-in - but those two requests never checked whether the address was already locked. So each wrong guess made during a lockout pushed its end another 15 minutes out, and the guessing itself was never refused. Both requests now refuse while the address is locked, with the same answer sign-in gives, and a failure that arrives during a lockout no longer moves when it ends.
- Blocking someone now silences them on your phone too. Blocking a person already hid their messages from your timeline, but the notification sent for each message had its own recipient list that knew nothing about blocks - so a blocked person could still put their name and the first 140 characters of every message on your lock screen, and your unread badge kept counting them, with muting every colleague as the only way out. Blocks now apply to notifications in both directions, in channels and in direct messages that existed before the block, and to huddle rings, so a person you have blocked can no longer ring your phone. Unblocking restores the notifications.
- A machine's address is checked no matter how the machine was registered. Foxl Code refuses to send a task - which carries a GitHub token and your model credential - to a private, loopback, link-local or cloud-metadata address, or over plain http. That check only ran for machines added as an existing host; a machine added as a launched EC2 box could be given any address at all. It now runs for every machine, runs again at the moment a task is dispatched, and a machine whose stored address fails it is marked failed with the reason shown in the Machines pane instead of being used. The deprecated IPv6 site-local range and the short names cloud providers use for their metadata service are refused as well.
- The desktop app no longer hands its connection token to pages on local dev ports. The packaged app's local API accepted cross-origin reads from the Vite development origins (localhost on ports 5173 to 5175), and the page that bootstraps the app carries the token that unlocks every local API route, so a page served from one of those ports could read it. Those origins are now admitted only in development, and the app shell is never readable cross-origin. Starting the agent from a plain GET link (
/api/goal?q=...) is gone too: it is a JSON POST now, which a foreign page cannot send without a CORS preflight. - A crafted link on our own relay can no longer sign you into someone else's account. An old sign-in hand-off address on relay.foxl.ai accepted login tokens from the link itself and passed them straight into the app, so a link that looked first-party could quietly log a visitor into an attacker's account, where everything they then wrote could be read by that attacker. Nothing has used that address since v0.1.3; it is gone, and a check now keeps any relay route from accepting sign-in tokens out of a link again.
- Linking a GitHub account to Foxl Code now finishes only in the browser that started it. Before, the link was completed by the page GitHub sent you back to, and a crafted link could bind the GitHub identity of whoever clicked it to someone else's Foxl account - which Foxl Code treats as proof that you own your repositories. GitHub now hands your browser a one-time code that only your own signed-in session can redeem, within five minutes, once. If pressing Link GitHub ends with "started from a different Foxl account", press it again from the account you are signed in to.
- A Foxl Code agent can no longer approve its own pull request, and every approval names the exact commit that was reviewed. The credential a cloud agent carries could reach the endpoint that records a review verdict - the second of the two gates before an automatic merge - so a prompt injection hidden in a README or an issue could have had an agent mark its own PR as reviewed, or a sibling task's. Only the independent reviewer's credential can report a verdict now, and only for the one task it was asked to review. Separately, a verdict used to attach to whatever commit was current at the moment it arrived, so a push made while the reviewer was still reading could have been merged as if it had been reviewed. A verdict is now refused unless it names the commit that is still the head, and the newer commit gets its own review.
- A sign-in link now only completes in the browser that started it. On app.foxl.ai and code.foxl.ai, a specially crafted link could quietly sign your browser into someone else's account, so everything you did next - chats, notes, Code tasks, shared-folder edits - landed there and was readable by them. Starting a sign-in now leaves a one-time secret in your browser that the sign-in service hands back, and a link that cannot present it is ignored, removed from the address bar, and explained on the sign-in page. One visible consequence: a magic link opened in a different browser or on a different device than the one that requested it no longer signs that other browser in - request the link from the browser you want to use.
- Removing someone from the Foxl Code beta now also stops the work GitHub triggers on their behalf. The beta allowlist closed the app and the scheduled loops for a removed user, but a push to one of their task branches, an approval on a pull request, or a finished build could still make Foxl mint a fresh GitHub token, spend a reviewer turn, wake their coding agent, or merge to the default branch for them. Each of those paths now checks the same allowlist first and records that it declined, so a user the operator cut off is cut off everywhere. Nothing changes when no allowlist is set.
- Android backups no longer carry your sign-in or your meeting notes off the phone. Android's automatic backup to Google Drive, and the copy-everything-to-a-new-phone transfer, used to include Foxl's private data - so a backup restored onto another device arrived already signed in to your account, with every meeting transcript, summary and recording. The app now tells Android to leave all of that out. Your notes are no longer copied into Android backups, and a new phone asks you to sign in.
- The desktop window now hands a clicked link only to your web browser, and a page can no longer write or delete files outside the folders you chose. Three holes in the desktop app's bridge to the operating system, found by the 2026-09-02 audit: a link in a chat reply or a tool result could name a non-web scheme (
smb:,ms-msdt:,file:) and one click handed it to the OS; a Notes recording id containing..could read, write or delete a file outside the recordings folder; and a Notes auto-save export accepted any path at all. Now only http(s) links leave the window, recording ids must be plain identifiers, and an auto-save export must land inside the folder you picked. Nothing to configure; a refused action is logged and reported instead of being quietly redirected. - A Microsoft or Slack sign-in now only completes for the sign-in this desktop started. An unused server route could finish an integration sign-in from details supplied by whoever called it, which would have let another account be connected as yours. The route is gone; connecting Outlook or Slack works exactly as before, through the browser window Foxl opens.
- Signing out on a shared phone now stops that phone receiving your notifications. Until now a phone's push registration stayed attached to every account that had ever signed in on it, so if you signed out of a shared iPad and someone else signed in, your message previews and other alerts kept arriving on their lock screen - indefinitely. A phone now belongs to one account at a time: signing in takes it over, signing out releases it, and existing duplicate registrations are cleaned up when the update rolls out.
- The Foxl Code assistant running on your own computer now obeys the same shell rules as the Foxl agent. When you chat with Foxl Code on this machine, it can run shell commands for you - and until now those commands skipped the protections every other Foxl shell command goes through: your blocked-command rules were not consulted and no approval prompt could appear, even though the same command typed at the agent got both. That mattered because this chat is reachable from your phone and from app.foxl.ai through your desktop connection. Both are applied now, from the rules you already have; nothing to turn on, and if you have approvals switched off nothing about your day changes.
- A folder name can no longer change what Codex trusts. When Foxl opens a Codex pane it writes a small "this folder is trusted" entry into your Codex configuration, so the pane does not stop on a first-run question. A folder whose name contained a quote character could append settings of its own to that file - including trusting your entire disk for Codex sessions you start yourself, outside Foxl. Such a name is now refused, with the reason logged, and Codex simply asks its own question instead.
- Microsoft 365 requests now encode every id and search value before it reaches the URL. A message, folder, event or task id chosen by the assistant - which can be steered by text inside an incoming email or invitation - could previously rewrite the request itself: widen a mailbox read from 50 headers to hundreds of full message bodies, drop the limits Foxl had set, or point the call at a different Microsoft Graph route, all with your signed-in Microsoft account. Every value now stays inside the path segment or query parameter it was meant for, and an empty id is refused instead of being sent.
- Deleting your account now removes everything the service kept under your name, including any coding-agent credential you had uploaded. Account deletion worked from a hand-written list of tables, and that list had fallen behind the database again: twenty-four kinds of per-user data survived a deletion. The most serious was the Claude or ChatGPT subscription credential a Foxl Code cloud machine runs with, which stayed stored indefinitely with no account attached; also left behind were the encrypted copies of assistant replies parked for a suspended phone, your notification badge count, your daily usage rollups, the questions the coding loop had asked you, your remote machines, and your channel memberships, mentions and reactions. All of it goes with the account now. Channel messages you posted stay with the workspace, as before, and a check in the build fails whenever a new kind of per-user data is added without a decision about what happens to it on deletion.
- A Foxl Code run can no longer pick its own compute discount, and a garbled end-of-run report can no longer leave a task stuck on "running". The coding container's finish report carried an "idle time" percentage that the relay multiplied into the compute charge, even though no container measures it (every one sends the same fixed value) and anything steering the agent could send a different one: a report of 100% idle cut the processor part of the bill to zero, and a non-numeric value crashed the charge, so nothing was billed and the task stayed "running" forever. The relay now bills compute from what it knows itself - its own clock, the machine profile and a fixed idle fraction equal to what every honest run reports, so honest charges do not change - keeps the report only as an audit note, and always records the task's final status even when the report is unusable.
- Opening a sign-in link on a second device no longer signs the first one out. When you asked for a magic link on one device and opened it on another - the common case of requesting it on a laptop and tapping it on your phone - the new session was mistakenly filed under the first device's identity, which quietly logged that device out at its next refresh and showed the wrong device in your session list. The redeemed session now belongs to the device that actually opened the link, and the device that only asked for it stays signed in.
- Sign-in links and callbacks are no longer cacheable. Every response that carries an access or refresh token - the magic-link redirect and deep-link page, the Google, Apple and GitHub callbacks, and the token-refresh and password-login responses - now sets
Cache-Control: no-store, so a shared proxy, browser cache or mail-scanner log cannot retain a live session token. - Foxl Code: a cloud run whose machine died mid-task is now settled right away. When a coding agent stopped without reporting back, the watchdog marked the task failed after fifteen minutes but never told the billing side, so the compute that did run was never charged. The watchdog now finalizes the run the same way a normal finish does, and you get the same "task failed" notification.
- Low-severity hardening from the 2026-09-02 audit, Foxl Code server and runtimes. A per-task budget override above the larger of your per-task budget setting and ten times the estimate is refused rather than merely logged; a coding agent can only record a pull request on its own repository; plan documents prove the repository and installation they name; schedule and Work requests write the same cross-tenant audit row every other surface does; repository files served by Foxl Code carry
nosniffand an attachment disposition; the session verifier accepts only the algorithm the relay signs with; two unused Settings fields are validated instead of stored raw; a machine's reported error is bounded on every path; each cron leg reports its own failure; and the cloud runtimes validate the task id and git ref they are handed. (#946, #920, #913, #919, #930, #914, #917, #916, #932, #926, #927, #925, #924, #933, #912, #918) - A sign-in link can now only be finished by the browser that started it. Signing in with Google, Apple or GitHub hands your browser back to Foxl with a one-time code, and Foxl checked that the accompanying ticket was genuine and recent - but not that it belonged to the browser presenting it, and not that it had never been used before. Someone could start a sign-in as themselves, keep the return link instead of following it, and send it to you; opening it would have signed your browser into their account, so anything you then wrote would land where they could read it. Foxl now leaves a short-lived note in your browser when you start signing in, finishes only a return that matches it, and accepts each one once. A return that does not match shows a plain "start sign-in again" page and signs nothing in. The desktop and phone apps already had their own check for this; the web sign-in did not.
- Sign in with Apple now insists on a verified address, and remembers your Apple ID rather than your email. Apple can pass along an address it has not verified, and Foxl accepted it as proof of ownership and matched it to whichever Foxl account held that address - the check Google sign-in has always had was missing here. Apple sign-in is now refused unless Apple says the address is verified, and once you have signed in with an Apple ID, that ID is what finds your account from then on, so changing the email on your Apple ID no longer creates a second Foxl account.
- Foxl Code no longer sends its internal error text to your browser. When something failed inside the Foxl Code service in a way it had not planned for - a database not yet migrated, a GitHub call that failed - the raw internal message, including table and column names and GitHub API addresses, came back as the error you saw. The service now answers with a generic error plus a reference id, and writes the real cause to its own logs under that id so we can find it when you report it. Errors that were written for you - a refused request, a missing machine, a budget floor - read exactly as before.
- The reviewer that can merge a pull request on your approval now leaves the same audit trail as every other Foxl Code agent. Every agent Foxl runs on your behalf records the GitHub-touching tool calls it makes, so "what did it do" can be answered afterwards - except the one that reviews a pull request after you press Approve, which is also the one allowed to merge it. Its tool calls are recorded like the rest now, tagged with the review they belong to.
- The agent now asks before sending a file to a chat, and can only message people you allowed. The
channel_sendtool used to accept any file on your disk and any recipient id, with no approval prompt, so a malicious web page or message could have had the agent send a private key to a stranger's Telegram chat. It now asks for approval the wayexecdoes, refuses any file outside your Foxl workspace, and refuses any recipient that is not in that channel's allowlist on the Channels page. - Your Claude Code or Codex sign-in is only ever copied to your own Foxl account, and only from this computer. When you sync a coding-assistant sign-in to Foxl Code, Foxl reads that credential off this machine and uploads it for you. Until now the request could say which account should receive it, and it could arrive from another device through your desktop connection - so anything that could reach your desktop could have had your sign-in delivered somewhere else. Foxl now uses the account this computer itself is signed in to, refuses any destination named in the request, and only performs the sync when it is asked from Foxl on this computer. If you are signed out here, it tells you instead of sending anything.
- The Feed Generator's watch command runs only if you set it and your tool-approval rules allow it. The optional
watchcommand in HEARTBEAT.md ran on every tick with no approval check, and HEARTBEAT.md is a file the agent itself can write, so a prompt injection could plant a command that ran unattended from the next launch on. Foxl now runs only the command you set through the Feed Generator settings, refuses and logs a command that appeared in the file any other way, and puts it through the same permission rules and approval prompt as any shell command. A run nobody approves is skipped, not executed. - A coding agent can no longer attach someone else's pull request to your task. When an agent reported the PR it had opened, the link it sent was checked for shape only, so a prompt-injected agent could name a pull request in an entirely different repository and it would appear as your task's "View PR" link and in its list of pull requests. The reported link now has to be a pull request of the task's own repository, with a number that can actually exist; anything else is logged and ignored while the task carries on. The task's activity feed and notifications are covered too: they no longer show, or offer to merge, a pull request the agent merely claimed.
- The agent's
web_fetchtool now refuses a public web address that secretly points at your own computer or network. It already refusedlocalhostand private IP addresses by name, but a domain name can resolve to one of those addresses anyway (for example127.0.0.1.nip.io), and a malicious page could use that to make the agent read a service running on your machine and hand the response back to the model. The tool now looks up the address itself, refuses if any answer is local or private, and connects only to the exact address it checked - on every redirect too. - A purchase is credited only to the account that started the checkout. Lemon Squeezy customers were matched to Foxl accounts by the email typed into the checkout, which nobody verifies, so someone who paid once with your email could have become the account your later subscription was credited to - you would be charged and stay on the free plan. A payment whose checkout proof names a different account than the one on file is now applied to nobody and queued for a person to look at, and a Lemon Squeezy customer can be bound to only one account. Billing is not switched on yet, so no live purchase was affected.
- A sign-in link now only completes in the desktop app that started it. For twenty minutes after you pressed Sign in, the desktop app used to accept any
foxl://sign-in link fired at it - by a page in your browser or by another program on your computer - and could quietly switch you into someone else's account. Every sign-in the app starts (Google, Apple, GitHub and the email link) now carries a one-time code that the returning link has to match, anything else is refused, and the app tells you when a link was refused so an expired email link is not mistaken for a sign-in that did nothing. - The agent can no longer rewrite its own standing instructions without asking. The workspace memory tools could edit SOUL.md, HEARTBEAT.md and AGENTS.md - the files that shape every conversation and drive the heartbeat timer - with no approval prompt, so a malicious web page or message could have planted a permanent instruction the agent would follow in every future run, including unattended ones. Those three files are now off limits to the agent entirely (you still edit them on the Workspace page), and saving or editing the remaining memory files asks for approval the way writing a file does.
- Two test-only API routes no longer exist on a shipped desktop.
POST /api/test/notificationandPOST /api/test/approvalwere built for the end-to-end suites but were registered in every build, so anything that could reach the local API could show every connected client a made-up notification, or put a tool-approval prompt on your screen for a tool nothing had asked to run - and pressing "Always allow" on that fake prompt installed a real permission rule. Both routes now exist only when the server is started withFOXL_TEST_ROUTES=1, and "Always allow" can only create a rule for a prompt that a real tool call opened, so a fabricated prompt cannot become a permission even on a test server. The "Send test" button in Settings > Notifications still works on a shipped desktop; it now shows the bell entry and the OS notification directly instead of asking the server to broadcast them. - Restoring a skills backup can no longer delete anything outside the skills folder. The undo for "Sync skills" read the list of skills to put back from a small file kept beside the backup, and trusted it: a crafted entry could name any folder on the computer, and that folder was removed before the copy. Every entry is now checked to be a plain skill name and the restore refuses outright if any is not. Each skill is also copied into place beside the old one and swapped in, so a copy that fails halfway leaves the installed skill exactly as it was.
- A stolen sign-in token alone can no longer impersonate your desktop. Connecting to the relay as your desktop now also requires a secret that only your desktop holds: the Foxl app creates it once, keeps it on this machine, and the relay pins the first one it sees. Anyone else presenting just your sign-in token is refused. Desktops on older versions keep working while they update; there is nothing to set up.
- A custom tool can no longer take a built-in tool's name or erase its safety rules. Saving a custom tool called
exec(orExec, orfile-readnext to the built-infile_read) used to silently remove the built-in refusals forrm -rf /,rm -rf ~,mkfsanddd, and then broke every agent run with an opaque "already registered" error. Such a name is now refused when the tool is created or renamed, with a message naming the built-in it collides with, and registering a custom tool's approval rule leaves the built-in refusals untouched. - Your Telegram bot no longer tells strangers it is online. Two commands, /status and /help, answered anyone who found the bot, while every other message already required the sender to be on your allowed list. Someone who guessed the bot's name could learn that a Foxl desktop was connected and reachable, and get their own user id back to quote when asking you to let them in. Both commands now stay silent for anyone not on the list, the same way photos and files from a stranger already did.
- A notification can no longer sign you into someone else's account or hand another app a link. Tapping a notification - or that notification's row in the in-app list - opens the link it carries. The in-app row accepted any link at all, including ones that launch other apps on your phone, and both places kept the link's
#fragment when they navigated inside Foxl. That fragment is exactly where the app looks for sign-in tokens after a reload, so a crafted link could plant someone else's tokens there and your next sign-out would have signed you straight back in as them. Notification links now open only when they are ordinaryhttps://links, a link into the app never carries a fragment, a link that looks like a sign-in token is refused outright, and every place a notification can be opened from goes through that one check. Today every such link is written by Foxl's own servers and nothing has been seen exploiting this; the change is there so that a future server bug cannot turn into an account takeover. - A fault inside the tool-approval system now refuses the tool call instead of running it. If the approval prompt could not be raised - for example because the connection that carries it failed - the agent used to run the command anyway, with a single warning in the server log. The same was true when the permission system failed to attach to an agent at all: it kept its full toolset with no rules and no prompts. Both now fail closed: the call is refused with a readable reason in the conversation, and an agent whose safety hooks could not attach refuses every tool until Foxl is restarted.
- The diagnostics report leaves your conversations out unless you ask. The System Report in Settings, meant for pasting into a support thread, used to include the last ten messages of your most recent conversation and the titles of your ten most recent ones alongside the versions, paths and logs. It now contains diagnostics only. If a conversation is relevant to the problem, a separate "Include recent conversation" action asks you to confirm before it adds that text to the download.
- A misbehaving coding-agent container can no longer fill the database every Foxl Code user shares. A container reporting on its task could post events of any kind and any size, as fast as it liked, and every one was stored twice with nothing ever cleaning up - so a single compromised run could have driven the shared database to its size limit and taken every other user's tasks down with it. Events are now checked against the list of kinds the runtimes actually send, capped in size (64 KB, above the largest real one), limited to 600 a minute and to 5,000 events or 8 MB per task, and the stored events of tasks that finished more than 30 days ago are swept out on a schedule.
- The status page no longer accepts a webhook address that names an internal host with a trailing dot. Subscribing to incident updates on status.foxl.ai is open to anyone, and the page posts every update to whatever address it stores, so the address filter is the whole guard. That filter was a copy of the relay's link-preview filter and had fallen behind it:
https://localhost./andhttps://metadata.google.internal./slipped past the name checks (a trailing dot is the same host to every resolver), and two reserved IPv4 ranges were not refused. The copy now matches the relay's filter, both filters refuse those two ranges, and a CI test fails whenever the two disagree again instead of leaving that to a comment. - Signing in as a different person on a shared browser now removes the previous account's data, as it was always meant to. If your session expired or was rejected and someone else then signed in on the same browser profile, they inherited everything the first account had stored locally: the chat history kept for offline use, notification text, the list of tools the agent had standing permission to run, and any saved API key. The check that was supposed to catch this compared the new sign-in against itself, so it could never fire. The previous owner is now recorded before a new sign-in is stored and compared properly, and every sign-in path goes through the same check. Signing back in as yourself, and the routine token refresh, leave your data untouched; your theme, language and other device preferences are kept in every case.
- Links in replies and documents open only web pages, email, and the few apps Foxl supports. A link in an AI reply, or in a Markdown file from your workspace, could point at almost any program installed on your computer, and the link text did not have to say so. Links now open only web and email addresses plus Obsidian, VS Code, Slack and phone numbers; anything else stays a plain, unclickable link. Hovering a link that would open another app now shows which one.
- A shell command now sees only the integration secrets its own skill declares, and prints none of them. Every stored integration value used to be passed to every shell command the agent ran, whatever skill was in play, so a single
envcommand - which a planted web page could ask for - handed the model every token you had entered. A command now receives a stored value only after the agent has opened the skill that declares it, in that conversation; a command that names a value it did not get is told to open the skill first; and a credential's value is replaced with a marker in the command's output before the agent reads it. - The Logs console now masks connection tokens and provider key shapes. The recent-logs view keeps thousands of lines of raw server output and is readable from your phone, and its masking missed several real shapes: the token in a tunnel URL or a header dump, Anthropic and OpenAI keys, Slack and GitHub tokens, and AWS secret keys. They are masked now, and ordinary log lines are left exactly as they were.
- A saved API key is shown as its last four characters only. Settings used to display a stored provider key as its first four and last four characters, which for a short key is most of the secret, and the same masked value was returned to every connected client. The mask is now a fixed
****1234- enough to tell which key is in use, not enough to recover it - and a key shorter than 16 characters shows nothing at all. Transcription keys pasted into Notes are also checked for a plausible shape before they are stored, and a rejected paste says so instead of saving something no session could use. - The desktop auto-updater is pinned to a version past its published advisory. Foxl Desktop's update client was allowed to float across a range that npm flags for a credential leak on cross-origin redirects. Foxl's update feed is public and sends no credential, so the advisory did not apply, but the component that decides what you install next now ships as one known, reviewed version rather than whatever the build machine resolved that day.
- Importing another agent's configuration can no longer overwrite your SOUL.md or plant instructions in it. The OpenClaw / Claude Code importer used to write the imported agent's personality text straight into SOUL.md - the file Foxl embodies in every conversation - replacing whatever you had written there. It now leaves an existing SOUL.md untouched and writes the import to SOUL.imported.md for you to review, quotes the imported text as a description rather than as instructions, and only reads a source folder that sits inside your home directory.
- Tool approval rules can ask or deny, and a rule about one tool now beats "auto-approve all". Settings -> Tool approval used to save every rule as "allow", and a hand-written "always ask before exec" still lost to the auto-approve switch. Each rule now carries allow, ask or deny; the more specific rule wins (a rule for
exec(rm *)beats one forexec, which beats the switch), and between equally specific rules deny beats ask beats allow. Auto-approve all works exactly as before for every tool you have not written a rule about. - A skill can no longer switch on a tool that your tool profile excludes. A skill may declare the tools it provides, and until now that declaration overrode the tool profile: connecting or disconnecting an integration such as Outlook re-registered every skill's tools and handed
execback to a run you had narrowed to theminimalprofile. The profile is the upper bound now - a skill can add a tool only where the profile already allows it,minimalstays minimal, and the server log names any tool a skill asked for that the profile refused. - The desktop's connection token no longer lands in log files or in the copied log. The local server announces the token that authorises every local API call on its own output, and both the app and the background service wrote that line into their daily log files - readable by anything running as you, unlike the token's own store - while "Copy log" put it on the clipboard. Every line that is written or copied now masks that token, and any other credential-shaped value, to its first eight characters. The app itself still receives the token exactly as before.
- A symlink inside your workspace can no longer reach files outside it. The workspace checked paths by name only, so a link placed in the workspace folder - by a command the agent ran, an unpacked skill, or a synced folder - could be followed out to the rest of your disk by every workspace action: opening, saving, searching, moving, copying and deleting, including from the phone. Every path is now resolved through the links it contains before it is allowed, using the same check Foxl Code already uses. Links that stay inside the workspace keep working.
- The relay's web framework is updated past a published denial-of-service advisory. The version it ran carried twelve published advisories, one of them a slow-path in the cross-origin preflight handling (GHSA-8j4g-w8fx-2239); the relay's own configuration did not reach that path, and the update clears all twelve.
- A Foxl Code machine you own now honours your "ask before acting" setting. The agent that runs tasks on your own box always launched the coding CLI with permissions skipped, whatever Settings said, so turning approvals on had no effect on the one machine where it matters most - the one with your home directory and your credentials on its disk. The setting is now read the same way it is for cloud tasks, and the terminal says which mode the run was launched in.
- One task on your machine can no longer leave a trap for the next. The small script that hands git its GitHub token during a push was written once, kept inside the folder the coding CLI used as its home, and reused by every task after it - so code from an untrusted repository could edit it and read the token of whatever repository ran next. Each task now gets its own freshly written script and its own home folder, both removed when the task ends.
- A different copy of Foxl can no longer silently take over the background service. With "keep running when closed" on, every launch repaired the background service's file so it kept pointing at the installed app - and any copy of Foxl you happened to open could repoint it at itself without a word. The service now stays with a copy that carries the same identity: on Windows and Linux that is the installed path, so a build you did not install is refused; on macOS it is the signing team and bundle identifier, so a genuine Foxl signed by us is still allowed while anything else is refused. A refusal is written to the log, and turning the mode off and on in Settings is how you move the service on purpose.
- Only the Flow pill can type a dictation into another app, and only the one it just captured. The paste that lands your words in the frontmost application is a synthetic Cmd/Ctrl+V, and until now any part of the app's own interface could ask for it with any text. It is now honoured only from the dictation pill, only within a few minutes of you pressing the hold key or shortcut, once per capture, and only for ordinary text - a request carrying escape or other control characters is refused rather than typed.
- Screen and system-audio capture is granted only while the Notes recorder asked for it. The desktop used to answer any request to capture the screen and system audio with a silent yes and no on-screen indication, and that answer was shared by every window the app opens - so a compromised page could have started an unseen recording. Capture is now allowed only in the moment the Notes recorder starts a recording, and is refused otherwise.
- The app opens files only from your own folders, and never launches a program. Cmd-clicking a path in a reply, or Notes' "Open file", used to hand any path straight to the operating system, which opens a document but also runs a script or an app bundle. Files now open only from your workspace, Documents, Downloads, Desktop and the Notes folders, and anything that would run rather than open - a script, an installer, an app - is refused and the refusal is written to the log. Folders still open anywhere,
~works everywhere, and "Reveal in Finder" still works for any file that exists. - The Foxl app can no longer be used as a plain Node interpreter. Until now another program on your computer could start the signed Foxl app as a bare scripting runtime and run its own code under Foxl's name - with the microphone, screen-recording and other permissions you had granted Foxl - or attach a debugger to it. The packaged app now refuses those switches, and it verifies its own bundled code before it loads it, so a tampered copy stops instead of running.
- Your desktop's own secret is kept in the system keychain, the settings file is no longer world-writable, and turning off "keep running when closed" wipes the sign-in tokens it kept. The secret that identifies this desktop to the tunnel is now sealed with your computer's keychain instead of sitting readable in a settings file, and that file is readable by your account only (it used to be writable by everyone). The background service still needs its sign-in tokens in a private file while it is on - it runs without the app and cannot use the keychain - but the moment you turn the mode off, those tokens are removed rather than left behind.
- A single relay request can no longer spend more credits than your balance holds. When a request was admitted, the relay set aside credits for a reply of at most 16,384 tokens but let the model produce up to its full 128,000-token maximum, so one long reply on a frontier model could bill about 155 credits more than had been set aside - and several requests at once multiplied that into a balance far below zero. The relay now sets aside credits for exactly the reply length it forwards to the model, shortens that length to what your balance can pay for when it is running low, and declines the request outright when even a short reply would not fit. Each plan also has a cap on how many requests it can have running at the same time (2 on Free, 8 on Pro, 32 on Ultra, 64 on Enterprise); a request over the cap gets a clear "too many requests in flight" answer and can simply be retried.
- An SVG or HTML file from your workspace can no longer run as the app. Opening one in the browser or on your phone used to offer an Open button that handed the file to a new tab under the app's own address, so a crafted file could have read your session there. An SVG now previews as a picture only, and for these files the Open button is gone: Download (Share on a phone) is the one way to take the file out. A side effect worth knowing: SVG previews now work in the desktop app too, where they used to show "This file could not be displayed".
- A link inside a Word document can no longer run code in the app. Opening a
.docxfrom your workspace or a Shared folder renders its hyperlinks into the page, and a crafted document could hide a script-running link behind ordinary link text. Links in a rendered document now open only web and email addresses, in a new tab; anything else is made inert. The same document could also carry an embedded web page (an HTML fragment pasted into the file) whose script ran the moment the document was opened, with no click at all; embedded HTML fragments are no longer rendered. - Turning on LAN access no longer switches off the desktop's protection against DNS rebinding. With
PILOT_ALLOW_LAN=1set, the check that refuses requests addressed to a name other than your own machine was skipped entirely, so a malicious web page could reach your desktop's local API by pointing its own domain at your computer. LAN mode now accepts your machine's own name and addresses - and anything you list inPILOT_ALLOWED_HOSTS, for a reverse proxy or a Tailscale name - and refuses everything else, exactly as it does with LAN off. - The optional
PILOT_API_KEYlock now covers every sensitive read. The short list of reads allowed without the key was matched by prefix, so it also covered custom-tool exports (including their API keys and shell commands), raw workspace files and previews of deleted chats. The list is exact now and those reads require the key like everything else. A second defect meant the list never actually applied over HTTP, so with a key set even the health check demanded it; the health check, the For You usage counters and the model catalog are now reachable without the key, as intended. The full Overview dashboard is not one of them: it includes the goal of the current run, so it needs the key like everything else. - Running a custom tool from the Tools page now asks first, and nothing can talk your desktop into starting a program you did not agree to. Your desktop is reachable from your phone and from the web app, so anything that could reach it could ask it to create a shell tool and run it, or to start a command of its choosing - with no prompt shown to you, on your own machine. Three things changed. Pressing Run on a shell or script tool goes through the same approval prompt the agent's own tool calls use, and if nobody answers it the command is refused rather than run. The MCP inspector takes one of your saved tools instead of a command from the request. And the first time a saved MCP tool's program is started - by saving it, by re-checking it, by the inspector, or by using it - Foxl asks you, showing the command it is about to run; you are asked once per tool and it is remembered until you change that tool's command, arguments or environment. A program Foxl does start is now given a minimal environment rather than every API key the app holds, so an MCP server that used to pick up a token, an HTTPS proxy setting or a certificate bundle from your environment will report its own error until you add what it needs in that tool's Env field.
- Your existing MCP tools need one approval each. After this update they show as needing approval instead of connecting on their own, and the agent will not see their tools until then. Open the Tools page, press the re-check button beside each one, and approve the command it shows. This is asked even if you have "auto approve all tools" switched on, because that switch is about tool calls rather than about starting programs; for the Run button on shell and script tools, that switch still applies as it always has.
- The app opens or reveals only files in your own folders, and only web links. A request to open or reveal something on your computer used to go straight to the operating system, so anything that could reach the desktop - including a phone or browser connected through the relay - could ask it to launch a program, run a script or open any kind of link. The desktop now opens a file only from your workspace, skills, Documents, Downloads or Desktop folders and never one that can execute, opens a folder from anywhere except inside an app bundle, and opens a link only when it is a normal web address. Anything else is refused and written to the log with the reason.
- A stored skill value can no longer change
PATH, the shell, or any of the other program-selecting variables listed below, for Foxl's shell commands - even when a skill asks for it. Foxl lets you store environment values for skills, and a shell command receives the ones declared by the skill it is using - which is the point. But a skill could declarePATH, an editor or a proxy in that list, and a value stored under such a name then decided whichgit,nodeorsshevery later command actually ran, or what a shell did before it started, with nothing on any screen showing it. Stored values can still add or change ordinary variables. Refused now, whatever a skill declares: the command search path and the shell itself; anything that loads code into a program before it starts (the dynamic linker, and the Node, Python, Perl, Ruby, Java, Go, Rust and OpenSSL start-up settings); shell start-up files; git's own settings, apart from author and committer identity; editor, pager, password-prompt and proxy helpers; the configuration files of npm, AWS, kubectl, Docker and the GitHub CLI; TLS trust; and the home, temporary and program folders, including their Windows equivalents. Each refusal is written to the log once, with the reason and how to remove the entry. This is a named list rather than a rule about every variable a program might read, so build and package-manager settings a skill declares (a compiler,make, a Rust or Ruby toolchain, a package registry) still reach the command. - A provider's API key is now sent only to that provider's own servers. The endpoint override in Settings > Provider accepted any web address, and your saved key for that provider followed it on every request. It now accepts only the provider's own hosts, including its regional endpoints, and says which hosts those are when it refuses. An endpoint saved earlier that is not one of those hosts is no longer used; the provider's default applies until you choose a listed host. For vLLM and LM Studio, which legitimately run anywhere, moving the endpoint to a new host forgets the key you saved for the old one - in the running app as well as on disk, so no restart is needed - and you enter the key for the new host deliberately.
- "Always allow" on a shell command now approves the command you saw, not everything that starts the same way. One click on
ls -laused to remember a prefix, so a laterls; <anything>- orlsof- ran without asking. It now remembers the exact first word as a whole word (lswith plain arguments), and if the command you approved contains a;, a pipe, a redirection,$(...)or a line break, that single call is approved and nothing is remembered. A remembered command also never covers a later call that brings its own environment variables - a changed search path or a preloaded library changes whatlsactually runs, and on Windows a variable can carry a second command - so that call asks again, even when it was already waiting behind the one you approved. - The
code_searchandbrowseragent tools no longer pass any text through a shell.code_searchused to hand the directory and file pattern it was asked to search to a shell unquoted, andbrowserdid the same with its whole command line, so a malicious web page, repository file or chat message could have made the agent run arbitrary commands on your machine - with no approval prompt, becausecode_searchwas always allowed andbrowserhad no approval rule at all. Both tools now pass their arguments directly to the program (ripgrep or grep, agent-browser) with nothing in between to interpret them,browserasks for approval the wayexecdoes, and a browser command containing shell punctuation outside quotes is refused with an explanation instead of being run. A code search of a folder that does not exist, or with an invalid pattern, now reports the error instead of answering that nothing matched. On Windows thebrowsertool is unavailable for now: it reports an error instead of running, until a follow-up starts agent-browser there without a shell. - Meeting transcripts and AI summaries on the phone are now stored encrypted. On iPhone and Android, Notes kept your recordings - the full transcript, attendee names and the AI summary - as plain text in the app's own storage, which is included in an unencrypted device backup, so anyone with that backup could read every meeting with no key. They are now encrypted on the device with a key held separately, the same way your chat history already was, and existing notes are converted automatically the first time Notes opens. Signing out removes both the notes and the key from the phone. If a device cannot unlock its saved notes - the key is missing or is not the one that sealed them - the notes list says so instead of looking empty, and Notes refuses to save over them. Nothing is deleted; new notes are not saved on that device until it is resolved, and signing out is what clears the locked notes along with the key.
- The desktop app now attaches only to a background service that proves it is Foxl's. With "keep running when closed" on, the app used to treat whatever was listening on its local port as the Foxl service, load it as the app window and send it the local connection token - so another program on the computer that grabbed the port first could take over the window and receive the credential. The service now publishes a one-time identity in its private state file and the app makes the server prove it holds it before loading anything or sending anything; a server that cannot is refused, the refusal is logged, and the startup diagnostics screen says so instead of showing the impostor. This holds against a program running as another user or inside a sandbox; a program running unsandboxed under your own account can read the same private file, and this is not a defence against that. On Windows, the background service from the previous version cannot hand over on its own, so the first start after this update ends it where it can and starts the current one; if that does not happen, the startup diagnostics screen says to press Restart server or to sign out of Windows and back in.
- A finished Foxl Code task can no longer keep spending. Each cloud task carries a short-lived credential for its model calls. It used to stay usable after the task had wrapped up and was waiting for your review - for up to two hours, up to the task's whole budget - and could still post events into the task. It now stops working the moment the task's run is settled, whichever way that run ended: waiting for review, merged, failed or cancelled. A task whose agent is still working keeps it, including one whose pull request opened before the agent had finished, and resuming or reconnecting a task gives its agent a working credential again.
- The speaker-separation models are checked against a known fingerprint before Notes uses them. Installing the on-device transcription engine downloads two model files from the internet, and until now nothing confirmed that what arrived was the file we expected: a bad network could have swapped it, including by redirecting the download to an unencrypted address. Each file is now compared to a fingerprint recorded in the app before it is saved, a mismatch stops the install with a clear message instead of keeping the file, and the download refuses to leave https at any step.
- Signing out on the phone now removes the previous account's meeting notes and audio. On iPhone and Android, Notes kept its recordings, transcripts, AI summaries and audio in the app's own storage, and signing out only cleared the web-style storage - so the next person to sign in on that phone saw the previous account's meetings, with the audio playable. Signing out (or switching accounts) now deletes them from the device - the delete is handed to the phone before the screen reloads, so it is not lost to the reload
- and the Notes screen forgets them immediately rather than at the next relaunch.
- Live chat over the desktop relay is now described accurately: it travels under TLS and the relay can read it, in both directions. The Desktop Relay and Security pages said only "a chat reply while it streams" sat outside the tunnel's payload encryption. The prompt you send and the conversation history sent along with it take the same plain HTTP path, so the pages now say so, plainly. Nothing about what is protected changed; what changed is that the documentation no longer understates what is not.
- Blocking someone now hides their messages in threads, mentions and search too, not only in the channel timeline, and it hides yours from them in the same three places.
- Renaming a shared skill or document onto a name that already exists says so (409, "a skill with that name already exists") instead of a generic server error that looked like an outage and failed the same way on retry.
- Internal hardening from the 2026-09-02 audit, no user-visible change: the auth rate limit now applies on staging (#954); the session-revoke prefix is validated before it reaches a LIKE (#953); the "Talk to us" form has its own rate-limit bucket so it cannot deny token refreshes to people behind the same address (#942);
/openai/v1/responsesenforces the same per-minute burst window as/v1/messages(#957); the storage reaper never deletes an object a live file row still references (#963) and collects a purged workspace's files on its next pass instead of a month later (#961); a void-paused Lemon Squeezy subscription no longer keeps paid access (#960); a query-string token or WebSocket ticket that a route does not accept is answered 409 rather than a 401 that would loop the client through token refresh (#948); the link-unfurl filter blocks the IPv4-translated, 6to4 and Teredo IPv6 spellings of private addresses (#966); upstream model-provider error bodies stay in the relay log instead of being echoed to the client (#956). - An issue's description can no longer smuggle instructions to the coding agent. When Foxl Code starts work on a GitHub issue - from the Solve button, when you retry a task that was started from an issue, or automatically when an issue is opened - the issue's text now reaches the agent clearly marked as untrusted input, cut off at 8 KB, and placed after any note of yours rather than before it. An issue written to look like an instruction from you is read as part of the problem to solve, not as something to do, and the same holds for the reviewer that checks the resulting pull request.
- Connecting GitHub to Foxl Code now completes only in the account that started it, and only from the browser that authorized GitHub. Before, the link that "Connect GitHub" opened carried a value naming the account that would receive the connection, and anyone who opened that link and authorized GitHub would have had their own repositories connected to the account that made the link. GitHub authorization now only produces a short-lived, single-use code, handed to the browser that completed it (or, on the phone and in the desktop app, to the Foxl app on that device), and your repositories are connected when your own signed-in session redeems that code. A code redeemed by any other account connects nothing and is discarded, and the account that made a link receives nothing from someone else authorizing it. On the phone and in the desktop app the connect finishes when the page GitHub sends you to returns you to Foxl, automatically or through its "Back to Foxl" link. Foxl apps older than this version cannot finish a GitHub connect against the updated service; that page says so and asks you to update the app first.
- Losing access to a GitHub organization now also pauses your Foxl Code schedules there, and a member Foxl had never re-checked is no longer removed on a single bad read. Foxl learns that someone has left an organization in two ways: GitHub reports the removal the moment it happens, and Foxl re-verifies membership periodically on its own in case a report was missed. Two things were wrong. On the periodic pass, a member whose membership had never been re-checked counted as verified at the dawn of time, so one incomplete answer from GitHub - which pages its member list and is eventually consistent - removed them from the installation and cancelled their running tasks immediately, with none of the grace period everyone else gets. And when a removal did happen, by either route, that person's schedules on the installation stayed switched on, so the cron kept trying to start work against a repository they no longer had access to, failing quietly every day with the schedule still showing as enabled. A never-checked member now gets the same grace window as anyone else before anything is taken away, and a removal - whether GitHub reported it or the periodic re-check found it - pauses that person's schedules on the installation in the same step and records why in the audit log.
- Your local Foxl database is now readable only by your own account. The file that holds your conversations, notes, sign-in session and connected-service credentials was created with the operating system's default permissions, which on Linux lets any other account on the same computer read it. Foxl now makes that file owner-only every time it starts, so an existing install is fixed the first time this version runs. The data folders Foxl creates on a new install are private to you as well; folders that are already on disk are left exactly as they are.
Fixes
- Typing into a cloud terminal could stop working permanently, on every assistant. If you typed anything in the first two minutes of a Remote pane - which is exactly when a machine is still cold-starting and cloning your repository - that keystroke was held for delivery, correctly. What was wrong is everything after it: from that moment the pane could only ever answer "The machine is still starting", for as long as it stayed open. It could not tell you the machine had gone to sleep, it could not show you Reconnect, and it could not report an error, so a terminal that had genuinely stopped looked identical to one that was about to answer. Held typing is now delivered as soon as the assistant is ready even if you never touch the keyboard again, and once the startup window closes a machine that really is not there says so and offers Reconnect.
- Opening a long conversation on the phone is fast again. v0.6.27 encrypted the desktop tunnel's payloads, and that quietly made every large response far more expensive to download - a long chat could take several seconds to appear over cellular where it used to be immediate. The cause is that our relay's responses are compressed in transit, and encrypted data cannot be compressed, so switching encryption on did not cost a little overhead: it threw away the compression entirely. The tunnel now compresses your data *before* it encrypts it, which puts the download back where it was and keeps the relay unable to read the encrypted payloads. Measured on one real 1521 KB conversation: 1536 KB of download became 224 KB, so loading it goes from 1.9s to 0.6s on average LTE and from 4.6s to 1.0s on a weak connection. Nothing to turn on, and it applies to the whole tunnel - opening a chat, browsing files, the terminal - on the phone, in the browser and in the desktop app.
- Sending something large from the phone or the browser to your desktop no longer fails silently. The same v0.6.27 change could not encrypt a payload past a certain size and gave up without reporting anything, so a big enough request - saving a long note, writing a sizeable file - simply never arrived. Fixed, with the size limit removed entirely.
- A recording that could not be transcribed now says so, instead of running to the end with an empty transcript. Amazon Transcribe accepts a connection on the shape of its signature and only checks the credential when audio starts flowing, so a lapsed AWS session produced a live microphone, a "Recording" label, and silence - the service's own explanation was written to a developer console, which a phone and a packaged app do not have. The reason is now shown as it arrives, in Amazon's own words, and the recording stands down instead of running to the end and leaving you with a blank note. The same applies to a drained or rate-limited ElevenLabs key. One thing to know: a recording that stops this way does not keep its audio. That is unchanged from before rather than new, and it is being fixed separately.
- Foxl Notes on your computer refuses to sign a transcription socket with expired AWS credentials, rather than opening one that will be rejected. Failing at the start is what lets a phone fall back to the Foxl relay and keep recording; it also means the message you get names the thing to fix (renew the session) instead of describing a transcription outage.
- The Foxl Relay transcription engine appears again for the accounts that may use it. The option was hidden from everybody, including allowlisted accounts, because the app was reading the permission from a place nothing had written to since Notes was merged into the main app.
- On-device transcription is no longer offered on iPhone, iPad, Android or the web app. It runs the speech engine on an Apple Silicon Mac, so it could never work from those surfaces - the row was greyed out with no explanation, and could even appear selectable while a Mac of yours was awake, in which case picking it quietly did something else. Settings now says where it runs. If a Mac of yours has it selected, that choice is untouched.
Features
- Claude Fable 5.1 is in the Amazon Bedrock model list. If you have connected your own AWS account under Settings, Model & provider, it is now one of the models you can pick there. It is the same class as Fable 5 at the same price per token, with cache reads costing a quarter of what they did - which is most of the bill on long agent runs that re-read the same context. Verified against Bedrock in both US regions before shipping, so it works with no region setting of yours to change. It runs on your AWS bill, not on Foxl credits, so it does not appear on the phone, on the web app, or anywhere a Foxl plan pays for the model.
- Settings, Model & provider now has real controls for a bring-your-own-key provider - five of them, and they apply to all nineteen. Until now the only thing you could set for OpenRouter, DeepSeek, Groq, Z.ai, a local vLLM and the rest was the API key, which left several things unreachable from the app entirely:
- Maximum reply length. Some providers - OpenRouter among them - reserve this whole amount against your balance *before* answering and refuse the request outright when the balance cannot cover it. If you have seen "requires more credits, or fewer max_tokens", this is the setting that fixes it; raise it instead when you want a long report in one turn.
- Endpoint. For a regional host or a local server on a different port. The desktop has been able to do this for a while and there was nowhere to type it.
- Only free models. OpenRouter serves 425 models of which 18 cost nothing. One switch offers just those, everywhere - the model picker, a scheduled run, a per-surface pin - so a key with no credit on it can still be used for real work.
- Which upstream to prefer. A reseller serves one model through several operators; you can now ask for the cheapest, the fastest, or the quickest to start, and separately refuse operators that would ignore what Foxl sent or that train on your data. The section says plainly which of these can leave a model with nowhere to run.
- What the key has spent. One button asks the provider and shows the total, today's figure and whatever allowance is left, so a refusal for lack of credit is something you can see coming rather than discover mid-sentence. Which controls appear is the provider's own answer, not a list inside Foxl - so a provider that has no free tier simply shows no free-models switch.
- Most remote access is now encrypted between your own two ends, so the relay carries ciphertext it has no key for. When you reach your desktop from a browser or your phone, the two ends agree on a key directly and the relay in between only passes the bytes along. This covers terminal output and what you type into a terminal, the responses to every request your app makes to your desktop - file contents, workspace listings, settings, tool output - and the addresses of those requests too, so the relay no longer learns which endpoints you touched. Each connected client gets its own key, so one browser tab cannot read another's traffic. Nothing to turn on, and an older phone or desktop keeps working exactly as before until it updates. Three things are not covered yet and the docs list them rather than rounding them off: a chat reply while it is streaming, a file preview's raw bytes, and a notification's title and body - that last one because the relay is what builds the push your phone shows on its lock screen, so it has to read the text.
- Your desktop now has a safety number. It is a short code derived from a key your desktop keeps. Your browser remembers it the first time it connects and refuses the encrypted session if it ever changes. If you reinstall the desktop app the code changes.
- On-device transcription tells speakers apart now. When you record with "On device", Foxl Notes labels who said what - Speaker 1, Speaker 2 - the same way the Amazon path does, and the audio is still processed on your Mac. This was listed as the thing the on-device option could not do when it shipped; the obstacle turned out to be packaging rather than capability, so it runs two small extra models (about 33 MB, downloaded by the same Install engine button, no account needed) beside the speech model. Measured on conversations with known speakers: the right number of people on all fourteen test recordings, and 99% of the transcript attributed to the right person - 93% in the hardest case, two men with similar voices talking over each other with no pause between turns. Two things worth knowing: when two voices are genuinely very close it will treat them as one person rather than split one person in two, which is the safer mistake for a meeting record; and the labels are Speaker 1..n, which you can rename in the transcript. If you already installed the engine, Settings will offer Install engine once more to add the speaker models - transcription keeps working in the meantime, just without labels.
Changes
- The "Foxl Relay" transcription engine in Notes is now limited to specific accounts. That engine streams audio to Amazon Transcribe on Foxl's own AWS account, and Foxl runs as a free project funded out of pocket - so it is no longer offered to everyone. The option is hidden in Notes settings for accounts that do not have it, and the other destinations are unchanged: Amazon Transcribe with your own AWS account (the default), on-device transcription on Apple Silicon, and Deepgram / AssemblyAI / OpenAI / ElevenLabs with your own key. If your recording provider was already set to Foxl Relay, Settings now says so and asks you to pick one of those instead.
Fixes
- The desktop app opens. The first build of this version did not: it stopped at launch with
Cannot find module './tunnel-sessions.js'and showed an error dialog instead of a window, on macOS, Windows and Linux alike. One file that the tunnel needs was left out of the packaged app, so nothing but a reinstall could get past it. If you already installed the version that failed, download it again from the same place - an app that cannot start also cannot update itself. - Chat works again on OpenRouter - and on the eighteen other bring-your-own-key vendors that share its plumbing. Picking one of them and sending a message answered a bare
HTTP 500with nothing else on screen. The provider had been selected correctly a second earlier; the send itself was what failed, because the chat request re-applies the provider from the message and those vendors are not stored under their own name internally, so the re-apply refused an id it had just written. Every one of them was affected the same way: DeepSeek, Groq, Z.ai, Kimi, Qwen, Together, Mistral, Fireworks, Perplexity, xAI, Cerebras, SambaNova, AI21, Hugging Face, MiniMax, and a local vLLM or LM Studio server. - The model picker no longer shows a second, unusable OpenAI entry once you add a key for a different vendor. Adding an OpenRouter key made OpenAI's own models appear as their own section, looking exactly like the real thing - and choosing one sent an OpenAI model name to OpenRouter, which does not have it. OpenAI is listed when you have an OpenAI key, and not otherwise.
- A turn on one of those vendors no longer asks for the model's entire output budget. Foxl requested up to 128,000 output tokens for a chat reply, which OpenRouter reserves against your balance up front and refuses outright when the balance cannot cover it (
This request requires more credits, or fewer max_tokens). The number was not even the right model's: it was matched by name against a different provider's catalog, soz-ai/glm-5.2inherited the ceiling of a model on AWS. A turn now asks for a sensible amount, and never more than the vendor says that particular model allows. - Switching from one of those vendors back to a direct provider no longer leaves the previous vendor's endpoint in place. Changing the model from the composer alone could leave the next request pointed at the vendor you had just switched away from, carrying that vendor's key.
- Closed a hole that let any other program on your computer use Foxl's local API without its access token. The desktop app runs a server on your machine for the web and phone apps to reach through the relay, and a secret token is what stops anything else on the same computer from talking to it. That check was skipped when the address was written in capitals, so a request to
/API/...instead of/api/...was answered as if it had the token - which covers the terminal, the tool runner and the list of provider keys. It now checks the address the same way the server routes it, in every letter case, and the token comparison no longer leaks timing information. Nothing about how you use the app changes. - The iPhone and Android apps now refuse a sign-in callback they did not ask for. Foxl opens sign-in in the system browser and comes back through a
foxl://link, and that link could be opened by any web page you visited - so a page could hand the app someone else's session and quietly replace yours, sending the notes, chats and files you made afterwards to their account instead. The app now mints a one-time value before it sends you out to sign in and requires it back on the way in, which is the same check the Mac and Windows apps have always done. Sign-in itself is unchanged: the value survives the phone closing the app while the browser is open, so a normal sign-in still completes when you come back. - A Foxl Code terminal in the sidebar now says which agent is in it, and shows where it runs as an icon. A locally-run agent's row read "This computer" and nothing else, so the one thing worth knowing - that it is a Kiro CLI, or a Claude Code - was the one thing missing, while a cloud row spent its text on "... on Remote". Every row leads with the mark of the agent actually running in it (a local pane resolves that against the CLIs installed on your machine, so "account default" shows what really launched), the label names that agent, and a cloud / laptop / server glyph at the end of the row says where it is. Interactive terminal sessions on the Tasks page are named the same way.
- The floating meeting panel's assistant can answer questions about you again. Ask it "who am I?" and it used to say the transcript does not identify you - true of the transcript, and beside the point on a computer where Foxl Agent already holds your profile, your notes and your past conversations. The panel's ask bar now runs on exactly the same engine the in-window Notes assistant does: your USER.md profile, whatever Settings > Tools has switched on, your custom tools and MCP servers, and a search over earlier meetings and chats. It says which tool it is using while it looks, and lists what it used underneath the answer. Questions asked in the floating panel and in the main window now land on one thread, so each can recall the other. One switch governs both (Notes settings > "Use Foxl Agent tools"); with it off, both go back to reasoning about the transcript alone.
- The Notes assistant now really is the same agent as Foxl Agent, not a lookalike. It was assembled separately from the same parts, which is close enough to look identical and was not: a Notes question got no thinking budget, no prompt caching, none of the automatic model fallback you configured, no retry when the model was briefly overloaded, and a weaker safeguard against a long meeting overflowing the model's context. On a Claude Pro or Max subscription it also sent the wrong tool format, which is the thing that burns subscription quota. All of it now comes from the one place the chat agent is built, so asking Notes "who am I?", "what did I decide about this last month?" or "what does my CV say?" works exactly as it does in chat - your profile, your saved memory, your past meetings and chats, your files. The assistant's own instructions stay short; only the machinery under them changed.
- "Use Foxl Agent tools" in Notes settings no longer shows OFF when it is on. The switch is on by default and always was, but it drew itself as off whenever the AI destination looked unavailable, while every request still sent it as on - so the one place you would check said the opposite of what was happening.
- Turning notifications on in iOS Settings now actually works. If you declined the notification prompt and later switched notifications on for Foxl in the Settings app, the phone never registered for them - so nothing arrived, indefinitely, and Foxl's own Notifications screen still said they were off. Only fully quitting and reopening the app fixed it. Foxl now re-checks when you come back to it. It will not ask you again on its own; coming back from Settings is not a moment you asked to be interrupted.
- The app icon's unread count no longer resets itself when you open Foxl. Opening the app reported "nothing unread" before it had finished reading what had arrived while it was closed, which threw away the real count - so the next notification showed 1 on the icon instead of the number you actually had waiting. Foxl now asks what it is still owed before saying anything, and the count keeps counting.
- A cloud terminal in Foxl Code no longer swallows what you type while its machine is starting. Opening a Remote terminal on Kiro CLI or Claude Code and typing straight away lost the typing: the pane said the machine was still starting and would answer as soon as its terminal was up, and then the terminal came up empty. Codex was unaffected, which is why this read as those two assistants being broken rather than as a typing problem - Codex simply reaches its prompt in about six seconds where the other two take about twenty, and everything typed inside that gap went nowhere. Your keystrokes are now held on the server and delivered, in order, the moment the assistant is actually ready to read them. They survive closing the pane, opening another pane beside it, reloading the page and closing the tab - all four of which used to throw the typing away.
- A cloud terminal that had gone to sleep can be reconnected from the Runtimes screen. It told you to reconnect and offered no way to do it, so a pane left open for more than about fifteen minutes could only be closed - which threw away the checkout the agent had been working in. There is a Reconnect control now, and it resumes on the same workspace.
- A terminal that was wrongly reported as asleep recovers by itself. Once the pane decided a session was gone it never changed its mind, so a single bad answer left a recovery card sitting over an agent that was working fine until the pane was closed and reopened. It now clears as soon as the agent proves otherwise.
- Foxl Code's Work screen ran off the side of the phone, and took the whole page with it. Its five tabs - Needs you, Backlog, Working, Done, Activity - were laid out in a row that could neither shrink nor scroll, so on a 390-point screen the row was 516 points wide and the entire page scrolled sideways: every card below it moved too, and Done and Activity sat off-screen with no way to reach them. The two longest labels also wrapped onto a second line inside a row too short to show it, so "Needs you" was clipped in half. The tabs now scroll sideways on their own, with a soft edge on the right showing there is more to swipe to, and each one is a noticeably bigger target for a thumb. Nothing about the row changes on a desktop.
- The on-device transcription panel no longer appears on machines that cannot run it. It needs an Apple Silicon Mac, and your Notes settings are shared across your devices - so if you chose "On device" on a Mac and then opened Settings on Windows, Linux or your phone, you saw the whole panel: an Install button that could not work and a status line about a Mac you were not looking at. Those machines now see one line saying what it needs, and the greyed-out "On device" option in the picker says why it is greyed out instead of leaving you to guess. Nothing about recording changes; a machine that cannot run it already fell back to the other transcription options.
- On-device transcription in Foxl Notes is about four times faster, and the live line no longer falls behind the conversation. It shipped pointing at the speech model's unquantized build, and the cost of that turned out to be almost entirely in generating the text rather than in listening to the audio: measured on an M5, a 19 second stretch of speech took 4.1 seconds to transcribe, and because the greyed-out live line re-transcribes the whole sentence each time it updates, the finished text arrived up to 4.3 seconds after the speaker had stopped and the live line's updates stretched further and further apart. On the 8-bit build the same clip takes 0.9 seconds, the worst delay drops to 0.42 seconds, and the live line keeps a steady cadence. The transcribed text is unchanged: on clean audio and with noise added, in English and in Korean, the two builds produced character-for-character the same output. The engine also loads twice as fast when you press record, and the one-off download is now about 1.3 GB instead of 2 GB. If you already installed the engine, Settings will offer the install button once more to fetch the smaller model.
Features
- Foxl Notes can transcribe entirely on your Mac, with no audio uploaded. Recording and transcription in Settings has a third option, "On device", which runs speech recognition on your own Apple Silicon GPU instead of sending the meeting to Amazon. The audio is not uploaded or metered, and it keeps working with the network off - so a confidential conversation, an interview, or a meeting on a machine with no internet access can still be recorded and read back. It needs a one-off download of about two gigabytes, which you start from that same Settings row and can watch progress for; it lives outside the app, so a Foxl update does not fetch it again. Two things it does NOT do yet, and the setting says both before you pick it: it does not tell speakers apart, so a group meeting is transcribed as one person, and it does not translate the other party live. The AI summary still uses your Foxl account. Choose Amazon Transcribe when you need speaker labels; choose this when you need the audio to stay put.
- The Notes transcript and AI assistant now share one panel on the right, and it can be resized. They used to dock in two different places - the transcript as a fixed narrow column, the AI assistant stacked underneath the editor - so opening both left the notes themselves squeezed from two sides at once, and neither panel could be made any wider. They are tabs in one panel now, the notes surface keeps its full height, and you can drag the panel's edge to whatever width suits the screen. Foxl remembers it. The transcript also gained a talk-time bar at the top when more than one speaker is present, showing how long each of them has held the floor.
Fixes
- Recording on your iPhone with Amazon Transcribe produced no transcript at all, and nothing said why. Notes on a phone signs its own connection to Amazon using a one-hour, transcribe-only pass your computer hands it, so a long meeting keeps going even if the computer goes to sleep. That pass allowed the wrong one of Amazon's two streaming permissions - the connection was accepted, audio streamed for the whole meeting, and Amazon quietly refused to transcribe any of it. It could only ever affect the phone and the web app, which is why the same setting worked on a Mac, and it looked like a broken microphone rather than a permission: recording ran normally to the end and saved an empty transcript. Switching to Foxl Relay was the only way through. Fixed, and the transcription probe now streams real speech through that pass with a control that fails the old way on purpose, so a handshake can never again be mistaken for a working connection.
- A cloud terminal whose agent is still running is no longer told it went to sleep. Foxl asks the machine for the terminal's current screen, and if that one request came back empty it concluded the session had been reaped - showing "This session went to sleep" over an agent that was working, with a Reconnect button that in one pane is not even on screen. It had a grace period for the half-minute a machine takes to start, but the grace was measured from when the task began, so once it ran out the verdict could never change back: a single hiccup twenty minutes in read as gone for as long as the terminal stayed open. Foxl now also asks whether the machine's own output stream is still connected, which stays true for a terminal that is simply idle and waiting, so a momentary failure to read the screen recovers by itself instead of ending the session on screen.
- A speaker you renamed in a Notes transcript gets their own colour again. The colours were keyed on the automatic "Speaker 1", "Speaker 2" labels, so the moment you renamed someone - which is the point of being able to rename them - they and everyone else fell back to the same grey. Any name now gets a stable colour of its own, and the automatic labels keep the colours they always had.
Features
- Your agent can fall back to another model when the one you picked is unavailable, so an overnight run stops dying at a rate limit. A provider that answers "too many requests", "overloaded" or is simply having an outage used to end the run there. Foxl already retried, but retrying asks the *same* model again, which cannot help when that model is the thing that is unavailable - and the runs this hurts most are the ones with nobody watching: a 3am schedule, a Slack mention, something you started from your phone. Settings, Provider now has Automatic fallback: switch it on and list the models to try instead, in order. It only engages after the retries are exhausted, so a healthy primary is always used first and nothing changes for an ordinary turn. The list is drawn from every provider you have set up, not just the current one - which is the point, because when a vendor is down its other models are down too. Off unless you turn it on, since falling back changes which vendor sees the conversation and what the turn costs.
Fixes
- Bringing your own Anthropic API key is much cheaper now. Foxl asks the model to cache the unchanging front of each request - the system prompt and the tool definitions - so the next turn is billed for reading it rather than sending it again. That has always been on for Anthropic models served through AWS Bedrock and through foxl.ai, but the path that uses your own Anthropic key had no way to switch it on until the agent library added one. So every turn re-paid full price for roughly ten thousand tokens of preamble it had already sent. A cached read costs a tenth of that.
- The token and cost figures in the status HUD were wrong on GPT-5.x and Grok, and they are right now - including on the chats you have already had. Providers do not agree about what an "input token" is: Bedrock's Claude models report the cached part of a prompt separately from the input count, while GPT-5.x, Grok and ChatGPT report a single input count that ALREADY contains the cached part. Foxl added them up the same way for both, so on the second family it counted every cached token twice and then billed it at the full input price on top of the cache price. Measured against a real call: $4.21 charged where the truth was $0.38. What you saw was a context bar reading more than 100% of a window the request had comfortably fitted inside (
1.5M / 1.0M) and a cost that could be nine times too high. Both are computed once now, from figures that mean the same thing whichever model answered, and Foxl repairs the history it already stored the first time you open this version - on the machine this was found on that returned 421.7 million phantom tokens and about $2,100 of cost that was never spent. - A chat's usage now includes the subagents it spawned, while its context bar keeps showing only the chat's own fill. That pair is the point of delegating: the work moves off your context window, and until now the window was the only half you could see, because a subagent's tokens were filed under an internal id that no chat ever read. So a fan-out that burned hundreds of thousands of tokens showed up nowhere at all. The HUD's "This chat" panel gains a Delegated line naming those tokens and how many subagents produced them, and the context bar is unchanged by them on purpose - a subagent's prompt is not what is sitting in your window.
- A language that got stuck on an older build now unsticks itself - you no longer have to go and choose Auto detect by hand. v0.6.24 stopped Foxl Code from freezing your language, but it could only stop it happening again: the frozen value was already saved on your device, and an update cannot tell it apart from a language you picked on purpose. So an iPhone switched to English in iOS Settings kept showing Foxl in Korean, with Foxl's own Language row reading 한국어 instead of 자동 감지. This release clears a saved language that nothing recorded you choosing, once, and from now on every choice made in Settings is recorded as yours and is never touched again. If you DID pick a language by hand before this release, Foxl goes back to following your system once and you can pick it again in Settings, General - there is no way to tell the two apart after the fact, and following the system is the setting almost everyone wants. Nothing else about the picker changes.
- Closing a Foxl Code terminal you opened now stops the agent in it. Press Cmd+T on Runtimes and you get a terminal on a cloud machine; until now pressing its X only took the pane off your screen, so the machine kept running and billing with nothing attached to it, and the run stayed in your task list as a live
Terminal - ...row you had to go and stop by hand. Closing one of those cancels it, and the agent still commits and pushes whatever is in the tree on its way out. The X says so before you press it, in the pane and in the sidebar's list of open terminals. A run you are only watching is untouched. Panes opened from "Watch a run", and the one Runtimes opens for you when you arrive, are windows onto a job that was dispatched somewhere else, so closing them keeps saying (and doing) what it always did: the agent keeps running and reopening reattaches. - A Foxl Code terminal on Remote running Codex no longer opens on a question and then ignores you. Codex asks "Do you trust the contents of this directory?" the first time it runs somewhere new, and in the cloud there was nobody to answer it: the pane drew the question, every key you typed went nowhere, and the only clue was a machine that looked like it had started and gone quiet. Foxl now marks the task's own checkout as trusted before Codex starts, exactly as it already did for Codex on your own computer, so the terminal opens straight into its composer.
- Foxl Code tasks that run on Remote no longer stop partway through with nothing to show. Any task that took longer than about fifteen minutes was being shut down mid-work by the cloud runtime, because Foxl was reporting the machine as idle the whole time it was working. Nothing reached you when it happened: the task sat on "running", its terminal stayed empty, and hours later it was quietly marked cancelled. Foxl now tells the runtime it is busy for as long as the agent is actually working, so a task runs to its finish - it writes the code, runs the tests, pushes the branch and opens the pull request - or stops at the time limit you set in Settings and says so. Short tasks were the only ones that ever completed before; they are unaffected.
Features
- On iPhone and iPad, Foxl's language now has its own row in the iOS Settings app, and it follows your system language unless you say otherwise. Settings, Apps, Foxl, Language lists all ten languages Foxl speaks, with the system one marked Default. That is where iOS puts a per-app language and where people look for it first, and until now the row was not there at all, because Foxl had never told iOS which languages it speaks. Nothing changes unless you use it: the picker in Foxl's own Settings still works the same way, and left on Auto detect it follows whatever you choose in iOS.
- Foxl Notes suggests what to say next, in the language the meeting is being held in. Turn on Live reply suggestions (the meeting panel's Options menu, or Settings, Notes) and every time the other person finishes talking a card appears with a line you could actually say: what it does in a few words, the sentence itself, and the same sentence in your own language underneath so a glance is enough. The four buttons under the stack ask for a different angle on the same moment - agree, push back, ask, suggest - and each one adds a card rather than replacing the one you were reading. Nothing disappears on a timer. The cards stack up with the time they arrived, so a suggestion that landed while you were listening is still there when you look up, and you can scroll back to one from earlier in the call. Tap the copy button on a card to put the line on your clipboard. It costs one AI request per turn of the other person, so it starts switched off.
- The suggestion cards have their own text size, and their own window. Card text is a separate slider from the caption size, because a caption is scanned continuously and a card is read in one glance - one slider for both made whichever you did not set it for the wrong size. And "Own window" pops the stack out of the meeting panel into its own floating always-on-top window, so the transcript and the suggestions can sit side by side instead of taking turns behind a tab. It carries the size slider, an always-on-top pin and a clear button, and it keeps mirroring the cards while it is closed, so reopening it is instant and current.
- Foxl Notes transcribes with your own Deepgram, AssemblyAI, OpenAI or ElevenLabs key, not just Amazon Transcribe. Recording had two destinations and both of them were Amazon: the Foxl relay's gateway on Foxl credits, and Amazon Transcribe on your own AWS account. That is a fine default and a bad ceiling - Amazon needs an AWS account and a region before it transcribes a word, and if you already pay Deepgram or OpenAI for speech recognition there was nowhere to say so. Settings, Recording and transcription now lists four more providers alongside the two that were there; pick one, paste its API key, and recordings, imported audio files and Dictate anywhere all go there instead. Your provider bills you directly and no Foxl credit is involved. The key is stored encrypted on your computer and is not sent to Foxl's servers. It is also never handed to the browser: your desktop opens the connection to the provider itself and passes the audio through, which is what the vendors' own documentation asks for - they all say not to put an API key in client-side code. Two consequences worth knowing before you switch. This needs the Foxl desktop app, so on the phone and on app.foxl.ai a recording still runs on Foxl credits (nothing breaks - it falls back on its own and starts recording). And AssemblyAI and OpenAI do not label speakers while streaming, so with either of those the whole transcript is attributed to one speaker; Settings says so under the provider you chose, while Amazon, Deepgram and ElevenLabs all separate voices.
Fixes
- Opening Foxl Code once stopped Foxl from following your system language. The language setting starts on Auto detect, which means "use the system language, and keep using it if I change it later". Visiting Foxl Code quietly froze it to whichever language had been detected at that moment, so changing the language on your phone or your computer afterwards did nothing. If yours is stuck, open Settings, General and choose Auto detect once.
- A Kiro pane no longer stops on a question you cannot get past. Kiro's newer engine asks two things the first time it runs - whether to convert your saved agent configs to its 3.0 format, and whether you really meant to let it use every tool - and it asks the first one before anything else appears. Neither is answered by the flags Foxl passes, so a pane opened Kiro, drew one menu, and sat there: measured at 255 bytes of output in 22 seconds, with the composer never arriving. Foxl now answers both before it launches, and the pane comes up ready to type in about 3 seconds. The configs answer is "not now", so nothing of yours is rewritten - Kiro's own note says a 2.0 config keeps working - and an answer you have already given by hand is left exactly as it is. Cloud Kiro terminals had the same gap and get the same fix.
One thing this does not change: after the pane opens, Kiro spends a while on
Initializingwhile it starts the MCP servers you have configured. That is Kiro's own startup, and how long it takes depends on your servers - on one machine here the slowest took 31 seconds by itself, which is most of the wait. You can type during it; the message is queued. - A cloud Kiro terminal comes up ready to type at, instead of saying "Initializing" forever. Opening a Kiro CLI runtime in Foxl Code drew the welcome screen, printed one line of error text that scrolled away under it, and then sat on
Initializingfor the whole session - so the one thing you could not do with a terminal was type into it. Kiro's new engine claims its session by making a hard link, and the cloud disk your workspace lives on is the one kind of disk that does not support hard links, so the claim could never succeed and start-up never finished. Kiro now keeps its own session files on the machine's local disk, where that works, and comes up at its prompt. Your checkout stays where it was, so nothing about the 14-day workspace changes; Kiro's own chat scrollback no longer survives the machine being recycled, which nothing could read back anyway. Tasks you DISPATCH to Kiro were never affected - they run its older engine, which is why this only ever broke the terminal. - A Kiro task no longer claims to be running a Claude model, or sets aside your Foxl credit to pay for one. Kiro runs on your own Kiro account, and Foxl never tells it which model to use - but it was still recording Claude Opus against the task, so the Runtimes header and the terminal both printed
claude-opus-5under the Kiro mark, and the task reserved credit priced for Opus tokens that Foxl never pays for. On a low balance that reservation could refuse the task outright. A Kiro task is now recorded the same way a Cursor one already was - the vendor picks the model - so it shows no model, reserves only what the machine costs, and is no longer measured against the Claude model list. Nothing about which model Kiro actually uses changes. - Foxl Notes AI works on your own provider key again. If your model came from one of the nineteen OpenAI-compatible providers - OpenRouter, DeepSeek, Groq, Z.ai, Together, Mistral, xAI and the rest - every Notes AI feature refused with "OpenAI API key not configured", while the same model answered perfectly in Agent chat. Notes was asking a part of Foxl that only ever looked for an OpenAI key, so it could not see the provider you had actually chosen. Summaries, auto-titles, coaching reports, the HUD ask and live translation all run on your selected model now. Two things worth knowing if you were hit by this: with an OpenAI key ALSO saved, the refusal became a request to OpenAI carrying the other provider's model name, so if you saw a puzzling OpenAI charge or a 401 from OpenAI while using a different provider, that was this; and a key you paste into Settings now takes effect immediately instead of at the next restart.
- The model picker shows every model your provider actually serves. Foxl shipped a short hand-picked list per provider, and for a reseller like OpenRouter that list was six models out of the 387 it serves - so most of the catalogue was unreachable, and the free models were not offered at all, which left anyone on a free key unable to select a model their key could pay for. Foxl now asks each provider you have configured for its own catalogue and shows the lot, keeping the hand-picked entries and their proper names at the front. Nothing is asked of a provider you have not set up, and a default install is unaffected. This also fixes a related limit: the largest real catalogue was over the size Foxl was willing to read, so it came back empty and looked like a provider serving nothing.
- A Foxl Code cloud terminal now accepts what you type while its machine is still starting - including everything you type after that. A cloud terminal opens straight away and its machine takes about half a minute to come up behind it, so a key pressed in that window cannot be delivered yet. Foxl held that key and retried, which is right, but it held it in the same queue every later keystroke waits in - so the first key typed during the start-up blocked every key pressed after it, for as long as it kept retrying. The terminal looked completely alive the whole time, because output arrives by a different route than typing does. The worst version of this was an agent that opens by asking a question: it drew "Do you trust the contents of this directory?", and then the arrow keys that answer it, and 1, and Enter, all did nothing - a question on screen that could not be answered, on the one surface whose whole job is to accept typing. Keys typed during a start-up are now held together, in the order you typed them, and go out the moment the machine answers.
Features
- Foxl Code keeps your Claude and ChatGPT logins topped up from your computer, so a cloud task stops being refused for a subscription you are signed in to. A cloud coding task runs on your own subscription, and the copy Foxl Code holds is a snapshot of the login sitting on your machine. Foxl Code could renew that snapshot on its own, but only until the next time you used
claudeorcodexyourself, because the vendors hand out a replacement token each time and only one side can hold the current one. From then on the cloud copy was dead, and the next task ended with "your Claude credential has expired and could not be refreshed. Open Foxl Code Settings, Agent credentials, and sync it again from Foxl Desktop" - a chore, raised on a machine that was holding a working login the whole time. Now your computer hands a fresh one over shortly before the cloud copy would run out, on its own. There is a switch for it beside the Sync button in Settings, Agent credentials, and it is on unless you turn it off. It sends only what has gone stale, it never sends anything while the switch is off, and it is absent on code.foxl.ai, which has no computer of yours behind it.
Changes
- Runtimes sits directly under Tasks in the Foxl Code sidebar. The two are the halves of one loop - say what you want, watch it happen - so they are still adjacent with no gap between them; Tasks now leads it.
- Foxl Code's review pane takes comments on a line of the diff, and sends them back to the agent. Click a line number, say what should change, and the footer offers Request changes. Each comment travels with its file, its line and the line itself, so the agent arrives at the right place instead of working it out from prose, and it addresses the feedback on the same branch it already pushed to. Until now the pane could read a diff and merge it: asking for one change meant opening github.com, which is the trip this pane exists to remove. An optional note carries anything about the pull request as a whole. If a pull request has no agent behind it the comments are still posted on GitHub, and it says that rather than claiming something was restarted.
- "needs you" on the Foxl Code home is a link now. The summary line under the greeting reads
2 needs you - 3 working - 97 done, and the first item was the one number you have to act on with no way to act on it - you had to find the Work page yourself. It opens Work underlined on hover, in the same colour it always was, and it stays a link at zero so the control does not appear and disappear as the count moves. - Foxl Code settings now say which subscription unlocks which coding assistant. Agent credentials lists all six assistants with what each one can actually run on - a Claude Pro/Max plan, a ChatGPT Plus/Pro plan, an Anthropic API key, or that vendor's own key - and whether your account is ready for it. The answer used to be spread over three paragraphs in different places, so the commonest wrong conclusion was that one subscription covers all six.
- The coding-agent picker in the Tasks and Terminals headers can open that screen. A row reading "needs your credential" now has somewhere to go: "Subscriptions and keys" takes you straight to the fields. The Terminals menu's old closing line, which named Settings without being able to reach it, is gone.
- The Foxl Code Tasks header is one control now, the same one the Terminals header has:
+ | Remote | Claude Code. It used to be four separate chips saying one sentence with the words scattered - a machine pill, the repo picker, an agent pill and a labelled New-task button. Read left to right it now says what it does: start a task, on that machine, running that agent. The+lost its "New task" label to buy the width back; hovering it still says so.
Fixes
- A Kiro terminal in the cloud no longer opens on a question you cannot answer. Kiro asks you to confirm trust-all-tools mode the first time it runs, with a three-way choice you pick using the arrow keys - and in a cloud terminal that question arrived while the machine was still coming up, so there was nothing to press and the agent never got past it. Every other assistant already had its first-run prompts answered ahead of time; Kiro's one equivalent had been missed, so it happened on every new session. It is answered up front now, and if you had already set the preference yourself, that and the rest of your Kiro settings are kept.
- Typing into a cloud terminal while its machine boots is no longer thrown away. The pane said "The machine is still starting, so that did not reach the agent yet. It will answer as soon as its terminal is up", which was true about the first part and not the second: the keystrokes were dropped, so the terminal came up blank and the only way to find out was to type it again. What you type during the roughly thirty seconds of startup is now held and delivered, in the order you typed it, as soon as the machine answers. A machine that never arrives still stops waiting and offers Reconnect.
- A Foxl Code task that runs on your own computer opens like any other task. With "run coding tasks on this computer" switched on, pressing New task started the agent correctly and then handed you a dead screen:
The live event stream dropped: Error: stream 404. The task existed only on your machine, and every part of the task page was asking the cloud about it. It now has its own page - the live terminal you can type into, the status, the branch, a Stop button, and the pull request link when one lands. - The right-hand rail no longer shows an error about a task that is running fine. It asked the cloud about every selected task, including one running on your own computer, and turned the resulting "no such task" into a red line beside a healthy run.
- A task in the "On this computer" list is pressable while it is still running. A finished one linked to its pull request and a running one did nothing at all, which meant the agent's output had no door: it is the only place that output exists. Every row opens its task now, and the pull request moved into that task's header.
- When Foxl Code cannot reach a backend, the terminal says so and names the fix. It used to report the bare
stream 404, which named neither the host it tried nor anything to change, while every other request on the same screen explained it in full. - Foxl Desktop no longer sends a cloud coding task to the wrong service. On a setup pointed at a relay it cannot map to a Foxl Code host, it asked the relay to start the task and reported the resulting error as a problem with your repository. It now says which setting is missing and starts nothing.
- Files shows your files again - and for the first time, the files a task actually changed. The page had two private sources and could not read either. It picked between them using a setting that describes the CONTAINER's disk, which is the same value for every account, so it only ever asked the one source that was empty - and that source was pointed at a workspace nothing had ever run in, so it was empty by construction too. Measured on the live bucket: a 1003-file checkout was sitting there that nothing in the product would ask for. Files is now four shelves beside Shared, each loaded only when you open it: Tasks (the checkout a coding agent edited, per task), Computer (the same for a task that ran on your own machine, plus the local checkouts chat reads and writes), Storage (your private cloud files), and Session (what the chat brain itself wrote). One shelf being unreachable no longer blanks the others.
- A finished task's files are readable, not just a running one's. The workspace outlives the agent by about two weeks, and just after it finishes is when you want to look - so this surface deliberately has no "is it still running" gate. A workspace that has since expired shows as empty rather than as an error you can do nothing about.
- A file browse can no longer start an agent. The Files page passed its request mode straight through to the runtime, and the runtime dispatches on it, so a value it did not recognise fell through to the path that runs the model. It accepts exactly two read-only modes now.
- A file browse cannot reach anyone else's work. Every path is resolved one segment at a time from the real workspace root, with symlinks followed and checked before the comparison - so a link committed into a cloned repository cannot walk out of it. Which workspace you are reading comes from a task row looked up under your own account, never from anything the request can say.
- A hairline no longer floats in the Terminals header when you have one machine. The machine picker hides itself when there is nothing to switch between, and the divider beside it did not go with it, so the pill drew two dividers around nothing.
- Settings no longer offers Foxl Code settings to an account on the Code waitlist. Foxl Code is in private beta, so it tells you your account is on the waitlist - and Settings went on listing six panes for it (Coding agent, Defaults and budget, Container, Notifications, Machines, This computer), each a form that loaded nothing and could save nothing. The whole Code group is hidden while you are waiting, in Settings and in the Cmd+K search, and it comes back on its own the moment access is granted. Foxl Code itself is untouched: the product is still there and still says where you stand.
- A coding agent opened on this computer now runs the same one your terminal runs. When two copies of a CLI are installed under one name - normal when a wrapper sits alongside the original - the pane could start the other one, because the shell it launches in does not read
~/.zshrcor~/.bashrc, which is where most additions to your path live. Claude Code showed that as a model problem rather than a path one: it read the settings written for the copy you use, could not use the models named there, walked down its fallback list and stopped at "There's an issue with the selected model". The pane now puts the program Foxl itself resolves in front, which is the onewhich claudenames in your terminal, and leaves your path untouched when the two already agree. - A cloud terminal you had just opened said its session had gone to sleep. Open a Foxl Code terminal on Remote, type, and the pane answered "This session went to sleep. Reconnect wakes it on the workspace that was kept." on a session two seconds old, with no Reconnect anywhere on that screen to press. A cloud session gets a fresh machine, which takes about half a minute, and for that whole window the machine answers "I have no session for this" to exactly the same question a machine recycled after fifteen idle minutes answers it to, so the two were indistinguishable and the pane assumed the worse one, permanently, one second into a normal start. The two are now told apart, so a terminal that is merely starting says so ("Starting the agent's machine", and that there is nothing to press), a keystroke typed too early says the machine is not ready yet instead of naming a recovery you do not need, and the recovery card no longer appears over a session that is coming up. Typing during a Reconnect gets the same treatment. A session that really did go to sleep is unaffected: same sentence, same button, and your workspace is still what it resumes on.
- A Foxl Code terminal you open on Remote now starts at the width of the pane it is in. It was always 120 columns wide whatever your window was, so the agent's output wrapped in the wrong place - narrower than the same terminal on this computer, and much wider than a phone - and it stayed wrong for the rest of the session, because the correction was sent while the cloud machine was still starting and there was nothing there to receive it. The width is measured before the session is asked for and sent with the request, so the first thing the agent draws already fits; the terminal also re-sends it the moment the machine answers, so a pane you resize while it starts up catches up too.
- Foxl Code settings can be saved again if you had set an environment variable that Foxl later took over. Saving anything on the Autonomy card or the Settings page failed with "reserved environment variable: CODEX_HOME" - including an autonomy switch that has nothing to do with environment variables. The variable had been fine when it was set; Foxl started setting that one itself afterwards, and every save sends your whole settings row back, so the name Foxl now owns came along and was refused. Such a variable is dropped from your settings on the next save instead of blocking it, which changes nothing about how your tasks run - Foxl has been supplying its own value for it all along. Typing one of the reserved names into the form yourself is still refused, and still tells you which name it was.
- A file path in a reply that starts with
~is clickable for real now, and clicking it opens the file. Cmd-clicking one used to do nothing at all: the underline appeared, the cursor changed, and then silence, with no error anywhere.~is something your shell expands, not something the operating system understands, so~/Downloads/report.pdfwas being looked for inside Foxl's own program folder, where it does not exist. Now the home directory is filled in before the path is handed over, everywhere it can be handed over. - And it opens the file rather than just pointing at it in Finder. A path named at the end of an answer is usually something you want to read, so Cmd-click now opens it in whatever application handles that kind of file. A folder still opens in your file manager, as before.
- A Foxl Code task on Claude Code could not sign in, so it did nothing and then ran out of time. The agent launched, printed "Not logged in - please run /login" to a terminal nobody was looking at, and sat there until its eight-hour ceiling: no edits, no pull request, and a task that looked busy the whole time. Your Claude subscription was fine; one flag on the launch put the CLI into API-key mode, where it never reads the subscription at all. Kiro and Codex tasks were unaffected. Fixed on all three places a task can run: Foxl's cloud, the shared runtime, and a computer of your own.
- A pull request no longer contains Foxl's own instructions file. Every task on a repo without a
CLAUDE.mdorAGENTS.mdadded one, holding our internal agent rules, as a change you were asked to review and merge. The file is still written so the assistant can read it; it just stays out of the commit now. A side effect worth having: a task where the agent did nothing at all now opens no pull request, instead of one containing only that file. - A pull request is titled after what you asked for again. Once a repo had a project brief, the title came out as "Project memory from previous Foxl Code tasks on this repo (may be stale)" - the heading of a note Foxl adds for the agent, not your request.
- The microphone works on Android. Starting a recording in Foxl Notes, or tapping the mic in the composer, was refused outright: the app never got to ask, so the permission dialog never appeared, and the message pointed you at a system setting that had no switch to turn on. Nothing you could do from your phone would have fixed it.
- An iOS reply no longer dies when you switch apps mid-answer. Send a message and leave for another app and the answer was cut off partway, because the app was not asking iOS for the few extra seconds it needed to finish. It asks now, so the reply lands and is waiting for you when you come back.
- Notifications reach the bell again after you sign out and back in on a phone. The app remembered which alerts it had already filed, but forgot the alerts themselves, so anything that arrived before you signed out was skipped forever: live banners on your lock screen and an empty "Nothing here" inside the app. Signing out now clears both, and it also stops a reply you typed from a notification being sent under the next person's account on a shared phone.
- A second phone no longer wipes the number on your first phone's icon. The badge is one number per account, so an Android install kept resetting the count an iPhone was keeping, and the next notification started over at 1 instead of continuing. Each phone's own icon badge still works exactly as before.
Changes
- The Foxl Code Tasks header is one control now, the same one the Terminals header has:
+ | Remote | Claude Code. It used to be four separate chips saying one sentence with the words scattered - a machine pill, the repo picker, an agent pill and a labelled New-task button. Read left to right it now says what it does: start a task, on that machine, running that agent. The+lost its "New task" label to buy the width back; hovering it still says so.
Fixes
- A hairline no longer floats in the Terminals header when you have one machine. The machine picker hides itself when there is nothing to switch between, and the divider beside it did not go with it, so the pill drew two dividers around nothing.
- Settings no longer offers Foxl Code settings to an account on the Code waitlist. Foxl Code is in private beta, so it tells you your account is on the waitlist - and Settings went on listing six panes for it (Coding agent, Defaults and budget, Container, Notifications, Machines, This computer), each a form that loaded nothing and could save nothing. The whole Code group is hidden while you are waiting, in Settings and in the Cmd+K search, and it comes back on its own the moment access is granted. Foxl Code itself is untouched: the product is still there and still says where you stand.
- A coding agent opened on this computer now runs the same one your terminal runs. When two copies of a CLI are installed under one name - normal when a wrapper sits alongside the original - the pane could start the other one, because the shell it launches in does not read
~/.zshrcor~/.bashrc, which is where most additions to your path live. Claude Code showed that as a model problem rather than a path one: it read the settings written for the copy you use, could not use the models named there, walked down its fallback list and stopped at "There's an issue with the selected model". The pane now puts the program Foxl itself resolves in front, which is the onewhich claudenames in your terminal, and leaves your path untouched when the two already agree. - A cloud terminal you had just opened said its session had gone to sleep. Open a Foxl Code terminal on Remote, type, and the pane answered "This session went to sleep. Reconnect wakes it on the workspace that was kept." on a session two seconds old, with no Reconnect anywhere on that screen to press. A cloud session gets a fresh machine, which takes about half a minute, and for that whole window the machine answers "I have no session for this" to exactly the same question a machine recycled after fifteen idle minutes answers it to, so the two were indistinguishable and the pane assumed the worse one, permanently, one second into a normal start. The two are now told apart, so a terminal that is merely starting says so ("Starting the agent's machine", and that there is nothing to press), a keystroke typed too early says the machine is not ready yet instead of naming a recovery you do not need, and the recovery card no longer appears over a session that is coming up. Typing during a Reconnect gets the same treatment. A session that really did go to sleep is unaffected: same sentence, same button, and your workspace is still what it resumes on.
- A Foxl Code terminal you open on Remote now starts at the width of the pane it is in. It was always 120 columns wide whatever your window was, so the agent's output wrapped in the wrong place - narrower than the same terminal on this computer, and much wider than a phone - and it stayed wrong for the rest of the session, because the correction was sent while the cloud machine was still starting and there was nothing there to receive it. The width is measured before the session is asked for and sent with the request, so the first thing the agent draws already fits; the terminal also re-sends it the moment the machine answers, so a pane you resize while it starts up catches up too.
- Foxl Code settings can be saved again if you had set an environment variable that Foxl later took over. Saving anything on the Autonomy card or the Settings page failed with "reserved environment variable: CODEX_HOME" - including an autonomy switch that has nothing to do with environment variables. The variable had been fine when it was set; Foxl started setting that one itself afterwards, and every save sends your whole settings row back, so the name Foxl now owns came along and was refused. Such a variable is dropped from your settings on the next save instead of blocking it, which changes nothing about how your tasks run - Foxl has been supplying its own value for it all along. Typing one of the reserved names into the form yourself is still refused, and still tells you which name it was.
- A file path in a reply that starts with
~is clickable for real now, and clicking it opens the file. Cmd-clicking one used to do nothing at all: the underline appeared, the cursor changed, and then silence, with no error anywhere.~is something your shell expands, not something the operating system understands, so~/Downloads/report.pdfwas being looked for inside Foxl's own program folder, where it does not exist. Now the home directory is filled in before the path is handed over, everywhere it can be handed over. - And it opens the file rather than just pointing at it in Finder. A path named at the end of an answer is usually something you want to read, so Cmd-click now opens it in whatever application handles that kind of file. A folder still opens in your file manager, as before.
- A Foxl Code task on Claude Code could not sign in, so it did nothing and then ran out of time. The agent launched, printed "Not logged in - please run /login" to a terminal nobody was looking at, and sat there until its eight-hour ceiling: no edits, no pull request, and a task that looked busy the whole time. Your Claude subscription was fine; one flag on the launch put the CLI into API-key mode, where it never reads the subscription at all. Kiro and Codex tasks were unaffected. Fixed on all three places a task can run: Foxl's cloud, the shared runtime, and a computer of your own.
- A pull request no longer contains Foxl's own instructions file. Every task on a repo without a
CLAUDE.mdorAGENTS.mdadded one, holding our internal agent rules, as a change you were asked to review and merge. The file is still written so the assistant can read it; it just stays out of the commit now. A side effect worth having: a task where the agent did nothing at all now opens no pull request, instead of one containing only that file. - A pull request is titled after what you asked for again. Once a repo had a project brief, the title came out as "Project memory from previous Foxl Code tasks on this repo (may be stale)" - the heading of a note Foxl adds for the agent, not your request.
Features
- Ask the Notes assistant something and it can now use the same tools Foxl Agent has on your computer. It used to see the transcript and nothing else, so "you have access to my CV and my Obsidian notes, right?" got a no from a product that has been able to read files for a year in the next tab. Now an ask can open your files, search your code and notes, fetch a link, and run a command, using whatever you have switched on in Settings > Tools, custom tools and MCP servers included. It tells you which tools it used under the answer. On by default, and there is a switch in Settings > Notes > AI features. Needs Foxl running on your computer.
- It can also remember what you said in earlier conversations. Your Notes threads are saved where the assistant can search them, so "what did I say about this last week" finds the meeting you said it in, and so does Foxl Agent chat. Meeting threads stay out of your chat list; they are only reachable by search.
- Automatic work is deliberately unchanged and still runs on the fastest path: the post-meeting summary, the auto title, live translation and dictation clean-up use no tools, so nothing you were not waiting for got slower.
- The Tasks header now says which coding agent your next task will run, and lets you change it there. The Runtimes header already carried that dropdown; the screen where tasks are actually started did not, so the choice lived only in Settings and nothing on screen said what it currently was. All six agents are listed, with the ones that need provisioning or a credential of yours marked. It sets your account default, so it also applies to scheduled tasks and to the autonomous loop - never to a task already running, and the menu says so.
- Foxl Code's orchestrator can read GitHub when it runs on your own computer. It could plan and start work but not look at the repository it was planning about: every GitHub read answered "no GitHub token available - connect a repo first", which named the wrong problem, since the repo was connected and the credential was the missing half. It now authenticates the way you already do (
gh auth login, your git credential helper, orFOXL_CODE_GITHUB_TOKEN), and the refusal names the real cause when no credential exists. Reads stay confined to the repository you have selected.
Fixes
- The round buttons in the top corners no longer come up as squares on iPhone and iPad. Occasionally the sidebar button on the left and the buttons on the right rendered as a square, or as a rounded square, instead of a circle - and once it happened it stayed that way until the app was restarted. The buttons are drawn by iOS itself, and their corner rounding was measured only once, when the button first appeared: if that measurement landed before the layout had settled to phone width (or while an iPad window was wide), it captured the wider layout's small corner and then kept it even after the button grew back to its round size. It is re-measured whenever the button changes size now, so it corrects itself instead of waiting for a relaunch.
- The app could come up to a loading screen and stay there after an update, and Restart server could not get it back. If you have "keep running when closed" switched on, the background service that owns the server is reinstalled on every launch - and one step of that reinstall could finish with the old service removed, the new one never registered, and the app told it had succeeded. The app then waited on a server nobody was starting, and the Restart button asked the system to restart a service that no longer existed, which is why it answered instantly and changed nothing. Reinstalling now proves the service is really registered before it reports success, every launch checks for the missing case and repairs it, and Restart server reinstalls the service when it is gone instead of failing. If the service truly cannot be started, Foxl now runs the server itself so the app still opens, and says so in Settings rather than leaving you on a blank screen.
- The server-diagnostics screen also told you the wrong runtime: it printed the app shell's Node version under "runtime" while the server has been running on Bun since v0.6.10. It now names the runtime the server is actually on, says whether the background service is registered, and points at the service's own log instead of showing an empty one.
- Searching your past conversations is fast and ranked now, and it never was. When the agent looks back through what you have said before, it is supposed to use a proper full-text index - the reason the app started shipping a different SQLite build eleven releases ago. That search was written in a way the database refuses, so every single lookup quietly fell back to reading every message you have ever written and comparing text. It still found things, which is why nobody noticed: what it could not do was tell a conversation that is genuinely about your subject from one that mentions it once in passing, and it got slower with every conversation you added. The index is really in use now, the best match comes first, and the excerpt you see is the part that matched.
- A long chat no longer loses its history in the middle of a turn. On a conversation that had grown large - a research session with big tool results, a document being built over an hour - the agent could hit the model's context limit mid-turn, throw away the ENTIRE conversation, and then answer your next message as if it were the first one. It did not say so: the reply arrived looking normal, and the only way to notice was to ask the agent what it could still see. Two things caused it and both are fixed. The conversation is now compressed on the way up - when it reaches 70% of the model's window, the oldest part is summarized and kept - instead of only being dealt with after the model has already refused the request. And the summarizer can now actually run: its "always keep this many recent messages" setting was larger than the number of messages a big conversation typically has, which made summarizing arithmetically impossible for exactly the chats that needed it, so the only remaining escape was to drop everything. Compaction is also written to the log now, with the message count before and after, so a turn that loses context can no longer do it silently.
- A new chat is empty now, including the message box. Cmd+N (and the sidebar +, the Chat row, and File > New) started a fresh conversation but left everything you had been about to send sitting there: the half-written sentence, the images and files you had attached, and the cards for any long text you had pasted. The attachments were the expensive part, since the next message you typed sent them along with it. Pressing it a second time on an already empty screen did nothing at all, so there was no way to clear it from the keyboard. The find bar and the open file tabs from the previous conversation also stayed behind, and both now go with it.
- New task in Foxl Code really does start a new task now. Pressing it left the previous conversation on the screen, and reloading brought back one you thought you had thrown away, because there was only ever ONE draft behind the composer: a single conversation per account that every new task reused, on this device and on the server. So there was no new conversation to hand you. Now a task gets its own identity the moment you type something and press enter, exactly like a new chat in Foxl Agent, and until then the screen holds nothing at all: no transcript, no leftover half-written message in the box, and nothing on the server for a reload to find. Whatever the old shared draft was holding is deleted rather than carried forward, and your existing tasks and their conversations are untouched.
- Pressing a choice Foxl Code offered you now settles it everywhere, instead of leaving the button you just pressed still asking. When the agent stops to ask you something, that ask was drawn TWICE on one screen - once in the chat and once in the "Needs you" rail - and each copy tracked separately whether it had been answered. So answering in the chat left the rail showing the identical question with both buttons live and its badge still counting it, and answering in the rail left the chat's copy standing. Measured on the shipped bundle: two copies, four live buttons, badge unchanged. The answer was really being sent the whole time, which is what made it read as a dead button rather than a failure.
- An answer now sits in the conversation where you gave it, instead of piling up at the bottom. Answered asks were pinned under the transcript rather than placed in it, so they never moved: keep chatting and an exchange from five turns ago was drawn BELOW the newest reply, with up to five of them collecting in a block at the end. An ask that is still open stays where it was, at the tail under the reply that asked it.
- A coding task running on your own computer is finally VISIBLE in Foxl Code. Turning on local tasks worked - clones happened, assistants ran, real pull requests were opened on GitHub - and the Tasks list showed none of it, because it only ever listed tasks from Foxl's cloud. So the one thing you could not do with the feature was see it. Tasks that ran on this machine now appear under On this computer, with the assistant that ran them, the goal, the repository, how long ago, and a link straight to the pull request once there is one. Only where a Foxl desktop is actually reachable, so the group simply is not there on the web when your machine is asleep.
- A coding task on your own computer now shows you the pull request, even when the assistant opened it itself. Every one of the six assistants was asked to leave git alone and most of them do it anyway: three of them commit, push, open a pull request and then put the branch back the way they found it. Foxl was looking in exactly one place for the work, so a task could finish with a real pull request live on GitHub and tell you nothing happened, or open a second pull request beside the assistant's own. Now the task recognises its own work by commit, adopts the pull request that already exists, and says which of the two of you opened it.
- And a task no longer ships an empty branch. If the assistant did its work on a branch it named itself, Foxl was pushing its own branch, which was still sitting where the clone started - GitHub then refused the pull request with "no commits between", and the work stayed on your disk. The commits that get pushed are now the ones that were measured.
- A Foxl Code terminal running Codex was configured with a model id OpenAI does not serve. The pane said
gpt-5.6-soland the container was set toopenai.gpt-5.6-sol, which is the same model spelled the way Amazon Bedrock spells it. On a ChatGPT plan the Codex CLI talks to OpenAI directly, so it was being asked for a model that does not exist there, and it failed mid-run inside the terminal rather than saying so. The same mistake ran the other way on the unified shell runtime, where Codex on Bedrock was handed the short id Bedrock does not accept. Each auth path now gets the spelling it actually uses. - A terminal you opened with no coding assistant in it no longer claims to be running one. A plain shell showed an assistant's mark and a model name beside it, because the task row keeps both for reasons that have nothing to do with what is on your screen.
- The runtime line under a terminal stops inventing facts. It printed
claude-opus-5whenever the real model had not arrived yet, which on a Codex pane put a Claude model under the Codex mark, and it printedautoas though Cursor were a model called "auto". Each of those is now simply absent until there is something true to show. The branch name also appears immediately instead of a few seconds in.
Fixes
- You can now actually turn on running Foxl Code tasks on your own computer. The switch shipped as an environment variable, and on a normal install there is nowhere to put one: the desktop keeps running when you close it, so its server is started by a background service whose configuration the app rewrites every time you open it - anything you added by hand was undone by the next launch. The answer is stored on your machine now, so it survives a restart, an app update and a reboot. It is still off until you say yes, and saying yes has to come from the machine itself rather than from the web or your phone, because it decides where your code runs.
Features
- A terminal on your own computer now opens in the repo you picked, running the agent you picked. The Foxl Code header reads as one sentence - a repository, then
+ | This computer | Claude Code- and until now the middle part was the only one your own machine paid attention to: the agent came from a dropdown underneath the terminal, the folder from a second one beside it, and the repository at the top reached that pane not at all. So you could havefoxl-ai/acme-webselected while the agent ran in your home directory, with nothing on screen disagreeing. All three now mean the same thing on every machine. - Your repos are cloned into
~/workspaces, and a checkout you already have is used as it is. A repo goes in~/workspaces/<owner>/<name>, so two owners of the same name never collide. If that folder is already there - because you cloned it yourself, or worked in it last week - Foxl starts the agent in it and touches nothing: no second clone, and no fetch or pull that could raise a conflict in a working copy you were in the middle of. - Settings -> Code -> This computer is where all of that is configured: the clone folder, the folder a terminal starts in when no repository is selected, and whether a coding agent asks before it edits files and runs commands.
- Foxl Code can run a coding task on your own computer. Point it at a repository and the clone, the coding CLI, the commit, the push and the pull request all happen on your machine, with your own CLI login and your own GitHub credential - nothing about the task runs in Foxl's cloud. Any of the six assistants can drive it (Claude Code, Codex, Kiro, Cursor, Hermes, OpenCode), each launched the way that vendor's CLI actually wants, and a CLI you have not signed into says so in its own words instead of failing as "the task failed". The orchestrator you talk to in Foxl Code is what starts it, and it tells you which machine the work is on. Off until you turn it on -
FOXL_CODE_LOCAL_AGENT=1on the desktop server - because it moves where every Foxl Code task executes, and that is your decision rather than a release's. Your existing tasks keep running in Foxl's cloud exactly as before.
Changes
- The autonomous activity panel is gone from the Foxl Code home. It was a collapsible box above the conversation whose collapsed state was one line about whether the machine had been busy - "Worked 4 times in the last day", or "Quiet for a day" beside the time of the last run - and expanding it printed the loop's own narration of each tick. The home screen is for saying what you want and watching it happen, so a panel reporting that nothing had happened is the one thing there that never helped. What the loop actually produces still has its own surface, derived from the issue ledger rather than from narration, and the ticks themselves are still recorded.
- The strip under a local terminal is gone. It carried an agent list, a folder list, a switch, and a line reading "Runs as you, on this computer. Stops when it sleeps." - four rows of settings under the output of a session none of them could change, on the one screen where the terminal's height is the whole point. The agent and the repository are the header's job now, the folders and the switch are in Settings, and the sentence went because the pane's own title already says "This computer", so did the button that opened it, and so does the sidebar row beside it.
Fixes
- Opening Foxl Code's Runtimes no longer flashes two grey boxes at you. The page drew a pair of large grey placeholder blocks while it waited, which was left over from the read-only card grid this screen replaced - so it promised a shape the page cannot render and a count it never opens (it opens one terminal, not two), directly after the app's own blur-and-mark wait had just finished. There is one wait now, the same mark used everywhere else, and it hands over to the terminals without a second style of loading in between.
- Returning to Runtimes shows your terminals immediately. The saved arrangement of panes was read one frame too late, so every trip back to the page painted the loading state first and replaced it a moment later - a flash, for a workspace that was already known. It is read before the first frame now, so coming back from another screen puts you straight back in your panes, and closing every pane no longer waits on the task list to tell you the workspace is empty.
- Runtimes no longer sits on a loading state forever when you are signed out. With no session there was no request to end the wait, so the placeholder never cleared.
- Foxl Code's model picker offers the models you actually have, and chat runs on them. It listed Opus 5, Fable 5, Opus 4.8, Sonnet 5 and Haiku 4.5 under a "Foxl" heading, and picking any of them answered "foxl.ai is not serving model inference right now" - because foxl.ai serves none, deliberately, and those five names were a hardcoded list the picker fell back to whenever the catalog came back empty. An empty catalog is exactly what "we serve no models" looks like, so the fallback fired on the normal case. The picker now reads the same providers Foxl Agent does - your own AWS keys, an Anthropic or OpenAI key, a Claude or ChatGPT subscription, Ollama or any OpenAI-compatible endpoint on your machine - grouped by whose they are, and a turn on one of them runs on your computer instead of being sent to foxl.ai. With nothing set up it says so, and says where to fix it, rather than offering five models that cannot answer.
- Choosing a model that lives on your machine while that machine is away now says so. It used to be sent to the cloud anyway, which spent credits you did not choose and failed regardless. Foxl says which computer it needs and offers you the other choice.
- A local terminal that could not reach your computer now says so, instead of the pane breaking. It was supposed to show "This computer did not answer" with a Try again button, and that panel could never actually appear: the code returned it one step too early, which React treats as a fault and reports as a broken pane. So the one situation the message exists for - the desktop app not running behind the page you are looking at - was the one where you could not read it.
- Foxl Code no longer runs anyone on a two-year-old model by accident. If you had ever picked a default machine without also saving a model in Settings, your account was pinned to Claude Opus 4.7 - not by you, by the database: the settings table has carried
claude-opus-4-7as a column default since 4.7 was the flagship, so a row created without naming a model got one written for it. Every part of the product then honoured it, which is why opening a plain terminal could come up on Opus 4.7 and the model picker had nothing to show for it (older models are hidden, so there was no name on screen to disagree with). The database no longer chooses a model for anyone, affected accounts are repaired, and the four default model names now live in one file instead of nine places.
Features
- A Foxl Code terminal can now be just a terminal. The agent picker beside the
+in the Code header has a new first choice,Terminal, and it means what it says: the pane opens a login shell on the machine you picked, with no coding assistant launched in it. Your own computer has always been able to do this, so the same keystroke gave you a terminal on one machine and a coding agent on every other one; nowCmd+Tmeans the same thing everywhere. The shell starts in the repository's checkout on that machine, anything you commit is pushed to the session's own branch when you are done, and closing the pane opens no pull request. It needs no model and no API key of yours, because nothing in it calls a model until you ask for one yourself. - The
+ Terminalbutton in the Code header is now just+. The pill reads as one sentence left to right - open a terminal, on that machine, running that - and with the newTerminalchoice above it the old label named the same thing twice while taking the width a repository name needs. Hovering it still says "New terminal", with the shortcut.
Changes
- The Foxl Code sidebar has one gap in it instead of two. Runtimes and Tasks sit together at the top - say what you want, watch it happen - and Work, Repos, Files and Schedules are one block below them. Schedules used to sit alone under a second gap and Work above the first, which put a separator after nearly every pair and made the run of six rows evenly spaced again, with more air in it.
- The free machine Foxl Code runs your work on is called
Remotenow, notFoxl Cloud. Nothing about it changes: same machine, still free, still the default, still not removable. The name does, because Foxl's direction is a machine you run yourself rather than infrastructure rented from us, and a brand on the managed box read as the opposite. To you there is this machine, your own computer, and any box you have added yourself, which is what the list now says. - A Foxl Code task on the Codex agent starts again. Codex keeps its own working state in a handful of small databases, and the cloud machine's shared folder cannot hold the kind of database it uses. Older Codex versions worked around that quietly by going without most of them; the version now shipping does not, so it refused to start and said another copy of Codex was already using its data. There was no other copy - that message is Codex's guess at a locked file, and it sent the first look at this hunting a process that did not exist. Its state now sits on the machine's own disk, where every one of those databases is created properly. The Codex version is pinned too, so the tool cannot change underneath a task with nothing recording that it moved, which is how this arrived in the first place. Two things worth knowing: Codex's own record of a session no longer survives the machine being recycled, which nothing relied on since a Codex task has never offered Reconnect, and your ChatGPT sign-in now lives on a disk that is erased with the machine rather than one kept for two weeks.
- Foxl Code tasks run on a free account again. While Foxl is free there are no paid plans to sell, so the per-plan limits a task started against had nothing behind them and no way past them: the default coding agent was refused outright because the free plan listed no models, and even with that open the pre-flight credit check compared a task's $500 default budget ceiling against a new account's welcome credits and refused every first task regardless of balance. Both are switched off for as long as plans are unsold, in one place, so turning them back on is a single line. Nothing else moved: the plans themselves still describe what each tier includes, the limit on how many tasks run at once still applies, and an account that has actually run out of credits is still stopped before it starts another task.
- A first message on a fresh install now says what to do about it. Nothing had been connected yet, so the reply came back as the raw text a cloud SDK prints when it finds no credentials at all - naming no cause, no setting and nothing to try. It now leads with the one thing that fixes it and where that lives, and still prints the original text underneath so it can be searched or pasted into a report. Two other refusals got the same treatment: a request refused because foxl.ai serves no model inference used to arrive as a bare code that reads like an outage, and a model your account cannot use said only that, with no next step. None of them suggest buying anything, because there is nothing to buy.
- The model list explains itself when it is empty. Opening the picker with no provider connected said "No models match your search." over an untouched search box, while the composer above it still displayed a model name. It now says that no provider is connected, offers to open the right settings pane, and keeps the search message for an actual search that found nothing.
- Foxl Notes says what it still needs before you press record, not after. On a fresh desktop, transcription is signed with your own AWS credentials and the summary runs on whichever model provider you have connected - and with neither in place, recording opened the microphone and then failed with a raw error, while the summary failure was written into the note as its own text. Notes now shows what is missing up front, names each piece, and links straight to the pane that fixes it. It says nothing once both are in place, and it stays quiet when the desktop is simply not running, which already has its own message.
- Two pieces of advice inside Notes that could not work have been replaced. A failed summary suggested signing in to use your Foxl credits, and a missing model suggested signing in or setting a self-hosted model - three remedies across two messages, all of them switched off. Both now point at the model provider setting that actually serves Notes.
- The Foxl Code setup checklist had three steps and needed four. A task cannot start without your own model access, and nothing in the checklist mentioned it, so it was possible to finish every listed step and have the first task refused by a message buried in a tool result. There is now a step for it, before the one it is a prerequisite of, and it checks itself off when a subscription or key is in place.
- That checklist is reachable again after its first step. Installing the GitHub App redirects the tab and returns you to the repository list, and the only route back to the checklist required having no installation - so on the web the later steps could never be seen. It is now offered whenever setup is unfinished, once per visit, and never when you have deliberately gone to write a task.
- The autonomous activity panel stops printing the same timestamp twice. When the loop had done nothing for a day, its collapsed heading read "Quiet for a day - last ran 6d ago" and the row's own right-hand stamp then said "6d ago" immediately after it, so the line ended in the same time repeated back to back. Both came from the one value. The heading now says only that it has been quiet and the stamp keeps saying when the last run was, in the place every other row in the app puts a time.
Fixes
- Closing a Foxl Code terminal now sticks, and arriving no longer fills the screen with terminals you did not open. Opening the Runtimes workspace put up to three terminals on screen by itself, and pressing the X on one only held until you clicked to another page and back. A cloud session deliberately keeps running after its pane closes, so you can reopen it and carry on - but that also made it the newest live run, which is exactly what the page re-opened for you, so a closed terminal came back on its own. A visit now opens at most one terminal (your newest run), every terminal you close stays closed for the rest of the session, and a workspace you emptied stays empty.
- Channels and DMs stop jumping too far up when the phone keyboard opens. The message bar was still paying for the floating tab bar while the keyboard was up - a bar that is faded out and sitting behind the keys at that moment - so the card floated about 124px above the keyboard and the conversation above it was squeezed by exactly that much. The transcript reserved a second bar's worth of empty space under its newest message as well, on a scroller the tab bar cannot reach at all. Both are gone: the card now comes to rest on the keyboard the way the Agent and Foxl Code message bars already did, and the last message sits just above it, so a short DM no longer shows its only line clipped under the header. With the keyboard closed nothing moves except that the card clears the tab bar by the same margin as the other two chats. In a room with only a message or two, that line also stopped sliding up under the header and dropping back while the keyboard opened.
Fixes
- A terminal in the Foxl Code sidebar stops flashing the wrong icon before its agent's mark appears. Every row in the Runtimes list leads with the mark of the coding agent in that pane, and a pane running a plain shell instead shows a
>_. Those two came from the same missing value, so a pane whose agent we simply had not been told about yet was drawn as a shell and then corrected itself a moment later - on every page load, for every agent pane, because a restored layout knows which panes exist one round trip before it knows what is in them. The row now keeps that space empty until the mark is real, so nothing claims to be a plain shell that is not one. The same rows also stop showing a laptop for a terminal that is running in the cloud: which machine a pane is on is known from the start for Foxl Cloud and for this computer, so only your own remote machines wait for their details, and those now show a plain terminal until they arrive rather than a guess. The Runtimes row itself carries a terminal now rather than an ECG trace, which is what it was when the page was a read-only list of machines. - Closing a cloud terminal from the sidebar warns you that the agent keeps running. It already did from the pane's own close button, and the sidebar row said only "Close" - but only because it had mistaken every freshly-restored pane for one on your own computer, where there is nothing left behind to warn about. Both X's now say the same thing, which was the point of saying it at all.
- A Foxl Code task terminal shows the agent's output and nothing else. The pane used to mix in lines we wrote ourselves - one announcing that the agent had started, one per shell command, notes about pull requests and budgets, and bracketed messages when our own connection dropped - all timestamped and coloured like terminal output. A terminal reads as a transcript of what ran, so those were indistinguishable from things the agent had said. It was most visible on a task whose machine had been recycled: the pane held a single line saying the agent had started, so the product looked like it had run an agent that then printed nothing, when in truth nothing had printed at all and the only text on screen was ours. All of it is out of the pane. Task progress lives where you can tell it apart from a program's output - the status pill, the pull-request link, the budget chip and the alert chip in the header - and if a reconnect fails or a keystroke does not reach the agent, that is now said in a strip over the pane that goes away by itself once the condition does.
- A cloud terminal that went to sleep now offers the Reconnect it tells you to press. A Foxl Code task's machine is recycled after fifteen idle minutes, and the next thing you type into its terminal is what discovers that. The pane said "this session went to sleep - use Reconnect to wake it on its saved workspace" and then showed no Reconnect, because the only thing that put that button on a task still marked Running was a check that runs for the first eighteen seconds after the pane opens and never again. So a terminal you had been using for a while could only ever print the sentence. Typing again printed it again: one line per keystroke batch, reported as twenty identical red lines and no way out. The keystroke now asks the machine whether it is really gone, and that answer is what raises the button - the same read-only check as before, just no longer limited to the moment you opened the pane. The message is one strip over the pane that says it once and clears itself when the session answers again, instead of a red line per keystroke batch, and your work is not affected either way: Reconnect resumes on the same saved workspace.
- "Which agent" moved out from under the terminal and into the button that opens one. A cloud pane carried a strip reading "New cloud panes run / Claude Code (account default)" with "Keeps going when you close your laptop." beneath it. Neither line was about the pane it sat under: the pick governs the NEXT terminal, and a pane cannot change what the agent already running in it is - so with four panes open you saw four copies of one setting, under output none of them applied to. It is the third segment of the header button now, which reads left to right as what it does: "+ Terminal | Foxl Cloud | Claude Code". The agents that need a key of yours are still marked, in the same words Settings uses. The durability promise is gone from the footer; the pane's close button already says it at the only moment it changes anything ("the agent keeps running"). Every cloud pane gets a row of height back, which on a terminal is the whole point.
Features
- Tell Foxl Code which folder to work in. A coding agent started on "This computer" used to open in your home directory, so the first thing you had to do was
cdto the project - and an agent outside your code cannot read it, run the tests or open a branch. Add a folder in the strip under the terminal (a native picker on the desktop, a typed path from a browser) and new panes start there. The list remembers what you use most and marks any entry whose folder has gone missing. The folder is only a starting point: branches and worktrees stay the agent's own business, and if the folder you picked has gone away Foxl says so and starts nothing rather than quietly running somewhere else.
Fixes
- One type treatment across the Foxl Code header, and "+ Terminal" now names the machine it opens on. The Runtimes bar carried three sizes and two text colours side by side - the page title and the repo picker at 14px dimmed, the machine chip and the New-terminal label at 12px full black, which reads as bolder as well as smaller. They all match now, and New task on Tasks moved with them since it is the same control in another slot. The machine chip is also no longer a separate control on Runtimes: it is the right half of the New-terminal button, because on that page the pick is exactly where the next terminal opens.
- Four more places on the Runtimes workspace that said the wrong thing. The machine button claimed "terminals and tasks" even when the pick was This computer, where a Foxl task cannot run at all - it now says so, and names where tasks go instead. A local pane and a cloud pane in the same split both had a footer reading "New panes run", for two different settings with two different lists; they now say "local" and "cloud", which is what their screen-reader labels always said. Closing a terminal from the SIDEBAR is the same act as closing it from the pane, so it now carries the pane's own warning that a cloud agent keeps running. And the workspace menu's closing paragraph is one line instead of three - it described a layout you are looking at; the part that survives is the 10-second refresh interval, which nothing else on screen can tell you.
- Korean in the Terminal no longer loses every syllable but the last. v0.6.15 stopped the in-progress jamo from reaching the shell, and took the finished syllables with it: typing
한글입력put력on the command line. xterm hands over a completed syllable one task after the composition closes, and a Korean keyboard opens the next syllable's composition in the same keystroke - so the guard was still shut when the finished text arrived. The terminal now holds back the in-progress jamo itself, rather than everything that arrives while the keyboard is composing, so a finished syllable cannot be caught by it - and neither can a key you pressed mid-composition, which the old guard also threw away. Both terminals (Foxl Agent and Foxl Code). - Sign-in, chat, Notes and Foxl Code could all fail to save at once, and the cause was a log nobody reads. Every GitHub webhook the Foxl Code integration received was being stored whole - the entire message body, kept forever - and continuous-integration events alone were adding tens of megabytes a day. That filled the shared database to its ceiling, and once full it rejects EVERY write in the service, not just the one that filled it. Foxl now records that a delivery arrived without keeping a copy of its contents (GitHub keeps those, and can replay them), and old records are cleaned up automatically instead of accumulating. The stored data was 398 MB of a 500 MB limit; it is a few megabytes now.
- Foxl Code now ignores GitHub events it has no use for, instead of filing them. Nearly two thirds of what GitHub was sending - a notification for every individual CI job, every push, and every comment on an issue or a pull request - reached no feature at all, and each one still cost two database writes. Those are answered and dropped immediately now, and the subscription itself has been trimmed to the six events Foxl acts on. One consequence worth stating plainly: ordinary comment activity on your issues and pull requests is no longer sent to Foxl at all.
- The Hermes mark was invisible in Settings in dark mode. Its artwork is a black silhouette that ships with a light and a dark file, and the assistant picker was reading the light one directly instead of asking for the right variant - so on the dark UI it was a black logo on a near-black panel.
- Foxl Code's terminal starts the assistant instead of sitting there. On the shared shell runtime the CLI was launched in a terminal whose home directory was not the workspace, so it could see none of the files Foxl writes for it before a run: the ones that skip onboarding and the trust prompt, your assistant settings, your instructions, and - if you sign in with a Claude subscription - your credential, which was sitting one directory away unused. The pane came up and stopped on a prompt with nothing saying why. Measured against the live runtime rather than inferred: a fresh terminal there reported
HOME=/home/nodewhile the container itself runs on/mnt/workspace. The terminal now takes both the home directory and the image's program search path from the container, so the assistant starts, a reconnect finds its own transcripts again, and the subscription credential is cleared from the workspace at the end of a run the way it was always meant to be. - An agent pane works again if your shell is fish. v0.6.15 taught the pane to repair PATH before starting a coding agent, and it wrote that repair in POSIX shell - so on fish (or nushell) the pane answered with a syntax error instead of starting the agent, on a launch that had worked before. The repair is now only used with shells that speak it.
- On Windows the agent list no longer offers an agent it cannot start. A file named exactly
claude, with no.cmdor.exe, counted as an installed agent - which PowerShell cannot run, so the pane opened and the launch failed with "is not recognized". - Dragging a file onto the agent no longer acts when you change your mind. Letting a workspace row go over the files panel it came from inserted a reference anyway, so a drag of a few pixels did something. The panel refuses the drop now, and the cursor says so before you release.
- A file dragged in while reading a subagent's transcript is no longer attached invisibly. That view has no message box, so the file quietly went into the draft of the conversation behind it and turned up later out of nowhere. It is not a drop target at all now.
- Dragging selected text into the composer works again. The chat page cancelled every drop it did not recognise, so dragging a few words in from anywhere inserted nothing at all. Text dropped on the composer is inserted by the browser now; a link dropped anywhere else is still refused, because the browser's default there is to navigate away from the app.
- Foxl Code: the backlog says which repository it is showing. With one repository on the account the list resolves without the filter chip, and no row carries a repo name, so the only per-repo list in the product did not name it.
- The floating Notes panel's Live tab keeps the whole meeting. It was fed only the last 80 lines, so in anything longer the beginning of the meeting quietly went missing - scroll up in the panel and the transcript just stopped, as if the top had been cut off. It now mirrors the entire transcript, the same thing the main window's transcript panel has always shown, so you can scroll back to the first thing anyone said.
Changes
- Foxl Code's GitHub webhook documentation now matches what it actually subscribes to. The design notes had claimed CI events were not subscribed months after they were, which is the kind of stale note that gets a working feature reported as broken.
- Closing Foxl and opening it again gives you a fresh terminal, not the last one's ghost. Quitting the app was supposed to end every terminal it had open, and it did not: the shutdown asked for the terminal manager and then exited without waiting for the answer, so nothing was closed. Every session stayed on disk and came back on the next launch as a live-looking tab, replaying its old output - including the
exityou had typed - and pressing Cmd+T reattached to one of those instead of opening a new shell, because the app counted the ghosts as terminals you already had. Two more leaks fed the same pile: a terminal you had finished with kept its saved output after the app stopped tracking it, and closing a terminal wrote its scrollback back out a moment later, one orphaned file per close. The old files are swept on the next launch, so the count does not keep growing on installs that were already carrying them. On macOS this could also leave the previous server holding its port, which is the other half of "reopening does not feel stable". - Error messages appear again, everywhere in the app. Every pop-up message Foxl tried to show you - a save that failed, a voice error, a file operation that did not work, 94 of them across 15 screens - was being sent to a message tray that was not the one on screen. The app and its shared component library had each ended up with their own copy of the toast library, and a copy keeps its own queue, so the message was queued in one and the visible tray listened to the other. Nothing failed and nothing was logged; the message simply never arrived. There is now one copy, checked by a gate so it cannot split again.
- Pressing + for a new terminal tells you when the desktop says no. It could refuse (a concurrent-terminal limit, or the terminal component failing to load) and the button simply did nothing at all - the refusal was thrown away. It now shows the desktop's own reason. The + button also stopped going grey at five terminals: the limit had moved to twelve and the button had not, so it disabled itself while the desktop was happy to open more.
- A finished terminal is no longer handed to you as a live one. Splitting the terminal view, or reopening it while one session had ended, could put you in front of the dead session while the working one sat a tab away - it showed old output and then quietly ignored everything you typed. Split now only offers live sessions, and nothing ever defaults to a finished one. Selecting a finished tab yourself still shows its last output, which is the reason those tabs stay.
- Closing a terminal can no longer signal an unrelated program. The force-kill that follows a close five seconds later was aimed at a stored process number with no check that the process was still the shell it belonged to, and the operating system reuses those numbers. It now fires only if the shell really has not exited.
- A browser extension can no longer be routed into a terminal session. The extension connection is deliberately exempt from the desktop's connection token, and the terminal route matched anywhere in the address rather than the path, so a connection to the extension endpoint that mentioned the terminal path in its query was served by the terminal. Both are matched on the path now. Also hardened: a terminal id from a URL could reach outside its own folder when reading saved output.
- Foxl Code: an open terminal in the sidebar now leads with the agent's mark, the way a task row does. These rows carried a bare cloud, laptop or server, which answers "which machine" - a fact the row's own label already states ("This computer", "Foxl Cloud", or the box's name) and the pane header states again. Every other mark in that column identifies who is working, so the one row leading with a piece of infrastructure read as a different kind of thing. A terminal with an agent in it now shows that agent's icon and its status dot; a terminal running a plain shell shows the machine drawn INSIDE a terminal frame, which is also what a pane header shows now rather than picking one of the two.
- The "New terminal" row is gone from that sidebar list. It was never on screen without the + Terminal button beside it in the header, so it was a duplicate of one action sitting inside the list of what is open, which makes the count wrong at a glance.
- Settings: the default coding assistant is a dropdown, like the model provider. It was a full-width card per assistant - mark, name, description and a status chip - and at six assistants that is 477px of the pane spent on one field, measured, which pushed the model and budget controls below it off the screen. It is one 38px row now, with the assistant's mark and any warning shown on the closed control, the same shape the model-provider picker has always had. The selected assistant's description sits under it, and "Not provisioned" and "Needs your credential" still read differently, because only one of them is something you can act on.
- Every Settings row that names a coding assistant now shows its mark, not just the picker: the Codex model row, the Kiro and Cursor key fields, and the two Agent-credentials rows - whose labels name a subscription ("Claude Pro/Max", "ChatGPT Plus/Pro") rather than the assistant, so they were the hardest to find and are exactly where a "Needs your credential" warning sends you.
Security
- A tool you told Foxl to ask about now actually asks. If you turned "auto approve all tools" off, the approval prompt appeared for
execand the Terminal and for nothing else - three kinds of tool were listed as needing your approval, were shown to you as needing it, and then ran without asking.file_write, which takes any path and any content, was one of them: enough to replace a shell profile or a git hook, so "nothing runs a shell without my say-so" was not true. So was every custom tool you wrote - a custom tool wrapping a shell command, or one evaluating JavaScript, ran unattended even though v0.6.10's note said it would ask. And so was any rule you set yourself in Settings > Tool approval for anything outside a short built-in list: that screen offered a choice with no effect. The cause was two separate lists that both had to name a tool before a prompt could appear, and the second one silently allowed anything it had not heard of. It now asks about anything your rules say to ask about. Nothing changes if you leave auto-approve on, which is still the default; and the tools that deliberately never prompt (reading a terminal's output, polling a background command, MCP servers) still do not, because a prompt on every status check is how people learn to click through them. - A machine you own can no longer point Foxl at an address it should not reach. A Foxl Code machine reports its own address on every heartbeat, and Foxl sends that address a task carrying a GitHub token and, on your own-key setups, your model credential. The check that refuses a private or cloud-metadata address missed five ways of writing one - a trailing dot (
localhost.reads aslocalhostto every name server), four ways of hiding an IPv4 address inside an IPv6 one, and the whole100.64.x.xrange, which is what Tailscale uses, so it was the likeliest one to matter for the "point Foxl at a server you already have" setup added in v0.6.14. All of them are refused now, with the reason shown beside the machine, and ordinary public addresses are unaffected.
Features
- Hermes is selectable in Foxl Code. It had been greyed out as "Not provisioned" since the backend was added, because its CLI was in no container image we ship - the vendor's npm installer drags a browser stack that pushed the shared coding-agent image 47 MB past a hard AWS limit, so the whole image could not be deployed. It installs from PyPI now instead, with no browser tooling, in a two-stage build that leaves the build-only pieces behind: the image is 1277 MB against the 2048 MB ceiling, and all six assistants are in it. Hermes runs on your own Anthropic API key (a Claude subscription cannot work there - the two are different credentials on the wire), so it now asks for that key instead of showing you a switch you could not turn on.
- Drag a workspace file straight into the agent's prompt. The files panel beside the chat lists what the agent just wrote, and until now the only way to point the next turn at one of them was to type its path. Drag a row onto the composer instead: an image is attached so the model can see it, and anything else lands as a clickable file reference at your cursor. Dropping a file from Finder still attaches it as before.
- Foxl Code: browse your repository's open issues and pull requests in-app. A new Backlog tab on Work shows what is open on GitHub with nothing running on it yet, and the buttons that were already there - have an agent solve it, decline it, read the diff, merge it - work from that list. Fetched when you open the tab, so it costs nothing on every other visit.
Changes
- The Runtimes workspace has room to breathe. Each pane's title, its model and spend line, and the agent's own output all sat 8 pixels from the sidebar, and the terminal text had no margin at all, so a log line started further left than the title above it. A pane's chrome and its output share one gutter now, so the column reads as a single edge instead of three.
- The machine dropdown is gone from inside a terminal pane. Every pane carried a "Foxl Cloud / This computer" picker above the terminal, which looked like the machine that pane was on and was not: a pane runs one session, so switching it mid-run did not move your agent anywhere - it replaced what the pane was showing and left the agent running, billed, attached to nothing. It also printed a machine name the pane's own title prints one line above it. The pane now shows its machine as an icon beside that title - a cloud, a laptop or a server - and where the next terminal opens is the machine picker in the header, which is what that control was always for.
- The footer under a terminal reads as a control now. "New panes run Claude Code (account default)" and "Keeps going when you close your laptop" were both faint grey text with nothing separating them, so the one you can click looked exactly like the one you cannot. The agent picker is a proper field with a chevron on its own footer bar, and the promise underneath stays plain prose. Same treatment on a "This computer" pane, including its acts-without-asking switch.
- Foxl Code's Runtimes is one clean line again. The terminal workspace had grown a toolbar of its own - the pane count, "+ Terminal Cmd+T", a "Watch a run" picker, Equalize and Zoom - stacked directly under the header, on the one screen where height is the whole point. It is gone. Most of it was already somewhere better: the count is the sidebar's list of open terminals, "New terminal" is a row in that list, and Zoom is a button on each pane's own header. New terminal now sits in the header beside the repo and machine pickers, exactly where Tasks keeps New task, and the two verbs that had no other home - Watch a run, Equalize - are in the small menu next to it, along with the keyboard shortcuts.
- "Needs you" is shared by every Foxl Code screen. The right-hand queue of decisions waiting on you - open questions, plans parked for approval, merge-ready and CI-red pull requests - used to appear only on Tasks. It is on Runtimes, Work, Repos, Files and Schedules now, with the same header button opening and closing it everywhere, so you can see what is waiting without navigating away to find out.
Fixes
- Terminal: Korean, Japanese, Chinese and other non-ASCII filenames printed as question marks (
lsshowed???????? ?????? (2026??? 7???).pdf). The server now starts with a UTF-8 locale even when the OS gives it none, which is what a Dock-launched app gets. The same fix applies to the agent's own shell commands, so file paths with non-ASCII names are readable there too. - A coding agent that runs in your terminal now runs in the pane too. Starting Claude Code, Codex, Kiro or any other agent in a Runtimes pane could fail with a Node version error while typing the same command at the prompt just below it worked - the pane ran the agent in a non-interactive shell, which never reads
~/.zshrc(or~/.bashrc), so nvm, fnm, volta, asdf and mise were all invisible to it and the agent was launched by whatever oldernodehappened to be found first. The pane now looks in those install directories as well, and puts a version manager'snodein front when it is newer than the one the shell found. - An agent installed only through a version manager is offered again. The menu of agents was built from PATH alone, which a desktop launched from the Dock may never have been given (and in "keep running when closed" mode is whatever it was at install time), so an nvm-installed
clauderead as not installed at all. - A Foxl Code terminal connects, instead of explaining why it will not. Two refusals are gone. Pressing Reconnect while the agent was still working printed
reconnect failed - its agent is already attachedin red and then made things worse: the live view was torn down and every new one closed on arrival, so a healthy task became an unreachable terminal. It attaches to the agent that is there now, anything you typed goes to it, and the red line no longer appears - including on tasks that already have one in their history. And a session whose cloud workspace had been cleared (a Foxl Code update, or 14 idle days) used to offer only a paid Retry on a brand-new task; it now rebuilds the workspace from your branch and opens the terminal there, saying so in the pane, since pushed work survives and only the uncommitted tail was lost. - The Foxl Code terminal is black again, in light theme too. It had started following the app's colour theme, which made a cloud task's terminal near-white in light mode while every other terminal in Foxl stayed black - Foxl Agent's, and a Foxl Code pane running an agent on your own machine. A split with one of each in it looked like a rendering fault. One terminal surface now, the same in both themes and the same in both products. The panel around it still follows the theme, so its header stays readable in light mode.
- A terminal on this computer no longer prints everything twice. Opening a Cmd+T pane on Runtimes replayed the session's history into it twice, one copy directly under the other, so a reattached agent looked like it had run its banner and its last answer two times. The history had two sources that both wrote into the same buffer, and now it has one. The Foxl Agent terminal drawer could do the same thing on reopen and is fixed with it.
- The Cmd+T terminal now uses the same type size as the Foxl Agent terminal. It was a size larger than both the Agent drawer and the cloud pane it splits beside, so one workspace showed two type sizes for the same kind of surface.
- Open a second local terminal and the first one stopped taking input. Every terminal but the newest went dead: its output stopped arriving, it never re-fitted, it did not even say it had disconnected - and it still forwarded your keystrokes, so the agent received what you typed and you saw none of it. One line caused it (the panel's double-mount guard was shared by every panel on the page instead of belonging to one), and it made the whole split workspace unusable: two Runtimes panes, a split in the Terminal drawer, or a Code pane open beside the drawer were all enough. Sometimes the older pane never painted at all, which looked exactly like a terminal that had crashed.
- A terminal you closed in Foxl Code is now closed everywhere. Pressing X removed the pane and left the shell running: it stayed in the Agent product's terminal list (both products share one pool), the two surfaces disagreed about what was live, and the next pane you opened ADOPTED it - so a terminal you had closed came back with its scrollback. X now ends the session, its process and its saved scrollback. Navigating away from Runtimes still leaves your agent running and still reattaches when you come back, which is the case that distinction exists for.
- A terminal whose connection dropped no longer sits there unable to be typed into. A server restart, an update or a sleeping laptop closed the socket, and the pane printed one "[Disconnected]" line and then swallowed everything - the only way back was to switch away from the window and return. It now redials by itself (five tries, backing off), which is safe because the shell itself lives on the desktop and outlives the connection. A process that really exited is not chased.
- Typing Korean in a terminal now puts Korean on the line. Hangul arrived one jamo at a time -
ㅊㅇㅈㄹㅇwhere whole syllables were typed - because the terminal sent each keystroke to the shell while the input method was still building the syllable, so the half-finished letter went first and the finished one followed. It waits for the syllable now. Both terminals are fixed (Foxl Agent's and Foxl Code's), and the same applies to Japanese and Chinese, which compose the same way. This was always happening; until the locale fix above it showed up as question marks rather than as the wrong Korean. - The bottom tab bar no longer sits on top of a Foxl Code terminal's command box on a phone. It hides while the terminal is open, which is what Foxl Agent's terminal page has always done - the tab bar is drawn by iOS above the whole page, so nothing in the page could get over it.
- A closed terminal said "[Process exited with code null]". It says "[Terminal closed]" now, and closing a session from one surface is reported to every other surface showing it instead of leaving a live-looking pane that silently drops keystrokes.
- The Runtimes list in the sidebar now matches the Tasks list. Its rows were indented further than everything else in that column - a terminal's name started eight pixels right of every nav label, every chat title and every task title - so the one list that looked custom was that one. Same row spec now: same indent, same icon size, same type.
- Only one of the Tasks / Runtimes lists is open at a time. Both expanded at once put two scrolling lists in the Code section and pushed Repos and Files off the screen. The list under the row you are on opens; the other closes. Opening a terminal also stops highlighting two rows at once.
- Foxl Code: new terminals split the same way every time. Cmd+T used to pick the direction from the shape of the pane you were in, so repeated splits alternated between side-by-side and top-and-bottom and you could not tell where the next terminal would appear. It now follows one axis, shown by a button in the header; Cmd+D and Cmd+Shift+D split right and down as before and each one also sets the axis for later.
Features
- Cmd+T runs a coding agent on this computer. "This computer" was a row in the machine list that said "Coming soon" and could not be picked. It is selectable now, and choosing it in the header dropdown means Cmd+T on Runtimes starts a coding agent on your own Mac - Claude Code, Codex, Kiro, Cursor, Copilot, Gemini, Grok, Droid, Amp, Aider, Goose, OpenCode, Charm, Cline, Kilocode, Codebuff, Auggie, Continue, Antigravity, Trae, MiMo Code, Qwen Code, Mistral Vibe, Kimi, Rovo Dev, Devin, Autohand, Ante, Pi, oh-my-pi, Prime Agent, Hermes, Command Code, OpenClaude, OpenClaw - whichever of them you have installed. Or any other CLI agent: point it at your own command and that works too. Foxl finds them itself, and it finds the ones a simple name check misses, because half of these ship under a different binary than their product name (Kiro is
kiro-cliand needschat --tui, Cursor iscursor-agent, Continue iscn, Antigravity isagy). It runs as you, on your own files, with your own credentials, and the agent does not run through the relay. A blank terminal is still one click away if that is what you want. Reopening a pane reattaches to the agent you had, with its scrollback, rather than starting a new one. Dispatching an unattended Foxl task to this machine is still not available (that is the clone-and-push half) and the machine row says so. - Foxl Code tasks can run on a machine you own. Settings > Code > Machines is new. Foxl Cloud stays the default, stays free and is unchanged; alongside it you can now launch an EC2 box in your OWN AWS account, or point Foxl at a server you already have. Your CPU, your disk, your VPC, your bill. The launch runs in your terminal with your own
awsCLI, so Foxl does not need a credential for your account, and the box opens no inbound port: it dials out over a Cloudflare tunnel, so there is nothing to expose and no certificate to install. The wizard shows a monthly estimate for three usage shapes with the price basis attached and a link to AWS's own calculator, and it says plainly that the disk keeps billing while the instance is stopped. - A machine picker in the Code header, and a per-repository pin. The header names the machine your next task will run on and lets you switch it - one list of your machines, with a single "Always use this for \<repo\>" row under it. You can pin ONE repository to ONE machine, which is what makes unattended work land in the right place: schedules and the autonomous loop never pick a machine themselves, so before this a repository that needed the x86 box could only be steered by hand. Precedence is the task's own choice, then the repository's, then your account default, then Foxl Cloud, and anything that falls through is recorded. The dropdown decides where the NEXT pane or task goes, so it never reshapes a terminal you already have open.
- Foxl Cloud is a terminal now, not a form. Picking Foxl Cloud (or your own box) in a Runtimes pane used to give you a box that said "What should this agent do?" and a Run button - a way to file a job, next to a pane on your own Mac that was a live agent you could talk to.
Cmd+Tmeant two different things depending on a dropdown, and only one of them was a terminal. Now both are the same: the pane opens the coding agent on the machine you picked and you type at it, in the cloud exactly as on your own computer - and it keeps going when you close your laptop. Choose which agent, on either machine: Claude Code, Codex, Kiro, Cursor, Hermes or OpenCode, right under the terminal, with a note beside any that still needs a key of yours. Closing a cloud pane does not open a pull request - your work is pushed to that session's own branch and nothing is announced; the agent opens a PR when you ask it to. - Your default coding agent was being ignored unless it was one of three. If you set Foxl Code's agent to Cursor, Hermes or OpenCode in Settings, it was saved, it was shown back to you as your choice, and then every task ran Claude Code anyway. Asking for one of those three per task was accepted and quietly ignored the same way. All six work now, from Settings and per task.
- A terminal workspace for watching runs. Runtimes is a workspace of live terminals now rather than a list of cards, and the panes are a real split layout:
Cmd+Tadds one where it fits,Cmd+Dsplits right,Cmd+Shift+Dsplits down, and dragging the line between two panes resizes them. Up to six, and each one either starts a new agent or attaches to a run already going, so two attempts can be watched side by side.Cmd+Shift+Enterzooms one pane to the whole workspace and back,Cmd+[/Cmd+]move between panes, and Equalize puts every divider back in the middle. Your arrangement survives leaving the page and coming back.Cmd+Fsearches a terminal's 5,000 rows of scrollback. Each pane carries that run's status, backend, model, branch and live spend, and its Stop / Open on GitHub / Copy task id actions. On a phone the workspace shows one pane at a time instead of splitting, since two panes on a phone are too narrow for a CLI to lay itself out in.
Changes
- Stop now really stops a task running on your own machine. Stopping used to update Foxl's records and leave the coding agent running on your box until its time limit, so it kept spending your CPU and your model credit after you asked it to stop. It commits and pushes what it has, then exits.
- Keyboard shortcuts are a settings screen now, and they can be changed. Settings > Shortcuts lists every key Foxl listens for, grouped by product and searchable - type "delete" or type the keys themselves. Press Record on a row, press the combination you want, and that is the shortcut; there is a Reset on any row you changed and a Reset all at the bottom. If two commands that share a screen end up on the same combination, both rows say so and name each other, rather than one of them quietly winning. The keys are printed the way your system writes them - ⇧⌘F on a Mac, Ctrl+Shift+F on Windows and Linux - from one saved setting, so a shortcut you set on one machine reads correctly on the other. Rows the app sets itself (saving a file, a new line in the composer, the ones the editor and the terminal own) are listed too, marked as such, because half of what this screen is for is answering which keys are already taken. Two rows are waiting on the feature they belong to: running a task in the cloud, and running it on this computer.
- Dictate anywhere has its own transcription provider and language. Settings > Notes > Dictate anywhere gains a Transcription provider row and a Transcription language row, just above the cleanup model. Until now dictation quietly used whatever the recording group above it was set to, and nothing on any screen said so - which is the wrong shape for it, because a meeting is an hour of audio once while a dictation is a few seconds of it many times a day. So the two are separate picks now: send dictation to Amazon Transcribe on your own AWS account or to Foxl Relay, independently of what your meetings use. The AWS region stays shared, since one account has one region. The language defaults to Auto-detect, which is Amazon's own language identification - see the fix below.
- Foxl Code search is the app's own search bar now, not a separate popup. Cmd+Shift+F in Foxl Code opened a task-search palette of its own, which on the Mac desktop stacked on top of the search bar at the top of the window - two search boxes for one keypress, neither aware of the other. That palette is gone. Your tasks are a group in the search everything else already uses, alongside pages, conversations and workspace files, with a Tasks filter beside the existing ones; picking one opens it exactly as clicking it in the list does. On the web, Windows and iPhone, where there is no search bar in the window, the shortcut opens the same centered overlay Chat uses and tasks appear there too, so nothing lost a way in.
- First run now ends by asking you to choose a model provider. The setup tour gains a fourth and last card, which opens Settings > Model & provider and points at the provider picker. On a fresh desktop install nothing is configured yet, so the card before it - "Start your first chat" - hands you a composer whose first message comes back as a provider error, and nothing on that screen said where the models come from. The tour closes on that pane and leaves you there, on the one thing that has to happen first. Not shown on app.foxl.ai, which has no provider to set up.
Fixes
- The Terminal works again on Windows too, and typing is the part that was broken. Since v0.6.10 a terminal on Windows showed you the PowerShell prompt and then ignored everything you typed - the output side worked, the input side went nowhere, so the session just sat there. Same root cause as the Mac fix below (v0.6.10 changed the engine the local server runs on) but a different half of it, and one that could not be fixed the same way. Windows now runs the server on the previous engine instead, which restores the terminal. The one trade: searching your conversation history on Windows goes back to the slower method it used before v0.6.10.
- On the web, the cookie notice no longer covers the first thing in the sidebar. On a first visit to app.foxl.ai or code.foxl.ai the analytics notice sat across the whole width just under the header - and the sidebar's top row, Chat, was entirely behind it and could not be clicked until you answered the question. On code.foxl.ai it also covered the page title. The notice now starts where the content does, so the navigation stays usable while it is up. Nothing changes in the desktop app, which never shows it.
- Settings no longer cuts off which transcription provider you picked. "Amazon Transcribe (your AWS account)" was clipped mid-word - with no ellipsis, so there was nothing to say it had been cut - in both Settings > Notes > Recording and Settings > Notes > Dictate anywhere. Those two rows now size to their own text, in every language.
- "Dictate anywhere" no longer appears in Settings where it cannot work. On the web and on the phone the row was listed and opened a screen with a heading and nothing under it: the feature needs to hold a key down for you in other apps, which only the desktop app can do. The row now appears only where it does something.
- The Dictate anywhere screen does not say its own name three times. The pane title, the section title and the first row all read "Dictate anywhere"; the duplicate section title is gone.
- The Terminal works again on macOS. Since v0.6.10 opening a terminal on a Mac gave you a cursor and nothing else: the session really started, but no output ever came back, typing produced nothing on screen, and a shell you exited still showed as running. It was not the terminal itself - v0.6.10 changed the engine Foxl's local server runs on, and on macOS that engine cannot read a terminal's output the way the previous one did. It is read a different way now. Linux was never affected, and Windows uses a different mechanism again. Everything the terminal does is now verified end to end on the engine the app actually ships with, including a 338 KB burst of output, so this cannot go quietly missing again. Nothing else was affected, which is why it took four releases to notice.
- Settings > Appearance > "Reset onboarding" no longer starts setup on top of Settings. It returns to the main screen and restarts setup there. It used to reload the page it was on, so the look picker opened over the settings form you were still reading - startling, and the wrong screen behind a flow whose tour points at the sidebar.
- A tour card no longer misses a control that mounts late. All four tours re-measured for 400ms after switching surfaces and then gave up, so a card whose subject is a lazily loaded page landed in the corner pointing at nothing. They wait for the control to arrive now.
- Dictate anywhere tells you which key to press on Windows and Linux. Holding a key needs something only macOS provides, so on those two systems Foxl quietly used a shortcut instead - Control+Alt+D - and the settings screen printed it nowhere. The note above it even said "the shortcut below is being used instead" with nothing below it, and the switch's own description said the feature "can only listen once macOS allows it", which is not a sentence that means anything on a PC. The shortcut is now a row you can read and change wherever holding a key is unavailable, and the wording says what is actually true on the system you are using. Nothing changes on a Mac.
- Linux says what it needs in order to type. Typing into another app on Linux goes through
wtype,ydotoolorxdotool, none of which Foxl ships - so on a machine with none of them dictation put the text on your clipboard and never explained why. Settings > Notes > Dictate anywhere now names them. - Linux stops reserving space for macOS window buttons. The strip along the top of the window kept 78 pixels clear at its left end for the close/minimise/zoom dots, which only macOS draws there - on Linux the window manager draws its own title bar above that strip, so those 78 pixels were empty and the sidebar button floated in from the edge for no reason. Reclaimed. macOS is unchanged, and Windows never had the strip at all.
- The Linux download no longer carries Windows and macOS binaries. The AppImage included the Windows console helpers and both other platforms' native modules - about a megabyte of files Linux can never load, including Windows debug symbols. They are removed from the Linux build, which is smaller for it. Nothing about how the app runs changes.
- Foxl starts on Windows again without Node.js installed. Since v0.6.10 the app has shipped its own JavaScript runtime for the background server, and on Windows it then refused to use it: a machine with no Node.js or Bun of its own showed "No JavaScript runtime was found for the Foxl server - the install may be damaged", which reinstalling could not fix, because the reinstall put back the same working file. Nothing was damaged. The runtime is named
node.exeon purpose - the "keep running when closed" service records that exact path when you switch it on, so renaming it would strand those installs - and Bun treats being callednodeas a request to behave like Node, in which mode it declines to print its version. That version check was how Foxl decided the file was usable. It asks a different question now, one both runtimes answer under any name. macOS and Linux were never affected: their copies are namednode-arm64andnode-x64, which is not the name that changes Bun's behaviour. - "Auto-detect" detected nothing and transcribed everyone as English. It really detects now. The transcription language row offered an Auto option that asked Amazon Transcribe for
en-USoutright, on both the live-recording and drag-a-file-in paths. So a Korean or Japanese speaker who chose it got a meeting transcribed as English: billed, with no error anywhere, because the connection opens normally and the words come back as nonsense. It reads as Transcribe being bad at your language rather than as Foxl asking for the wrong one. Measured on 5.8 seconds of Korean, the old path returned "And young Isa's semida." Auto is now Amazon's real language identification, and it leans toward your app language so it settles on the right one from the first words instead of guessing for a second. Verified against the real service end to end: the same Korean audio comes back as "안녕하세요, 오늘 회의는 3시에 시작합니다. 미리 준비해 주세요. 감사합니다.", and English audio is still detected as English even with Korean set as the preference - so it is identifying what you actually said, not just trusting the app. It is the default for a new install, it covers recordings, dragged-in files and Dictate anywhere through one shared definition, and it works whether you transcribe on your own AWS account or through Foxl Relay. If you had already picked a specific language, nothing changes. - The transcription language row claimed changes apply mid-recording. They never did - the language is fixed when you press record, including across the reconnect that happens every few minutes, because Amazon binds it when the connection opens and switching would mean losing whatever was mid-sentence. The description now says it applies to your next recording.
- Changing the dictation language did nothing until Foxl was reopened. The dictation pill read the language once, when it was pre-warmed in the background, and never looked again - so a language picked in Settings only took effect on the next launch, while the cleanup model beside it applied immediately. Both are now read at each press.
Features
- Live translation has its own model picker. Settings > Notes > AI features gains a Live translation AI model row, under the target language, so the model that translates each incoming line is yours to choose. It was already a different model from the one that writes your summaries: translation runs once per spoken segment while you are reading the line, so it has always run on a small fast model (Haiku 4.5), where a summary reads the whole transcript once and wants the best model you have. There was just no way to see that or change it. Pick anything your Model & provider can serve, or "Same as Model & provider" to follow Foxl Agent.
Changes
- "AI model" is now "Summary AI model", and "Translation model" is "Live translation AI model". That pane picks a model for three separate jobs - summaries and coaching reports and the meeting copilot, note titles, live translation - and the row labelled just "AI model" gave no clue which of them it was.
- The Model provider row and the Foxl Agent model card are gone from Notes AI features. Both repeated what the section heading above them and the model row below them already said, which is that Notes AI runs on the model you set for Foxl Agent unless you pick one here, and neither could be operated. What survives is the part nothing else on the pane could tell you: when no desktop answers, or the one that answers has no provider set up, the pane says so and offers the door that fixes it.
- One first-run flow instead of two. The old welcome card - the "Welcome to Foxl" feature list, the "Install Chrome Extension" step, and the sign-in / download-the-app step - is gone. A new install now opens straight into the appearance-based setup (pick a look, answer two quick questions), which is the flow that already sets something the app then uses. The Chrome extension still installs from Settings > Web access, and sign-in still appears the moment you do something that needs an account.
- Chat on the web and on the phone says what to do instead of failing. foxl.ai serves no model inference, so a message sent with your desktop unreachable had nowhere to go: it travelled to foxl.ai, was refused there, and came back as an error after the wait. It is answered on the spot now, and the answer names the fix - open Foxl on your computer, where your model is configured once for all three products: your own provider key, a local model, or the Claude or ChatGPT subscription you already have. Nothing else about that screen changes. Your saved conversations still open and read exactly as before while the desktop is away, because that has never needed a model.
Fixes
- Attaching a PDF to GPT-5.6 or Grok 4.6 works. The same file that Claude read without complaint came back
400 Unsupported file type: '<your file name>'on every model served through your AWS account's OpenAI-compatible endpoint - GPT-5.6 Sol/Terra/Luna, GPT-5.5, GPT-5.4 and Grok 4.6 - and the name in that message was missing its.pdf, because Foxl had removed it. Amazon's Converse API (which is how Claude receives a file) refuses a document name containing a dot, so Foxl strips the extension and states the type in a separate field; the OpenAI-style endpoint has no such field and reads the type off the file name alone, so stripping it left nothing to read. The extension is now kept for the models that need it and still removed for the ones that reject it. Measured against the real endpoint with one PDF per model: all six answered 200 and quoted the document's contents back. The same check ran for every file type Foxl can attach: PDF, DOCX, XLSX, CSV, TXT, MD and HTML all read correctly on those models now (as do JSON and XML, which travel as text). - A file those models cannot read says so in words. The two exceptions are
.docand.xls- the pre-2007 Office formats - which AWS's OpenAI-compatible endpoint does not accept even though Claude reads them without trouble. Attaching one used to surface a raw400; Foxl now names the file and tells you to re-save it as.docxor.xlsx, or to ask a Claude model instead. A file in some other binary format gets the same treatment rather than being sent as if it were text.
Features
- Dictation can ask AWS to hurry. Settings > Notes > Dictate anywhere has a Service tier row when your models come from your own AWS account: Priority is the fastest and costs more per token, Flex is the cheapest and the slowest, and Standard stays the default because the premium is a decision rather than a default. Measured on Gemma 4 31B, Priority answered in 499ms against Flex's 1597ms, and it is the single biggest lever on how long you wait with your cursor in another app - bigger than the choice of model. It applies to the AWS models served through Bedrock's OpenAI-compatible API (Gemma 4, GPT-5.x, Grok), and the row only appears when your Model & provider is your own AWS account. If you then point dictation at a model somewhere else with the Cleanup model row below, the tier is simply not sent - the setting follows AWS, not the row above it.
- "Wait for the full answer" is a setting now, on by default. That is what dictation cleanup has always done, and it is the faster of the two: the tidied text arrives in one piece, which is how it has to be pasted anyway. The switch is there for the case that needed it - a model server of your own that refuses a request like this, since some answer only a streaming one. What lands in your document is the same either way.
- Notes, Code and Settings explain themselves the first time you open them. Foxl already gave the Agent product a short walkthrough on a new install - three cards, each anchored to the sidebar row it is about. The other two products got nothing, so Notes opened as an empty editor and Code as an empty task list with no obvious first move. Both now get the same three cards on their first visit, and the control each card describes is ringed while you read it. Settings gets two, and they point at the two features that only live there and that almost nobody found: installing the browser extension, so Foxl can work in the tabs you already have open instead of a separate window, and Dictate anywhere, where you hold one key and talk into whatever app has focus. Each card selects the pane or page it is talking about, so you are reading it against the real thing rather than a description of it. Once each, dismissable with Escape, and both of the Settings > Appearance buttons below bring them back. A tour never appears over a pane you asked for by name - a jump from the command palette lands where you sent it.
- A Reset onboarding button, in Settings > Appearance. It sits under "Show setup again" and does the other half of that job: rather than replaying the look picker and the tour, it forgets that setup was ever finished on this device and reloads, so the welcome screens start over from the beginning - including Foxl Code's setup page. It works on the desktop app and on the phone apps too, which normally skip the welcome card: asking to see it is a different thing from arriving for the first time. Nothing on your account changes and your other devices are untouched, so there is no confirmation to click through - and you can find it by typing "reset onboarding" into the command palette.
- Notes and dictation can each run on their own model now, from any provider you have configured. Settings > Notes has three model rows - AI model (summaries, coaching reports, the meeting copilot), Title model (auto title) and Cleanup model (dictate anywhere) - and each is an independent choice. They all default to following Foxl Agent, so nothing changes until you pick something. The point is that these jobs want different models: a summary reads a whole transcript and wants your best model, while a title is one short line and a dictation cleanup is a punctuation pass you wait on with your cursor in another app, where the cheapest fast model wins. Each dropdown lists everything your configured providers can serve, grouped by provider - your AWS account, your Anthropic or OpenAI key, a local Ollama, and your Claude Pro/Max or ChatGPT Plus subscription - with the provider you are already on first. Picking one here does NOT move your agent chat; it moves only that one row. Two consequences worth knowing: your Claude Max or ChatGPT Plus plan can now write meeting summaries without a separate API key, and auto title has a control at last (it was always a fast model, hardcoded, with no way to see or change it).
Fixes
- Gemma 4 answers in chat now. Picking it still failed with a wall of text about a JSON-RPC error, or with "the provided model identifier is invalid" - which one you got depended on where you picked it. Both are fixed. The previous release fixed this for scheduled and autonomous runs only: chat, the Chrome extension, channel replies and scheduled tasks each build their own request, and the fix had only reached one of them. All of them share one rule now, and a build check keeps it that way.
- Gemma 4 and the other AWS models are in the model lists. Settings > Model & provider offered nothing under "AWS Bedrock" for Gemma 4, GPT-5.x or Grok 4.6 - they were only reachable by knowing to switch the provider dropdown to a second AWS entry - and Settings > Notes > Dictate anywhere's Cleanup model dropdown left them out entirely, while telling you a model you had already chosen was "not served by the provider" and to pick from a list that could not contain it. All three now appear wherever the chat model selector already showed them, because they run on the same AWS account.
- Gemma 4 says what it is for. It was the one model in the chat picker with a blank description line. It now reads "Fast text cleanup and summaries - no tools", which is also the useful warning: it is the cheap fast model for tidying text, and it is not the one to pick for work that needs the agent's tools.
- The Input Monitoring permission has its own row now, like the typing one. In Settings > Notes > Dictate anywhere, "Allow Input Monitoring" used to be a loose button under a warning, and it only appeared while the feature was switched off or while you had picked "Hold a key while speaking" - so if you were on the press-to-start fallback because macOS was blocking the key, there was no way to grant the permission from that screen at all. It is a labelled row beside the typing permission now, on screen whenever the grant is missing. Pressing it still puts Foxl in the Input Monitoring list and opens System Settings at that exact pane, so there is a switch waiting to be turned on.
Changes
- Amazon Bedrock is one provider again. Settings > Model & provider listed it twice - "AWS Bedrock" and "Bedrock Mantle (OpenAI + Grok)" - over the same AWS account and the same credential, because Bedrock serves Claude and GPT-5.x over two different APIs internally. That is our plumbing, not something you should have to pick: choosing GPT-5.6 meant switching provider, and switching took every Claude model off the model list, so the two halves of your own account could never be seen together. There is one Amazon Bedrock row now, and its Default Model dropdown lists everything your account can serve - Claude, GLM 5 and Kimi K2.5 alongside GPT-5.x, Grok 4.6 and Gemma 4. Nothing to re-configure: a desktop already pointed at the Mantle entry lands on the merged row with its model intact, and the request still goes over whichever API that model needs. The dictation Cleanup model list gains the same models for the same reason - it was hiding exactly the small fast ones that row is for.
- The Cleanup model dropdown matches the Default Model one. Settings > Notes > Dictate anywhere listed every option as two lines, the name over its id in monospace, which made the closed control a two-line block sitting in a row of single-line ones. Options are one line with a short provider badge now, and the selected model's id reads underneath the dropdown - the shape Settings > Model & provider has always used.
Features
- Dictation can run on its own model now, picked from a list. Settings > Notes > Dictate anywhere has a Cleanup model row again, and it is a dropdown rather than a box you type an id into: it offers the models your configured provider actually serves, the same list Settings > Model & provider builds. It defaults to Same as Model & provider, so nothing changes until you choose - and choosing does not move anything else, because chat and dictation keep separate selections. The point is that the two jobs want different models: dictation is a short mechanical tidy-up you wait for with your cursor in another app, so the cheapest model that can punctuate a sentence beats the smartest one available. Only the list is shared; the choice is per surface. If a model you pinned earlier is not one your current provider serves, the row says so and the cleanup falls back to that provider's own model rather than failing.
Fixes
- "Allow Input Monitoring" opens System Settings now. In Settings > Notes > Dictate anywhere, that button asked macOS for the permission - and macOS only ever asks you once per app, so every press after the first did nothing at all and the button looked broken. It now takes you straight to Privacy & Security > Input Monitoring, where the switch actually is. The "Open settings" button for the typing permission does the same.
- Dictate anywhere cannot be switched on while macOS is blocking it. The whole feature is a key you hold, so if macOS has not allowed Foxl to notice that key the switch is greyed out and says why, with the button to fix it beside it - instead of turning on and then quietly doing nothing. If you already had it on, you can still switch it off.
- Gemma 4 and Notes AI work again on the default setup. Picking Gemma 4 for chat failed with a cryptic "Generation failed" error, and on a fresh install every Notes AI feature - summaries, auto-titles, the dictation cleanup - reported "the provided model identifier is invalid", because the request used the display model name instead of the id Bedrock expects. Both are fixed: Gemma 4 now answers in chat, in Notes and in dictation, and so does whatever model your Agent is set to. Gemma stays a fast plain-text model (it does not drive the agent's tools), which is what it is built for.
- Recording works again on iPhone and Android. Pressing record on a phone opened the microphone and then stopped, with a message about connecting a desktop. Transcription had moved onto your own AWS account, which the Foxl desktop signs for using the credentials on that computer - so a phone could only record while a computer was awake and reachable, and otherwise could not record at all. A phone now falls back to Foxl's own transcription when there is no computer to borrow credentials from, which is how it worked before, including recording that keeps going on iOS when you switch apps or lock the screen. Nothing changes on the desktop, or on a phone that can reach your desktop: those still transcribe on your own AWS account.
- A refused microphone says what to do about it. Instead of the browser's raw "Permission denied", the message now names the permission to allow. Android also no longer claims "no microphone found" before the permission prompt it needs has even been answered.
- Dictate anywhere now actually types the result, on all three platforms. The paste was the one step that could fail without saying so, and it failed three different ways. On macOS it went through an AppleScript keystroke, which needed a second permission beyond the one the settings screen asks for and, when it did run, could report success while typing nothing at all - measured 0 out of 16 attempts. It now posts the keystroke directly, needs only the Accessibility permission you were already asked for, and can answer whether it holds it instead of guessing: 13 out of 13 in the same test. On Linux the first tool tried was one that cannot work on a Wayland desktop (the default on current Ubuntu, Fedora and Debian), and it left the Control key held down afterwards, so your next keypress became a shortcut - the Wayland tool is tried first there now, the modifier is released, and a third tool covers desktops with neither. On Windows there is a second mechanism for machines where company policy blocks the first.
- The pill tells you when it could not type. A failed paste used to close the pill exactly as a successful one does, so dictation appeared to work and the words simply never arrived. It now says the text is on your clipboard, and a missing permission still says which permission.
- Your clipboard is no longer risked on a paste that will not happen. Foxl checks that the dictation really reached the clipboard before pressing paste - if another app is holding the clipboard open, pressing paste would have typed whatever was there before, which can be something you never meant to paste.
Features
- Dictate into any app, not just Foxl. Settings > Notes > Dictate anywhere: hold a key, say what you mean, let go, and the tidied-up text is typed straight into whatever had your cursor - a mail draft, a terminal, someone else's chat box. The default key is Fn (Globe), and you can pick another (either Command, Option, Control or Shift key - left and right are separate - or F13-F15). A small pill appears at the bottom of the screen while it listens, showing a live waveform, then a spinner while a model cleans up what you said: filler removed, your own corrections applied ("Thursday, wait, make that Friday" becomes Friday), punctuation and lists added. The cleanup runs on whatever Settings > Model & provider is pointed at, the same model as chat. On by default, but it cannot hear anything until you allow it: macOS asks for two separate permissions - one to notice the key you are holding, one to type the result into other apps - and the settings screen tells you which one is missing. Until Foxl can type, the text is put on your clipboard instead, so nothing you said is lost. There is also a press-to-start / press-to-stop shortcut for setups where holding a key is not available. Desktop only, macOS for now.
- Google's Gemma 4 31B is selectable now, on Bedrock with your own AWS account. It is the cheap fast tier rather than a frontier model: $0.14 per million input tokens against Opus's $5, 256K of context, and a complete short answer in under half a second. Useful wherever you want a quick mechanical answer instead of a considered one. Available in all four Bedrock regions that serve it, so nothing is pinned. The two smaller variants Bedrock also serves are deliberately not offered: the smallest transcribed a self-correction instead of applying it on all ten test runs, and the middle one is correct but slower than the 31B at the same price.
- The Chrome extension is on the Chrome Web Store now, so installing it is one click. Until today the only way to give Foxl your real browser was the manual one: download a zip, unzip it, open
chrome://extensions, turn on Developer mode, choose "Load unpacked" and point Chrome at the folder - and then live with Chrome asking you to disable developer-mode extensions on every startup. Foxl now offers the store listing where you need it: a step in onboarding, and the primary button in Settings > Web access. Chrome keeps it up to date on its own and the startup warning is gone. The manual route is still there as the second button - it downloads the extension's source and you load that folder - because a store install is not always possible: an enterprise policy can block the Web Store, some Chromium forks do not carry it, and the store build is one review behind a release. - Foxl Notes AI now runs on the model you set for Foxl Agent. Settings > AI features no longer has a model of its own: summaries, auto-titles, coaching reports, the HUD ask and live translation all use whatever Settings > Model & provider is pointed at - Bedrock with your own AWS account, an Anthropic / OpenAI / Google API key, a Claude Pro or ChatGPT subscription, Ollama, or any OpenAI-compatible endpoint. One setting for chat, Notes and Code, and the panel names the provider and model it will use with a link to change it.
Changes
- Conversation search is about 3 times faster, because the agent server runs on Bun now. Foxl ships its own JavaScript runtime for the background server, and that runtime changed from Node 22 to Bun 1.4. The reason is search: the Node build Foxl shipped had no SQLite full-text support, so searching your conversations scanned every message in the database every time. Bun's does, so the full-text index Foxl has always tried to build finally builds. Measured on a real 1 GB library of 1,967 conversations and 25,256 messages, the same eight searches took 591 ms instead of 1,820 ms, and returned exactly the same results. Searching also stops getting slower as your history grows. The first launch after this update is a one-time exception: it builds that index, which took about 2.4 seconds longer than a normal start on the library above and added about 36 MB to the database. Every launch after that is back to normal. Nothing about your data changes and nothing needs re-importing, in either direction - going back to an older Foxl works too.
- Smaller download, less CPU. The macOS download drops by about 16 MB and the installed app by about 81 MB, and Linux by about 39 MB, because the new runtime binary is smaller. The server also uses roughly a third less CPU for the same work, which matters most on a laptop where Foxl runs all day. Two costs in the other direction, both measured rather than estimated: Windows grows by about 6 MB, where the old runtime happened to be the smaller of the two, and the server holds about 23 MB more memory while sitting idle. Startup time is otherwise unchanged.
- The Flag control on an AI reply is switched off. Reporting a model's response was added in v0.6.9 and is now behind
AI_RESPONSE_REPORTS, off, so no Flag button appears in an assistant turn's action row on Foxl Agent or Foxl Code. Reporting and blocking a message written by another PERSON, in channels and DMs, is a separate control and is unchanged. Nothing is deleted: the dialog, the relay route and its migration all stay, so turning it back on is one line. - A reply no longer carries the time of day. In a transcript you read top to bottom,
07:06 PMunder every answer was information nobody asked for. The usage receipt it used to open now has its own button, beside Copy and Regenerate.
Fixes
- Voice dictation no longer loses the first words you say. The microphone opens before the transcription socket does, and every audio frame captured while that socket was still connecting used to be thrown away - so anything spoken in the first fraction of a second was simply gone. The audio is held and sent the moment the socket is live. Most noticeable if you start talking immediately rather than waiting for the mic button to light up.
- Dictation is faster from the moment you start speaking to the moment the text appears. Three things, each measured: audio now reaches the transcriber in 64ms frames instead of 256ms ones; the wait after you stop talking ends when the transcriber says it is finished rather than after a fixed 1.5 seconds; and the partial-results stabilization that Notes needs for a live meeting transcript - and that dictation never reads - is switched off there, which alone took the first words on screen from 1145ms to 626ms. Meeting transcription is unchanged.
- The token counts in the titlebar panel and the ones on a reply now say the same thing. They were two readings of the same rows and they disagreed in public: for one turn the panel reported
Input tokens 90.6KandCached 90.6K (100%)while the reply's own receipt reportedInput 4,Cache read 45.1K,Cache write 45.4K - the panel had added the three counts together and called the total "Input", then printed the same total again on a second row. The context readout split the same way:
5%in the panel,45.4K / 1.0Mon the reply. The panel now renders the reply's receipt, so there is one set of labels, one formatter (a million tokens used to print as "1000.0K" in the titlebar) and one pair of thresholds on the context bar. Only the heading differs: the model on a reply, "This chat" or "Usage - last 24h" in the panel. - "Auto-approve all tools" is on by default again, and it now actually applies. A fresh install approves every tool call without a prompt, as it did before v0.6.9, because an approval modal stalls the runs Foxl exists to do unattended - a schedule, a request from your phone, a Slack mention - and a stalled tool call times out and reads as a failure rather than as a question. Two things changed: the default is seeded once per install, so turning the switch OFF now stays off across restarts instead of coming back at the next launch; and the switch is no longer ignored when the app sends its first message immediately after start-up, which could leave Settings showing it ON while
execand the terminal kept asking for the rest of the session. - Foxl Relay is no longer offered where it cannot answer. foxl.ai serves no model inference, so it is gone from the provider list in Settings > Model & provider and from the Notes AI provider row instead of sitting there marked "Ready" and failing on use. Nothing is removed: the option comes back on its own if hosted inference is switched back on.
- A desktop that is not reachable now says so when Notes asks it for a summary, instead of quietly writing an empty one over the note.
- Recording on the iPhone is back to the microphone alone. v0.6.9 added system-audio capture through iOS's broadcast sheet, so every recording asked you to confirm a second dialog before it could hear the other side of a call. It is removed: press record and it records, with no extra tap and nothing to dismiss. The "Capture system audio" setting goes back to being a Mac-only option, where the system grants the capture without asking. Nothing else about an iPhone recording changes - it still keeps running with the screen locked, still transcribes live, and still saves audio you can tap a line to replay.
- Stopping a recording works again on a phone. The tab bar at the bottom of the screen is a floating capsule that the page passes underneath, and Foxl Notes was the one screen that never made room for it - so the Stop button sat under the tab bar, and tapping Stop navigated you somewhere else instead of ending the recording. The whole Notes screen now ends above the tab bar, which also brings back the last row of the recents list on the Notes home and the bottom of the Add-context screen.
Features
- Foxl Notes can now run its AI on a model you host yourself. Settings > AI features has a Model provider row: keep Foxl Relay, or pick Self-hosted and give Notes the base URL of any OpenAI-compatible endpoint - Ollama, vLLM, LM Studio, llama.cpp's server - plus the model name it serves, and an API key if your server wants one. Summaries, auto-titles, coaching reports, live translation and the floating meeting copilot all go there instead of to foxl.ai, and none of it needs a Foxl account: the AI switches turn on as soon as the URL and the model name are both filled in. Recording and transcription are unchanged. The model list and the translation-model picker are hidden while Self-hosted is selected, because your endpoint serves the one model you named rather than a catalog.
- Foxl Notes transcribes with your own AWS account now, and it finds your credentials by itself. Settings > Recording and transcription has a Transcription provider row set to Amazon Transcribe, and there is no key to enter: Foxl signs the connection with the same AWS credentials the rest of the app already uses - environment variables,
~/.aws, the profile you picked under AWS Authentication, a live SSO session,credential_process, an instance role. The panel says which one it found and offers a Re-check, so you can tell a working setup from an expired SSO session before you press record. The only thing you set is the region. Everything downstream is unchanged - live captions, speaker labels, click-to-play timestamps, dragging an existing audio or video file in to transcribe it - and none of it needs a Foxl account or Foxl credits, because Amazon bills you directly for the audio. Foxl Relay is still listed as the other provider but no longer transcribes; if that was what you were using, choose Amazon Transcribe to keep recording. - Foxl Code runs on your own Claude or ChatGPT subscription now. Foxl does not sell model access, so cloud coding tasks had nothing to reach a model with. Open Foxl Code > Settings and you will find Agent credentials: if Foxl Desktop is running on the same computer, press Sync and it hands over the Claude Code or Codex login you already have there - nothing to copy, nothing to paste. On the web you can upload the credential file instead. Your subscription is stored encrypted, is never shown back to you, and is removed from the task machine when the agent finishes. Foxl keeps track of when it expires and renews it on its own where it can; where it cannot, the Settings page says so rather than letting a task fail for a reason you cannot see.
- Bring an Anthropic API key instead, if you would rather. Same section. It works for Claude Code and it is what the OpenCode assistant uses - it cannot use a subscription, because only Claude Code and Codex can sign a request with one.
- Every assistant now says why you cannot use it. The picker used to grey a backend out with "Not provisioned" whether it was genuinely unavailable or simply waiting on a key of yours. Those are different problems, and only one of them is yours to fix, so they now read differently - and Kiro, which was switched off wholesale, is available to anyone who adds their own Kiro key.
- You can now report a message and block the person who sent it. Channels and DMs let one person's text reach another, and until now there was nothing to do about a message you should not have received. Long-press any message from someone else on a phone, or use its
...menu on a computer: Report opens a short form with a reason and an optional note, and Block stops the two of you seeing each other's messages and stops either of you starting a new direct message. Blocking is reversible from Settings > Account > Blocked accounts, and the person is never told. The report form can do both at once, since somebody who has just been harassed usually wants both. - AI replies are reportable too. Every response now carries a flag button beside Copy, using the same reason list. Replies come from third-party models that apply their own safety filtering, and this is how you tell us when that was not enough.
- Settings > Appearance > Surface now offers fourteen washes instead of two, grouped like a colour picker. Dawn and Mist are still there, under Washes, alongside Sand and Sage. Colors is a row of six single-hue tints - Blue, Violet, Pink, Coral, Crimson, Green - for when you want the sidebar a particular colour rather than a particular mood. Spectrum is new and holds the gradients that run through more than two colours: Rainbow, Trans, Sunset and Aurora. Every swatch paints the real thing, so the tile you press is the colour you get, and picking one still leaves the reading area untinted. Each of the fourteen was tuned so the sidebar's labels keep exactly the contrast they have with no wash at all - turning this on never costs you legibility, in light mode or dark.
- Settings > Notifications is now one screen for every kind of notification Foxl sends. It used to be two different screens behind the same name, and which one you got depended on the device you opened it from: on a computer you saw the banner rules for that machine and could not see or change what gets pushed to your phone, and on a phone you saw the push categories and could not see the banner rules. Neither screen mentioned that the other existed. Now there is one screen, grouped by where a notification actually arrives: this device, your phone, and email. Your phone's push categories are settings on your account rather than on the handset, so you can turn one off from your desktop without picking up your phone.
- Email notifications can finally be changed from inside Foxl. Product updates and tips were only adjustable through the link at the bottom of one of those emails, so if you had deleted it, or never got one, there was no way to change them, even though the page that link opens told you to manage them in your account settings. Both are in Settings > Notifications now, along with a clear notice if you have previously unsubscribed from everything, and a way back if you want to. Sign-in links, receipts and payment problems are part of the service and are not listed, because they cannot be turned off.
- Messages from any connected channel can be silenced. Foxl supports 41 channels, and only five of them had a switch. A message arriving from Signal, Matrix, Teams, LINE, IRC or any of the other 36 always raised a notification with no way to decline it. There is now an "Other channels" switch covering all of them.
- Foxl Notes on iPhone can now record what you HEAR, not just your microphone. With earphones or AirPods in, the other side of a meeting plays inside your ears and never reaches the microphone, so an iPhone recording came back one-sided - your voice and nothing else. The desktop app has captured both sides for a while; iOS now does the same. Press record and iOS asks you once to confirm; from then on the audio of whatever you are listening to (meeting apps, calls in other apps, voice messages) is mixed into the same transcript as your own voice, with one speaker stream, so nothing is transcribed twice. Decline the confirmation and the recording simply continues from the microphone alone, exactly as before. Turn it off under Notes > Settings > Recording > Capture system audio. Two limits worth knowing, both set by iOS and not by Foxl: cellular phone calls cannot be captured at all, and copy-protected playback is muted by the system.
- Recording from your phone or from app.foxl.ai no longer leans on your computer every few minutes. Amazon caps a transcription connection at five minutes, so a recording quietly reopens one throughout a meeting - and on a phone each of those used to be a round trip to your desktop, in the middle of the audio, with the recording stopping if the machine went to sleep. Your computer now hands the phone a one-hour pass that can do exactly one thing, start a transcription, and the phone reopens its own connections locally after that: nothing to wait for, and an hour-long meeting keeps recording even if your desktop sleeps. If your AWS account cannot issue such a pass (AWS SSO cannot), your computer signs each connection instead, exactly as before, and needs to stay reachable for the meeting.
Fixes
- Reconnecting to a task no longer loses your credentials. Pressing Reconnect re-launches the assistant, and it was being launched without the credential the original run had - so a task with a perfectly good workspace could not reach a model.
- The Foxl tile in Settings > Appearance > Color theme showed a blue dot for a palette whose buttons are black. Every other palette's tile paints the colour that palette's buttons and active states use, so Emerald's dot is that green and Dracula's is that purple. Foxl's tile took the brand blue instead, which the theme reserves for selection outlines - so the one tile you would use to go back to Foxl was the only one not describing itself. It now shows the same black (white in dark mode) the theme actually leads with.
- Your profile photo now reaches the people you message. A photo you picked on the Account page was only ever saved on the device you picked it on, so it showed up in your own sidebar and nowhere else: every message you sent to a team channel still carried your old picture, for you and for everyone in the channel, and your phone and your other computers never saw the new one either. The photo is now saved to your Foxl account, so it appears everywhere your name does - channels, DMs, member lists, mentions and huddle invites - on every device you sign in to. Remove photo now clears it for everyone too, instead of only on the device you press it on.
- On the web app in a browser, Settings > Notifications showed a full set of switches for desktop banners that a browser cannot show. They did nothing at all. That section now says so in one line and points at push and email, which do work there.
- Two entries in the notification test picker, WhatsApp and Web, showed an internal placeholder instead of their names in every language.
- The "Run now" menu in Settings > Heartbeat no longer carries its own two test-feed items. They fired the same notifications the test picker in Settings > Notifications already sends, and that one exercises the full path including the buttons and the link the notification opens.
- The Notifications settings screen no longer offers the phone push list to someone who is signed out, where saving could never have worked, and says to sign in instead.
- Opening notifications from the bell no longer shrinks the screen behind it. The bell sits in the sidebar footer, so on a phone the menu is already open and pushed back when you press it - and the sheet then scaled that whole view down a second time, sidebar included, springing it back on close. The sheet now opens over it flat, the same way Settings already did. Sheets that do leave a screen visible behind them, like the model picker, still lift off it as a card.
- The Sign In page no longer scrolls, and the form is now actually in the middle. Opening Sign In from the sidebar put a scrollbar on the page at every window size, however tall you made the window, and left the form sitting slightly below centre. The page was asking for the full height of the screen while living inside the area below the header, so it always overflowed by exactly the height of the app's own chrome - 62px, at every size measured. It now fills the space it is actually given, so there is no scrollbar unless the form genuinely does not fit, and it is centred in that space.
Changes
- Foxl is free, and nothing in the app or on the site says otherwise any more. Credits, usage meters and upgrade prompts described a balance that cannot be spent: Foxl supplies no model inference, so those credits had nothing to buy. Gone from the sidebar (the "12% used" bar and the Upgrade link), from Account (Credits, the per-model usage breakdown, the storage cost) and from Foxl Code's own account screen (credit balance, compute and storage totals, the per-model chart and the ledger). What is left on Account is your profile, which is what an account screen is for.
- The website no longer advertises plans it will not sell. The pricing section on the Foxl Code page is gone rather than trimmed to a single free column, the Pricing and Refunds links have left the footer, and the credit price table has left the pricing page - it quoted a per-message price for messages that cannot be sent. The Terms now have a short "Price" section saying Foxl is free instead of a subscriptions-and-payment one, the Refund policy says there is nothing to refund, and the privacy policy no longer lists a payment company among the services your data reaches, because it does not reach one. Both pages stay where they were, so any link to them still works.
- The collapsed sidebar is back to the shape it had in v0.6.2. Pressing Cmd+B leaves the narrow bar showing the pages of the product you are in, with your chats and tasks along with them as their first letters; Notes and Code are not offered there, as before. Widening the sidebar again is one click on it.
Features
- The Agent / Notes / Code switcher is back at the top of the sidebar. This release had replaced it with three rows in the navigation, one per product. The idea was that you could always see all three - but the two you are NOT using then sat above the pages and the list of the one you are, and on a phone, where the drawer is the whole screen, that is the most expensive space there is: in Foxl Notes, Agent came between the Notes row and your own recordings. Putting the current product's row first was tried and moved the cost around rather than removing it. The segmented toggle carries the same three destinations in the height of one row, so it is back, and the sidebar below it is your product's pages again. All three names are still on screen at all times, and the collapsed icon rail still lists the products since the toggle is hidden at that width.
- You can now get Foxl updates a release early, under Settings > Updates > Beta updates. Turn it on and the desktop app starts offering beta builds as soon as they are put out, before they go to everyone. A beta is the same Foxl signed the same way, using your normal account and your normal data - it is not a separate environment or a test server, only the app itself is ahead. When the matching stable release ships you move onto it automatically, so you are never left behind on an old beta. Turning the setting back off keeps you on the build you are running until that stable release arrives rather than putting you backwards onto an older one. Beta builds are marked as prereleases, so leaving the setting off means you will never be offered one, and the download links on our site always point at the stable release.
- Every reply now carries a receipt. Hover an assistant message and its timestamp appears; open it and you get the model that answered, the tokens it read and wrote, what the prompt cache saved, how full the context window is, and the estimated cost of that turn. It is the whole turn rather than the last model call, so a reply that ran six tools reports what the reply cost. There is no new button in the message footer: the timestamp is the door, so the transcript gains a fact and no extra chrome. Rows recorded before this update show the model and the time and simply omit what was never measured.
- The status HUD in the titlebar can now keep its numbers on screen instead of behind a click. Clicking it still opens the same panel it always did - tokens in and out, how much of the prompt was cached, estimated cost, context used, which MCP servers are connected, which tools have been called - and that stays the default. What is new is a switch in the corner of that panel: turn it on and those readouts move into the bar itself as one segmented pill, updating live while an agent works, so watching a long run no longer means holding a dropdown open. The status dot at its left folds the readouts away and brings them back when the window gets tight, and the chevron beside them opens the full panel exactly as before, so nothing becomes unreachable in either shape. CPU, memory and disk are deliberately not there: those describe the machine rather than the run, and the System page already answers them.
- You can choose which key sends a message. Settings > Appearance > Send messages with: Enter (Shift+Enter for a new line, the behaviour Foxl has always had) or Cmd+Enter, which turns Enter back into a plain new line for anyone who writes long prompts. Command+Enter sends in both modes. The choice is remembered per device, because the right answer depends on the keyboard in front of you.
- Pin the chats you live in. Any conversation's context menu now has Pin, and pinned chats sit in their own group at the top of the sidebar instead of sliding down the list every time you answer something else. Up to eight, per device.
- Open a second conversation beside the one you are in. "Open beside" in a chat's context menu docks it as a resizable pane on the right, so you can read one thread while writing in another instead of bouncing through the sidebar and losing both scroll positions. The pane is read-only for now, and "Open here" swaps it into the main pane when you want to answer in it. Desktop widths only, and the width is remembered.
- File paths in a tool's arguments are clickable. A path in an expanded tool row (what
file_writejust changed, whatfile_readlooked at) opens the workspace viewer at that file, and at the cited line when the tool named one. Backticked paths in the model's prose have been Cmd-clickable for a while; the ones in the rows underneath were the last dead ones on screen. - A scheduled heartbeat can wait for something to happen.
HEARTBEAT.mdtakes an optionalwatchblock with a shell command: Foxl runs that cheap command on the interval and only wakes the agent when its output or exit code CHANGED, then hands the agent that output so the run starts knowing what it is reacting to. A 24/7 agent stops paying for a model turn every interval to discover that nothing happened, and the interval can get shorter rather than longer. Off unless you configure it. - Schedules ships with four pre-made jobs, and every one of them is switched off. A morning briefing on weekdays at 8:30, an evening wrap-up at 6:00, a Friday weekly review, and a Sunday pass over what Foxl remembers about you. They are there so the page shows what the agent can do on a schedule instead of an empty list, and nothing runs until you turn one on - Foxl does not start doing work on your machine because you installed it. They are otherwise completely ordinary schedules: edit the prompt, change the time, Run now, delete. Deleting one is permanent - it does not come back on the next launch, which is the part that decides whether a shipped row is furniture or yours. And when you want it back, "Start from a pre-made schedule" appears under the list with exactly the ones you do not currently have; picking a card opens the normal form already filled in, so you can read the prompt and adjust the time before you save it. An install that already has schedules of its own gets nothing added to it by this update.
- Grok 4.6 is selectable everywhere Foxl runs a model. xAI's frontier model for coding, agentic work and knowledge work is now in the picker on the desktop app, app.foxl.ai, the phone apps, Foxl Notes and Foxl Code - on your Foxl credits, with no xAI key, and also on the desktop with your own AWS account. It brings a 500K-token context window and four reasoning depths (low, medium, high, xhigh); reasoning is always on, so turning thinking up asks it to think longer rather than switching it on. It lists at $2.20 per million input tokens and $6.60 per million output, which puts it between the fast and flagship GPT tiers, and it is available on Pro and above.
- A file Foxl writes for you arrives whole, or not at all. Until now the agent had no way to write a file except by handing it to the shell, and the shell reads the contents: a dollar amount like
$0.35, anything in backticks, or an&in the filename could be taken as an instruction instead of text, and a long document could stop halfway and still be reported as saved, because a half-written file looks exactly like a finished one from the outside. Foxl now writes files directly. The contents are passed as data, so nothing in them is interpreted; a replacement is swapped in as one step, so an interrupted save leaves your existing file untouched instead of half-overwritten; and after writing, Foxl re-reads the file and reports its real size and checksum, so it can tell you a file is saved only when it has actually seen it on disk. Long documents are written in pieces and joined as they go, which is what makes a 25 KB note reliable.
Changes
- "How much may Foxl do on its own" is one card in one place now. It used to be two, on two screens: Settings > Autonomy held the switches (start agents without asking, find its own work, merge its own green PRs) while the Schedules page held the clock (how often it checks, how often it looks for new work, quiet hours) - and each screen carried a paragraph telling you the other half was somewhere else. They are the same question, so they are the same card: Autonomy, on the Schedules page in Foxl Code, under the schedules it governs. Every switch, every timer and the loop's own health line are still there, and each interval now sits directly under the switch it paces instead of being a number with no subject - the check interval and quiet hours under "wake up on a timer", the survey cadence under "find work when the queue is empty". One Save button, and Settings no longer has an Autonomy pane. The daily spend cap stays in Settings under Defaults & budget, beside the per-task ceiling, because money is not timing.
- Foxl is free, and it now runs on your own model access rather than ours. The Pro and Ultra plans are no longer offered, and foxl.ai no longer serves model inference - so Foxl asks you to bring a provider key, point it at a local model, or sign in with a Claude or ChatGPT subscription you already pay for. That last option is the one worth knowing about: if you already have Claude Pro/Max or ChatGPT Plus/Pro, Foxl adds no bill at all. Everything else the service does is unchanged - accounts, cross-device sync, the desktop tunnel, Channels, notifications and shared folders all keep working exactly as before. If a request does reach our model endpoint it is declined with a message saying which of the three options to pick, rather than failing silently or signing you out. This is a switch rather than a removal: nothing was deleted, and the plans and hosted models can be turned back on without you reinstalling anything.
- Work's "Needs you" tab is one list now, in priority order, and every card can be dismissed. It was three lists stacked on top of each other, one per source, and it looked and behaved like it: three different card sizes in the same column, three ways of printing a repository (
acme-webon one card,foxl-ai/acme-webon the next), three ways of printing an age (waiting 4d,26d ago,idle 185h), and buttons that were stretched to fill one card and label-width on the one below it. Because the blocks were never sorted against each other, where a card landed depended on which list it came from rather than on how much it mattered: hard-capped runs from 26 to 91 days ago sat above pull requests that were approved and one press from shipping. Now every row is ranked on one scale, most blocking first: a question holding up an agent, then a plan waiting for your go-ahead, then finished work you only have to merge, then work Foxl can be sent back to do, and post-mortems last. Oldest first within a tier, so the thing you forgot floats up. - Dismissing works everywhere, with one press. The red-build rows could not be cleared at all, so they sat there for days with no control that would remove them. Suggestions could, but it took three interactions through a menu and a text field. Every card now has an X in the same corner (44px on a phone), and hiding one hides the whole subject rather than leaving a sibling row behind. Explaining why is still offered, under the card's own menu, because that is what stops Foxl proposing the same thing next week. A red build you hide comes back if it fails again: the dismissal is per failure, not a permanent mute. The one card with no X is a plan waiting for approval, because there is nowhere else in the app to find it.
- The same piece of work no longer appears twice, or contradicts itself. One failing build could produce two cards with two "Fix it" buttons, and one task could show "Approved and waiting on you to merge" directly above "This run has shown no sign of life", with a Merge on one and a Retry on the other. Everything about one pull request or one run is a single card now, and a second thing worth knowing about it appears as a quieter line underneath instead of as a card that argues with the first. A run that finished and is waiting on you is also no longer reported as dead.
- The repo filter now narrows the whole tab. It used to skip part of the list, so picking a repository still left other repositories' rows on screen and the control read as broken. Rows that belong to no repository still always show.
- Switching product keeps your place, and Settings is one row. Going back to a product returns you to the page you were last on in it, instead of resetting you to its front page: Files, then Notes, then Agent now ends up back at Files. Cmd+1 / Cmd+2 / Cmd+3 jump between the three and restore your place too. There is one Settings row instead of a different one per product. And clicking Notes when you are already in Notes opens a fresh empty note, the same as Cmd+N - Agent and Code have their own Chat and Tasks rows for that, and Notes did not.
- Nothing in the sidebar is tinted to show where you are. The current product was briefly painted in the accent blue; the switcher marks it as a raised tab instead, and a page you are on is marked more quietly than the headings above it. The one coloured highlight in a list should be the thing you have selected, not the heading above it.
- The Files view's top row on a phone is one Refresh button now, not three. v0.6.6 turned those three icons into glass chips, and two of them did not belong on a phone at all: open-folder reveals the workspace directory in a desktop file manager, which a phone does not have, so it was a control that could only ever do nothing, and search duplicated scrolling a list that is already the whole screen. Refresh keeps the 44px chip that matches the sidebar toggle beside it. The desktop toolbar still has all three buttons, unchanged.
- The narrow icon sidebar is legible again. Collapsed, it now shows the three products at the top, a divider, and then the pages of whichever product you are in - all in one centred column, with the one you are in marked. Before, the product icons and the page icons sat in two columns eight pixels apart, and your conversation list came along as a stack of single letters (one per chat title) between them, which pushed the icons that mean something off the bottom. Lists do not appear in the narrow bar at all now; the row above each one is its door.
- The phone's bottom bar is one row for the whole app and no longer rearranges itself. It used to be a separate row per product, which meant tapping a tab could replace the row it was in, and on Foxl Notes there was no bottom bar at all - the app's main navigation simply vanished on one of its three products. The shipped row is now Chat, Notes, Tasks and Channels: each product plus your workspace conversations, one tap from anywhere. It is still yours to change under Settings > Bottom bar - any destination, any order, up to five, labels on or off - and if you had already customised a row, that row is what you keep.
- The cookie notice on our websites is live, because Google Analytics is now actually configured. The consent-gated tag has been in the code for a while with no property behind it, which meant the notice never appeared and nothing was ever counted. Now foxl.ai, docs.foxl.ai, app.foxl.ai and code.foxl.ai ask once, on your first visit, and the answer is remembered for every one of them - one cookie on the parent domain, so you are not asked four times. Decline and nothing is loaded: no gtag.js request, no analytics cookie, no page view. Accept and we count page views (via Google Analytics). "Cookie settings" in the foxl.ai footer takes the choice back at any time, and withdrawing stops collection in the tab you are already in rather than just clearing a cookie. The Foxl desktop app and the iOS and Android apps contain no analytics and send no analytics data, which is why they never show the notice - a hostname allowlist keeps the tag on the four websites and nowhere else.
- Settings > Tab bar is no longer shown in the desktop app. The row of tabs it arranges lives at the bottom of a phone screen, and the desktop window cannot be made narrow enough to draw one - so the pane sat there editing chrome that build never shows, and desktop search offered its rows as though they led somewhere. Both are gone on the desktop. Nothing changed on the phone or in the browser: the pane is still there, still per-device, and still says that what you set is saved on this device and takes effect at phone width. No layout you have already arranged is touched, on any device.
Fixes
- The second card of the first-run tour pointed at nothing, and now it introduces your own agents. It was about connecting apps, and it was written when Integrations was a row in the sidebar; that moved into Settings a release ago, so the callout had no target left and floated in the empty space beside the list - which reads as a rendering fault rather than as a tour. It now points at Agents, a row that is really there, and says what that screen is for: give a worker its own instructions, its own tools and its own model, then hand it the jobs you would rather not do twice. Connecting apps is still where it was, under Settings.
- Deleting a file no longer leaves the app unable to be clicked. Right-clicking a file in the Files tree, choosing Delete and confirming it deleted the file correctly and then stopped the whole window from responding to the mouse - no dialog on screen, no error, nothing to do but reload. Keyboard still worked, which is what made it read as the app having crashed. Two copies of one internal library had ended up in the build, and each kept its own idea of whether the page was supposed to be clickable: the right-click menu handed the page back, and the confirmation dialog then took it away again on its way out. Now there is one copy, so the lock is released by whoever took it. Two other confirmations opened the same way and are fixed with it - "Restart" on the relay under Mobile/Web, and archiving a shared skill.
- A brief disconnect no longer takes over the screen. Losing the agent connection for a few seconds used to raise a full-screen panel with a blur over whatever you were reading, six seconds in, including for the reconnects that heal themselves a moment later. Now it starts as a small chip under the header with a Retry button, the transcript stays readable and scrollable underneath, and the full panel is kept for an outage that is actually persistent or has stopped healing itself, where it has a reason and a countdown to show you.
- A message typed with no signal is queued instead of lost. On the phone and the web app, sending while offline used to fail the request and turn your text into an error bubble. It now goes into the send queue above the composer, which says it is waiting to reconnect, survives the app being killed, and sends in order the moment the network is back. The queue's existing Remove and Send-now controls work on it.
- Selecting text in a tool row no longer collapses the row. Dragging across a command to copy it ended in a click on the row, which folded it and threw the selection away.
- Copying a reply now pastes the reply and nothing else. Selecting an assistant message and pasting it into a document brought two empty grey boxes along above the text - the message's own Copy and Regenerate buttons, which sit in the same row as the words - plus the "Thought for 4 seconds" and "Used tools" lines and, in a dark theme, the app's own text and background colours. What lands on the clipboard now is the message: its paragraphs, headings, lists, tables, code blocks, links and any image you attached, in your document's own styling.
- A model you picked from one of the third-party providers now runs your agents, not just your chat. Choosing DeepSeek, Groq, Z.ai, Kimi, Qwen, OpenRouter, Together, Mistral, Fireworks, Perplexity, xAI, Cerebras, SambaNova, Cohere, AI21, HuggingFace or MiniMax worked in the chat pane and quietly did not work anywhere else: the Agents page, every schedule and every subagent sent that provider's model name to OpenAI instead, so it failed with an OpenAI error naming a model OpenAI has never had - or, if you had no OpenAI key, with a complaint about a missing OpenAI key for a provider you were not using. All three places that talk to a model share one definition of "which endpoint and which key" now.
- Gemini with your own Google AI Studio key works in chat. It was being sent to Amazon Bedrock, which answered that
gemini-2.5-prois not a valid model - a confusing failure that named the wrong service. Saving a Google key also takes effect immediately instead of on the next restart. - vLLM and LM Studio no longer need an OpenAI key to run a local model. They ask the server on your machine which models it has loaded, so those models appear in the picker; MiniMax does the same with your key. Previously all three could be configured and none of them had anything to select.
- A provider whose key you deleted now says so instead of borrowing your OpenAI key. Removing a key while that provider was selected left the endpoint in place, and the next message went to that vendor carrying your OpenAI credential.
- Picking Gemini CLI for a scheduled or background run now explains why it cannot do that, rather than failing with an unrelated Bedrock error. It runs as its own command-line process with its own tools, so Foxl's tools are not available to it; chat is unaffected.
- Tapping Settings in Foxl Code or Foxl Notes on a phone now opens the settings list, not one section buried inside it. Both products dropped you straight into a single pane - Autonomy for Code, Recording for Notes - so the fifteen other sections were one unmarked back-press away and nothing on the screen said a list existed. The phone now lands on the grouped list, the same place Settings opens from the Agent product. A link or a command-palette pick that names a section still goes straight to it, and the desktop two-pane view is unchanged, since its section rail is on screen either way.
- Runtimes opens as a list now, and both layouts show 12 at a time. The page used to open as a grid of cards, which is a pleasant shape for three runtimes and a lot of scrolling for thirty: a runtime is a row of facts - status, repo, model, branch, spend - and those line up down a column. The card grid is still there behind the switch in the section header, and the switch still remembers which one you picked, so if you had already chosen cards you keep cards. Both layouts are paged now, twelve to a page, with the range and a Prev/Next pair under the list; the count beside "Active runtimes" still reports everything that is running, not just the page you are looking at. Flipping between list and cards keeps you on the same twelve rather than scrolling the window out from under you, and a runtime finishing while you sit on the last page moves you back a page instead of leaving you on an empty one.
- A shell command the agent runs gets three minutes instead of one, and one that is waiting for input no longer waits at all. Anything that legitimately takes longer than a minute - searching a whole home folder, cloning a repository - used to be cut off at sixty seconds and reported back as a failure, and because the command was killed partway anything it was writing was left half-finished. The agent can still ask for a longer limit when it knows the job is long. Separately, a command that stopped to read input nobody was going to type used to sit there for the entire limit before being killed; it now ends immediately with the shell's own error, so the agent sees what was actually wrong instead of a timeout.
Features
- Channels is now one screen for every conversation, including the ones that come from Slack, Telegram and Discord. Connecting a bot under Settings > Integrations > Channels already worked - somebody messages it, Foxl answers with your local tools, the reply posts back to that platform - but there was nowhere in the app that showed a word of it. The transcript was filed as an ordinary chat, so a stranger's message landed in your own AI-assistant sidebar between your private chats, with
[telegram/alice]inlined into every line and no indication of which platform the answer went out on. Channels now lists those conversations in their own group beside your team's channels and DMs: who wrote, what they said, what Foxl replied - and each reply is labelled, so an answer the AI wrote can never be mistaken for one you sent. You can also reply yourself, straight from that thread; it goes out on the channel it came from, in the right Slack thread, and it is only recorded once the platform has actually accepted it. Tapping a "message from Telegram" notification lands on the thread instead of on the assistant chat, and the Channels row in Settings links to the conversations it has collected. Threads live on the desktop, so they show up wherever your desktop is reachable - including a phone on the relay - and they no longer need a team: a user in no shared workspace can read and answer them. - Every subagent is now one of the ones you can edit, and a new switch decides whether it starts from the conversation or from a clean slate. Delegation had two kinds of worker and only one of them was on the Subagents screen: when the main agent named a type it ran the definition you wrote, and when it named none it ran a hidden generic worker that no file described, so editing
general-purposechanged nothing about the case that came up most. There is one kind now. A spawn that names no type runsgeneral-purpose, so the prompt, the toolset and the model you set there are the ones that actually run. The new Inherit conversation context switch is the setting that made that possible. On, the subagent starts already knowing the conversation and shares its cached prompt, so handing it work is much cheaper and you do not have to brief it from scratch - the main agent is told which subagents already have the context so it stops re-explaining. Off, it starts fresh from the task alone and uses its own prompt, its own narrower toolset and its own model. The trade is real and the editor says so in plain terms wherever it applies: a subagent cannot both inherit the conversation and hold a reduced toolset, because sharing the cache means running on the same tools.general-purposeships with it on, which is exactly how untyped delegation already behaved, so nothing gets more expensive; the read-onlyresearcherandcode-reviewership with it off, so their restrictions still bite. An existing install keeps whatever you have chosen.
Fixes
- The mark on the phone's first chat screen stopped flying off the top when the keyboard opens. Tapping the message field is meant to lift the screen onto the keyboard, and it does - but the Foxl mark above "What can I help you with today?" travelled twice as far as it needed to: it left the top of the screen entirely during the animation and then dropped back down into place at the end. The greeting is centred in the space above the composer, so when the keyboard takes that space it only has to move half as far, and it now animates exactly that far and stops. The same screen in Foxl Code gets the same fix.
- Foxl Code's Working and Done lists stopped updating whenever everything was working. The Work page's task stream skips its background refresh while the live connection is up, on the grounds that the connection announces every change - but it was never subscribed to those announcements. So on the healthy path it had no source at all: a task moving to review, a pull request merging, a run finishing did not appear until the connection dropped, you navigated away and back, or you reloaded. It listens now. Only the good path was affected, which is why it went unnoticed: losing the connection made the list start working again.
- Swiping in from the left edge on a phone opens the sidebar again. v0.6.6 gave that edge to an interactive swipe-back, so the gesture people had been using to reach their chats started navigating backwards instead. The two cannot share it: both are the same drag from the same 24 pixels, and the back gesture engaged first every time, so the drawer's swipe silently stopped existing. The edge belongs to the sidebar. Back is still a tap on the Back chevron in the headers that draw one, and on Android the system's own back gesture is unchanged.
- Opening the app no longer accuses your desktop of being offline before it has asked. Every cold open on the phone put up the orange "Desktop offline" warning and then withdrew it a moment later, because the app started from "offline" and had no way to say "still looking" - so a desktop that was up the whole time was reported as away on every single launch. The app now says nothing about the connection for the first couple of seconds and only reports it as offline once that is actually the answer; a desktop that answers in time goes straight to connected with no warning in between. The connection attempt itself starts the instant the app opens, exactly as before, so nothing reconnects any slower. The connection dot in the sidebar follows the same rule and says "Connecting..." for that window instead of showing a state it has not established.
- The sidebar's nav icons are back when the sidebar is open, and on the phone. They had been showing only on the collapsed icon rail, so an expanded sidebar was a column of plain labels - and since the phone drawer is never collapsed, iOS and Android never showed them at all. The Settings row and the account row had kept theirs the whole time, which made the top of the sidebar disagree with its own bottom. Every nav row now carries its icon in all three states: expanded, collapsed to the rail, and in the mobile drawer.
- "Needs you" and the home summary now count the same thing, and every row in it can actually be acted on. The two numbers were computed from different data: the summary line asked whether a task had an open QUESTION, so it read "0 awaiting input" while the rail beside it read "Needs you 3" - the three being red builds, which that definition cannot see. There is one definition now, rendered by the same function in both places and read from one shared snapshot, and one name for it in each language. Two of those three rows also had no button at all: the "Fix it" verb was gated on a task still being in review, which stopped being the right test when the action learned to reconnect to a settled agent, so a task Foxl could have picked straight back up looked like a dead end. And the third row should not have been there - its pull request had already merged, because the code that clears a notification when a PR closes was skipped whenever the owning task had gone terminal. Merged and closed pull requests now drop out of the queue on their own, so the ones already stuck clear themselves.
- Changing your profile picture on the Account page works, and says so when it cannot. Clicking your photo opened the file picker, and then nothing happened - no new picture, no message, no explanation. Two things caused that: ordinary photos were refused before anything tried to read them (anything over 2MB, which is most pictures straight off a phone, plus several formats the pickers on iOS and Android hand over), and the one place the refusal was written to the screen only existed inside the profile editor, so a photo picked from the picture itself failed in total silence. Photos up to 25MB are accepted now - they are scaled down on your device either way - and every attempt says what happened, whether it worked or not. The picture in the sidebar follows the change straight away instead of waiting for a reload.
Features
- The Files view has a proper header, an always-visible search, and a real empty state. The file tree used to start cold - no title, and the surface's only name was a word the desktop chrome tucked into a corner and a phone hid entirely, so on a phone the page had no title anywhere. Files now opens with a title and a line saying what it holds, the same shape the rest of the app's pages use. Search is no longer hidden behind an icon that cost a click and hid the fact the tree could be filtered at all - the field is always there at the top of the list, with its result count inside it. And an open pane with nothing selected now shows a centred prompt to pick a file rather than a stray label. Both the Foxl Agent and Foxl Code file views get the same treatment.
- A Foxl Code schedule can now ask you what to do, or file the issues itself, instead of only opening pull requests. Every schedule used to end the same way: it started a coding agent, which changed the code and pushed a branch. So the two schedules people most want could not be written at all. "Every morning, look at the repo and tell me what needs doing" became an agent pushing a branch at 09:00, and "keep my backlog stocked" opened the work before anyone agreed it was worth doing. A schedule now picks what each run produces: a pull request as before, a question listing the action items it found, or GitHub issues with the reasoning behind each one. The two new kinds change no code at all, and that is enforced by where they run rather than by asking nicely in the prompt - they never get a checkout, so there is nothing to push. A question arrives the same way every other Foxl Code question does, so it reaches a locked phone and can be answered from there; issues count against the same open-issue budget the autonomous loop respects, so two features cannot quietly fill your tracker together.
- The Foxl Code home screen now shows the state of every task, on one screen, above the composer. Four screens each answered part of "what is happening": the sidebar list is short and grouped by day, the right rail lists decisions waiting on you, Inbox is a feed of events, and Work is one repository at a time. None of them answered which task is blocked on you right now. The home screen now opens with a board: how many are waiting on your answer, how many are working, how many are done, and then the rows themselves - grouped so anything blocked is at the top. Each row names the task, what came of it (merged, awaiting review, checks failed and which check), its pull request number and how long the run took. A task stopped on a question used to look exactly like one still running, everywhere in the app; it no longer does.
- Foxl Code's Work page is three plain answers now, not a mirror of GitHub. It used to be four tabs of raw issues and pull requests, one repository at a time, in developer language - and it left five things unanswered: the scope changed silently between tabs (some cross-repo, some tied to one repo), nothing could be dismissed, it was unclear what you were meant to do, "CI red" meant nothing to a non-developer, and only twenty merged items ever showed. Work is now Needs you / Working / Done, across every repository by default, with one filter chip to narrow to a single repo. Needs you leads with the decisions waiting on a person, each with the one button that settles it; Working is what your agents are doing right now; Done is everything that shipped and pages back through your whole history rather than stopping at twenty. The status words are plain - "Checks failed", "Ready for your review", "Agent is working"
- and every row can be dismissed or deleted.
- iOS gets the native gestures it was missing. Swipe in from the left edge to go back, and the screen follows your finger with the one underneath sliding in behind it - the same interactive back every iOS app has. Sheets that leave the screen visible behind them now lift off a stack the way the system's do, that screen settling back as a card, and they respond to a flick by where it was headed rather than to how far it happened to travel. Pull a list down past its top to refresh it, and tap the status bar to jump back to the top.
- Long-press a conversation on iPhone and the real iOS menu appears - the row lifts, the rest of the screen blurs, and Rename and Delete arrive with a haptic. The long-press did nothing before on a phone.
- Text follows the iOS text-size setting and the system typeface. Foxl was the one app on the phone that did not move when you changed Display text size; now every screen does, and body text is San Francisco with the platform's own spacing.
- A destructive confirm on iPhone is a proper action sheet - the dangerous choice in red at the bottom edge under your thumb, with Cancel set apart - instead of a dialog whose two buttons looked the same.
- Report an issue, from Settings. Settings > General now carries a Report an issue row. It copies the build you are running, your platform and your language, then opens the Foxl Discord so you can paste them with what went wrong - reports arrived without that line before, and asking for it is a round trip before anyone can start looking. File paths are deliberately left out: the data directory and workspace both contain your home directory, and this text is written to be pasted into a public channel. The row is also findable from the command palette by typing "report" in any of the ten languages, along with eight other rows in General that search could not reach before (language, launch at login, keep running when closed, show in menu bar and the rest).
- Subagents are now something you write, not one fixed kind of worker. When Foxl delegated a piece of work it always spawned the same thing: the same instructions and every tool the app had. The Agents screen has a Subagents tab where each one is a named prompt plus exactly the tools it is allowed to use, and optionally its own model - so a reviewer can be given read access and no shell, and a researcher can be stopped from writing anything at all. The main agent sees the list with your description of each and picks by name when it delegates. Three are there to start with (general-purpose, researcher, code-reviewer); you can edit those, duplicate them, or write your own, and a "restore" button brings back any starter you deleted without touching the ones you changed. Definitions are plain JSON files under
~/.foxl/agents/, so they can be hand-edited and shared. The run history that used to be this whole screen is still there on its second tab, and the screen remembers which one you were on. - A subagent can only ever be given LESS than the app allows. The per-tool switches on the Tools page stay the final word: a definition narrows what an agent may do and can never widen it, so turning a tool off there switches it off for every subagent regardless of what any definition asks for. A definition that names a tool which is currently unavailable - switched off, or waiting on a skill or dependency - says so in the editor and keeps the setting, rather than quietly dropping it.
- The subagent editor is built for a phone, not shrunk onto one. It is the same shape Schedules uses, for the same reasons: the roster is a table on a wide screen and cards on a phone (a five-column table at 390px is a sideways scroll), the editor opens as a panel that says which agent it is editing instead of unrolling under the list, and the prompt and the toolset are two tabs rather than one very long column - so on a phone the tools you came to change are on screen when you arrive. Opening the editor no longer throws the keyboard up over the form before you have read it, every control including the tool chips is a full-size tap target, and when the keyboard IS up the panel gives it that space, so Save stays reachable instead of sitting underneath the keys.
- A first run that asks two questions and then shows you around. A new install opened straight into an empty chat, which is the least informative screen the app has: nothing said what it could do, and the two things worth setting on day one (how it looks, and how much technical detail you want) were several clicks into Settings. Foxl now opens with a short setup over the live app - pick a light, dark or system mode and one of eighteen colour palettes, then optionally say what you do and how technical an answer you like - followed by three cards pointing at Schedules, Apps and Chat. Nothing is required: Continue works with nothing selected, "Skip all" and Escape leave at any point, and the palette applies as you tap it so you are choosing against the real app rather than a preview. An install you have already used is never shown it, and Settings > Appearance has a "Show setup again" button for anyone who skipped past it.
- Eighteen colour themes. Emerald, Monokai, Solarized, Amber, Dracula, Nord, Rose Pine, Catppuccin, Tokyo Night, Gruvbox, Ice, AMOLED, Kiro, IntelliJ, High Contrast, Everforest, AMOLED Midnight and AMOLED Grey Calm, in Settings > Appearance as well as in first run. Each is a full palette - the canvas, cards, text and the accent - and each has its own light and dark rendering, so it composes with the light/dark switch rather than replacing it. Every tile in the picker paints that theme's real colours, and all 396 text-on-surface pairings across the set were measured to clear the WCAG AA contrast floor. Not choosing one leaves Foxl looking exactly as it always has.
- iOS and Android get the setup flow as a sheet, not a shrunken desktop dialog. It rises from the bottom edge, the palette grid scrolls while Continue stays pinned above the home indicator, every control clears the 44pt touch floor, and each selection has a haptic. The tour docks as a bottom sheet there instead of pointing at a sidebar that is a closed drawer on a phone, and the iOS tab bar stands down while setup is on screen rather than floating across it.
- Integrations is back in the sidebar, as your connected apps. It had moved into Settings, which filed "the services your agent can reach" under configuration - so the answer to what Foxl can do for you right now was three clicks deep, next to the language picker. There is now an Apps section under Agents listing what is actually connected, with Explore beside it for everything else. A fresh install sees a "Connect your first app" row rather than an empty heading.
- Foxl now connects to MCP servers on the new 2026-07-28 protocol, and still to every older one. That revision removed the connection handshake and the session header entirely, so servers built on it are a genuinely different shape on the wire and Foxl could not talk to them at all - it only ever spoke the March 2025 version. It now asks each server which revisions it supports and uses the newest one both sides know, falling back to the old handshake for the servers you already have configured. Nothing to change in your settings either way. Tools -> the server's row shows which revision was agreed, so a server on the new stateless protocol is visibly different from one on an older one.
Improvements
- The first screen on the phone is a centred welcome instead of a left-aligned list. Opening Foxl on iOS or the web app on a phone showed a greeting, a small label and three full-width rows with an arrow on each, all flush left - four different left edges and one ragged right one, which read as unfinished. It is now the Foxl mark, one large question, and the starter prompts as tappable chips that centre themselves, so the eye lands on the choice rather than reading two labels first. The chips are 44px tall, and the whole screen fits without scrolling in all ten languages.
- The phone's home screen only mentions your desktop when something is wrong. It used to carry a permanent grey line reading "Ready" whenever the desktop was reachable, which spent the most prominent row under the greeting on a fact that is only interesting when it is bad. Connected now says nothing at all, and an unreachable desktop is called out as a warning instead of a grey aside.
- One Foxl logo everywhere. The sidebar used a lightened mark on dark backgrounds and a near-black one on light; it and the phone's home screen now both show the original black logo, in both themes.
- Runtimes can be a list instead of cards. The page only ever drew a card grid: three columns of a status pill, a repo name, a model and a budget bar, which is one screenful for four sessions and a lot of scrolling for twenty. A switch beside the "Active runtimes" count now folds the same data into one row each, with the spend figures in a straight column down the page so the runtime about to exhaust its budget can be found by scanning rather than by reading every card. Cards stay the default and the choice is remembered per browser, separately from the one on Repos. Either layout opens the session on click and carries the same right-click menu and the same actions button, so Stop runtime is one tap away in both.
- The Files view's top-right controls are glass on the phone, like the rest of the header. Search, open-folder and refresh sat at the top of the file list as three small flat icons while the sidebar toggle beside them was already a rounded glass chip - the one row where the mobile header was left half-finished. They are now 44px chips that match it: real iOS Liquid Glass that lenses the file list scrolling underneath on iOS 26, and the same frosted CSS chip on Android and the web app. The desktop toolbar is unchanged.
- Foxl Code's home screen is a chat home again: the mark, one question, and a single line of counts. It had grown into a stack of four blocks under the greeting - a board listing up to 24 tasks grouped by who was blocked, a footer saying how many more were not shown, and a collapsible panel narrating what the autonomous loop had been doing. On a phone that stack is centred in the space above the message bar, so a list that tall pushed the logo and the heading clean off the top of the screen: the app opened on a wall of task rows with nowhere for the eye to start. What survives is the one thing that reads at a glance, "0 awaiting input · 4 working · 77 done", directly under the question, so the screen matches the Foxl Agent home. Nothing became unreachable: every task still shows its own state ("Running", "Checks failed", "Review approved") in the sidebar one tap away, and the loop's activity feed still appears above the conversation as soon as the home thread has a message in it.
Changes
- Foxl Code has one "Needs you" list now, not four. Work and Inbox sat next to each other in the sidebar and both opened on a tab called "Needs you" - and neither was the whole answer, because they read different tables computed from the same GitHub state. So one green pull request could show up three times at once, on two screens, offering three separate Merge buttons, and clearing one list left the others full. Inbox is gone as a page: its feed of everything the agents did is now Work's Activity tab, where it reads as history instead of competing to be the decision list. Work's own first tab is the single list of decisions waiting on you, with duplicates about the same pull request folded into one row that keeps the richest version of it - the reason it is waiting, and Dismiss and Snooze. Budget warnings and hard-capped agents still surface there, since nothing else reports them. The desktop side rail no longer repeats that list beside itself on the Work page; it stays on Tasks, where it is the only thing on screen answering the question. Every old link still lands:
/inbox,/code-inboxand/activityall open Work, on the same tab they used to. - Integrations moved back into Settings > Connect. It sits between Workspace and Mobile/Web now, rather than as its own sidebar row, so the sidebar is the shorter list of places you work and the things you connect Foxl to live together under Settings. All six tabs come with it (Integrations, Skills, Shared, Channels, System, Custom), and Skills/Channels stay one click away inside that section.
- Live translation now lives inside the Notes AI features settings. It had its own section in Settings; it sits under AI features now, behind a labelled icon, so every AI-powered Notes option is in one place. The feature itself is unchanged - the same toggle, target language and translation model, just one section over.
- Sidebar rows answer the pointer. Hovering a nav row, a conversation or a recording swells its rounded chip by 1.5% as the highlight fills in, so the row under the cursor reads as the one you are about to click rather than only as a shade of background. It is deliberately small (about three pixels of width on a full-size row) and it runs on the app's standard motion timing, so reduced-motion settings collapse it. Touch screens are left out: there is no hover to end on a phone, so a tapped row would stay enlarged.
- Notifications look like notifications now. An unread one is marked in red - the same red as the count on the bell, because they are counting the same thing; it used to be a blue dot under a red badge, which is two different answers to one question. Every unread count in the app is that one red now, including the badge on the phone's tab bar, which was near-black.
- The notification list dropped its decoration. Each row carried a small coloured square with an icon in it - a sparkle, a clock, a hash - repeating what the row's own first words already said ("Agent Done: ...", "Schedule: ..."), so a list of twelve kinds of notification was a column of twelve coloured squares. A row is now the unread dot, the title, the message and the time, separated by a hairline, and the whole row is what you click. "Read all" and "Clear" are plain words rather than a word with an icon pressed against it.
- The black "Open" button on every notification is gone. It went exactly where clicking the notification already went, so it was the row printed twice - and three solid black pills down a narrow panel were the loudest thing on screen. Buttons now appear only when there is a real decision to make (approve or deny, install an update, join a call), and those are quiet tinted labels. Notifications already in your list lose their duplicate button too.
Fixes
- Tapping a conversation-search result on a phone no longer lands you somewhere else, with the keyboard up. Picking a result opens that conversation with the matches highlighted, and the highlight pass used to make the FIRST match in the whole conversation the current one - so the app arrived at the message you tapped and then slid away to a hit hundreds of lines above it, with the counter reading "1 of 89" for something nobody had asked about. It now starts at the match inside the message the result named, and the landing scroll is instant so the two movements do not fight each other. It also stops focusing the find field on arrival: the query was already typed in the search sheet, so the only thing the focus did was raise the keyboard over the bottom half of the message being jumped to and set the composer animating. On a desktop, where there is no on-screen keyboard, the field still takes focus so Enter keeps walking the matches.
- Sign out from the sidebar now actually signs you out on the phone. Tapping your name at the bottom of the sidebar and choosing Sign out cleared the session and then signed you straight back in, every time, so that door could not sign you out at all. Sign out on the Account screen always worked, which is what made it look like nothing in particular. The phone was replaying the sign-in link it had been opened with: the sidebar's Sign out reloads the app, and the reload handed it that same link again a moment later, credentials and all - so it kept being handed back the account it had just left. A sign-in link is now spent once and never replayed, so both doors sign you out and you stay signed out.
- A custom tool that runs a shell command, evaluates JavaScript or writes a file now asks before each call, like the built-in
exectool always has. The approval gate matches on the tool's NAME and treats a name it has never heard of as allowed, and custom tools are registered under their own names - so none of them matched anything and all of them ran unattended. A custom tool wrapping a shell command was therefore a shell with no per-call prompt, sitting beside anexectool that has one, and it is the model that fills in the arguments. If you have already switched on "auto approve all", or set your own rule for a tool, nothing changes: your rule still wins. Read-only file tools, HTTP tools and MCP tools are unaffected. - A permission rule for a tool whose name contains a hyphen did nothing. Tool names may contain hyphens - a custom tool called
deploy-prodkeeps its name, and every MCP tool is exposed as<server>__<tool>where the right half usually has one (create-issue). The rule compiler did not accept the character, so a rule written WITH an argument pattern (deploy-prod(rm *)) was stored under a name no tool is ever called and never matched again. A "deny" rule in that shape told you something was blocked when it was not. - A custom file tool's blocked-path list now applies to the path it actually opens. It was compared against the path template before it was resolved, so the
~/.sshand~/.awsentries could only ever match a literal~/- which opens nothing - while the real path to an SSH key went straight through./etc/passwdspelled//etc/passwdor reached via..slipped past for the same reason. Paths are resolved first now,~is expanded (so a~/notes.mdtemplate works for the first time), and macOS's/private/etcspelling of the same files is covered. - A Foxl Code task row opens its own menu, not the whole list's as well. Holding (or right-clicking) a task in the Tasks list opened two menus at once, stacked: the row's Copy task id / Cancel / Delete, and the list's New task / Delete all. A row now shows only its own actions; the list's still open from the empty space around the rows.
- Foxl Code updates itself over one live connection instead of asking five times a minute. The task list, the questions waiting on you, plans parked for approval and the suggestion feed each used to be their own repeating request, so the app talked to the server constantly whether anything had happened or not - which is what put twenty thousand requests through a single idle phone in six hours. All four now arrive on one connection that stays quiet until something actually changes, and goes completely silent while the screen is off. Anything running is picked up within ten seconds, and when nothing is running the app stops asking almost entirely. If that connection cannot be made - an older app against a newer server, or a network that blocks it - everything falls back to the old requests, so nothing depends on it working.
- On a phone, each chat in the sidebar no longer sits in its own pale rectangle when a Surface theme is on. Appearance > Surface paints the sidebar as one vertical wash, but every conversation row underneath Chat was painting a flat panel colour of its own, so the rows read as a stack of boxes laid over the gradient instead of sitting in it - most obviously on Dawn, whose wash is both darker and warmer than that flat colour. The row had the fill so it could cover the Rename and Delete buttons it slides away from; those now slide in from the edge with it, so the row needs no colour at all and shows whatever the sidebar is actually painting. Desktop was never affected - it has no swipe row - and it is the look the phone now matches.
- Foxl Code stops calling home while nobody is looking at it. Left open on a phone or in a background tab, the app kept asking the server for your task list and your open questions every five seconds, around the clock - a single idle device sent over twenty thousand requests in six hours and took the account to 90% of its daily request limit with nobody using it. Two things were wrong: the two fastest polls were the only ones in the product that did not stop when the screen was hidden, and the question poll ran twice over because two parts of the screen each asked separately. Both now pause while the app is out of sight and refresh the moment you come back, and the two halves of the queue share one request. Nothing on screen updates any later than before - opening the app, or answering a question, still refreshes it that instant.
- After signing out, the sign-in screen is the whole screen again. Signing out and coming back left the app's chrome behind on the phone and the web: the bottom tab bar floated over the sign-in form and the sidebar button sat in the corner, both offering a signed-out person a way into screens that need an account. The form itself sat below the middle of the screen, because it was centring inside the app's page area instead of the display. Signed out now always lands on the same clean sign-in screen the app opens with, on every route that asks you to sign in.
- The iPhone and Android apps open on sign-in, not on a setup sheet. A new install landed on the two setup screens - pick a look, then a couple of questions about you - before it showed anything the app actually does. On a phone that is a form standing in front of the product, and both things it asks for are already in Settings, one tap away, on a screen you chose to open. The phone apps skip it: sign in, and you are in Foxl. Everything it offered is still under Settings > Appearance. The setup screens stay on the desktop app and on foxl.ai in a browser, where they also explain that a desktop app exists.
- The setup screens no longer put a coloured bar across the top of a narrow window. On a phone-sized screen the brand panel shrank into a solid accent strip pinned above the content, which read like a web page's masthead rather than the app's own setup screen - and it was the only thing on screen that was not part of the question being asked. It is gone below the tablet width; the step counter and the title now start at the top, the way a phone presents setup. The wide two-column layout on a desktop is unchanged.
- A long press on the phone shows one menu, not two, and never a stray one. Pressing and holding a chat in the sidebar popped two menus stacked on top of each other - the app's own rename/copy/export/delete menu, and a second, smaller iOS "rename/delete" lift menu. The same iOS menu also appeared where it made no sense: over the pet, on the Files and Channels rows, even on the sidebar toggle, because it was tracking chat rows that were still there behind the closed drawer. There is now one menu - the full one - anchored to whatever you actually pressed.
- A long press on a sidebar row opens its menu instead of selecting the text. On the chat, Notes and Code lists a press-and-hold used to start highlighting the row's title and drag it out from under your finger. Holding a row now lands on its menu, the way a native app behaves, on both iOS and Android.
- The Agents screen says what went wrong when it can't reach the local server. The Runs and Subagents tabs used to show a bare "Error" with a Retry button; they now name the cause - the agent server is unreachable - and tell you to check that Foxl is running before retrying, in all ten languages.
- The companion counter in Settings counts all 15 characters, not 9. There are fifteen cards in that pane and the number above them said "9/9", so six of your companions were never counted however many you collected - and the same collection read 15/15 in the den and on the summon screen. The commons are most of what a draw gives you, but they have their own cards and you can pick one as your on-screen companion, so they count.
- One button in the corner of the Foxl Code terminal on iOS, not two on top of each other. The sidebar button from the screen underneath kept drawing over the full-screen terminal - a thin ring and its icon, a few points off the terminal's own Back button and taking the tap - so pressing Back could open the sidebar instead. It now stays away for as long as the terminal is up, and the terminal's own Back, keyboard and refresh buttons are the same glass chips the rest of the app uses.
- The message bar now sits on the keyboard instead of floating above it. On iPhone there was a band of empty background between the two - 124px of it - because the bar paid for the home indicator twice over and kept a full tab bar's worth of clearance for a tab bar that is behind the keyboard. On the new-chat screen that surplus was enough to push the greeting up under the header buttons. The bar and the messages above it still travel together, in one smooth move, and with no tab bar on screen the bar simply sits lower.
- A queued message lines up with its own buttons. The text sat noticeably higher than the send-now and remove icons beside it, with a wide band of empty space under it, so each row read as a caption with a pair of buttons floating below. Rows are a third shorter now and everything shares one centre line.
- You can add a message to the queue while a reply is still coming in, on a phone too. Sending mid-answer used to be desktop-only - Enter queues, and a phone has no Enter - so the button was Stop and nothing could reach the queue panel above it. It now queues whenever you have something typed, and sends as one turn when the answer finishes.
- A photo you add to the queue is actually sent. The queue only ever carried the text, while the composer was emptied either way - so attaching an image mid-answer and tapping the button took the image away, showed an empty queued row, and threw it out when the turn ended. The attachments now travel with the queued message, and a message that is nothing but an attachment queues properly instead of vanishing.
- Typing in Korean, Japanese or Chinese mid-answer no longer stops the answer. While the keyboard is still composing a character the app cannot yet see what you have typed, so the button was still Stop - and tapping it cancelled the reply instead of queueing the message. The button now checks what is actually in the box before it does anything.
- A pasted screenshot no longer disappears from a short conversation. Opening a chat you had attached an image to could replace it with "Attachments not loaded (large conversation)" - on a conversation two messages long. A limit meant for transcripts too big to open was being applied per image instead of to the transcript, and an ordinary full-screen screenshot is past it, so the message it showed was not true either. Images are now dropped only when the conversation as a whole really is too large to load, and the newest turns keep theirs. Measured on one real history: of 90 conversations affected, 76 were nowhere near the limit.
- A conversation that IS too large now really does get smaller. Fixing the above left the opposite gap: only an individually enormous attachment counted, so a chat whose weight was spread across a dozen ordinary screenshots was left entirely alone and still failed to open. It is the conversation's total that decides now, and the oldest turns give theirs up first - the ones you just scrolled to keep theirs.
- And the attachments are one click away instead of gone. The notice in their place was a dead end - it said the attachments were not loaded and offered no way to load them, even though the app had always been able to fetch a single message's attachments on request. It now has a button that does, and says so if the fetch cannot reach your desktop rather than quietly showing nothing. Documents come back too: a turn holding a screenshot and a PDF used to return the image, clear the notice, and lose the file with nothing on screen saying so. Still one message at a time and only when you ask.
- An MCP tool can no longer run twice for one request. When a tool took longer to answer than the app was willing to wait, the app assumed the connection had used a stale guess about which version of the protocol the server speaks, reconnected, and sent the same request again - so a tool that sends mail sent it twice, while the agent saw one call and one error. It now only retries when it is certain nothing reached the server, or when the request is a read that cannot have an effect.
- The first-run setup screen no longer has invisible buttons on top of it. On iPhone the app's own frosted controls are drawn by the system, above the web page, so they stayed on screen over the setup flow - painting circles across it and, worse, taking taps meant for the sheet: pressing Skip all opened the menu hidden behind it. Swiping from the left edge during setup also navigated away. The setup screen now tells those controls to stand down, the way every other full-screen panel does.
- The Fix it button's explanation is translated. The tooltip saying that Fix it wakes the same agent, reads the failing check and pushes to the same branch was written in English only, so it appeared in English on an otherwise translated page in eight languages.
- status.foxl.ai no longer republishes the exact words an upstream service used to refuse us. The page prefers a real reason over "check failed", which is right, but those reasons come from services that name internal identifiers in them - so a credentials problem with our model provider would have printed our own cloud account id and user name on a public page, in its JSON feed, in its RSS, and to anyone subscribed to updates. The reason is now scrubbed of identifiers before it is stored, and still says which component failed and how.
- The companion list no longer offers "Follow along". It was one card among sixteen that did not name an animal - it meant "whoever you last brought out", so its picture and its effect depended on state you could not see from the pane. It is gone: every card is a companion, the one currently on screen is the one marked, and drawing a new companion selects it.
- "Show outside the app window" can no longer be turned on when you have no companion. With nothing drawn yet there was no animal to put on the desktop, but the window was still created - a small invisible patch of your screen that took clicks meant for whatever was behind it, with nothing on it to explain itself or to right-click. The switch is now unavailable until you have a companion, and an app that was already left in that state closes the empty window and turns the setting off by itself.
- Shaking the phone no longer asks to undo your typing. iOS treats a physical shake as an undo gesture, so walking with the app open, a car ride or a train put an "Undo Typing" alert on screen with nothing to undo. The iPhone app turns that system gesture off; undo inside the Notes editor is unaffected.
- The phone apps stay portrait instead of rotating into a broken layout. Turning the phone sideways ran the header and content under the notch or camera cutout and the rounded corners, because the app pays for those edges itself and only ever paid the top and bottom ones. Chat, notes and tasks are single-column reading surfaces, so portrait is the shape they were designed for. Fixed on iPhone and Android alike. Tablets are unaffected and still rotate freely, on both iPad and Android.
- On iPhone, the message bar and the conversation now rise together when the keyboard opens. The bar slid up over the keyboard smoothly, but the messages above it did not move at all while that happened - they stayed put for the whole quarter-second and then jumped the full height of the keyboard in a single frame, just after the bar had already come to rest. Closing the keyboard was the same thing backwards, and more obvious: the messages dropped all at once on the first frame while the bar took the rest of the animation to follow them down. Both now travel as one, on the same curve, in both directions. Scrolling back through older messages first is unchanged - the conversation deliberately holds still there, and only the bar moves.
- Typing in a channel no longer pushes the message you are replying to off the screen. Channels and DMs had none of the keyboard handling the other two chat screens have: when the keyboard opened, the room lost that much height while staying scrolled where it was, so the newest message slid out of view and nothing brought it back. The message bar did not follow the keyboard either - it and the whole conversation jumped into place in a single frame once the keyboard had finished opening, and dropped all at once before it on the way out. All of it now moves with the keys, like the Agent and Code screens.
- The tab bar no longer sits between the message bar and the keyboard. On a phone the Chat / Channels / Files capsule rode up with the keyboard and came to rest in the gap above it, where it could not be tapped anyway. It now fades out while you are typing and comes back when the keyboard goes away.
- Notes panels follow the keyboard too. The transcript and the AI panel had the same one-frame jump the chat transcript had, in both directions.
- The search palette and the repository picker fit above the keyboard on iPhone. Both shrink to the space the keyboard leaves - but they were only listening for the signal a mobile web browser sends, which the app itself never sends, so on the phone they kept their full height and their lists ran behind the keyboard with the scrollable part off screen.
- The iPhone tab bar is in your language again. Its labels came out in English on every language the app supports - so on a Korean phone the row along the bottom was the one control still reading "Chat / Channels / Files" while everything above it was translated. Nothing was missing from the translations: the tab bar was asking for them from a place in the app that could not reach them, and quietly showed its English spare instead. It now reads the same translations as the rest of the app, and follows a language change immediately rather than at the next launch.
- The Surface swatches in Settings > Appearance show the right colours again. Each tile is meant to preview its own preset, and instead all of them showed whichever one was currently selected - so picking Dawn made Mist look like Dawn, and on Default, where nothing is tinted, both gradient tiles were blank white boxes with nothing to compare. The tiles now paint their own preset in both light and dark mode, which is the whole point of choosing by colour rather than by name.
- The close button on a pop-up panel sat in the middle of it on iPhone and iPad, inside a circle. It was offset by the height of the status bar, which is the right thing to do for a panel that starts at the top of the screen and meaningless for one centred in the middle - so on something like the "Install Foxl to use Terminal" prompt the X landed a finger's width down from the panel's own top edge, on top of the sentence it was covering. The ring around it was a keyboard focus outline: these panels move focus to their first control when they open, and on a small screen that control is usually the X, so opening one by tapping drew a highlight nobody had asked for. The X is back in the corner where it belongs, the ring now appears only when you are actually navigating by keyboard, and a panel tall enough to fill the screen keeps clear of the status bar and the home indicator so its title and buttons stay reachable.
- A local MCP server with a long tool list is no longer cut short. Servers are allowed to hand their catalog over in pages, and Foxl read only the first one and treated it as the whole list, so tools past that point were missing with nothing reporting it. Every page is read now.
- A skill no longer asks you to install something that is not a program. Each skill lists what it needs, and the Skills page reads that list to tell you what is missing - but it was reading it by a different rule than the Integrations page, so two screens described the same skill differently. The Outlook skill needs a connected Microsoft account, and was reported as needing a missing command called
integration:microsoft. The local text-to-speech skill needs two settings, and was reported as needing two missing commands named after them - which could never be satisfied, because the page looks for a program by that name and a setting is not a program. Both screens now read the list the same way, so what a skill needs is described once. - A value you set for a skill now clears the warning about it. Skills that need an API key or a folder path can be given one from the Integrations page, and Foxl passes it to the skill when it runs - but the "missing" notice beside it only ever checked your shell environment, so it stayed on screen after you had just filled it in. It now counts the value you saved.
- The Integrations page lists the commands a skill can use, where it used to show none. Some skills accept any one of several programs (Code Search takes
rgorgrep, for instance). Those alternatives were dropped when the page built its list, so those skills appeared to require nothing at all. They are listed now. - Repos says "Repos" on a phone again. Its two header buttons kept their full labels on a narrow screen and took the row first, so the page's own title was cut to "Rep..." - the one word on the screen that could not be guessed. Sync and Connect are icon buttons on a phone now, the same as the New button on Schedules, and they keep their labels on a wide screen.
- Foxl Code's Work screen is laid out for a phone. Its four tabs did not fit the width, so "For you" and "Open issues" broke onto a second line and spilled out of the strip they sit in; the tabs now stay on one line, fill the row, and scroll sideways on a narrow phone. The rows waiting on you lined up narrower than everything else on the page and are flush with it now, and their buttons share the row evenly instead of one stretching to the full width beside a small one. Every button on the screen - Merge, Solve, Fix it, Diff, Dismiss and the overflow menus - is a proper thumb-sized target, and an issue's or PR's title gets the width its actions used to take.
Removed
- Channels is a Foxl Agent screen only; Foxl Code's copy of it is gone. One page had two doors, so the sidebar row, the phone tab-bar entry, the unread badge and the
/channelsURL all existed twice - once per product - and had to be kept in step by hand. The Code side is the one that went: the sidebar row under Files, its cell in the Code tab bar (Tasks / Work / Repos is the shipped row now), and/channelson code.foxl.ai, which lands on Tasks like any other unknown path. Anyone who had put Channels in a customised Code tab bar keeps the rest of their layout. Channels itself is unchanged. Same page, same channels, same messages, same unread counts, reached from Foxl Agent beside Chat. Nothing was archived and no conversation moved; on the desktop and iOS apps it is one product switch away. The Integrations setting also called "Channels" - the inbound Slack, Telegram and Discord adapters that let you message the agent from those apps - is a different feature and is untouched.
Features
- foxl.ai says what Pro and Ultra cost. Both plans read "TBA / pricing to be announced" on the pricing page, the homepage and the Foxl Code page, which is the one thing a visitor deciding whether to try it needs. They now show $20 and $200 a month with their credit allowances, and search engines see the same figures in the page's structured data instead of a placeholder. Enterprise is still "talk to us", because it is quoted per deal - the form beside it records the enquiry.
- An open tab now tells you when it is running an older version of the web app. Deploying replaces the files the page loads from, and a tab left open across that does not fail politely - it breaks at whatever moment you open a screen it had not loaded yet, because the missing file comes back as a page instead of code. The app now notices when a newer build is being served (on returning to the tab, and periodically) and offers a reload. It never reloads on its own: anything you have typed stays where it is until you choose to.
- The browser extension now says what it needs instead of failing silently. It talks only to Foxl Desktop on your own machine, so somebody who installs it without the app had nothing to connect to - and the only sign of that was a grey dot whose tooltip said "Disconnected". It now tells you the desktop app is required, links to it, and offers the custom-port setting; if you HAVE had it running before, it says it is reconnecting instead, because those are different problems. That second screen also keeps a quiet way back to the download, and stops claiming an automatic reconnect once a month has passed with no desktop answering - otherwise somebody who uninstalled the app would be promised a reconnection to it forever. The extension and the desktop also exchange versions now, so an extension that has auto-updated past your desktop app says so rather than half-working.
- Foxl Code: the container your tasks run in is yours to configure, whichever coding assistant you use. Settings -> Code -> Container is a new pane with four things that used to be fixed for everyone: whether the agent may edit files and run commands without stopping to ask, how long a task may run before it is told to commit and stop, instructions it reads in every repo, and environment variables for the commands it runs. Nothing here is Claude-specific - the instructions are saved as
CLAUDE.mdfor Claude Code andAGENTS.mdfor Kiro, Codex, Cursor, Hermes and OpenCode, and the one approvals switch becomes whichever flag that CLI has. A repo that ships its own instructions file keeps it, and all four settings apply when you reconnect to a task instead of reverting to the defaults. Environment variables are key/value rows and the time limit is a row of presets, so this is usable on a phone; raw config JSON is still there for one assistant at a time, under Advanced. - The iPhone tab bar is the real iOS one now. It was a web capsule painted to look like glass, because the material iOS 26 actually uses cannot be applied to a bar whose icons and labels are web content. The bar is now the system's own: real Liquid Glass, SF Symbols that fill in when selected, system badges, and the platform's own spacing and tap behaviour. Your tab layout, order and the labels switch carry over exactly as you set them. On Android, on the web and on older iOS nothing changes.
- Text size follows iOS Settings. Foxl ignored Display and Brightness, Text Size entirely, so it was the one app on the phone that stayed put when you moved that slider. It now scales with it. The range is deliberately narrower than iOS allows, because the largest accessibility sizes overlap a screen this dense.
- Tapping the tab you are already on scrolls back to the top, the way it does everywhere else on iOS. It used to buzz and do nothing.
- Confirmations that delete something are real iOS alerts, with the destructive choice in red instead of two buttons that look equally safe.
- The phone tells you what happened. Actions that finish, finish partially, or fail now have the three distinct iOS feedback patterns, so you can tell them apart without looking at the screen.
- Screens have a direction on a phone. Going somewhere new slides in from the right and going back slides in from the left, the way iOS has always signalled which way you moved. Before, every navigation in both directions was the same small upward fade. Unchanged on a desktop, where nothing is being pushed, and unchanged if you have Reduce Motion on.
- Tapping a notification on iOS and Android now opens what the notification was about. A message from a colleague took you to the screen you were last on rather than to that channel: the tap navigated to a path that is the Channels page only on code.foxl.ai, and in the app it resolves to Integrations - which on a phone opens as a settings sheet over whatever was behind it. A channel notification now opens that channel, scrolls to the message it named and flashes it, whether the app was open, in the background, or closed. A Notes notification opens the note that finished instead of leaving the last one you had open on screen, and the notification rows in the bell lead to the same places as the banners.
- Four more notifications that led to the wrong place, or nowhere. A Feed item took you to Schedules, which cannot show it. An "Agent Done" notification dropped the id of the agent it was about, so it opened the list instead of that run. The Foxl Den notification and product-update announcements appeared in the bell with an Open button that did nothing at all. And a Foxl Code task notification opened the Work list from the bell while the banner for the same event opened the task. Every push the server can send is now checked against both doors - the banner and the bell row - so a notification that leads nowhere fails the build instead of shipping.
Fixes
- Foxl Code stops retrying the same issue forever. The autonomous loop is told to retry a failed piece of work once, and that instruction was the only thing stopping it: every retry is a new task with a fresh budget, so a loop that kept deciding to try again could spend one budget after another on a single issue with nothing counting the chain. There is a real ceiling now - one automatic retry, one manual one after that - and once it is reached the loop is told the refusal is final rather than something to wait and re-attempt.
- "Fix it" on a failing build now actually sends the agent back at it. The button asked the agent's machine to pick the task up where it left off, which only works while that machine is still awake - and it goes to sleep after fifteen idle minutes, so a row that had been waiting hours or days could never succeed. Worse, the one thing that was supposed to happen next never did: the "that machine is asleep" answer arrived in a shape the app did not recognise, so instead of waking it up again the button reported an error and stopped. Pressing Fix it now wakes the agent on its own saved workspace - the checkout, its dependencies and its own notes are all still there - and only when that workspace is genuinely gone does it say so and leave Retry to you, rather than quietly starting a paid run from scratch.
- Reconnecting to an agent works, including while it is still busy. Every reconnect this product has ever attempted had failed. Three of them failed for a reason that was not a failure at all: the agent was still working (cancelling a task tells our records immediately but leaves the agent running), and being told "already live" was reported to you as an error instead of simply putting you back in front of it. It now reattaches, and anything you typed goes to the agent that is already there. Two others were attempts on runs that never got as far as a checkout, where the message blamed a Foxl update for clearing a workspace that had never existed; those now say what actually happened.
- A terminal that has gone to sleep says so. Typing into an agent whose machine had idled out returned an internal relay error - the same unhelpful message whether Foxl was broken or your agent had simply been left alone for fifteen minutes. It now reports that the session slept and offers to wake it. The same correction fixes the agent's own status reads, and the message that tells you a code review could not run because a Foxl component has not been rolled out yet - that one had been replaced by a raw error code that read as a problem with your repository.
- Answering the agent's question now gets you an answer back. Foxl Code would ask something, you would reply, and the thread would sit on your own message forever - the reply was written to the autonomous loop's own log, which is shown in one collapsed panel on another page. Replies now land in the conversation you answered in, and they appear there while you are looking at it instead of on the next reload. Two related dead ends are gone with it: a reply no longer waits for the loop's next scheduled beat, and a reply is no longer discarded outright when you have switched the loop off - turning it off means "stop deciding work for me", not "ignore what I typed".
- Questions and notices read as chat. A clarification arrived as an amber warning card and your answer became a grey receipt slab, and the loop's notices were centered amber pills - so the most conversational thing in the product was the only thing that did not look like the conversation. They are ordinary chat turns now: the ask on the left, your answer in a bubble on the right, notices in the same column as any reply. Only a failed send is still coloured.
- The autonomous-activity feed is visible again. It was only rendered on a completely empty home screen, so it disappeared for good once you had sent a single message. It now sits above the conversation at any point, newest first, with a time on every entry.
- You pick the repository the loop works in from a list, and it tells you which one it is using. It was a text box over a rule you could not see: the loop only works in a repository you have already run a task in, so a typo - or a repository you have access to but have never used - was silently refused and it quietly went and worked somewhere else. The dogfooding account sat on a demo repository for days that way. The field now offers exactly the repositories that are allowed, says "Working on owner/name" underneath, and if a saved choice ever stops being usable it tells you that instead of pretending.
- The activity panel says whether the loop has been working, before you open it. Its heading was the words "Autonomous activity" and a timestamp, which tells you the machine is alive and nothing else. It now reads "Worked 4 times in the last day" or "Quiet for a day", so the collapsed panel answers the question by itself.
- The self-directed loop stops quietly parking itself. It was treating pull requests waiting on a human to merge as its own backlog and filing nothing for days on end while reporting success every time. Open PRs are finished work, not a reason to stop; the only limit is its own issue budget. Consecutive empty surveys are now counted, shown in Settings, and after two the loop must either act or say plainly what it is blocked on.
- The desktop app reported its version to the browser extension as "1.0.0", regardless of what was installed - a placeholder that shipped in every release. It now reports the real build, which is also what makes the version notice above possible.
- Cmd+N clears the screen in Foxl Code too. The shortcut (and File > New) reset the URL but left the open task on screen, so it read as a dead key in the one product where the sidebar's + button worked fine. All three doors now run the same "new in this product" action: a fresh conversation in Agent, an empty note in Notes, an empty task composer in Code.
- Opening something by its own URL now scrolls the sidebar to it. Landing on a chat from a link, a reload or a search result highlighted the row in the list without moving the list, and Settings never moved its left rail at all - so the pane you asked for was selected while the rail still showed a different group, which reads as having landed somewhere else. Chat, Settings, the Foxl Code task list and the Notes list all bring the selected row into view now, and leave it alone when it is already visible.
- "Jump to the end" in Notes works on a note nobody is recording. The note body offered that button only while a recording was running, so a long note - the whole screen on a phone - could only be scrolled back down by hand. It is now the same button, in the same place, that Foxl Agent's chat uses, on the note body, the transcript panel and the AI panel, on desktop, iOS and Android.
- On a phone that button was partly behind the Notes action bar, and tapping it opened Ask AI. The note body claimed the strip of the screen the bar sits on, so anything anchored to the bottom of the note landed under it - measured at 32 of the button's 44 points, with the centre of the tap going to the wrong control. The body now ends where the bar begins.
Changes
- Foxl Code Settings no longer has an "Instructions & MCP" screen. Both controls on it promised more than they delivered: the custom-instructions box said it was appended to the agent's system prompt when the text was actually prepended to your own prompt, and the MCP connectors box accepted a JSON blob that was written into the task runtime with no check that any of those servers were reachable, no place to put a credential, and no effect at all on the assistants that do not read that file. Rather than leave a half-built screen in Settings, it is gone. Autonomy, Coding agent, Defaults & budget and Notifications are unchanged (Container is new this release, see above), and text you had saved is still in the database rather than deleted, so nothing is lost if this comes back done properly.
- Workspace storage and Channels bills now land after your credits arrive, not before. Both were charged on the day of the month you signed up for Foxl, while the credits that pay for them arrive on your subscription's renewal day. Those are different days for every paying customer, so the bill could land while your balance was at its lowest point of the month, and for storage that meant new uploads were paused for an account that was fully paid up. Both meters now use the same renewal date the rest of the billing page does, including its time of day.
- A workspace bill that could not be paid is no longer forgotten. If a storage or Channels charge failed because the balance was short, it was retried only until the end of that calendar month and then never again. The unpaid period is now recorded and retried, oldest first, once credits are available, and it shows up in the workspace's billing history as unpaid instead of being invisible.
- An upgrade whose confirmation from our payment provider went missing now completes on its own. Moving from Pro to Ultra takes effect when the prorated invoice is paid, and that arrived as a single notification. If it was lost, the account stayed on the old plan with the old monthly credits indefinitely, and the five-minute reconciliation could not correct it. It now asks the provider for the invoice directly and applies the plan the moment it sees it was paid.
- Foxl Code no longer starts a task for an account that has run out of credits. On a paid plan there was no credit check at task start, so a task could open, spend real compute, and then fail every model call because credits were exhausted. It now declines with a clear message before anything is spent. A task already running is unaffected and can still overshoot, as before.
- A free workspace no longer sees an estimated storage or Channels bill. Free plans are never charged for either, but the forecast priced them anyway.
- After a failed payment, credit usage is measured from the right date again. When a subscription lapsed, the old renewal date was kept as the usage-window anchor while credits went back to refilling on your signup date, which inflated the "used this period" figure for the rest of the period.
- Shell commands ask for your approval again. Foxl ships with rules that make the agent stop and ask before it runs a shell command, opens a terminal, or manages a background process. A separate rule was also being written on first launch that auto-approved every tool, and it outranked the three that ask - so on every install those prompts never appeared, and anything the agent read could put a command on your machine without your say-so: a web page it fetched, a file in the workspace, a Slack mention, the text of an issue. The blanket rule is gone, and it is removed from existing installs on the next launch. If you turned "auto approve all" on yourself in Settings, that choice is untouched. Two routes to a shell were still unprompted underneath that rule and are closed with it: typing into a terminal the agent did not open (it can list the ones you opened yourself), and writing to or killing a background command. Reading a terminal, polling a running command and fetching its log still do not interrupt you, because those are how the agent watches work it already started.
- Your saved provider API keys can no longer be sent to somebody else's server. The endpoint that tests a key accepted the address to test against and the key to use as separate, independent inputs, so a request naming an outside address and no key was answered with your stored key in plain text. A custom address now has to come with its own key; the stored one is only ever sent to the address you configured.
- Saved provider API keys are harder to read out of a stolen database. They were encrypted with a key computed from the machine name and the install path, both of which anyone holding the database file can guess, so the encryption added nothing against a copied backup. The key is now random, kept in a separate protected file, and existing keys are re-encrypted the first time they are read.
- Credit warning emails now reach everyone, including anyone who has bought extra credits. The 80% and 100% notices measured your remaining balance against your plan's monthly allowance, so any account holding credits beyond that allowance - every account with signup credits, and every top-up ever purchased - produced a negative figure and was silently skipped. A free account with signup credits scored -2000%, and on Pro with one 1,000-credit top-up the "80%" notice could only arrive once about 93% was really gone. The notices now use the same period figure your account page shows, so the two can no longer disagree.
- A relay hiccup no longer signs you out. Any failed token refresh was treated as a dead session, so a brief server error, a dropped connection, or two of the app's own screens refreshing at the same moment could end with you back at the sign-in screen on a session that was perfectly valid. Only an actual rejection clears it now; anything else is retried.
- A relay hiccup no longer clears Foxl Notes' local data. The same failed refresh ran a full sign-out inside Notes, which discards offline transcripts, notification history, your avatar, standing tool approvals and any provider key you had entered - at exactly the moment offline data matters most. Notes no longer signs anybody out.
- Signing in on two windows at once can no longer log you out of every device. Four separate places refreshed the sign-in token against the same stored copy with no coordination, so a slow reply could put an already-used token back on disk. The relay reads a reused token as a stolen one and ends every session on every device. There is one refresh path now, and a reply that arrives late is discarded instead of overwriting a newer one.
- The chat composer's send button no longer slides off the screen at large text sizes. The row could not give: the model name held its full width, so everything after it was pushed past the edge and there was no way to send a message. The name shortens now and the send button stays put. Affects the in-app UI font-size setting as well as the new iOS text-size support.
Fixes
- "Keep running when closed" now picks up an update without waiting for you to open the app. The background service had no updater of its own, so after an update installed itself the machine your phone talks to kept running the previous build until the app was next launched - measured at 21 minutes of a 0.6.0 server answering an iPhone, and in practice as long as you leave the app closed, which is the whole point of the setting. The service now notices that the build on disk is no longer the one it is running and restarts into it within about two minutes. On macOS and Linux it replaces itself completely; on Windows it replaces the part that serves your phone and the rest is updated the next time you open the app.
- Scrolling back through a live transcript no longer drags you to the bottom. Notes followed the newest line unconditionally, and during a recording a line updates every few hundred milliseconds - so scrolling up to re-read something was undone before you got there. The transcript, the AI panel and the note body now follow the newest text only while you are already at the bottom; scroll away and they stay where you left them and offer a jump-to-latest button, exactly like chat and agent. Opening another note starts at its newest line again.
Features
- "Restart service" next to the background-service status. When the service is running but its server is wedged, the only ways out were turning the whole feature off and on - which restarts Foxl - or the server-crash panel. There is now a restart link on the status line itself, and it reports the outcome rather than just firing off the request.
- Starting a huddle now tells the other person. A huddle told nobody it had begun: you pressed the headphones, the header said "1 person", and whoever you wanted to talk to found out if and when they next opened the channel. In a DM there was no way to fix it by hand either, because a DM has no invite picker. Starting one now rings the other side of a DM - on their phone too - and posts a "started a huddle" line in the channel, so the call leaves a trace in the conversation and moves it up the sidebar. A huddle in a channel does not ring everybody in it; the line plus the pulsing headphones is the signal there, and the invite picker still works for calling someone in.
- "Talk to us" on both pricing pages is a form now, and it records the enquiry. It used to be a
mailto:, which left no record anywhere: the enquiry landed in one inbox, there was no team size to price against, and nothing counted how many conversations a deal takes. The form asks for a work email, company, team size and what they would have Foxl do, and posts to a new relay endpoint. If the post fails, the email address is shown as a fallback so an enquiry is never lost. - A daily growth digest. The relay's nightly pass now records one dated snapshot of the funnel - signups, activation, paid accounts by tier, MRR, the pipeline by stage, and how many interviews one close costs - and emails it when a recipient is configured. The subject line carries the blocker rather than a greeting: while checkout is unconfigured it reads
checkout DISABLED, because MRR is then pinned at zero by configuration rather than by demand.
Fixes
- An update that does not install now says so, instead of leaving you on the old version. Pressing "Install now" hands the new build to the operating system's installer, which runs as a separate program and replaces Foxl after Foxl has quit. If anything is still holding the app when it gets there - a leftover helper, a window that reopened mid-quit - it cancels the swap, and until now nothing anywhere reported that: the app restarted on the old version, the bell said the update was ready to install, and only trying again a second time actually worked. Foxl now records which version it handed over and checks on the next launch. If that version is not the one running, the bell and Settings say the install did not complete and offer to try again, and the log names the installer's own log file.
- And it is much less likely to happen in the first place. Foxl now makes sure it has really exited once the installer is waiting on it, and the main window refuses to be recreated while the app is quitting - so a click on the Dock icon in that last moment can no longer bring the app back and cancel its own update.
- No more "WebSocket was closed before the connection was established" error box. Restarting the app while its local broadcast connection was still being established raised an uncaught-exception dialog, most visibly right after an install or when turning the background service on. The connection is now torn down quietly, which is what a teardown should always have been.
- A restart you asked for no longer reports itself as a crash. Turning the background service on, restarting, and installing an update all disconnect the local agent for a moment, and the "Agent server stopped" panel could not tell that from a real failure - so it appeared mid-restart and began restarting the server underneath, which on an update is one of the things that can cancel the install. The app now says when a shutdown is deliberate, and the panel stays out of the way.
- The emoji picker closes when you pick an emoji. It stayed open, so the reaction you had just added was hidden behind the panel you had to dismiss by hand.
- A "started a huddle" line reads as an event, not as a message somebody typed. Server-written messages rendered with an avatar, a name, reactions and an edit/delete menu that acted on a row nobody authored.
- The huddle button in the channel header no longer wears a count while you are in the call. A small number pinned to a red button reads as something wanting attention, directly above a bar that already lists everyone in the room.
- Channels opens on the conversation you left, instead of a spinner. The channel list and the open channel's transcript were re-fetched from scratch on every visit - and every navigation in the app is a fresh mount - so leaving Channels and coming back, or switching between two rooms, cost a round trip to the server each way and flashed an empty conversation in between. Both are now painted immediately from what you last saw and refreshed behind it.
- The channel list no longer flashes "Loading" while it is up to date. The sidebar refreshes itself every 20 seconds and after every mute, star or mark-read, and each of those showed a loading row over a list that had not changed. Only a genuinely first load says it is loading now.
- Fewer requests per visit. Opening Channels asked the server to seed
#generalon every mount rather than once per workspace, re-read the open channel's member list every 20 seconds, and marked a channel read twice on a single click. - Your account and credits screens no longer get slower the more you use Foxl. Both of them, and the companion's gem counter, worked out the totals by adding up every single request on your account from scratch each time they were opened - so the busier the month, the longer they took, and there was no upper limit to it. They now read a running daily total instead. The numbers are identical, including the token count the companion earns from; what changes is that opening the screen costs the same on your thousandth request of the month as on your first.
- A desktop whose sign-in had expired stopped retrying every minute. It would ask the server to renew credentials the server had already refused, once every 45 seconds, indefinitely - it was doing nothing useful and it was most of the traffic Foxl's servers were handling. It now waits between attempts when the answer was a refusal rather than a hiccup, and signing in again still reconnects immediately, as before. A connection lost to a network problem or a server outage retries just as quickly as it always did.
- Notifications look like a notification list again, on the phone and on the full page. The bell sheet and the Notifications page each drew their own rows over the same inbox, and both had the same three problems: every row carried a dot (a near-black one when unread, a grey one when already read, so the marker meant nothing), the archive button was pinned over the row and landed on top of the body text of any two-line notification, and on the page that same button became a full "Archive" label inside the row, squeezing the text into a narrow column. Rows now follow the standard iOS list: a blue dot only when unread and nothing when read, a coloured tile per notification type so an approval request, a channel message and a schedule result tell themselves apart, the timestamp and the file button side by side in the row rather than over it, and separators that start after the tile. Approve / Deny are quiet tinted buttons instead of solid black and red pills, day headings are sentence case, and the page hero no longer states the same count three times.
- The Notifications page gained the things only the bell sheet had: a swipe to delete or to mark read again, and the buttons on a notification that is asking you something - an approval request could previously only be answered by opening the bell over the page that was already showing it.
Internal
- Plan list prices ($20 Pro, $200 Ultra, enterprise quoted) exist as a table in the code for the first time; they previously lived only in a doc comment and in the Lemon Squeezy variants, so revenue could not be computed at all. Enterprise is deliberately
nullrather than a number, and the price is NOT derived from the credit allowance (Ultra sells credits at half the Pro rate, so arithmetic would report double its real MRR).
Features
- Work opens on a "For you" queue that spans every repository. Green pull requests waiting on a press, failing builds, questions Foxl is blocked on, unclaimed issues and Foxl's own proposals now arrive in one ranked list, closest to done first. Before, the Work tab was one repository at a time and nothing told you which of them was waiting - so with three repositories connected you visited three tabs to find out. Every row carries the repository it belongs to, one line of why it is there, and its buttons: Merge, Fix it, Solve, Decline, Diff, plus Dismiss and Snooze.
- Decline an issue without opening GitHub. Any issue can be closed as "not planned" from the Work tab with a reason, which is posted as a comment so the trail exists outside Foxl. This was the most common triage decision and the only one that still needed a browser trip - and it is what frees Foxl to look for work again, since it stops surveying while its own filed issues are unread.
- Ask Foxl to review a pull request, from the product. An "Ask Foxl to review" button runs the independent reviewer on any PR in a connected repository, and "Request changes" records your own verdict and sends the agent back to address it. Both existed server-side and had no button anywhere, so the only way to trigger a review was pressing Approve on github.com.
- Foxl learns from a No. When you dismiss or decline something with a reason, the next time Foxl goes looking for work it is told what you turned down and why, and does not propose it again.
- Autonomy is one choice instead of six switches. Code Settings now leads with three options - only when I ask / work on its own, ask me to merge / merge its own green work - and the middle one is the default. The six individual switches behind them are all still there under "Advanced", and picking a preset changes nothing else on the page.
- Foxl Code's settings are one row per topic. The Settings sidebar lists Autonomy, Coding agent, Defaults & budget, Instructions & MCP and Notifications under a Code heading, and Recording, AI features, Live translation and Auto-save & export under Notes. Each product used to be a single row holding its entire settings page, so a switch was findable only by scrolling.
- "When Foxl works on its own" moved to Schedules. How often it checks on running work, its quiet hours and how often it looks for new work now sit beside your repository schedules, because that page already answered "when". The daily spend cap moved next to the per-task budget, for the same reason.
- Page-view measurement on the Foxl websites, and only if you accept it. foxl.ai, docs.foxl.ai, app.foxl.ai and code.foxl.ai can now count page views with Google Analytics. Nothing is loaded and no analytics cookie is set until you say yes: decline and the tag is never fetched at all, rather than fetched and asked to behave. Your answer is remembered across all four sites, so you are asked once, and you can change it at any time from the new Cookie settings link in the footer of foxl.ai - withdrawing stops collection immediately instead of at the end of the visit. The apps are deliberately not included. The Foxl desktop app and the Foxl apps for iOS and Android contain no analytics SDK and send no analytics data, which is why they never show the consent notice - there is nothing there to consent to. The web bundle they embed is the same one app.foxl.ai serves, so the tag is gated to an explicit list of two web hostnames rather than switched off per platform: a new place this bundle ever gets installed starts with analytics OFF and has to be added by name. The privacy policy has been updated in the same change: a new section 3 covers cookies and this choice, Google is named in the list of companies that process data, and the places that previously said "no analytics" now say what is actually true - the apps do not, the websites do, with consent.
Fixes
- A pull request cannot be merged on an approval unless its build passed. When Foxl reviews a PR you approved and its own verdict is set to merge, it now refuses unless CI reported green on the exact commit being merged. It had no build check at all on that path, so a red pull request approved on github.com could merge - and because branch protection is unavailable on this plan, that check was the only one there would have been.
- Foxl stops waiting on work that is already dead. A task stuck part-way through used to count as live for a fortnight, and while anything counted as live Foxl would not go looking for new work. A run that has shown no sign of life for longer than one can possibly last no longer holds the queue open. Nothing is cancelled any earlier than before; only the "is anything actually moving" question changed.
- "Find work when the queue is empty" is on for accounts that never chose otherwise. The switch was flipped on by default some releases ago, but any account that had opened Settings even once - for any unrelated reason - stayed on the old off value forever. If you deliberately turned it off, it stays off.
- The Settings page explained the wrong field. The note describing how many issues Foxl may leave open was printed under "What to focus on", so the limit had no explanation and the box beside it described something else.
- Connect GitHub works. On code.foxl.ai the button flashed and put you back on Tasks - no GitHub approval screen, nothing connected, no error - and it did that for every user in every browser. The server was fine: Cloudflare was answering the request from the static bundle without ever running the code that forwards it to GitHub, which it does for any request a browser makes by NAVIGATING to a page. Every investigation with
curllooked healthy becausecurldoes not send the header that triggers it. All three GitHub-facing addresses were dead the same way, so installing the app by hand could not work around it either. - Cmd+Q works again after you turn on "Keep running when closed". Switching that setting restarts the app, and the restart is arranged by a small helper process that waits for Foxl to exit and then starts it again. If the quit it was waiting for did not go through, that helper stayed behind attached to a running app, so the next time you quit Foxl for real, hours later, it was immediately relaunched. Quitting looked broken and nothing said why. The restart is now arranged at the last moment, once the app is genuinely on its way out, so a quit that does not complete leaves nothing behind. The reason a quit could fail to complete is fixed too: the floating Notes meeting window is prepared invisibly about eight seconds after launch so its first open is instant, and if a quit was already under way at that moment, preparing it cancelled the quit. No window is created while the app is closing now, including the meeting window, the huddle window and the desktop companion.
- The background service comes back on its own if something kills it. With "Keep running when closed" on, an OS service holds the local server and the phone connection. Anything that stopped that service without turning the setting off left it stopped, and the machine stayed unreachable from your phone until the next time you opened the app, with the switch still reading as on. The service now tells the system it wants to be restarted in that case, while a stop you actually asked for (turning the setting off, or an app update replacing the service) still stops cleanly. On macOS and Linux that means it is back within about ten seconds; on Windows the service is started by signing in, so it still waits for your next sign-in.
- Turning "Keep running when closed" off no longer leaves the machine unreachable. Both directions of that switch restart the app, because the local server and the phone connection change hands between two processes. When that restart silently did not happen, the app kept serving locally with no phone connection at all until some later launch. The restart is now forced through if it stalls.
- Every screen on your phone has a name again, at the size it was designed at. The page title was meant to be 28px; it had been rendering at 22px on every screen, in both products, because a single stylesheet rule aimed at the whole app was quietly overruling each screen's own setting. The same rule was flattening the other direction too: a 14px channel label and a 28px page title came out identical. With nothing on a screen bigger than anything else, no screen had an obvious starting point to look at, which is most of why the phone felt busy. Titles now render at the size they ask for.
- Foxl Code's screens use the same title as the rest of the app. Tasks, Work, Inbox, Repos and Runtimes had a second, smaller title of their own, so moving between the two products on one phone meant two different-looking headers in the same app. There is one now.
- The top of a phone screen no longer explains the feature to you. Work opened with three lines describing what issues and pull requests are; Inbox with two comparing itself to Work. Both are useful the first time and never again, so they are kept for wider screens and the phone goes straight to the content. An empty Notifications screen also said there was nothing to read three separate times; it says it once.
- Schedules shows your schedules sooner. A three-cell Total / Enabled / Total runs strip sat above the list restating the line directly above it, with two of its three cells usually reading 0. It is a desktop thing now, and the first schedule starts about 80px higher up the phone.
- Repos offers to connect GitHub once instead of twice. With no repos connected there were two identical buttons on the same screen; the one beside the explanation stays.
- The red number on the iPhone icon is the real count now, not always 1. Every notification Foxl sends carried a hardcoded badge of 1, so three replies arriving while the app was closed still showed 1, and the number only became true once you opened the app - which is the moment it stops being useful. The count is now kept per person and advances with each notification, and the app publishes what its own bell says whenever that changes, so the bell, the icon and the notification agree instead of each counting something different. Reading everything still clears it. Product updates and the occasional companion notification no longer touch the number at all: they add nothing to your inbox, and a badge on them used to reset a genuine count of five things down to 1.
- A huddle invite is marked time-sensitive, so a ring can reach you in Do Not Disturb. Every notification went out at the same normal priority, which Focus modes are free to withhold - and a huddle invite expires after two minutes, so the one notification that behaves like a phone call was the one guaranteed to be silently held back when your phone was face down. Everything else stays normal on purpose; a finished task or a colleague's message reads fine later.
- A follow-up notification replaces the one before it instead of stacking. A coding task that became ready to merge and then merged left two banners on the lock screen saying different things, and only one of them was still true; an expired huddle invite sat beside the live one. Updates about the same conversation, task, question, note or call now collapse onto the previous banner. Separate things stay separate - two colleagues' messages, two different issues, and a transcript and its summary are all still their own notification.
Features
- Click the companion out on your desktop and Foxl comes back to the front. The reverse of Cmd+W: that shortcut hides the window and leaves the animal out on the desk, which made it the only piece of Foxl still on screen and yet the one thing that could not bring the window back - the Dock or the tray were the only ways in. A left click now raises the window (re-creating it if it had been closed, and restoring it if it was minimized) alongside the reaction it already played. Dragging the animal still changes nothing about your window order, and right-click is still its menu. The same on macOS, Windows and Linux. That takes slightly different work per platform: the companion is deliberately a window that never takes focus, and Windows and Linux both refuse to let a program that is not already in front hand itself the focus, so the window is brought forward by z-order there rather than by asking for focus and hoping.
Fixes
- The desktop companion's menu no longer leaves the animal stuck to your pointer. Right-clicking it and choosing "Stay here" or "Let it wander" dragged the pet onto the menu row and then kept it glued to the cursor, with no button held, for the rest of the session - it also stopped wandering, because a pet being carried does not walk. Two causes, both fixed: a right-click was arming the drag as well as opening the menu, and the release that would have ended that drag is swallowed by the menu itself, so the gesture was never closed out.
- The desktop companion walks both ways again. It was drawn facing right no matter which direction it was heading, so it moonwalked through half of every trip. The in-app pet has always turned around correctly; out on the desk nothing was applying the mirror.
- A desktop companion's hover reaction now lasts exactly as long as you are hovering it, the same as in the app. Because the window out there IS the animal, the pet walks into a cursor that is parked over some other app - so the greeting was firing with nobody hovering anything, and then playing for a further two seconds after the pointer had gone. It also started while the cursor was still up to 22px clear of the art, since the window is a little larger than the drawing inside it. A deliberate click still gets its full reaction whether you keep the pointer there or not.
- Cmd+B did two things at once, and only one of them was asked for. The Channels message bar's formatting shortcuts (Cmd+B bold, Cmd+I italic, Cmd+Shift+X strikethrough, Cmd+E code, Cmd+K link) were bound on every chat composer in the app, and Cmd+B is also the shortcut that collapses the sidebar - so one press in the Agent chat wrapped the draft in
**AND folded the sidebar away, on a screen that has no formatting bar to explain either half. The formatting shortcuts now belong to the Channels message bar only, and they are exclusive while it has focus: Cmd+B there applies bold and leaves the sidebar where it was. Everywhere else (Agent chat, Foxl Code chat, and every other screen) Cmd+B is the sidebar again and nothing writes a mark. The Channels shortcuts work whether or not the "Aa" toolbar is showing, which is what its own tooltips advertise. - "Keep running when closed" now appears as Foxl, with the Foxl icon, in System Settings > Login Items. It was listed under the developer's name with a blank placeholder icon, which said nothing about which app had asked to run in the background. macOS names a background item after the app it belongs to, and the background service was not telling it which app that was. Machines that already have the setting on are corrected on the next launch; there is nothing to switch off and on again.
- Turning "Keep running when closed" on no longer looks like Foxl crashing. Handing the server over to the background service tripped the app's own crash-recovery, so the moment the switch went on the window dropped to the "server stopped" screen - and pressing Restart there made it worse, because it restarted a background service that was already healthy and left the machine unreachable for around twenty seconds each time. Foxl now waits for the background service to take over, says it is restarting, and restarts itself so it comes back attached to it. Turning the setting off restarts the app too, which is what reconnects your phone and the web app to it - before, that only happened the next time you opened Foxl.
- The Restart button reported failure while the background service was running perfectly. With "Keep running when closed" on, Restart handed the job to the service correctly and then spent thirty seconds waiting for a signal that, in that mode, nothing sends - so it always ended on "the server did not come back".
brew install --cask foxl-ai/tap/foxlinstalls the current version again. The Homebrew cask had been stuck on 0.5.14 since August 6: three releases went out without it, so anyone installing or reinstalling through Homebrew got a build from a week earlier. Publishing the cask is part of the release itself now, and the release checks the cask afterwards rather than assuming it moved.
Features
- Work opens on a "For you" queue that spans every repository. Green pull requests waiting on a press, failing builds, questions Foxl is blocked on, unclaimed issues and Foxl's own proposals now arrive in one ranked list, closest to done first. Before, the Work tab was one repository at a time and nothing told you which of them was waiting - so with three repositories connected you visited three tabs to find out. Every row carries the repository it belongs to, one line of why it is there, and its buttons: Merge, Fix it, Solve, Decline, Diff, plus Dismiss and Snooze.
- Decline an issue without opening GitHub. Any issue can be closed as "not planned" from the Work tab with a reason, which is posted as a comment so the trail exists outside Foxl. This was the most common triage decision and the only one that still needed a browser trip - and it is what frees Foxl to look for work again, since it stops surveying while its own filed issues are unread.
- Ask Foxl to review a pull request, from the product. A "Ask Foxl to review" button runs the independent reviewer on any PR in a connected repository, and "Request changes" records your own verdict and sends the agent back to address it. Both existed server-side and had no button anywhere, so the only way to trigger a review was pressing Approve on github.com.
- Foxl learns from a No. When you dismiss or decline something with a reason, the next time Foxl goes looking for work it is told what you turned down and why, and does not propose it again.
- Autonomy is one choice instead of six switches. Code Settings now leads with three options - only when I ask / work on its own, ask me to merge / merge its own green work - and the middle one is the default. The six individual switches behind them are all still there under "Advanced", and picking a preset changes nothing else on the page.
- Foxl Code's settings are one row per topic. The Settings sidebar lists Autonomy, Coding agent, Defaults & budget, Instructions & MCP and Notifications under a Code heading, and Recording, AI features, Live translation and Auto-save & export under Notes. Each product used to be a single row holding its entire settings page, so a switch was findable only by scrolling.
- "When Foxl works on its own" moved to Schedules. How often it checks on running work, its quiet hours and how often it looks for new work now sit beside your repository schedules, because that page already answered "when". The daily spend cap moved next to the per-task budget, for the same reason.
- Open an issue, get an agent. Filing a GitHub issue in a connected repository now starts a coding agent on it - no button, no chat turn. Before, an opened issue reached nothing at all: the only way from an issue to an agent was the Solve button on the Work tab, so an issue Foxl filed for itself and did not immediately pick up sat there forever. It only acts on issues opened by someone whose GitHub account is linked to Foxl and who is still a member of that installation, it will not start a second agent on an issue that already has one, and it respects the same in-flight task limit as everything else.
- Foxl Code can be pointed at one repository. Settings -> "Find work when the queue is empty" now takes a repository name. Left empty it keeps following you around, looking at whatever you worked on last; name one and it stays on that project - the one you would never get round to asking about. It still only looks at repositories you have actually run a task in.
- It remembers what went wrong. When a task fails, Foxl now writes down one line about why, and hands that to the next task in the same repository. A retry used to start knowing nothing about the attempt it was replacing.
- Settings > Appearance can put a soft vertical gradient on the app's chrome. Two presets - Dawn (cream fading to pale blue) and Mist (a single-hue blue) - wash the sidebar, the outer canvas and the window titlebar from top to bottom, while the content area is never tinted. Each option is shown as a real swatch rather than a name, so the choice is visible before it is made, and the presets compose with Light, Dark and System. Default is unchanged: an existing install keeps the flat surface it has today, and Default sits first in the picker. Text stays exactly as legible as it is on the flat surface. A gradient can only be darker than the surface it replaces, so the sidebar's labels are re-derived to hold their current contrast over the deepest point of each ramp - measured rather than eyeballed, in both themes.
- "Keep running when closed" (Settings > Desktop): your computer stays reachable from your phone and the web after you quit Foxl. Until now the local server and the relay connection both belonged to the app window, so closing it took the machine offline - which is awkward for something described as a 24/7 agent. Turn this on and Foxl installs a small background service (a launchd agent on macOS, a systemd user unit on Linux, a Task Scheduler task on Windows) that owns the server and the connection instead. The app then attaches to it when you open it, and quitting changes nothing.
Off by default, and turning it off puts everything back the way it was. When it is on, the app no longer starts a second server of its own - the two would fight over the same port - and the Restart button asks the background service to restart rather than killing it.
Notes: the background service runs headless, so desktop notifications and app auto-update still need the app open (a question from Foxl Code reaches you through your phone and the in-app panel as usual). On Linux the installer also asks the system to keep your user services alive after logout; if that prompt is declined, Foxl says so and the service runs until you log out. Logs are in
~/.foxl/logs/daemon-*.logand are pruned after 14 days.
Removed
- Foxl Code's Knowledge page is gone, along with its three tabs (the repository memory list, the security Activity log, and the prompt Inspector). The sidebar row, the phone tab-bar entry, the command-palette entry and the
/knowledgeURL went with it; that URL now lands on Tasks like any other unknown path, and anyone who had put Knowledge in their customised tab bar keeps the rest of their layout. The agent's repository memory itself is UNCHANGED - it is still written and read by the coding agent and still injected into every task prompt for that repo. What was removed is the read-only viewer over it, not the memory.
Fixes
- Notes: a sentence spoken across a transcription handover no longer sticks to the bottom of the live panel - and no longer goes missing from the saved note. Transcription reconnects every 4.5 minutes, and the reconnect used to discard the closing line each time: the service sends a sentence's finished version last, after being told the audio is done, and Foxl hung up before it arrived. The unfinished line then stayed unfinished for the rest of the meeting. Because the live panel shows in-progress speech below everything already transcribed, it parked itself under the newest text and covered it, with no speaker name and no error - a 15-minute call produced three of them. The same line was also absent from the note, its summary, its export and its shared text, all of which keep finished speech only, and its translation stayed stitched together from half-sentences. Foxl now waits for that closing line before hanging up, and if it never comes (the network dropped, the laptop slept) it keeps the words that were already transcribed instead of discarding them. The same fix applies at Stop, so the last thing said in a meeting is saved rather than dropped.
- The bell showed no number over an inbox that had unread items in it. A notification whose destination was the page you were already on was marked read the moment it arrived - within the same frame it was filed, before it had been on screen at all. Chat replies, channel messages and Foxl Code task updates all land on pages people sit on, so the count they were supposed to raise was the count most likely to be erased. The row stayed in the list, which is why the two surfaces disagreed: items visible in the sheet, nothing on the bell. Arriving on a page now reads the notifications that were already waiting there and leaves anything that arrives after you got there unread. A streaming reply no longer counts as arriving on a page either - every message appended to the open conversation used to re-run that check.
- The red number on the app icon did not match the one on the bell. They were computed differently: the bell counted the notification inbox, while the icon added unread conversations on top, so a phone could show three on the home screen and one on the bell for the same list - and tapping through every notification could not clear it. The icon badge is now exactly the bell's count, so everything it counts is reachable and it can always reach zero. The macOS dock badge deliberately keeps counting unread conversations alongside notifications, because on the desktop a reply that lands in a conversation you are not looking at files no notification of its own; it matches the sidebar's Chat row, which counts the same thing.
- Reading your notifications in the app left the banners on your lock screen. The app already respected the phone's notification centre in one direction - swipe a banner away and the in-app row went read - but never the other, so clearing the bell changed nothing outside the app and the same items kept sitting in Notification Center. Rows you have read or archived now have their banners removed, and so do rows you swipe away or clear, which was the case where the app's list was empty and the phone's was not. Unread items are left alone in both places.
- The pet showed a companion you did not own, and "Follow along" could land on a character you had never drawn. The gallery locked every unmet card correctly, but the code that actually draws the animal never asked what the account owned - so turning "Show pet" on with an empty collection produced a companion anyway (the fallback was a real 4-star doll from the summon cast), and "Follow along" could pick up a common that had merely been SIGHTED elsewhere in the app rather than drawn. Gifting away your last copy of a character left it walking around too, since the copy is spent the moment the gift is sent. All three now go through the same ownership check the gallery uses: with nothing owned the pet stays away and the Show pet row says to draw a companion first. Nothing changes for anyone who owns what their pet is set to, and a signed-out or offline app keeps drawing the companion it was already showing.
- The companion counter in Settings > Pet could never reach its own total. It counted the nine dolls but printed that against all fifteen cards, so an account that owned every companion in the pane read "9/15" and no amount of playing could complete it. The two numbers now come from one set: the nine dolls, which is the collection the draw is for - the six commons are the pool a draw comes out of rather than the prize, so a player's first two draws no longer look like progress they did not make.
- The chat's first screen could be scrolled, and there was nothing below it. Opening a new chat on the desktop left the transcript scrollable by exactly 20px at every window size - and scrolling moved nothing, because the greeting and the composer are pinned to the middle of the canvas. The scroller was reserving room for a floating composer to overlap the last message, on a screen that has no messages: while empty, the composer centres itself by filling the whole canvas, so the space reserved for it was the height of the window.
- Real iOS glass came back to the round buttons, and had been gone since v0.5.12. The header chips on iPhone are supposed to be actual iOS 26 Liquid Glass (a UIKit material, not a CSS blur), and they had quietly reverted to the CSS imitation for five releases. Nothing was switched off for performance: the native plugin lives outside the app's own source tree, and the file naming where to find it was written with a path three folders too deep, so the build looked for it somewhere that does not exist and linked nothing. Because the app is meant to fall back to CSS glass on older iPhones, a plugin that could not be found and one that is not supported look identical from the outside - so the build passed, the upload passed, and TestFlight marked it valid with the glass missing. The Agent screen's Back and Stop buttons now take the native material too. They had been left on CSS glass while the shell header beside them used the native one, so opening an agent swapped the treatment mid-screen. The message bar, the Channels surfaces and the bottom tab bar keep CSS glass, which is a limit of the platform rather than a choice about effort: the native material refracts every pixel inside its own rectangle, so it can only be given to a control whose entire foreground can be handed to UIKit - in practice a single icon, drawn as an SF Symbol on top of the material. A message bar holds a live text field, a model picker and two buttons; a tab bar holds four icons, four labels and a badge; the Channels list holds rows of text. Those came out smeared when it was tried, because a native view sits outside the web page's paint order and no stacking trick lifts web content above it. CSS glass is the correct tool wherever content sits ON the surface, and it is what those three keep.
- The companion can come out of the app window and live on your desktop. Settings > Pet has a "Show outside the app window" switch, and the pet's own right-click menu offers to let it out - after which it walks around your desk over your other apps, follows your cursor when asked, and can be picked up and carried anywhere, including onto another monitor in one continuous drag. Its menu offers the way back into Foxl. Off by default, and desktop-app only: a browser tab cannot paint outside itself, so the row explains itself rather than disappearing there. This shipped as a working feature on the third attempt, and the difference is the shape rather than the polish. The two earlier versions made the pet a transparent window covering a WHOLE DISPLAY that had to become click-through everywhere except the animal - so any bug that left it interactive stopped every click on that monitor until you quit the app, which is what happened. The window is now the size of the animal, about 76px, and is never click-through: there is no hit test, no gesture lock and no cross-monitor handoff, because a small window that always takes its own clicks needs none of them. The worst it can do is take a click in the 76px it occupies, which is the pet working.
- Open an issue, get an agent. Filing a GitHub issue in a connected repository now starts a coding agent on it - no button, no chat turn. Before, an opened issue reached nothing at all: the only way from an issue to an agent was the Solve button on the Work tab, so an issue Foxl filed for itself and did not immediately pick up sat there forever. It only acts on issues opened by someone whose GitHub account is linked to Foxl and who is still a member of that installation, it will not start a second agent on an issue that already has one, and it respects the same in-flight task limit as everything else.
- Foxl Code can be pointed at one repository. Settings -> "Find work when the queue is empty" now takes a repository name. Left empty it keeps following you around, looking at whatever you worked on last; name one and it stays on that project - the one you would never get round to asking about. It still only looks at repositories you have actually run a task in.
- It remembers what went wrong. When a task fails, Foxl now writes down one line about why, and hands that to the next task in the same repository. A retry used to start knowing nothing about the attempt it was replacing.
Fixes
- Connect GitHub works. On code.foxl.ai the button flashed and put you back on Tasks - no GitHub approval screen, nothing connected, no error - and it did that for every user in every browser. The server was fine: Cloudflare was answering the request from the static bundle without ever running the code that forwards it to GitHub, which it does for any request a browser makes by NAVIGATING to a page. Every investigation with
curllooked healthy becausecurldoes not send the header that triggers it. All three GitHub-facing addresses were dead the same way, so installing the app by hand could not work around it either.
Features
- The companions are plush dolls again, and there is a gallery to pick one from. The pixel art was drawn one animal at a time at 16x16, and at that size every character carried stitches, odd eyes, a bow, a bell, a patchwork seam and a tail within two pixels of each other - so instead of a shelf of toys it read as speckle, and no two of them were built the same way. Every companion is now generated from one shape language at 12x12: fewer, larger pixels, a heavier outline, and the marks their illustrations actually carry - the ragdoll's blue bow and gold bell, the grey cat's split panel and mismatched eyes, the bear's navy top hat. Because the shape is shared, no character can drift from the family. Settings > Pet shows the whole cast at once instead of hiding it behind a dropdown of names. Each card carries the character's ORIGINAL illustration at a size you can actually see, with the pixel sprite beside it at exactly the size it will be on screen - so the picker answers both what it is and what you will get, and the Size row has a live preview instead of three words.
- Companions are drawn, and most draws give you a common. The gallery has a Draw button that spends one gem, or five sparks when you have no gems - the same wallet and the same odds as the summon screen, which are published on both: SSR 0.3%, SR 0.7%, R 3%, and a common 96% of the time. Three commons joined the cast to fill that tier, so a draw always brings something home; it is usually the third sparrow. A character you have not met stays locked as a silhouette until it turns up, and after 60 commons in a row the next draw is guaranteed to be better. Gems come from real agent usage (one per 250k tokens, at most three a day) and sparks from tool calls. Neither can be bought, and there is still nothing for sale anywhere in this.
- The pet has a menu now. Right-click it on a desktop, or press and hold on a phone: pet it, call it over to where you pressed, tell it to stay put, draw a new friend, or put it away. It holds still while the menu is open, and a press that travels is still a drag rather than a menu.
- The companions are hand-drawn art at full resolution, and they act. Every character has a real four-to-six frame walk cycle and up to eight poses - standing, sitting, sleeping, waving, eating, crying, cheering, idling - drawn per animal rather than derived from one picture. Standing still, a companion drifts between its resting poses instead of holding a single frame; hover it and it waves, click it and it cheers. The art is no longer squeezed through a small grid, so the stitches, the bows and the fur read the way they were drawn.
- The companion lives where you put it. Drop it somewhere and that is its spot - it pooters around near there rather than setting off across the whole window, and it walks in short stints with long rests between them instead of pacing. Settings > Pet has a switch if you would rather it stayed perfectly still, and its menu has the same choice as a single row.
- Right-click it (or press and hold on a phone) wherever it is. The menu can send it after your cursor for a few seconds, park it where you pressed, draw a new friend, or put it away.
- Send a companion to someone. A character you own can be given away by email, with a note. The pet leaves your collection when you send it and arrives in theirs when they accept, so a gift moves an animal rather than creating one - and if the address has no Foxl account yet, the gift waits and is claimed the first time they sign in. An unclaimed gift comes back to you after a day, so a mistyped address cannot strand a character permanently, and you can take one back yourself before it is claimed.
- Gems and your collection live on your account now, not in the browser. They used to be stored locally, which meant they did not follow you between the desktop app, the web and your phone - and anything kept only in a browser can be edited by hand. A draw is now settled by the server, so the same wallet and the same collection show up everywhere you sign in, and a repeated tap on Draw cannot hand you the same character twice or spend the same gem twice. What is on this device already is moved up to your account the first time it syncs.
- The phone's bottom bar has a + now, and a lot more to put in it. Settings > Tab bar could change what was in a slot and drag slots around, but the only way to make the row LONGER was a 0-5 number picker that filled the new slot with a destination you never chose. Tap + instead and it asks: pick a destination and the row grows by one, up to five. The number picker is gone - the bar is as long as the tabs you put in it. The list of destinations you can dock is much longer. Tasks, Usage, Integrations and Mobile/Web are offerable for the first time - none of them had a way to be reached by tapping anything on a phone, since they left the sidebar for Settings - and Foxl Code's own Settings joins them. Any of them can sit in any product's row, so a Code queue or Notes can live in the Agent bar; tapping one switches product. An empty bar now asks which tab you want first rather than picking three for you.
- The agent's terminal is a screen of its own on the phone, in Foxl Code too. Opening Terminal on a task now pushes in a full-screen page from the right, the same way it does in Foxl Agent: just the agent's live output, and a keyboard built for it along the bottom. Swipe from the right edge to open it, swipe back from the left edge or tap the back chip to return to the conversation, which stays exactly where you left it. That keyboard carries the keys a phone does not have - Tab, esc, ^C, ^D, ^Z, del and the four arrows - so you can complete a path, answer a prompt, walk back through history, or interrupt a command that is running away. Before this there was no way to send any of them, which meant a running agent could not be stopped from a phone. Text goes through a proper command box, so Korean, Japanese and Chinese compose correctly instead of coming apart mid-word. The prompt and plan panels are not on this screen on purpose - they were taking the room the output needed, and both are still on the Conversation side. The desktop keeps its familiar layout, unchanged.
Changes
- Foxl Agent's workspace-files panel is now a rounded panel too. Opening it from the chat header slides in a white card that floats on the window's background, with a visible gap between it and the conversation, instead of a flat column meeting the transcript at a hard line. It is the same shape Foxl Code's review rail already uses, so the two products' right-hand panels now match. Resizing by dragging its edge, the file tree, the open-document tabs and the phone's full-screen version all behave exactly as before.
- Foxl Notes opens straight into the product. The five-step "Welcome to Foxl Notes" setup dialog is gone: the first visit lands on the notes themselves rather than on a language picker, a sign-in step, a microphone test and a page of tips. Nothing it configured is lost - the language lives in Settings > General, signing in is prompted where recording actually needs it, and the system-audio check is still a button in Notes settings. Settings > Notes no longer carries the "Show setup guide" row, since there is no guide to replay.
- A Foxl Code task that opened several pull requests now lets you see all of them. A plan that fans out across subtasks opens one PR per subtask, and resuming a task can land another - but the review panel could only ever show one, so the rest were unreachable from Foxl. When a task has more than one, its PR number in the review panel becomes a picker: choose any of them and the panel loads that PR's checks, files and diff, with the merge button acting on the one you are looking at. It opens on the same PR it always did, and a task with a single PR looks exactly as before - no picker where there is nothing to choose. Previously the second and later PRs were dropped from the task's record entirely, so they are now kept as well, along with whether each one is open, merged or closed.
- The right-hand review panel in Foxl Code is now a rounded panel of its own. Opening it slides in a white card that floats on the window's background, matching the way the sidebar already curves into the page, instead of a flat column meeting the content at a hard line. Dragging its edge to resize and collapsing it work as before.
- Removed the unused "bring your own Anthropic key" path on app.foxl.ai. The screen for entering that key was never reachable, so nobody could turn it on - but the relay half was live and would have skipped credit billing and the plan's model limits for anyone who sent the key by hand. Both halves are gone. This does not affect the desktop app's own provider keys in Settings, which are a different feature and work as before.
Fixes
- Sometimes there were several pets walking around at once. Each one was a real layer left behind in the page by an earlier mount, so they kept walking with nothing driving them from the app's side. The pet now clears any stray layer when it appears, and its animation loop retires itself instead of surviving a reload.
- A dialog opened from Settings on a phone was invisible to your finger. Any dialog that a control inside the Settings sheet opens - the tab bar's destination picker, the EULA - was drawn underneath the sheet that opened it. It was there, and every tap landed on the sheet instead, so the control simply did nothing. Dialogs and sheets now stack above the full-screen covers, like the menus and pickers already did.
- The tab-bar destination picker rises from the bottom on a phone now, on the same curve as every other sheet in the app, instead of zooming in from the middle like a desktop dialog.
- The Foxl Code terminal no longer sits in a slightly darker hole than the panel around it. In dark mode the terminal's own background had drifted a few shades away from the card it lives in, leaving a visible seam around the output.
- Foxl Code has its own sign-in screen again. code.foxl.ai used to open with a two-column door - the product's pitch on one side, the sign-in buttons on the other - and it went away when Foxl Code moved into the main app shell. Since then the site opened with the same generic screen as app.foxl.ai, which said nothing about tasks, repos or pull requests. It is back, with GitHub as the first option, since that is the account Foxl Code actually needs. Only the screen changed. Signing in with a password, the emailed link, and everything else about how sign-in works are the same as on app.foxl.ai, and app.foxl.ai, the desktop app and the phone apps all look exactly as they did.
- Arrange the phone's bottom bar yourself. Settings > Tab bar lets you set how many slots the row has - anywhere from one to five, or none at all - and choose what sits in each one. Drag the slots to reorder them, tap one to change where it goes, and turn the labels off if you would rather have more room for the icons. Destinations from the other products are allowed, so Notes or a Foxl Code queue can sit in the Agent bar; tapping one switches to that product. Each product keeps its own row, and the pane edits any of the three from one place. Nothing changes unless you change it: the bar ships with the same tabs it always had. Setting the row to zero slots removes it and gives that space back to the page rather than leaving a gap where it used to be.
- A real emoji picker in Channels. Reacting used to offer three emoji - a thumbs-up, a party popper and a pair of eyes - and there was no way to send a fourth, even though the server has always accepted any of them. There is now a picker with a search box, categories, and a "Frequently used" row that learns what you actually send. The three quick ones stay pinned where they were. It also opens on the message you clicked. The old strip anchored to the top of a group of messages from one person, so on any grouped message the buttons pointed at a different line than the one they would react to.
- Pick how much the channel list shows. Settings > Appearance now has a "Channel list" choice with a live example of each option: every channel with its last message and the time it arrived, or just the channel names, one tight line each - the classic Slack sidebar. Channels with unread messages go bold and full black in both. The same choice is on the workspace menu at the top of the list.
- Menus everywhere in Channels. Right-click a message for reactions, copy text, copy link, edit and delete. Right-click a channel for mark as read or unread, mute, star, add people, copy link, leave and archive. The workspace name and each section heading have their own menus too, with mark all as read, create channel, show only unread, sort by name, and collapse. The line under the workspace name used to read "All caught up" and do nothing. Marking everything read is now an action you can take rather than a state you are told about.
- Speak your message instead of typing it, in both chat and Foxl Code. There is a microphone in the message bar now. Tap it and talk; the words appear in the draft as sentences finish, and you can keep typing around them - dictate a clause into the middle of a sentence and it lands where the cursor is. What is still being heard shows under the bar in grey until it is committed, so nothing you say gets written twice. It is the same transcription Foxl Notes uses for meetings, so it handles ten languages and follows the language Foxl is set to. It runs on your Foxl credits and bills by the second, only while the mic is open - and it closes itself after a stretch of silence rather than leaving a hot mic running. The button is red while it is listening.
- A pet that walks around the app, with its own Settings pane. Settings > Pet turns on a small companion that wanders across whatever screen you are on. Pick it up and drop it anywhere and it stays put, then carries on from there - and it remembers where you left it. It walks with an animated step and turns to face the way it is going. Choose which companion appears, or leave it on Follow along, which keeps whoever you most recently brought out. Three sizes. Off by default, and it holds still when Reduce motion is on.
- Invite someone into a huddle, and answer with Join or Decline. A huddle used to be a room you had to already be looking at to know about: anyone in the channel could walk in, and nobody could be asked. Now anyone in a call can ring a specific channel member, and their phone rings too - the invite arrives as a card with Join and Decline, wherever they are. Decline is a real answer that travels back, so the person who invited you stops waiting instead of guessing whether you saw it. An unanswered invite expires after two minutes and says how long is left, because an invite that outlives its call would put you in an empty room. An invite that arrives while the app is closed is still there when you open it, as long as the call is still running.
- A huddle window of its own. On the desktop a call can be popped out into a small always-on-top window, so it stays visible and controllable while you are in a browser or an editor - which is when the in-app bar could never help, because Foxl was behind something else. On the web and on iPhone the same surface appears as a floating panel inside the app. Either way it shows what a single row could not: every person as a tile with their name, who is speaking, who is muted, and who could not connect. Closing the window does not hang up - Leave is the only thing that does. Notifications for huddle invites are their own switch in Settings, separate from channel messages, and muting a channel does not silence a call.
- Change workspace from inside Channels. The workspace name at the top of the conversation list is a button now, and it opens a picker of every workspace you are in. Previously that name was plain text that looked like a control and was not one: changing workspace meant opening the drawer, then Config, then the Workspace pane, then a row. With a conversation open there is a second one - the workspace name sits above the channel name. On a phone the list steps aside once you open a conversation, so before this there was nothing on screen telling you which workspace you were reading, and no way to leave it without going back first.
- React to, edit and delete a message on a phone. The reaction buttons only appeared on mouse hover, which does not exist on a touch screen - so on iPhone and iPad there was no way to react to a message at all. Editing and deleting had never been reachable anywhere. Press and hold a message, or use the button on its right, and all three are there.
- Schedules is now the same screen in Foxl Agent as it is in Foxl Code. The Agent side adopts Code's layout: a summary of how many schedules exist, how many are running and how many times they have run; one search box and one status filter that apply to whatever you are looking at; and three views behind a switch - a sortable table of your schedules, a calendar of the next seven days, and the run history. The run history used to sit permanently below the list with six filters of its own, so the schedules you came to manage were pushed off the screen by history you had not asked for. It is a view now, and it loads only when you open it. Creating and editing a schedule use one panel that slides in from the right instead of two separately-written dialogs, deleting asks in-app rather than through a browser prompt, and every row's Run now works independently - a slow schedule no longer freezes the button on every other row. The calendar reads its times from the same component that fires them, so what it shows is what will actually run, timezone and daylight-saving included.
- The phone app has a bottom tab bar. Chat, Channels, Workspace and For You on Agent; Tasks, Channels, Work and Repos in Foxl Code - all thumb-reachable at the bottom of the screen. Every destination used to sit behind one button in the top-left corner, which is the furthest point on a phone from the hand holding it. The side drawer is still there for everything else.
- Every screen says its own name. A phone screen now opens with a real title and, under it, one line of live state - whether your desktop is connected, how many unread messages are waiting, what is running. Before this the top of every screen was the same small grey word, so all of them looked alike.
- Channels looks like a messenger now. Each row shows who or what it is, the last message, when it arrived, and an unread count - with a face and an online dot for a direct message. Long-press a message to react to it, and there is a jump-to-latest button when you have scrolled back through history.
- The greeting is back on the phone home screen. "Good evening" over a few things to try, the way it looked before - and it now stays centred when a suggestion wraps onto a second line instead of drifting toward the top of the screen.
- The tab bar is a floating glass capsule. It sits inset from the edges and lifted off the bottom, so the page shows on both sides and underneath it - which is what makes the glass read as glass. The active tab is a pill that slides as you switch. Every screen scrolls beneath it, and the last row always clears it.
- One place for notifications on a phone. For You and the notification center were two screens showing the same things; the bell now opens For You, which is a tab.
- Copy and Regenerate stay on screen under the latest reply. They were revealed only by moving the mouse over the message, which meant they did not exist on a phone or tablet at all - a touch screen has no hover, so the buttons under the answer you had just received were invisible until you happened to tap the message itself. The reply at the bottom of the conversation now keeps its row visible everywhere. Earlier messages are unchanged, so scrolling back through a long conversation still reads as text rather than as rows of buttons.
- Tap a line in a Notes transcript on your phone to hear it. Playing the audio back from any point in the transcript worked on the desktop only: recordings kept their audio there and nowhere else, so on a phone the same tap did nothing. Notes now keep the recording on every platform, and an iPhone recording is kept too - that path records through the system audio engine, which produced no playable file at all before. Deleting a note deletes its audio with it.
- Share a note, and get the whole note. Summary, Transcript and Notes each have a share button next to Search, and one press shares all three together rather than whichever tab you happened to be on. Copy does the same thing to the clipboard. If the transcript was translated as you recorded, the translated lines come along in both - the transcript's own Copy button used to drop them silently, so half of what was on screen never reached the clipboard.
- Channels opens your team's chat instead of explaining what a workspace is. Anyone whose active workspace happened to be Personal - which is the default - landed on a full screen of prose about shared workspaces, with the team they were already in offered as buttons to press. Channels only exists inside a shared workspace, so it now resolves that itself and takes you straight to the conversation. The explanation is still there for the one case it describes: you are not in a team yet. It now carries a button that goes somewhere, which it did not when there was no workspace to list, and it is not shown when the workspace list merely failed to load.
- Foxl starts again when it was stuck on "Starting Foxl". The app could sit on its loading screen forever, reporting that the server was not bound while the server was in fact running and answering. One piece of startup housekeeping was failing on a search-index leftover, and because that step ran before the app announced which port it had opened, the window never learned where to look. The announcement now happens the moment the server is listening, so nothing that comes after it can keep the app from opening, and the leftover is cleaned up on the way in. Chat history is untouched by this - search falls back to a simpler match until the index rebuilds itself.
- The startup screen can reach Discord. When Foxl cannot bring the local server up, the problem is usually not one the docs cover, so there is now an "Ask on Discord" link beside the docs one. Both open in your browser rather than replacing the screen you are reading, which used to take the diagnostics and the Restart button with them.
- Older conversations open again. A chat from a month or two back could sit there loading and never arrive. Nothing had been lost - the transcript was simply too large to send: a single web page one tool had fetched was kept in full at 11 MB, and a handful of pasted screenshots came to 13 MB and 18 MB on one message each. Foxl now loads the readable part of a heavy transcript and says where it left something out, so the chat opens in a moment instead of not at all. The largest ones measured here went from 12 MB to under a megabyte. A tool result or an attachment that was left out says so in place, and the full value is still on disk. New chats keep tool output within a sane size from the start, so history stops accumulating this.
- Foxl tells you when it is only looking at recent chats. Asked about something from an older conversation, it would sometimes answer as though that conversation did not exist - it is shown a list of recent sessions, and nothing said the list was only the most recent few. It now sees more of them, knows the list is a window rather than the whole record, and searches your history before saying something cannot be found. The dates on those entries carry the year, so a chat from last year is no longer indistinguishable from one from last week.
- Session records are filed under the right day. A conversation that ended in the evening was saved under the next day's date, which put the list of recent sessions out of order.
- Attached images stop being copied into the offline cache. Screenshots and PDFs were meant to be left out of the on-device copy of your history, and on the desktop path they never were - so the cache held every attachment in full.
- Switching away from a chat on your phone no longer throws the answer away. Ask something, then background the app or lock the screen: iOS freezes the app within seconds, and the reply that was still arriving used to be replaced by "You're offline" - for a turn that had not failed at all. It kept running on our side, and it was still charged to you; there was simply nowhere for the finished answer to go. It is now held for you and appears in the conversation when you come back, whether you return to a still-running app or tap the notification and launch it fresh. A turn that genuinely fails still says what went wrong, and one you stop yourself stays stopped. A short reply now also just finishes: the app asks iOS for a moment to complete the turn instead of being cut off mid-sentence. The held reply is encrypted on your device before it is sent for safekeeping, and the key is kept on your phone, so the stored copy is encrypted to a key we do not hold, and it is discarded after a day.
- A finished chat always notifies you now, and the notification quotes the answer. If a reply lands while you are not in the app, the notification is no longer best-effort: it is sent whenever the turn completes without you there. Previously it depended on our detecting the exact moment your phone dropped the connection, so a reply that finished a beat too early arrived silently. Notifications also show the start of the answer instead of "Your response is ready." GPT models were missing this entirely - a backgrounded GPT chat finished with no notification of any kind, and tapping through had no conversation to open. Both are fixed, and every model now behaves the same way. Turning chat notifications off in Settings still turns all of this off.
- Foxl no longer closes itself on Android after you sign in. Signing in asked for notification permission, and allowing it took the app down - every launch after that, before anything drew, which is what "Foxl keeps stopping" was. Registering for push crashed the app outright rather than failing, because the Android builds carry no push credentials; the app now skips that step there instead. Nothing else changes: Android push has never delivered a notification, so there is nothing to miss until the server side exists.
- The two round buttons at the top of the screen are back on Android. The sidebar toggle and the chat menu were invisible - still there, still tappable, just not painted - so the sidebar, search and new-chat had no visible way in. Their icons were being hidden for an iOS-only glass effect that Android cannot draw, and nothing put them back.
- The Foxl logo on the Android boot screen is no longer clipped. The mark was drawn slightly too large for the circle the system masks it to, cutting the corner of an ear.
- The Android app wears the Foxl logo. Its launcher icon, its recents card and its boot screen were all showing the placeholder artwork the Android project was generated with - a light-blue X on a graph-paper circle - which is another vendor's mark, not ours. The boot screen shared the cause rather than being a second bug: Android draws the launcher icon there unless the app names something else, so the placeholder reached the one screen every launch passes through. Dark mode now gets a lighter version of the mark, since the near-black one is invisible on a dark plate, and the app's accent colour is Foxl blue rather than the stock Material pink that a text cursor was tinted with.
- An imported recording can be played back. Importing an audio file transcribed it correctly but never kept the audio, on any platform, so tapping a line in the transcript of an imported note always answered "No audio saved for this note."
- Changing your provider in Settings only takes effect once it saves. Picking one from the dropdown used to switch chat over immediately, so if the save then failed the app was talking to a provider the server had never been told about - visible only as replies from the wrong model.
- Files no longer sits pushed up from the bottom on a phone. It was paying the tab-bar clearance twice, once on a layer that could not use it.
- Foxl Code's setup screen no longer hides its own button on a phone. "Start a task", the last step and the whole point of the page, sat under the floating tab bar with no way to scroll it clear.
- The pet stays out of the way. Three things it was getting wrong: it walked over the message box on a desktop window, so clicks meant for the input hit the animal instead; while the phone menu was open it faded out but still swallowed taps, so a menu row under the invisible pet did nothing; and in the desktop app its walking area was measured from the window's title bar rather than the app header, which pushed it too low. Picking it up and dropping it on the message box now returns it to where it can actually stand.
- Two places showed a code name instead of words. Searching the workspace with no matches printed "workspace.no_results", and a conversation you never titled appeared as "chat.untitled" in titlebar search and in the trash list. Both now read properly, in all ten languages.
- Copy and Regenerate stay on the newest reply after you send the next message. The row was pinned to the last thing in the transcript rather than the last answer, so the moment you asked a follow-up the buttons on the reply you were reading went back to appearing only on hover - and if the new message failed to send or you stopped it, they stayed that way. On a phone there is no hover, so they were simply gone. Both chat and Foxl Code.
- Channels uses the whole width of the window. The messages and the box you type in were held to a 768px column, so on a wide window the conversation was a narrow strip with an empty half beside it. Both now fill the pane, the way every other chat app does. Foxl Agent and Foxl Code chat keep their reading column - a long answer is a document, a channel message is not.
- The workspace switcher appears once, not twice. With a conversation open on a desktop, the workspace name and its chevron showed both in the channel list header and again above the channel name - two controls, one destination, and the second one pushed the channel name onto its own line. On a phone it stays, because the list steps aside there and it is the only thing naming the workspace.
- The "this is the beginning of the channel" block stops taking over the conversation. The full introduction - the large tile, the heading, and the Add people card - is what an empty channel shows. Once there are messages it shrinks to a single line above the first one, instead of ~380px of welcome that has to be scrolled past every time the channel is opened.
- Starting up no longer shows a progress bar that is not measuring anything. The boot screen had a sweeping bar and lazy screens had a spinner; neither had a quantity behind it, since a bundle arriving has no percentage. Both are now the Foxl mark coming into focus, on the same timing as the rest of the app's motion. Under reduced-motion it fades rather than moves.
- The button beside a screen's title is no longer cut off at the top on a phone.
+ New scheduleon Schedules, and the settings button on the notification screen, had their top edge - and with it the top of their rounded corners - clipped by about 4px, so they read as square on top and round on the bottom. The title row now sits 4px lower, which brings the whole button back into view. - Opening a notification on a phone no longer leaves the menu covering it. The bell lives in the drawer, so the drawer was always open behind the notification sheet. Tapping "View all notifications" - or any notification row - dismissed the sheet and left you looking at the drawer, on top of the page you had just asked for. Anything that opens a page now closes the drawer with it. Swiping the sheet away still hands the drawer back, since that means you changed your mind.
- The message bar in Channels sits at the bottom of the phone screen again. It was floating about a tab-bar's height too high, leaving a band of empty space between it and the tab bar. The clearance for the floating tab bar was being applied twice on that one screen, and the extra one pushed the whole conversation up. Foxl Code was unaffected, so the same screen looked right on code.foxl.ai and wrong in the app.
- Foxl Code pages scroll on a phone again. Repos, Work, Inbox, Runtimes, Schedules, Knowledge, Settings and Account had no scroll of their own, so anything past the first screenful could not be reached at all - on Repos that meant every repository below the fold, and on Work every pull request. Dragging did nothing rather than showing a bounce, so there was no sign the page continued. The last row also sat under the tab bar; it now clears it.
- A Foxl Code task branched off a conversation now opens with that conversation. Starting a task from an existing chat used to show a single message bubble - the instruction the orchestrator had written for the agent, drawn as though you had typed it - with no reply underneath and none of the discussion that led to it. The task now opens with the real exchange, and the chat it came from keeps its own copy. This affected every task except the first one started from the home composer, so it also hit each extra agent when one request fanned out into several: those tasks had no transcript stored anywhere, on any device. The synthesized instruction is no longer presented as your words.
- The app reconnects by itself again after the network drops. On a phone or on app.foxl.ai, one brief loss of signal used to put a full-screen panel over everything for the rest of the session: it had no close button, and the condition it was waiting for to dismiss itself could never happen on those builds. The only way out was to force-quit. It now clears the moment you are back online.
- While you are offline, Foxl keeps checking. It used to stop trying and wait for the browser to announce that the network returned - which a phone does not reliably do after a sleep or a change of network, so a connection that came back could go unnoticed indefinitely.
- The reconnect panel can be dismissed, and says what it is doing. A close button, Escape, or a tap outside puts it away; a progress bar shows the wait until the next attempt. Dismissing it does not stop Foxl reconnecting in the background.
- Tapping empty space under a message no longer regenerates the reply. The Copy/Edit/Regenerate row was invisible but still tappable on every phone, so a tap on what looked like blank transcript could silently throw away an answer and ask for it again. In both Foxl Agent and Foxl Code.
- Archive is reachable on a phone, and the timestamp is safe to tap. In Notifications the Archive button only appeared on hover, so on a touch screen the feature was invisible - while remaining live on top of the timestamp, so tapping the time archived the notification with nothing to explain it.
- A failed save now says so. Saving a workspace file, and saving provider settings, both ignored the server's answer: a failure looked exactly like success. Worse, the provider save wrote your choice locally anyway, so the app showed one model while the server used another.
- An outage no longer reads as an empty workspace. When the file list could not be loaded, the page stated there were no files - indistinguishable from having lost them. It reports the failure and offers a retry.
- A chat can no longer hang forever while reconnecting. The reconnect handshake had no timeout, so a desktop that vanished mid-reply could leave the composer stuck.
- On a phone, Foxl Code's message bar is back at the bottom of the screen and the greeting is the thing in the middle. Both had ended up centred together, so the bar floated in the vertical middle with an empty half-screen beneath it. The greeting now centres in the space above a bar docked at the bottom, and the bar clears the floating tab bar rather than sitting behind it - previously the model chip and the send button were partly covered by the glass capsule. The desktop layout is unchanged.
- Foxl Code's model picker has no shaded plate behind it. It had a resting fill that Foxl Agent's model picker does not have, so the same control looked different in the two products. The repository picker beside it keeps its own surface, which is what keeps the two reading as separate controls.
- The message bar is frosted glass again instead of a window onto the chat behind it. It was translucent enough that the transcript scrolling underneath stayed readable through it, so text you had already read sat mixed in with the box you were typing into. Measured on a full conversation, most of the bar's surface changed as messages moved past below it; it is now about an eighth of that, level with the mobile message bar. It still reads as a material - it picks up the tone of what is behind it and the blur is stronger than before - it just no longer transmits legible text. Same in light and dark mode, on desktop and on the phone.
- The Agent sidebar's file browser is called "Files". It was called "Workspace", which is also what a workspace is - the shared space with your members, files and channels in it - so one word named two different destinations in the same sidebar. Foxl Code has always called that screen Files. Settings' "Organization" section is now "Workspace" for the same reason; the old /settings/organization link still opens it.
- Channels now sits at the same distance from the window edge in Foxl Code as it does in Foxl Agent. It is one screen shared by both products, but only Agent gave it the standard page margin, so the channel list on Foxl Code sat 20px further left and pressed against the edge of the content panel.
- Right-click menus are back at their original text size. Menu rows had been shrunk in three steps and then partly raised again; they now read at the size they had through the whole v0.4 series. Rows did not change height and touch targets on a phone are untouched, so nothing moved under your cursor or your thumb. A few of the longest translated labels take an extra line at this size, which is deliberate: the menu cannot get wider without running off the edge of a phone screen, and a second line is easier to read than a row you cannot reach.
- Dark mode is no longer split down the middle. The sidebar and the page beside it were six lightness points apart, so the seam between them was the most prominent edge on the screen and the content area read as the darkest thing in the app. The page canvas now sits one step below the sidebar instead of six, the way every other surface in the set is spaced - so the window reads as one surface with depth rather than a light panel next to a black hole. Text contrast is unchanged and still measured: every secondary label clears WCAG AA on every surface it can land on.
- A two-hourly schedule now reads "Every 2 hours". It used to spell out all twelve times of day ("Daily at 12:00 AM, 2:00 AM, 4:00 AM, ...") - correct, but 128 characters of it, which wrapped a row onto three lines. Any evenly-spaced hourly schedule now states its interval. Schedules that run at specific, unevenly-spaced times still list them, because that is what they mean.
- A page listing paused schedules no longer says it has none. With everything paused, the header advised creating your first schedule directly beside its own "0 of 3 enabled" count.
- The Mac app no longer modifies itself on first launch, so its Apple code signature stays intact. Foxl used to create a link inside its own application bundle the first time the local server started, which broke the seal macOS checks:
codesign --verifyreported the app as altered, and Gatekeeper began refusing the installed copy. The files it needed are now placed correctly when the app is built, so nothing is written into the bundle at runtime. The terminal and image tools work exactly as before. - Tightened the Mac app's requested system permissions. Foxl asked macOS for six capabilities it never used, including a blanket read-write exception for your entire home folder. Those requests granted nothing in practice and are gone; microphone and system-audio recording for Foxl Notes are unaffected.
app.foxl.ainow serves its Apple app-association file correctly instead of answering with the web app's HTML, which is a prerequisite for openingfoxl.ailinks directly in the mobile app.- Removing someone from a workspace now ends their access to its channels. Their access to the app was already revoked, but chat membership was tracked separately and was never cleared, so new messages kept arriving as phone notifications - with a preview of the message text - and
@-mentions of them still returned the full message body. They could also still react to messages and appear as "typing". Eviction now clears channel membership, and every read re-checks the workspace, so this cannot come back through a path that forgets. Direct messages are unaffected. - View-only members can no longer delete files from a restricted folder. Uploading already required edit access; deleting did not check at all.
- Closed a GitHub "Connect" link-forwarding hole. The connect step accepted a session token from its own URL without verifying it, so a crafted invite link could have attached someone else's GitHub installation - and their private repositories - to the sender's Foxl account. The link is now rejected unless the session it carries belongs to the person who created it.
- The "New" line marking where you left off in a channel never appeared.
- A direct message printed the other person's name twice on the same row.
- Tap targets across the app now meet the 44px minimum: the Workspace file tree (12 rows), the product switcher, and the reaction buttons were all smaller.
- Between a phone and a tablet width, Channels showed two panes with nothing selected and no way to open anything.
- Agents, Schedules and For You opened with a large empty gap above the title on a phone - the space for the top bar was being reserved twice.
- Tapping a notification about a channel message did nothing when the app was not already running, and
foxl://links could not reach Workspace, Agents, Schedules or For You at all. - Taps along the top of every phone screen did nothing. The invisible top bar claimed that whole strip, so any button underneath it was unreachable - including the back button in a channel.
- Several screens could not be scrolled at all, so anything below the first screenful was unreachable: For You, Agents, Schedules, Tools, Skills, Logs and Tasks.
- The newest message in a channel, the last file in Workspace, and the bottom of every image, PDF and Office preview sat underneath the tab bar.
- Reacting to a message could leave the emoji picker stuck open on a phone.
- The sign-in screen now sits in the middle of the screen instead of up against the top edge.
- Tapping a tab while the side menu was open navigated away instead of closing the menu.
- An empty Notifications page no longer offers a "Configure Feed Generator" link. The page lists a dozen kinds of notification now, so a single link to one source's settings read as the explanation for the empty screen.
- A chat started on your phone now appears on your desktop right away, and its messages are saved to the phone as soon as the reply finishes. Previously an open desktop window did not learn about the new chat until something else made it reload, and the phone only downloaded the chat for offline reading on a timer that runs at startup - so a chat begun later in a session could sit marked as not downloaded, about messages that were already on the desktop. The desktop also picks up the chat's generated title now instead of leaving it as "New Chat".
Features
- Channels and direct messages: talk to your team inside Foxl. A shared workspace now has chat. Create channels, open a DM with anyone on the team, reply in threads, react, attach files, and search what was said. Messages arrive the moment they are sent - there is no refresh and no desktop app required, so the same conversation is live on your phone, in the browser, and on your Mac. A channel can be open to the whole workspace or private, and a private one is invisible to everyone who is not in it - including its name. Use "Add people" to invite anyone from the workspace. Per channel you can mute it, star it to keep it at the top, mark it read or unread, leave it, or archive it when the work is done
- and reopen it later if it turns out not to be. Files you attach live in the workspace's own Shared files, under a folder per channel, so a file shared in conversation is still findable a month later. Phone notifications for channel messages are on by default and have their own switch under Settings > Notifications, separate from your agent's replies; muting one channel silences that room without turning the category off. Chat needs a shared workspace - a personal one has nobody on the other end.
- Foxl Code keeps recurring work, learned context, and pull-request review in one operational workspace. Schedules can be created, edited, paused, run immediately, and reviewed as a list, calendar, or execution history. Knowledge makes repository memory, agent activity, and the exact context sent to a new task inspectable. When a task opens a pull request, its review rail shows checks, changed files, a line-level diff, and an explicit merge confirmation without leaving the task. The new views are responsive, keyboard-navigable, and preserve tabs and filters in the URL.
- Shared workspaces now look like a drive: one folder per team, and you can choose who sees each folder. Every workspace gets a folder named after the team, and files live inside a folder rather than loose at the top level - so what you are looking at is a place, not a pile. Any folder can be narrowed to specific people, with view or edit access, and a narrowed folder disappears entirely for everyone else - including its name. Anything inside a narrowed folder stays narrowed, so a sub-folder cannot quietly reopen it. Folders you have not restricted stay visible to the whole workspace, exactly as before. Two smaller consequences: a new workspace has to have a name no other workspace is using, because the name is now the folder you and your team will be looking at; and files that were sitting loose at the top level are still there and still work - you just cannot add more.
- Cmd-click a path to your own files and it opens in Finder. When Foxl talks you through your machine -
~/Documents/MyVault,~/Library/Application Support/obsidian/obsidian.json- holding Cmd now turns those into links, and clicking one reveals it in Finder (or your system file manager). Paths inside the Foxl workspace keep opening in the workspace viewer as before. A command that merely mentions a path, likecd ~/Documents/MyVault, stays plain text: it is an instruction, not a destination. Desktop only, since a browser cannot open your file manager. - Drag files straight into a shared workspace. The Shared files panel took uploads only through its Choose files button; now you can drop them anywhere on the panel, and it highlights while you drag. Any file type works - images, PDFs, archives, whatever - and dropping several at once uploads all of them. Dropping a folder is ignored rather than uploaded as an empty file.
- Links to other apps work now. An
obsidian://link to one of your vault notes, avscode://link to a file, atel:number - clicking any of them opens the app it belongs to. They used to render as links and do nothing at all when clicked: the markdown renderer quietly emptied every address that was not a web or email one, so the underline was there and the destination was not. Ordinary web and email links are unchanged, and links that could run code (javascript:,data:,file:) are still refused - that is not something the new setting can turn on. If you would rather Foxl never hand an address to another application, Settings > General > "Open links in other apps" turns it off. - Hold Cmd and the file paths in a reply become links. When Foxl says the bug is in
src/notes.ts:12, holding Cmd (Ctrl on Windows and Linux) underlines that path and Cmd-clicking it opens the file in the workspace viewer - at line 12. Let the key go and the reply is plain prose again, because a paragraph where every path is underlined is a paragraph you stop reading. Only paths written inbackticksare considered, and only ones that really exist in your workspace:useEffectandexit 1are words in a sentence, and a path from some other machine has nothing here to open, so none of them light up. Line and column suffixes are understood (file.ts:42,file.ts:42:7, and a range likefile.py:290-308takes you to its start). A URL in backticks is clickable the same way and opens in your browser. - The Workspace behaves like a file manager now: drag, drop, copy, paste, rename, delete. Drag a file onto a folder to move it, hold Option while you drop to copy instead, and drop into the empty space below the tree to move something back out to the top level. Cmd+C / Cmd+X / Cmd+V work on the selected row, Enter renames it in place, and Cmd+Delete asks before it deletes. Right-click any row for the same actions plus New folder. Files go both ways across the app's edge. Drop files in from Finder to add them, and drag a file out of the tree onto your desktop or into another app to copy it there (desktop build). Anything that would overwrite an existing file asks first, and pasting into the folder something was copied from produces "name copy" rather than a refusal.
- Files and documents can be dragged straight into Shared. Moving something into
Sharedpublishes it to your workspace; dragging it back out makes it local again. A move keeps the document's identity, so its history, its search entry and everyone's access follow it rather than a new copy appearing. - Word, Excel and PowerPoint files are now read and rendered with
officecli, so the agent can actually SEE the document it is working on. The docx / xlsx / pptx skills used to reach for LibreOffice for everything a renderer should do - convert to PDF and rasterize just to look at a page, run a macro to accept tracked changes, run another one to recalculate formulas. LibreOffice is not installed on most machines, so those steps simply failed.officecliis a single self-contained binary that renders the real layout to PNG / HTML / SVG and evaluates Excel formulas itself, which closes the render -> look -> fix loop. Spreadsheet formulas now carry their computed values without any recalculation pass, tracked changes are accepted or rejected directly, and slide decks render per-slide or as a whole-deck contact sheet. Legacy.doc/.xls/.pptand real PDF export are documented as what they are - not supported by the renderer - instead of pointing at a tool that is not there. - Syncing skills now shows you a diff and asks before overwriting anything, and the update can be undone. Pressing Sync on the Skills page previews the change set - every file, with a line-level diff - and writes nothing until you confirm. Applying snapshots the affected skills first, so an Undo button restores exactly what was there before.
AGENTS.mdis now where other agent tools look for it:~/.foxl/AGENTS.md. That path and~/.foxl/workspace/AGENTS.mdare the same file, so a tool that only knows the common convention reads the instructions you already wrote, and there is no second copy to keep in step. Foxl sets this up the first time it starts and re-checks it on every launch, on macOS, Linux, and Windows. If you had already written your own~/.foxl/AGENTS.md, Foxl keeps it - your text moves into the workspace and the two become one file. Only when both files hold real and different content does Foxl change neither and say so, rather than picking a winner. On Windows a symlink needs permission (Developer Mode, or running elevated). Without it Foxl uses a hard link, which most editors separate when they save, so the workspace copy is the one to edit there. If the two do come apart, the next launch puts them back together in the case that actually happens: your writing is in the workspace copy and the home file is still the starter text Foxl wrote, so it re-links onto your writing. It also re-links when the two still match, and steps back only when both sides hold writing of their own. On a filesystem that supports neither kind of link - a FAT32 or exFAT drive, or a home directory redirected to a network share - no link is created and Foxl says why in its log.
Changes
- Deleting a workspace now says plainly that it is permanent, and names the date. The confirmation used to say only that members lose access and that it could be restored for 30 days, which reads more like archiving than deleting. It now states that after the window the files are permanently deleted and cannot be recovered, and it shows the exact date that happens rather than a number of days to count. After you confirm, that date is repeated once more - taken from the server, not from the dialog's estimate. The restore window is 7 days instead of 30. A workspace deleted before this change keeps the 30 days it was promised.
- Right-click menus read at a comfortable size again. They had been taken down to 11px, which is the smallest size anything in Foxl is allowed to be - a floor, not a size to sit on. Menu rows are 13px now. Group headings stay at 11px, so a heading is quieter than the rows under it rather than the same size as them. Row height did not change: menus are still 44px per row on touch and unchanged on a mouse, so nothing moved under your finger. Three menus are wider to match, since a bigger label needs more room before it wraps - the repository menu, the workspace tree's shared-folder menu and the Notes recording menu. In German, Spanish, Portuguese, Russian and French a few of the longest menu labels now take two lines rather than one; that is deliberate, because the width that would keep them on one line runs the menu off the side of a phone.
- "Shared" is now one shelf, and the workspace dropdown is gone. The Workspace page and the Shared skills tab each carried a picker whose first entry was "Personal". Both are removed: everything shared with you - across every workspace you are in - is listed together, and each shared skill names the workspace it belongs to on its own row. The picker looked like it filtered what you were seeing, and did not; what it actually changed was where the next thing you created would land.
- Shared always means shared with people. Creating a shared document, uploading a shared file or adding a shared skill now goes to a real workspace; if you are in none, Foxl offers to create one instead of quietly making something only you can see. Everything already stored under your personal scope stays exactly where it is, still listed and still editable.
Fixes
- A pasted-text highlight stays inside the message bar when you scroll a long draft. Paste something long, type enough after it that the box starts scrolling, and the grey capsule marking the paste slid out of the message bar entirely - floating in the conversation above it, or over the model picker and the send button below. Only the highlight escaped, so it read as an empty grey pill sitting in the middle of nothing. It now stops at the edges of the box, in both Foxl chat and Foxl Code.
- Adding a folder or a file to Shared now takes you to where it went. Typing a name and pressing Add folder appeared to do nothing, and dropping a file on the top level of Shared left "No files here yet" on screen. Both had actually worked: the top level of Shared lists folders, files live inside one, and a create or an upload from there lands in your team's folder one level down - so the result was real but off screen. Shared now opens the folder it put your thing in.
- A file you add to Shared shows up straight away, and deleting one works. Uploading a file to the Shared folder reported success and then the file was nowhere - not in the tree, not after a refresh - and trying to delete one said it no longer existed, about a row that was on screen. The Shared folder in the workspace tree was only ever listing shared DOCUMENTS. Files, which live in different storage, were never in it at all, so no amount of refreshing could show them. The tree now lists both, and delete looks in both places.
- Dragging in the workspace highlights only the row under the pointer. Every file in the folder lit up at once, because the highlight keyed on the destination folder rather than the row - and a file's destination is its parent, which it shares with all its siblings.
- Foxl Notes looks right again: the sidebar rows show their date and duration, and the floating panel has its frosted-glass look back. Each note in the list was cut off just under its title, so the
3h ago - 57:44line under it was sliced in half, and the small always-on-top Notes window had lost its translucency. One line caused both. A housekeeping change added a rule that was meant to ignore the old standalone Notes app, but the pattern also matched the live Notes source folder inside the app - and the styling tool skips ignored folders when it collects the styles a screen uses. So 126 styles used only by Notes were left out of the stylesheet: the ones that let a row grow tall enough for two lines, and the ones that make the panel glass. Nothing failed while this was true, which is why it shipped. - The Cmd+Shift+F hint in the search bar no longer draws its Shift symbol smaller than the others. In the shortcut badge at the right of the titlebar search field, the Shift arrow rendered at about two thirds the width of the Command symbol beside it and sat a pixel low, so the three characters read as mismatched sizes rather than one label. The badge asked for a monospaced font, and the mono webfont ships without the Command and Shift symbols - the browser quietly substituted a different face for those two characters, whose Shift is simply drawn small. The hint now uses the interface font, which designs those keyboard symbols as a matched set.
- "Connect GitHub" in Foxl Code now actually installs the GitHub App. Pressing it moved the browser to code.foxl.ai and stopped there. Two separate causes, both fixed: The connect callback decided which Foxl account should receive a repo grant by looking for an existing GitHub identity on the account - and an account only got one by signing up with GitHub in the first place. Every account created with Google, Apple or a magic link therefore failed the check, which was all of them. The account is now identified by the signed-in session that started the connect, and your GitHub identity is recorded as a RESULT of connecting instead of being required beforehand. This is the flow GitHub documents, and it is no less strict: a connect still has to authorize on github.com, and Foxl still only grants access to installations that authorization actually proves you can see. Separately, the flow always returned you to code.foxl.ai even when you had started it inside app.foxl.ai or the desktop app. Since your sign-in is per-site, that meant landing on a login screen - including when the install had succeeded. You now come back to the app you started from, on the Repos page, with the outcome shown.
- Foxl Code tells you what went wrong when a connect fails. Every failure now has a plain-language explanation and, where there is something to do about it, a button that does it - and the button matches the problem, so a connect that needs a retry offers one while an install that already landed offers Sync instead. Two cases previously showed a raw internal code, and "Link GitHub" could finish successfully and drop you on the chat screen with no confirmation; that now returns to Repos and says it worked.
- Two GitHub responses are no longer reported as the wrong thing. An organization owner still having to approve the install was reported as a malformed redirect, and an install that GitHub could not hand back a correlation token for was reported the same way - both now say what actually happened, and the second one points at Sync, which fixes it in one click. Separately, a GitHub outage while Foxl was asking which installations you belong to used to look identical to "you have none", which sent people to re-install an app they already had.
- iPhone: notifications you got while the app was closed now appear in the Notification Center. The banner arrived, but opening Foxl from the home screen or from the banner itself showed an empty inbox behind the sidebar bell - so a notification you saw on a locked screen and wanted to come back to was simply gone. Foxl reads the iOS notification centre on launch to file those rows, and that read is rejected by iOS until push registration finishes - which on a fresh launch happens after the app's UI is already up. Foxl gave up after the first rejection and waited for either a re-registration or an app resume to try again; neither happens on a cold start (iOS hands over the push token once per install, and a launch is not a resume), so nothing ever swept the stack. It now waits for registration instead of giving up. Tapping a banner also files that notification, marked read, since iOS removes it from the notification centre as you tap - previously the one notification you cared about enough to open was the one guaranteed to be missing from the list.
- The chat list no longer marks a chat that is fully downloaded. On iPhone every row picked up a cloud icon once its messages had synced, which is the state nearly every row ends up in - so the marker said the same thing about everything and meant nothing, in the same spot as the unread dot, which does mean something. Now only the chats you cannot read offline carry an icon: a crossed-out cloud for one that has not downloaded yet, and a filled cloud for one whose copy is behind your desktop. A chat that is fully here shows nothing at all - no icon, no tooltip, and nothing read out by VoiceOver. Its long-press menu still says "Saved on this device" when you ask.
- Skill updates now actually reach an existing install. Sync compared each local file against a repo snapshot it never took, so every difference was read as "you edited this" and preserved - and because every install differs from the repo by one legacy
enabled: trueline, that meant SKILL.md updates could never land. Files under a skill'sscripts/directory were invisible to sync entirely (the scan did not recurse), and a file deleted upstream was never removed locally. All three are fixed, behind the confirmation prompt above.
Features
- Work from Slack: mention @Foxl in a channel and the work happens on your desktop. A session opens on this machine, runs with your real local tools, and the answer comes back as a reply in the same Slack thread. Two top-level mentions in one channel are two separate conversations, and a follow-up inside a thread continues that thread's conversation with its history intact - so "and now do the same for staging" means what it should.
It connects over Slack's Socket Mode, so there is no public URL, no webhook and no inbound port: Foxl dials out to Slack. Configure it under Integrations -> Channels -> Slack with a bot token (
xoxb-) and an app-level token (xapp-, which needs theconnections:writescope). Foxl reacts witheyeswhen it picks the mention up and swaps that for a check mark or a cross when it finishes, so a long job never looks like an ignored one. Allowed Channels is required, and an empty list ignores every mention. Work arriving from Slack runs under this desktop's own tool permissions, which ship permissive by default - so the channel list is the gate, and it defaults to allowing nobody rather than everybody. Mentions that arrive while Foxl is asleep are not delivered; Socket Mode has no queue to hold them.
Changes
- Billing is harder to get wrong under load. Credit debits, request admission, Forge task budgets, storage charges, transcription reports and compute finalization are now atomic and retry-safe, so a dropped response or two simultaneous turns should no longer charge twice or charge nothing. Checkouts are bound to the signed-in account, duplicate payment webhooks are ignored, subscription changes apply in the order they really happened, and a paid upgrade waits for the invoice to succeed rather than granting access up front. Refunds and top-ups are matched to the exact order they came from.
Fixes
- Credits you have are credits you can spend. Every request briefly holds credits aside so two turns at once cannot spend the same balance, and that hold was calculated from the largest reply the model could theoretically produce - around 90x a real answer. On the free plan three of the four available models refused the very first message; on Pro the last third of the monthly allowance could not be spent on the most expensive model while the Account page still showed it. The hold is now sized for a realistic reply, and the actual charge was never affected.
- CI is three times faster, which shows up as PRs that stop waiting. Every automated check except desktop code signing and the iOS build moved off a single developer laptop onto a dedicated Linux machine running six checkers at once. The validation gate went from 16.7 minutes to 5.6 - which is now exactly as long as its slowest single check, meaning nothing queues behind anything else.
- The recording pill can be moved out of the way. The floating Recording / Back to Notes button can be dragged with a mouse or a finger and stays where you put it, while a short press still just takes you back to the note. A saved position that no longer fits the window is pulled back on screen instead of being lost off-edge.
- foxl.ai's homepage lines up at every width. The navbar and every section now share one content grid, the local-first security section was rebuilt with a calmer glass treatment, and the phone-to-desktop demo recomposes properly on small screens with reduced-motion respected.
- A schedule runs once, even if two things ask it to. A timer firing at the same moment as Run Now (or a retried webhook) could run one schedule twice and do its work twice. Each schedule now runs one at a time, and a schedule missed while the laptop was asleep is re-armed correctly instead of firing repeatedly or not at all.
- Cron expressions mean what they say, including timezones and daylight-saving changes - the previous implementation only handled part of the syntax.
- Two messages from the same chat cannot trip over each other, while different chats still run in parallel; and Signal's message polling no longer leaves a second reader behind after a reconnect.
- Two things happening at once no longer corrupt each other. Three cases, all reachable in ordinary use: a scheduled agent whose run overran its limit could be started a second time while the first was still going; two uploads replacing the same shared file could publish one file's bytes with the other's size and checksum; and accepting a team invite could consume the invite without actually adding you to the team, leaving nothing to retry. Each is now a single all-or-nothing operation.
- Notes autosave cannot overwrite itself. Two saves landing together could each write from a stale copy of the note, so one lost the other's edit. Saves and deletes are now serialised, a failed save says so instead of failing silently, and a note leaves the list only once its deletion actually succeeded.
- A fast click or a fast retype shows the right answer. Switching agents or changing a Workspace search before the previous request came back could paint the older result over the newer one. Stale responses are now discarded.
- The Code terminal is legible in light mode, using the published Snazzy Light palette instead of plain white, and the mobile Conversation/Terminal switch is back to its compact size while keeping full-size touch targets.
- A failed task reports itself once. There were two banners for one failure, and the embedded Code view added a second scrollbar inside the page.
- foxl.ai leads with the real app. The landing page's synthetic 3D device demo is replaced by a recording of the shipped app doing actual work - turning a CSV into a three-slide deck and opening it in the Workspace rail - with the download buttons, platform links and reduced-motion handling unchanged.
- Renaming a channel no longer wipes its saved tokens. Stored secrets came back from the server masked as
****, the edit dialog put that mask in its inputs, and saving wrote it back over the real credential - so editing a channel's name broke its connection. Secret fields now show as stored and blank means "keep it". - A pasted-text block has its outline back inside your own message. The border and fill were being drawn in the ink colour of the near-black bubble the chat used to have, so on today's light bubble the box was painted the same colour as what it sat on - the title and line count stayed perfectly readable while the box around them was gone.
- The pasted-text highlight reads clearly without adding a colour. Both the capsule in the composer and the block in the sent message are a plain grey wash now, a little stronger than before so the reference still reads as one object. A long paste is something you have already written; it should be easy to see and it should not compete with the text you are still typing.
- A long message can be scrolled again, which on a phone means at all. Paste something big into the message box and everything past the first few lines was unreachable: the box stops growing at a fixed height and the rest was being clipped rather than made scrollable. On a desktop the arrow keys hid it, because a text box follows the caret; on a phone, where dragging is the only way to scroll, the draft simply looked cut off. It scrolls now, the highlight behind a pasted reference follows the text properly, and dragging past either end no longer scrolls the conversation behind it.
- An opened paste is wide enough to read. Expanding or editing a pasted block left it at the width of the small chip, so a long paste was read through a 40-character window where nearly every line wrapped. Opening one now widens it to about 80 characters, and reading it and editing it are the same size instead of two different ones.
- Several pastes open and close together. With two attachments, opening one left a tall card beside a small chip and the row read as broken. They now open as a set, and only the one you clicked to edit gets a cursor.
- "Show in menu bar" works in the installed app. It worked while developing and did nothing in a release: the installed app never read the setting, so the menu-bar icon could not be turned off. It applies immediately now, and a check at build time refuses to ship a settings switch the installed app does not implement.
- Starting a channel that has no adapter now says so. Any unimplemented channel type reported success and wrote "connected" to its record, while the channels list recomputes status from what is actually running and kept showing it as disconnected - two disagreeing answers and no way to act on either.
- Channel errors no longer publish internals to the channel. A failed run replied with the raw error text - provider messages, model ids, file paths - at channel top level where everyone reads it. It now posts a short notice in the request's own thread and keeps the detail in the desktop log.
- Messages from a channel remember the conversation. Every inbound message ran as a cold single turn with no history, so a follow-up answered as though the previous exchange never happened, and a restart silently started a second conversation for the same chat while the first still sat in the sidebar.
Fixes
- The pasted-text chip works in Foxl Agent again. v0.5.12's release notes described a long paste as a tinted chip you could delete with one Backspace, and in Foxl Code that is what shipped - but in the Agent's chat the same paste came out as literal
[#1 ...]bracket text that Backspace chewed one character at a time. The chat page had stopped handing the composer the four things that draw the chip and make it behave as one object. Both chat surfaces now do, and a check that takes 90 milliseconds refuses to let either one drift again. - Linux has a real download link. foxl.ai offered Linux visitors the macOS DMG under the label "Linux build coming soon", even after the AppImage started shipping in v0.5.12. Linux now gets the AppImage, from a fixed URL that does not need editing at each release.
- "Show in menu bar" says what it does, and only does that. It described itself as changing what closing the window does, and it did - closing quit the app with the setting off. That was wrong on both counts: the dock icon reopens a hidden window either way, so the setting is now purely whether the menu-bar icon exists.
Features
- Foxl can be kept out of the menu bar. Settings > General > Show in menu bar turns the menu-bar icon off, and it takes effect at once rather than on next launch. Turning it off also makes the close button quit Foxl: closing the window normally hides it and leaves Foxl running in the menu bar, so with no icon there would be no way back to it.
- Appearance is its own Settings pane, and it does more than pick a theme. Under General you now get theme, UI text size, reduce motion, and an option for hand cursors over buttons. Text size scales the whole interface rather than only the words, so nothing overflows the box it sits in. Reduce motion is in addition to your system setting, never instead of it.
- Language has an Auto detect option. It follows your system language and KEEPS following it - picking the language you happen to be using today is a different choice, and it pins that language for good. A fresh install already behaved this way; now it is visible and reversible.
- GPT-5.6 Sol, Terra and Luna now hold a million tokens. AWS raised the context window for the three GPT-5.6 models on Amazon Bedrock from 272K to the full 1M, so a whole repository, a long contract, or an entire multi-step agent history fits in one request instead of being chunked. Prompt caching still applies at that length, which keeps repeated context cheap. The context meter and the compaction point move with it automatically. GPT-5.5 and GPT-5.4 are unchanged at 272K on Bedrock - AWS's announcement covers the 5.6 generation only - and a GPT model reached over a ChatGPT subscription still serves 272K, because that is OpenAI's own endpoint rather than Bedrock.
- Creating a shared workspace now visibly changes something. v0.5.11 moved shared documents into the Workspace tree and shipped only the server half, so making a team changed nothing anywhere in the app:
Sharednever appeared, nothing could create a shared document, and shared documents were findable by no search. All three now exist. The Workspace tree carries aSharedfolder with a "New shared file" action, the search box searches your team's documents alongside the local ones, and the folder itself opens the workspace's uploaded files. - A scope switcher on Workspace. Personal plus every workspace you belong to, in the sidebar header, deciding which one a new shared file is created in and whose uploaded files the panel shows. It appears once you are in at least one workspace - a dropdown with only "Personal" in it answers a question nobody asked. It does NOT filter the tree: the tree merges every workspace you can see, so a path there always means the same document regardless of this control.
- Upload, download and delete for shared files are back. The panel that does this was complete and was deleted in v0.5.11 only because the page hosting it was, which took the whole feature out of the product. It now lives inside Workspace, on the
Sharedfolder, still leading with what the storage costs and still distinguishing the three billing refusals ("upgrade", "pay the bill", "free some space") rather than reporting one generic failure. - Foxl Code shows your team's shared content too. code.foxl.ai's Files page had none of the above: it read only the orchestrator's private file mount, so a workspace you belonged to was invisible there even after the Agent side worked. It now carries the same scope switcher, the same
Sharedshelf with its documents and uploaded files, and the same New-shared-file action - reading the SAME active scope as the Agent side, so switching workspace on one is the switch the other sees. Shared documents open in place. - Foxl on Android, as a direct download. foxl.ai now offers Android visitors a real app instead of sending them to the browser: the release pipeline publishes a signed APK alongside the macOS and Windows builds, at a fixed URL that keeps working across releases. This is a sideload while the Play Store listing is in review, so the page says as much and tells you Android will ask for permission to install it - and the web app stays one tap away for anyone who would rather not. iOS still points at the browser, which is not an oversight: there is no way to install an iOS app from a link.
Changes
- Settings subheadings have room to breathe. A section title now sits clearly below the panel above it instead of looking like that panel's caption - the same spacing on every Settings pane in all three products.
- Settings > Trash is now Settings > Archived chats. "Trash" described the mechanism; the pane is where a deleted conversation waits for seven days and can be brought back, which is an archive. The notice inside a deleted chat, the link it offers, and the empty state all say the same thing now - they used to point at a name the nav no longer used. Searching Settings for "trash", "deleted" or "bin" still finds it.
- Right-click menus are one size and one system across all three products, and they exist in the places that were missing them. The menu type dropped to 11px with the icon size now owned by the shared component rather than by each call site, which is what had let four different icon sizes coexist inside menus whose text was already uniform. Widths were ad hoc (four values, plus six Workspace menus that passed none at all and rendered at the 128px floor); they are now one value, with one measured exception noted below.
- Foxl Code's task rows can be right-clicked. The seven task actions (open, open on GitHub, copy task id, copy branch, resume, cancel, delete) existed behind a right-click on exactly one surface, the shell sidebar, even though the shared menu component was written to be used by several. Work rows and Inbox notification rows now carry the same menu. The decision queue deliberately does NOT: its two row types are backed by a plan document and a PR notification, and neither carries a task id, so the menu would have aimed Delete at the wrong thing.
- The in-chat Workspace file tree has a right-click menu. Copy path and download were previously reachable only after opening a file into a tab.
- Right-clicking inside a note works. In the standalone Notes app it did nothing at all - not even Copy or Paste - because that Electron host registers no context-menu handler and Electron provides no default one for web content. Both Notes editors now offer undo, redo, cut, copy, paste and select all, each disabled when it cannot act rather than silently inert.
- Repo search on iOS is no longer hidden behind the keyboard. The picker sheet was capped in
dvh, a layout unit that does not shrink when the iOS keyboard opens, so typing a filter pushed the entire result list off screen. - Right-click no longer silently toggles a model favourite. That gesture opens a menu everywhere else in the product, and the only hint it did something different here was a tooltip that never appears on touch. In Foxl Code the star button it replaced was also dead on Pro-locked rows, which is why the hijack had been necessary.
- The animated "..." while waiting for a reply is gone. It was a second indicator for a state the app already showed three other ways, and on a thinking turn it ran at the same time as the "Thinking…" shimmer a few pixels away - two things moving to say one thing, which is what made it read as fidgety rather than as progress. What still tells you a reply is coming is unchanged and, unlike the dots, present in every phase of every turn: the composer's send button becomes a Stop button for as long as the stream is open, a thinking turn shimmers "Thinking…" on its own row, a tool turn shows the running tool with its spinner, and text streams in visibly once it starts.
The empty chat bubble the dots used to sit in is gone with them - it only ever existed to hold them, so leaving it would have traded an animation for a blank grey slab. Screen readers keep the announcement they had (the waiting state is still
role="status", just with nothing drawn), because the Stop button and the streaming text are the two signals assistive tech does not get for free. Applies to Foxl Agent chat, Foxl Code chat, and the agent detail view. - The notification bell moved into the sidebar footer on iOS and the web, carrying the unread count exactly as the desktop titlebar's bell does. Getting to notifications used to mean opening the account menu and picking a row - two taps behind a menu about your account, for the one thing there that is time-sensitive - with a red badge on your avatar as the only hint the surface existed. On a phone the bell takes the "new chat/task/note" +'s slot, which is the control that has alternatives (tapping the Chat row already starts a fresh chat; Notes and Code each have their own New button in the header). On wider screens both fit and both stay.
- A recent search can be removed. Hovering a row in the search field's "Recent" list now shows an X on its right that drops just that entry. A recent is a suggestion, and a suggestion you cannot dismiss is an obligation: one conversation opened by mistake used to sit in the empty state for six more picks before it aged out. Removal touches the LIST ONLY - the conversation itself is untouched, and it is still reachable by searching for it.
Fixes
- A reply that follows a tool run no longer starts with a stray indent. The earlier fix in this release removed the 36px inset from a turn whose only other row was a thinking line, but a turn that actually RAN something still indented every one of its paragraphs - the closing answer included, which is not between anything. So the same assistant began its sentences at two different left edges depending on whether it happened to use a tool. Prose still lines up with the tool rows it sits between; the conclusion sits on the margin every other reply uses.
- Pasting a long block into the composer works, and reads as one object. The paste is a tinted capsule in Foxl's blue - like a link chip - rather than bracketed prose, and the reference number that used to sit inside it is gone from view. Three things that were broken with it: sending did not clear the composer, so after one paste every later message sent the placeholder text again no matter what you typed; the preview could be opened but never closed; and the chevron beside the pencil looked like the expand control while doing nothing at all. A paste at the end of the draft now leaves a space after it, so the next word does not run into the chip.
- The Workspace opens immediately again, and
Sharedshows up for everyone who is signed in. Two separate problems with one visible symptom. Opening Workspace waited for a network round trip to fetch team documents before it would draw the local file list, and that request had no time limit - so a slow connection held back files that were already on disk. The local tree is now served at once and the shared shelf arrives on its own. Separately, the desktop only learned who was signed in as a side effect of choosing Foxl as the model provider, so anyone using AWS Bedrock, a Claude subscription or their own API key had aSharedfolder that could never appear no matter how they signed in. - A reply that did not stop to think is no longer invisible. An assistant turn whose answer arrived as plain text - no thinking step, no tool calls - rendered as nothing at all: the message was saved, the model had answered, and the screen showed an empty gap where the reply should be. It looked exactly like a message that had never been sent, which is why it read as the streaming bug fixed separately in this release. Because Opus 5 thinks by default, the turns that skipped thinking were the minority, so this surfaced as an intermittent "sometimes there is no answer" rather than as a consistent failure. Fixed on the Agent and on Foxl Code together, since both draw chat from the same shared components.
- Cursor's agent mark in Foxl Code is Cursor's actual logo now. What shipped was a hand-drawn stand-in - a grey-to-navy gradient hexagon with three hairlines - that resembled the real cube only in outline. Replaced with the 2.5D cube from Cursor's published brand kit, paths unmodified.
- The context menu now stacks above full-screen covers like the Settings sheet. Its three sibling overlays were raised for this in an earlier release and this one was missed, so any menu opened inside such a sheet would have been unreachable.
- Two menus are wider than the standard on purpose: their labels wrap to two lines in German, Spanish, French, Portuguese and Russian at the standard width. English fits, so this was invisible without switching locale.
- Removed a committed scratch directory whose files contained the Tailwind v3 spelling of a raw CSS variable, which this repo's own notes forbid keeping anywhere the class scanner can reach.
- The app icon goes back to the artwork it had before v0.5.11. That release grew the fox inside the icon's rounded-rect tile from 69% to 82% of it, to sit level with what Apple ships (Maps 84.5%, Notes 84.3%, Safari 80.9%) and with the apps Foxl appears next to in a list. The measurements behind that were right, and the fuller icon is still not the one we want, so the original is restored: the Dock icon is now pixel-for-pixel what it was in v0.5.10 and before. The tile was never the thing that changed - it has been the standard macOS size throughout, so nothing about the icon's footprint moves either way.
- A reply that only thought first no longer starts with a stray indent. When the turn's only other row was a collapsed "Thought for 2 seconds" line, the answer under it began 36px right of the edge every other paragraph starts on. On Korean text there is no capital letter to absorb that, so it reads as a space sitting in front of the first word - which is how it was reported (a Korean reply with a gap in front of it). The indent itself is deliberate and stays: prose drawn BETWEEN TOOL ROWS is padded to those rows' content column (24px icon + 12px gap) so a batch of commands and the text explaining it read as one thread. The defect was that the padding was unconditional, so a thinking line - a one-line disclosure, not a thread - earned it too. It is now applied only when the turn actually has tool rows. This is also why the gap seemed to come and go: a turn with no thinking and no tools renders through the message-bubble path at zero inset, so the same assistant in one conversation started sentences at two different left edges. Opus 5 thinks by default, which made the indented case the common one. Guarded from both sides, because a one-sided test would have accepted deleting the indent outright: one case measures a thinking-only turn against the bubble path (measured on the old code: 36.0px vs 0.0px, and an absolute-pixel assertion would have accepted 36 as a plausible edge), and a second case measures that prose between tool batches still lines up with the tool rows' content column. Fixed in Foxl Agent and Foxl Code together, since both render from the same shared timeline.
- Your own message now carries the quiet grey the assistant's bubble used to have, instead of a near-black slab. When the assistant reply lost its bubble, the tone that marked "this is chat, not page copy" went with it, and the only tinted object left in a transcript was the user's own high-contrast capsule - so the loudest thing on screen was the message you already knew, while the reply you were actually reading sat untinted. The bubble is now the same
mutedsurface the assistant's was, with normal body ink, which keeps a transcript to one surface colour. - Everything nested inside that bubble was re-toned to match. The pasted-text block, inline code and fenced code were all tinted for the old near-black ground, and two of them became invisible on grey rather than merely wrong: the paste block's fill and border used a near-white token, and code/fences use the same
mutedvalue the bubble now has - measured at exactly 1.000:1 against it, i.e. painted the same colour as what they sit on. Text contrast never showed this (the ink was 18:1 throughout); what had vanished was the surface saying "this is code". All of them are keyed off the ink colour of their own surface now, so they hold in light and dark. - A long paste now reads as an attachment in the message box, not as bracket text. Pasting a log or a config still drops a reference where your cursor is, so the paste keeps its place in the sentence - but that reference is now drawn as a tinted, rounded chip, the way a file attachment looks in a chat app, instead of as 22 characters of literal
[#1 ...]. It also behaves like one object: a single Backspace removes the whole thing, and the arrow keys step over it rather than parking the cursor inside it. - Deleting the reference now deletes the attachment, in both directions. Removing the card above the message box already stripped its reference from the draft; the reverse did not hold. Deleting the reference left the card sitting there relabelled "not placed", and the paste was still sent - ahead of your own words - so a paste you had removed a reference to was still attached, with a two-word label as the only evidence. The two are one object now, and either end removes both.
- A reference whose closing bracket got deleted could swallow the next one. Chewing the end off a reference (which used to be possible one character at a time) made it run on to the FOLLOWING reference's bracket and parse as a single one. The second attachment then vanished from the draft's point of view - its card disappeared while its text stayed - and on send the first paste expanded over the whole run, deleting the words you had typed between the two. Both causes are fixed: a reference can no longer be partially deleted, and a broken one now ends at itself.
- Removing an attachment no longer reformats the rest of your draft. The cleanup after removing a reference ran over the entire message, so it collapsed a deliberate double space, flattened an indented snippet, and trimmed the blank lines off a multi-paragraph draft - anywhere in the text, not just where the attachment had been. Only the spot the reference occupied changes now.
- A duplicated reference is removed everywhere. Copying the reference text left two pointers at one paste, and removing the card took only the first - so the same content was attached to the message twice.
- Pasted text can no longer break out of its own attachment. A paste that happened to contain the marker Foxl wraps attachments in ended the attachment early - which you could hit with no ill intent at all, by copying a Foxl message that already had one and pasting it back. Everything about it was silent: the attachment was truncated at that line so the model never saw the rest of what you pasted, and the remainder left the attachment to be read as your own words, meaning text you pasted as DATA arrived as INSTRUCTIONS. The same hole could manufacture a second attachment that no card in the message box corresponded to. Attachment content and titles are now neutralised on the way out, so one card always means exactly one attachment.
- A shared skill can be edited and removed, not just created. The relay has always supported both -
POST /shared/skillsswitches to update-in-place when given askillId, and archiving isPATCH status: archived- but no UI reached either, so a skill was write-once. Each row now has an actions menu with Edit and Remove. Two things this had to get right. The edit dialog fetches the body: the list endpoint blanks it on every row (otherwise a list would ship every skill's full markdown), so a dialog that trusted the row would open empty and saving would wipe the text. And editing something already published re-sendspublish, because the server recomputes status on that path - an update that omitted it would silently unpublish the skill for the whole workspace with no error. That button says "Save and keep published" for exactly that reason; unpublishing stays on the row where you expect it. Removal asks for confirmation and names the blast radius, since in a workspace it removes the skill for every member including people who already added it. - Settings > Organization is on the design system now. It had the same two defects the Shared tab did. The role pickers were raw
<select>elements (28-36px against the 44px minimum, no focus ring, OS menu) and are the standard Select; the three policy checkboxes were ~13px - under even the 24px WCAG floor, three in a row where a fingertip could hit two - and are Switches with a 44px hit area. The confirmations were nativeconfirm()andprompt(), which cannot be translated or styled and read as the browser asking rather than the app. Both are in-app dialogs. Deleting a workspace still requires typing its name, but the button is now disabled until the name matches instead of accepting anything and reporting a mismatch afterwards. - Settings > Organization is translated. It was ~30 hardcoded English strings including every error, both confirmations and the accessibility labels, and it printed raw wire values (
owner/admin/member, andfailedfor a bounced invite) straight to the screen. All ten locales now carry it. - Shared skills are their own Integrations tab, and can finally be added. v0.5.11 moved them from a sidebar page to a section at the bottom of the Skills tab, which traded one problem for a worse one: the section rendered below seven local skill shelves, returned nothing at all when you were not yet in a workspace, and unmounted the moment you typed in the search box above it. It is now a peer tab - Integrations / Skills / Shared / Channels - with its own
/sharedURL. The part that was actually broken: its empty state read "Publish a skill here and everyone in it can add it" while no publish affordance existed anywhere in the app. The relay has acceptedPOST /shared/skillsall along and the client wrapper was written, but nothing in the UI ever called it, so the copy was instructions for a button nobody had built. There is now an Add button (and one in the empty state), with a compose dialog that takes a name and a SKILL.md body. In a workspace it saves as a draft unless you publish, matching what the server does rather than hiding one of its two outcomes. - The tab's dropdowns are the app's own control again. The workspace picker and the "Share with..." picker were raw browser
<select>elements: 28px tall against the 44px minimum in DESIGN-PRINCIPLES, no focus ring, wrong radius, and the OS menu instead of ours. The "Share..." one also used an option as a fake placeholder, so the browser re-selected it after every choice and the control silently snapped back - it read as an action that had failed. Both are the standard Select now. - Shared skills work with no desktop connected. They live in relay, not on your machine, but the tab was showing the "connect your desktop" preview grid because it sits under the Integrations nav. It now renders for real on the web and on a phone.
- The tab is translated. The whole surface was hardcoded English - 19 strings including both empty states, every error, and the accessibility labels - and it showed raw server values (
draft,archived) as its status badge. All ten locales now carry it. - A member of an open-contribution workspace can share a skill into it. The picker filtered targets to workspaces where you are an owner or admin, but the server only requires that when the workspace turns on "only admins can publish shared skills", so the UI was hiding a workspace that would have accepted the skill.
- The adopt/remove control is a real button. It was a
div, so it could not be reached by keyboard or focused, and it stayed clickable while its own request was in flight. - "From this chat" listed other chats' files. It now knows who wrote what, because the server records it instead of guessing. The panel had no attribution to read, so it inferred: "any workspace file modified since this chat's first message". That has no upper bound, and an old chat can be reopened forever, so the window only widened - every writer sharing the workspace fell into it. Reopening last Monday's chat credited it with a document another chat wrote on Wednesday, the hourly heartbeat's daily memory log, the idle-session sweeper's log for a *different* conversation, and an org document a teammate edited from another machine.
The signal was always there and simply thrown away: every chat turn already runs inside a conversation scope, so which chat asked for a write is known at the moment of the write. That pair is now recorded, including for
exec- the tool that writes almost everything, via shell redirection - by diffing the workspace across one bounded command rather than over the whole chat. Six narrower leaks were fixed alongside it, each with its own cause: - Merely *reading* a file no longer claims it. The filename scan looked at every tool's input and output with no notion of read-versus-write, and
path/fileare exactly the fieldsfile_readand memory search use - so a chat that recalled an earlier chat's notes listed them as its own output, under the stronger of the two internal claims. memory/,Shared/andgenerated/are never claimed by the fallback. They are agent bookkeeping and org-owned documents; a shared document's timestamp is the moment *another person* edited it.- The fallback now has an upper bound - the chat's last message plus a short grace window - so "this chat's files" means written while the chat was active.
- Switching chats no longer shows the previous chat's files under the new one. The conversation id updates immediately but its transcript arrives over the network, so for that gap both guesses ran on the old chat's data. Milliseconds on a desktop, seconds over the tunnel.
- A bare filename in a command is no longer resolved by searching the whole workspace.
cd memory && cat 2026-07-24.mdwas attaching another chat's daily log; an ambiguous name now matches nothing rather than guessing. - A path containing
workspace/is only ours if it really is. Anexecthat inspected a CI checkout (/opt/ci/workspace/MEMORY.md, or a WindowsC:\build\workspace\USER.md) was producing a row for the user's own file. Also: the "new files" badge no longer inherits what you read in a *different* chat - it was keyed on path alone, and the agent reuses stable filenames. Files another chat produced stay fully reachable in the workspace tree below the list. They are no longer *claimed*, which is the whole difference. - An empty
Sharedfolder hid itself, which is why the feature could not be found. The desktop returned no folder at all when a workspace had no documents yet, on the reasoning that an empty shelf reads as "your team has nothing". For a signed-in member of a real workspace that is backwards: no documents yet is the normal first state, and hiding the folder removed the only place from which to create the first one. A signed-out machine still gets no folder, because there is no team to answer for. - Opening a shared document from the in-chat files panel 404'd. That panel resolves bytes through
/api/workspace-raw/<path>, which was pure filesystem with no shared branch - so everyShared/*file failed, silently on the desktop build where the URL is handed to a tag that reports nothing. It now dispatches on the same three-valued path classification the read path has used since v0.5.11, traversal rejection included: aShared/../MEMORY.mdmust not fall through to the local branch, which is the bug that made the classification three-valued in the first place. - On Foxl Code, one unreachable file service blanked the other. Everything on that Files page rendered behind the orchestrator's storage probe - and that probe is negative on every account, because the mode it reports on is switched off in code. So the page was its own "not wired up" notice and nothing else, which also meant the relay-backed shared shelf could never appear no matter how well it worked. The two are independent services now: the private half reports its own state as a note inside the file tree, beside a shared shelf that keeps working.
- Queued messages are a flat list again, not a 3D pile. Each message you typed while Foxl was still replying used to become its own floating card, and the group faked depth to show the order: every card a little smaller and a little fainter than the one below it, overlapping by ten pixels, each with its own frosted surface and its own shadow. Three queued messages measured 736, 706 and 677 pixels wide at 100%, 82% and 64% opacity - so the message furthest from the send box was both the smallest and the hardest to read, for no information you could not already get from its position in the list. They are now rows in ONE panel that sits directly on top of the message box: same width, same darkness, one hairline border, no shadow, and a small return arrow on each row pointing at the box they are going into. Rows are also shorter (32px instead of 40px), so a full queue takes up a third less of the screen. Two things stayed deliberately. The panel still tucks eight pixels under the message box, because that overlap is what makes the two read as one attached surface rather than two boxes with a seam - and tapping the top edge of the message box still puts the cursor in it rather than opening a queued message, which is a real bug this queue shipped once and is now measured on every run along with the flatness itself.
- The Linux and Android CI builds had never once succeeded, because the build machine rebooted itself partway through every run. An account-wide patch policy installed updates on each fresh runner and then restarted it about three minutes into boot - which is less time than any real build takes, so the job died every time (8 of 8 for Android, every run in the repo's history for Linux). Runners now opt out of that patching, which is pointless for a machine that exists for one job and is destroyed afterwards. The Android build is green for the first time - a 31 MB APK, built in 2m 10s on a runner that no longer restarts underneath it. The pool's own smoke test used to pass because it finished in four seconds; it now stays alive long enough to catch a reboot, so this cannot silently come back.
- A message that gets no reply now says why, instead of vanishing. Sending on Opus 5 frequently produced no answer, no error, and no sign the message had ever been sent. The cause was not the model: Bedrock reports a mid-stream failure (throttling, model-stream error) with a frame that carries no
typefield, and the relay forwarded it verbatim. The web client dispatches purely on that field, so the frame matched no branch - not even its error branch - and was dropped. The stream then ended with zero events, which the client finalized as a SUCCESSFUL reply with empty content, and an assistant row with empty content renders nothing at all. So a failed turn looked exactly like a turn that never happened. The relay now translates those frames into a real error event, the way the non-Claude streaming path always has, and reports a stream that dies or produces nothing rather than closing as if it had finished. The client treats a zero-content stream as a failure too, so the turn always ends in something visible. A throttle now reads "The provider is throttling requests. Wait a moment and try again" instead of silence. Opus 5 was hit hardest because thinking is on by default athigheffort, which holds the stream open far longer and gives a mid-stream failure a much wider window to land in. A thinking-only reply is still a real reply and is not reported as an error. - A second message sent while a brand-new chat is still being created is no longer lost. Creating the conversation is a round trip, and a message queued during it was stored against a conversation id that did not exist yet. The code moved the in-flight marker onto the real id but not the queued message, and the queue only matches on an exact id - so the message became unreachable, and the queue is not saved anywhere, so it was gone for good.
- The Notes sidebar now reads as part of the same app as Agent and Code. All three recording-list defects were measured in the browser rather than eyeballed, because the ones that mattered were invisible to a class-name review:
- The secondary text was not legible. The relative time, the duration and the summary preview were painted in a Notes-only alpha (
text-sidebar-foreground/35) that computes to 1.86:1 against the sidebar - rule 7 of DESIGN-PRINCIPLES wants 4.5:1 for 12px text, so it was under half the floor, and the selected-row variant was 3.23:1. Dark theme was 2.9:1 - 4.38:1. They now use--muted-foreground, whose value is 40.6% precisely because that is the lightest ink clearing 4.5:1 on every light surface including a selected sidebar row. The summary badge was 2.08:1 against rule 8's 3:1, and the empty state's icon and copy were short too. - Titles aligned to two different left edges. The summary badge was a flex sibling of the title, so it pushed the title right by its own width - only on rows that happened to carry a summary. Measured 42px against 24px on the row above: an 18px step that appeared the moment an AI summary landed. The badge is now absolutely positioned in the row's own left gutter, so every title starts at the same x whether the badge is there or not.
- It answered "when was this?" in a vocabulary no other list used. The list kept a local copy of the date bucketing that the shared
sidebar-date-scrubmodule was written to delete - it said "Jun 24" where Chat and Code said "June", and dropped the weekday name inside the last week. It also had no inline dividers at all on the desktop, painting the phone's floating pill there instead, and its hand-rolled scroll handler could strand that pill on screen with a stale label (its teardown cleared the pending hide timer, so any list update inside the 1s window cancelled the hide and nothing re-armed it). It now uses the shared module, so all three lists name a date identically. - The list had no bottom-edge fade, the one cue that says "there is more below"; it now uses the same measured
useScrollFadeas the other two. - New
npm run e2e:notes-sidebargate (foxl/apps/web) measures all of the above in a real browser in both themes plus the phone, and compares the Notes row against the Agent row in the same sidebar. 22 assertions. - iOS: a notification you already read no longer keeps its red dot. The app's unread state and the iOS notification centre were two unrelated ledgers, so reading a banner on the lock screen - or swiping the whole stack away - changed nothing in Foxl: the row stayed unread, the dot stayed, the badge stayed. The OS is now the source of truth. On launch and on every resume the app reads the delivered set: anything still sitting there is unread, and anything that has left a set the app had previously seen was dealt with by you, so it is marked read. Rows that never came from a push (desktop notifications, the Settings test button) are untouched, because their absence from the OS list says nothing about them.
- A push that arrived while Foxl was closed now leaves a trace. Only pushes that landed while the app was running were recorded, which is the opposite of the common case - phone in a pocket, three notifications arrive, open the app and the Notification Center said "Nothing here" under a badge that said 3. Those pushes are now filed from the OS delivered list, with the same routing and Open action a foreground one gets. The app also no longer erases your iOS notification centre on launch (it used to clear every delivered notification, which is what destroyed the evidence in the first place).
Changes
- "Shared" is gone from the sidebar; shared things now live where the things they are live. A row called "Shared" organises the app by WHO owns a file rather than by what it is, so the page had to re-implement every kind of thing that can be owned - it shipped a second Skills list and a second document browser, each styled differently from the real one, and the search box on it was a third search that was not the one in the title bar. Shared documents are now a
Sharedfolder at the bottom of the Workspace tree, and shared skills are a section of the Skills page, so there is one Skills UI and one file tree. - Foxl can read shared documents exactly like any other workspace file. This is the part that was missing: the old page could only display them, and the agent could not see them at all. The seam is underneath
readWorkspaceFile/writeWorkspaceFile/getWorkspaceTreerather than in an HTTP route, which is the one funnel both the Workspace page and the agent's own file tools go through, andfile_readnow routes aShared/...path through it - so "openShared/runbooks/oncall.md" works from chat with no separate tool and no second code path. Authorization stays on the relay, which is the only place that knows who else is in the workspace. Two things are deliberately NOT in this release, so they are stated rather than implied: the agent can read a shared document but has no free-form write tool yet (every writing tool constrains its path to a fixed set), and with the old page gone there is currently no UI for CREATING a shared document or running a shared search - both endpoints exist and are unchanged, they just have no caller. Since no shared documents exist yet, theSharedfolder stays hidden until the first document is created. Tracked infoxl/TODO.md.
Fixes
- Signing out left a live relay token on the desktop, so the next person on the machine saw the previous user's shared documents. The token is now kept in the desktop database so the
Sharedfolder survives a model switch, and nothing removed it: sign-out only cleared browser storage, and relay tokens last 12 hours. Sign-out now tells the local server to delete it, and the token goes with it across sign-out and restart. The first version of that call could not authenticate itself in a packaged build - it was answered 403 and the token stayed on disk, which worked in development and not in the app people install - so the sign-out request now carries the local connection token the same way file previews already do. file_readstopped being able to read ordinary files. Teaching the agent's one free-form read tool aboutShared/...paths classified EVERY path as shared, so reading any normal file answered "No shared document at ..." instead of its contents. Local paths read from disk again, and shared paths still go through the workspace, both pinned by tests.- A
Shared/../something.mdpath resolved to a LOCAL file. Rejecting the traversal returned "not a shared path", which sent it down the local branch, where it normalised back inside the workspace and passed the traversal guard. Reading it was merely confusing; writing it meant the user believed they had edited a document the whole team could see while a file changed on one laptop. Shared path classification is now three-valued - once the prefix matches, the path is remote and a malformed one is an error, never a local fallback. - A shared document's search result pointed at a page that no longer exists. Every indexed document stored
/shared?doc=<id>as its deep link, and because both Workers answer an unmatched path with the app shell, following one would have been a blank screen rather than a 404. Hits now link to the document in the workspace tree, and the Workspace page honours?file=, expanding the folders on the way to it. - Your usage now resets on your own date, not on the 1st. Credits were already granted on your own cycle - your renewal date if you subscribe, your signup day-of-month if you are on Free - but the "used this period" figure was measured over the calendar month, so the two disagreed and the percentage was the ratio between them. On a Pro plan renewing on the 20th, spending 480 credits before renewal and 5 after showed 49.5% used of 980 credits the day after renewing; the truth was 5 of 500, or 1%. It failed the other way too: on the 1st of a month, someone genuinely 80% through their period read as 0% used. Both are gone. Account now names the exact date your usage resets rather than claiming a month, in all ten languages - the Korean and Chinese copy had been promising a reset on the 1st specifically. If your date does not exist in a short month it falls back to that month's last day and then returns to your real date, so a renewal on the 31st reads Feb 28, then Mar 31.
- Pro credit refills no longer skip a period. Two ways a paying subscriber could be left short, both fixed. A renewal that arrived within a day of an upgrade was discarded by a "granted something recently?" check, so the new period started on the leftovers of the old one. And the backstop that repairs a renewal notification we never received only ran for people sitting at exactly zero - so a subscriber who began a period with 10 of 500 credits left and a lost notification stayed on those 10 for the whole period, with nothing anywhere to refill them. Both now ask the only question that matters: has this period been granted yet?
- The new period now begins at the moment you are actually charged, not at midnight on that date. Since billing runs at a specific time of day, a window that opened at midnight counted up to a day of spending that had really come out of the previous period's credits - on a Pro plan that could read as 45% used when the true figure was 2%, and it stayed wrong for the rest of the period. Free plans are unaffected: those credits genuinely do arrive at midnight UTC.
- The renewal notification from our payment provider was never granting your credits. It carries an invoice, not a subscription, so it does not include which plan you are on - and the code asked it for exactly that, got nothing, and stopped before adding any credits. Every renewal was actually being rescued by a separate safety net that only runs once you hit zero, which is why finishing a period with a few credits left meant carrying those few into the next one. The renewal now looks up your real subscription and grants properly.
- A second plan change never took effect. Upgrades and downgrades were recognised only once per subscription, ever: the first change worked, and every later one was discarded as a duplicate - so a second upgrade was charged without moving your plan or your credits.
- If a long turn ever spent slightly past your remaining balance, Account showed the full amount while the service enforced the smaller one, so you could see credits available and still be refused. Both numbers now agree.
- Subscribers billed on the 29th, 30th or 31st had their renewal date read back from a short month (February shows the 28th) and kept that shorter date afterwards, which started the next period a few days early and over-reported usage. Your real billing day is now remembered.
- Your reset date keeps showing during a billing-provider outage instead of disappearing from Account, and the 80%/100% usage warning emails now fire once per actual cycle rather than once per calendar month.
- Cancelling a subscription now returns your usage window to your signup day. It was still anchored to the billing day of the subscription you had just ended, so spending from your last paid period counted against your new Free allowance: someone who signed up on the 6th, billed on the 22nd, and spent 400 credits before cancelling read 97.6% used the day after their 10 free credits arrived untouched. That figure also decides the 80% and 100% warning emails, so it could tell you that you were out of credits while your balance was full. This affected almost everyone who cancelled, since your signup day and your billing day are rarely the same date.
- The command palette no longer shows a raw
{reset}in the Credits row's subtitle. Naming your reset date in that sentence made it the one searchable description with a value to fill in, and the palette has no date to fill it with, so it printed the placeholder literally in all ten languages. It now reads as a plain "current billing period" there - and Account drops the "resets on ..." clause entirely, rather than trailing off into a bare full stop, in the moments before your reset date has loaded. - A key saved for one vendor could be sent to another. Selecting an OpenAI-compatible provider overwrote the process's OpenAI credential with that vendor's key, and switching back to OpenAI did not undo it - so the next request to OpenAI carried, say, your DeepSeek key. That is a live credential handed to an unrelated company, and it also looked like your OpenAI key had broken. Vendor keys now travel in their own channel and never touch the OpenAI one.
- A key you saved in Settings stopped working after a restart. Only the Anthropic, OpenAI and Google keys were restored on boot, and a provider counts as configured by looking at the environment - so every other vendor came back reporting "not configured" with your key sitting encrypted in the database, and the only way to use it was to re-paste it every launch.
- Requests to a non-OpenAI vendor could go to OpenAI anyway. One of the two places that build a model set the custom endpoint through an option that does not exist, so it was silently discarded and the request went to
api.openai.comwith the wrong key attached. - Turning a skill off destroyed the thing that decides whether it can run. A skill declaring what it needs - binaries, environment variables - had those requirements written back in a form the reader does not understand, so they vanished on the next load. The failure inverted the check rather than merely losing it: a skill needing tools you do not have went from correctly reporting what was missing to claiming it was ready to run.
license,allowed-tools, comments and any other field the writer had no special case for were dropped by the same write. Editing a skill now leaves everything it does not change untouched. - Turning a skill off also froze its instructions forever, and could undo itself. On/off was stored inside
SKILL.md, the one file that syncs from the skills repo. Toggling a skill made its file differ from the repo's copy, which the sync reads as "the user edited this, preserve it" - so that skill stopped receiving updates for good. In the other direction, a skill the repo ships as off that you switched on got switched back off the next time the file legitimately changed. Your on/off choice now lives beside your other preferences, soSKILL.mdstays identical to the repo and updates keep flowing. Both directions are recorded, which matters more than it sounds: a skill you had ever switched off carriesenabled: falsein its own file, and remembering only your OFFs would leave the file with the last word - so the switch would go through, the row would say Enabled, and the skill would quietly come back off. Fourteen of the skills that ship with Foxl declare that same line, so the same would have applied to them out of the box. - Three of the new providers had no icon. GLM, Kimi and MiniMax fell back to a generic server glyph even though their logos were already sitting in the app - the row that maps a provider to its icon file was simply missing, which fails silently because the provider still works. Kimi needed the mapping most: its id is
kimibut the brand file is Moonshot's. - Cost tracking priced models that no longer exist. The per-token table still carried rows for the retired DeepSeek ids and a Fireworks model we no longer offer, while the models you can actually pick matched nothing - and an unmatched model is recorded as costing zero. The dead rows are gone. Spend on third-party vendors is still counted as zero, which under-reports, but that is deliberate: inventing a per-token price would mis-report every request instead, so those rows wait until someone reads each vendor's live pricing page.
- A code block's copy button is now always visible on phones. It was revealed by hover, and a touch screen has no hover, so on iOS the button never appeared at all: it was there, it was full size, and tapping the right spot did copy the code - it was simply drawn at zero opacity, which is indistinguishable from missing. It is now permanently visible on touch and unchanged on desktop, where hover still reveals it. Keyboard users get it on focus too, which was the same gap. This affects every code block in a chat reply on both Foxl Agent and Foxl Code, plus html/svg/mermaid preview blocks and Foxl Code's thinking blocks. A fence written without a language has no header row, so its copy button floats over the top-right of the code itself. That was invisible-and-therefore-harmless before; permanently visible, it landed a bare icon on top of the first line of code and made both unreadable, so the button now carries its own surface there. The surface fades in with the button rather than being painted always, or the block would wear an empty grey pad in its corner whenever the button is hidden.
- The Settings sheet's back button on phones looks like it used to again. Two changes in a row had been made to that one round control in the top-left of the Settings sheet, and together they turned it into something else: first the icon was split so it showed an X at the section list and an arrow only once you had drilled into a section, then its glass was replaced with a recipe that tinted from the text colour instead of the background. The result was a heavy grey disc with a hard ring around it, easily the loudest thing in an otherwise very light header, and it changed shape depending on where you were. It is back to one always-present back arrow in the softer translucent chip the sheet shipped with. Nothing about what it does changed: at the section list it closes the sheet, and inside a section it goes back one level. The now-unused tinted-glass recipe was deleted rather than left behind.
- The app icon looked about 60% full next to every other app; the fox now fills its tile. The rounded-rect tile was always the correct macOS size (824 of 1024 px, the exact standard), but the fox inside it was drawn at only 69% of that tile, leaving a wide empty ring. macOS's own icons draw their glyph at 81-85% of the tile (Maps 84.5%, Notes 84.3%, Safari 80.9%), and the apps Foxl sits beside in a list do the same, so Foxl read as underfilled wherever icons appear side by side. It was most obvious against a light background, where the white tile fades into the page and only the dark fox registers as the icon. The fox is now 82% of the tile. The tile itself is untouched - same size, shape, gradient and edge, bit-for-bit - so the icon's footprint in the Dock and everywhere else is exactly what it was.
- A reply now uses the full width of the conversation, out to where your own message ends. Removing the bubble from replies left behind the width it used to sit in, so every answer stopped about a fifth short of the right edge while your own message and the composer ran all the way to it - the two sides of the same conversation ending in two different places, which read as an indent rather than as a measure. Measured on desktop, each reply was giving up 140.8px of a 704px row; on a phone, 65.2px of 326px, on the screen with the least width to spare. Replies now end exactly where your message does. This is one shared component, so Foxl Agent, Foxl Code and the iOS app all pick it up together, and the overall reading column is unchanged.
- The chat composer no longer covers the bottom of an open document. It floats over the transcript by design, but it was measuring its position against a container that included the file panel, so it stretched across the panel too and hid the bottom 130px of whatever you were reading - the page just scrolled away underneath it.
- The file panel is no longer drawn over by the app's own header on a phone. The sidebar-toggle chip landed on top of the panel's title and the chat-menu chip on top of its close button, both still tappable, because a
z-indexset inside the shell's content area cannot outrank anything outside it. - Fixed an error thrown on every mount of the workspace editor. Monaco was left to find its own web worker and could not, so it threw
Failed to resolve module specifiereach time a file was opened for editing. It degraded quietly enough that nobody noticed, and no test opened that screen. - The desktop app was marking every chat "not downloaded". The sidebar was told to report sync state on a build that never computes it, and the empty answer read as "none of these are here" rather than "there is nothing to say" - so the one build where your history is unambiguously local was the one build that put a cloud on all of it.
- A cloud no longer flashes on every chat when the app starts. Reading the local cache takes a moment, and until it answered the app assumed the worst about every row. On the phone, where the indicator is always visible, that was the first thing you saw on every cold start.
- Right-click menus are sized for the lists they belong to. The menu text was 14px hanging off 12px rows, so opening it stepped UP in size as you drilled down, and its group heading was the boldest, darkest thing in the popover despite not being clickable. Text is now 12px throughout with a quieter heading. Rows keep their full 44px height on touch.
- A date separator in the sidebar no longer stays up forever once you scroll. Measured on both lists: scroll once and the separators were still fully visible six seconds later. Showing them makes the list taller, and the browser holds the visible rows still by nudging the scroll position - which counts as a scroll, which was read as "still scrolling", which kept them up, which kept the list tall. The loop needed no further input from anyone and re-armed itself about once a second. This shipped in the Agent chat list; it is fixed for both.
- The Foxl Code task list is ordered by the time each row displays. The rows show when a task last changed ("8h ago") but arrived ordered by when it was created, and those disagree constantly because tasks run concurrently and for very different durations - so a job queued last week and finished this morning sat near the bottom under an old date. The relative times now descend properly, and each date group appears exactly once instead of repeating.
- Tapping the top of the message box while messages were queued opened one of them instead of letting you type. The queued-message stack is meant to tuck under the composer's top edge, and it was doing the opposite: the last card was drawn over the composer across that 8-pixel overlap and took the taps there too, so aiming at the input expanded a pending message. It was worst on a phone, on the exact spot you aim at, and only while the queue was showing - which is the whole state the stack exists for. The cards now stay behind the composer while keeping their own order (the one going next is still the crisp card on top). Fixed alongside it: hovering a recessed card was supposed to lift it back to full size so the one under your cursor is always the readable one; it only brightened, and never grew.
Features
- Foxl Workspaces: one shared space across Agent, Code and Notes - with files in it, and a bill you can predict. A Workspace was already the thing that carried shared skills, documents and search to everyone in it; it now also carries FILES, and it is the same tenant Foxl Code means by a connected GitHub account rather than a second, parallel idea of "your team". What changed, and why each piece is the way it is:
- Code's Files and Agent's Workspace are one concept. Files are stored per scope (
personal:<you>ororg:<workspace>) and shared files are visible to every member. The two rosters behind them do NOT merge into one table, on purpose: GitHub is authoritative for who is in a GitHub org, Foxl is authoritative for who is in a Workspace, and neither can be derived from the other (a teammate who signed in with Google has no GitHub identity at all). So a Workspace LINKS its GitHub installations, and a member still needs GitHub's own proof before any repo access follows. - Real documents, not just text. PDFs, images,
.docx,.pptxand.xlsxupload and download intact instead of being mangled as text. Anything that could be interpreted as markup in the app's own origin (.html,.svg) is served as a download rather than rendered, since a shared file is a file somebody else opens. Opening these in place, rather than downloading them, is still to come. - Storage is metered, and the workspace has an explicit owner who pays. Every plan's storage allowance had been declared in the tier table since Foxl Code shipped and nothing had ever measured it. Now: Pro includes 5 GB, Ultra 50 GB, and only what a workspace holds ABOVE its allowance is billed, out of the same credits that pay for model calls (1.25 credits per GB-month). The free plan does not include shared file storage, and an upload that would need it is refused rather than quietly spending a free user's whole month.
- The bill lands on your own renewal day, not on the 1st. Credits arrive on each account's subscription anniversary, so charging storage on the 1st of the month would routinely bill a workspace before the credits that pay for it exist. Consumption is measured daily and charged in GB-months on the billing owner's anniversary (clamped for short months, the way a card does it), so a workspace that held 100 GB for most of a month pays for what it held rather than for whatever happened to be there on one day.
- A failed charge never deletes a file. It pauses new uploads and says so; reading everything you already have keeps working.
- Workspaces can be deleted. Owner only, and recoverable for 30 days. Deleting revokes pending invites and unlinks GitHub installs, but does not uninstall the GitHub App (it is not ours to remove) and does not erase the workspace's audit log (one the subject can erase is not an audit log).
- Four more model vendors, and the model lists behind all of them are honest again. GLM (Z.ai), Kimi (Moonshot), Qwen (Alibaba Model Studio) and MiniMax join the providers you can reach with your own key, and the vendors already listed got their catalogs re-read from the vendors' own documentation. That second half matters more than the first: several ids we were offering no longer exist. Picking DeepSeek used to offer "DeepSeek V3" and "DeepSeek R1", ids that appear nowhere in DeepSeek's current docs, so the request failed the moment you sent it - the picker was advertising models you could not use. Every id now ships with the date its vendor page was read, because these are not guessable: Fireworks spells decimal points with a letter (
glm-5p2is GLM 5.2), and OpenRouter publishes two names per model where only the undated one is accepted. Where a vendor's endpoint could not be confirmed, the entry is left empty rather than filled in with a plausible URL. - Models now say for themselves whether they can use tools or see images. Every third-party model was previously reported as tool-capable and vision-incapable, regardless of what its vendor said, so a vision model looked text-only and a text-only model was offered your tools. Each model now carries the capabilities its own vendor page states.
- Hermes wears the real Nous Research mark. It had been showing a blue circle with an "M" in it - a placeholder drawn in-house, not the actual logo.
- A chat you are reading offline can now be continued right where it is. When your desktop is asleep, opening one of its conversations on the web or the phone shows the saved copy kept on your device, read-only, because a reply belongs to the desktop that holds your files and tools. That was the end of the road: read it, and come back later. The notice now offers a second option - continue here as a new chat - and taking it copies the conversation into a new one on this device and unlocks the message box. The window does not change while it happens: the messages stay exactly where they are, on screen and in place, and the only thing that appears is the composer. The desktop's own chat is untouched, so the original is still there, still on the desktop, still readable offline; the copy is a separate conversation that lives on this device and is yours to reply to now. It stays yours when the desktop wakes up too, rather than being replaced by the desktop's version of history. One thing to know, because it is a real difference and not a detail: the new chat is answered over the relay, which cannot reach the tools your desktop agent used. It is given the words of the conversation, so it knows what was said - but not what was run. If the earlier answers came from reading your files or searching the web, the continuation cannot see any of that and may reach a different conclusion. For work that depends on your own machine, waking the desktop is still the better move. The new chat also does not claim to be waiting for anything. The sidebar marks a chat whose messages have not reached this device yet, and a copy you just made on this device was briefly getting that mark - a small cloud saying the messages arrive when the desktop connects, on the one conversation that needed neither. Rows that genuinely have nothing downloaded still say so.
- Foxl can be built and released for Android now. The mobile app has had an iOS host since v0.3.0 and no Android one at all - the platform folder was never generated, so there was nothing to build. It exists now, committed, and the release path is scripted end to end rather than "open Android Studio and click Generate Signed Bundle": one command produces a signed App Bundle and uploads it to a Google Play testing track as a draft. Verified by building for real - a 31 MB debug APK with the web app inside it, and a 29 MB signed bundle whose signing certificate reads back as the upload key.
Two things the Android host needed that iOS already had, and that a plain platform generation does not give you: the
foxl://deep link, without which sign-in cannot complete at all (the callback has nowhere to land, so the browser sheet just sits there), and the microphone, camera and notification permissions. Both are in the committed project now instead of being a checklist in a README that a fresh setup would skip. Android notifications do not work yet, and this does not change that: the server only speaks APNs, so a phone registers for push and then receives nothing. That is the next piece of work, not part of this one. - The workspace panel is a proper file viewer now: tabs across the top, the whole workspace as a tree down the side, and documents that actually render. The panel that opens beside a chat used to be a flat list of the files that chat had produced, one open at a time, with a back button to reach the list again. Three things were wrong with that and they compounded. Markdown, and every other text file, did not render at all - it showed a card with Open and Download buttons, so the agent's most common output, a .md report, was the one thing the panel could not show you. A .md now renders as a document (headings, tables, code blocks, lists) with a Raw toggle for the source, and source files open in the editor with syntax highlighting. You could only look at one file at a time, so comparing a deck against the spreadsheet behind it meant going back to the list between every glance, losing your place in both - files open as tabs now, up to eight, and closing one lands you on its neighbour the way an editor does. And you could not reach anything the current chat had not made - a file from an earlier chat, or one you put there yourself, needed the separate Workspace page, and a chat that had produced nothing showed an empty panel over a full workspace. The sidebar now shows the whole workspace as a nested tree, with this chat's own files called out above it and marked in the tree so they stay easy to find.
- The workspace panel works on a phone at all. The button that opens it is desktop-only, and nothing in the mobile menu replaced it - so the full-screen mobile presentation, which had been written and wired up, could not be opened. It is a row in the chat menu now. On a phone the tree and the document are stacked screens rather than two unusable columns, back returns to the tree without throwing away the documents you have open, and the tab strip sits above the tree so you can get back to them.
- The cloud beside a chat now tells you what is actually on your phone, and you can do something about it. There was already a small cloud on chats whose messages had not reached this device, but it could only say one thing - "nothing here" - and it said it permanently, on every row it applied to, which in a long list is a column of grey clouds nobody asked for. Three changes. It is now hover-revealed on a computer, so the list is quiet until you go looking, and it does not appear on the desktop app at all, because there the chat history IS on your machine and a sync indicator has nothing to report. On the phone, where there is no hover to reveal anything with, it stays visible - that is the device the answer matters on. And it can now distinguish a third state that was previously invisible: a chat you downloaded earlier that has since GAINED messages on your desktop. That one used to look identical to a fully current copy, so it opened, showed you the text, and quietly left the newest messages out.
- Press and hold a chat on iPhone for the sync actions. Download it to this device, sync a copy that has fallen behind, refresh one that is current, remove a download to reclaim the space, or sync everything at once - the OneDrive vocabulary, on the row it applies to. The menu names the state at the top, so the cloud is explainable rather than just decorative, and every action is greyed out with a reason when your desktop is not reachable instead of failing silently. Swiping still reveals Rename and Delete: a drag goes to the swipe, a hold goes to the menu.
Improvements
- The Foxl Code sidebar reads as two groups instead of one long list, and its task list now tells you when. All six Code rows used to sit in a single block under a "Workspace" heading, which made this the one product whose nav was an undifferentiated run of evenly-spaced rows. They are really two ideas - the work moving through the system (Tasks, Work, Inbox) and the things it runs against (Repos, Files, Runtimes) - so there is now vertical space between the two, and no new headings: two labels over three rows each would be more chrome than the rows they describe. The "Workspace" heading is gone with the split. The task list also picked up the same date scrub the chat list has: scroll it and quiet "Today / Yesterday / Fri, Jul 31 / July" separators appear between the rows, fading out about a second after you stop. They take no space when idle, so the list does not jump. On a phone the same thing arrives as a small floating label at the top of the list, because keeping the inline separators readable needs a pointer resting on the list and a finger cannot do that.
- Restored a Google sign-in credential that v0.5.7 removed by mistake. The v0.5.7 notes describe removing a committed OAuth client secret as a security fix. That was the wrong call: the credential is a desktop-app client, the kind Google explicitly does not treat as confidential because it ships inside every copy of an installed application and cannot do anything without someone approving a consent screen on their own machine. Removing it took away a value nothing else supplies. It is back, unchanged, and nothing needs rotating.
Features
- The Foxl Den is an easter egg now: tap the version seven times. The game used to be a switch labelled "Pixel Office" in Settings > Advanced > Experiments, which meant it was not really hidden at all - it named itself to everyone who opened that pane, and because the command palette builds its settings search from those same labels, typing "game" offered it to people who had never gone looking. So the switch is gone. The way in is tapping the version row in Settings > General > About seven times, the way Android hides its developer options, and seven more taps put it away again. Two other places were saying the quiet part out loud and have stopped: the palette no longer indexes it, and the mobile notification settings no longer list a "Foxl Den" category under a game-controller icon to someone with no game (your preference for it is kept, the row just waits until there is something to notify you about). Your den and everything in it survives locking and unlocking. One thing that used to be broken is fixed on the way past: flipping the old switch did not make the game appear until you restarted the app, because the header read the setting once at launch and never again - now the controller shows up the moment the seventh tap lands.
- Shared workspaces: create one, invite people by email, and the agent is theirs and the team's at the same time. Until now Foxl had exactly one kind of space - yours. Foxl Code had a rough approximation of a shared one, but it was really just the GitHub App installation: the roster, the admins and the identity all came from GitHub, so you could not create a workspace, and the invite path that its database schema anticipated was never built. Now there is a Foxl-native organization. You name it, you own it, and you add people by typing an email address. They get a link, and joining is bound to the address it was sent to, so a forwarded link is not a way into your workspace.
Everything shared hangs off one idea: a scope, which is either
personal:youororg:the-team. Your own space is not "no organization" - it is a scope you happen to own alone, which is why a skill you wrote for yourself can be shared to the whole team without changing shape. What travels with a workspace: - Shared skills. Publish a skill and everyone in the workspace can add it. Whether it is on is remembered per person, so turning one off for yourself does not edit the copy your colleagues are reading. Sharing to the whole organization is admin-gated by default and COPIES rather than moves, so you keep your own version to keep working on.
- Shared workspace documents. Runbooks and notes that belong to the team rather than to one laptop. Any member can write them; skills stay admin-gated, because a skill changes how the agent behaves for everybody.
- Shared search. One search across everything your workspaces have shared, spanning Foxl Agent and Foxl Code. It is scoped in the query itself, so a result from a workspace you are not in is never considered - not filtered out afterwards, which leaks through result counts. Your own chats and local files are not included in shared search and are still searched from the title bar.
- Admin control. Who may invite, and whether members can publish shared skills. The same identity and configuration carries across surfaces: it is the same workspace on app.foxl.ai, on code.foxl.ai, in the desktop app and on the phone, because it is keyed to your account rather than to a machine. Removing someone takes effect on their next request rather than whenever their session expires, and a workspace can never be left with nobody who can administer it - the guard is a single atomic statement, so two admins leaving at the same moment cannot both slip through.
- A chat that had only synced its title used to be a dead tap; now it tells you what is going on, and fills itself in. On the web app and on iPhone, the list of your chats syncs on every load but a chat's MESSAGES only sync when you open it - so most rows in the sidebar were a title with nothing behind them. Tapping one did nothing you could see: the address bar changed, the row highlighted, and the pane kept showing whatever was there before. Those chats now open and say they live on your desktop and will fill in when it connects, with the composer replaced by that sentence rather than left enabled over an empty history. A mistyped or deleted chat is NOT told that - it would be a promise the app cannot keep.
- And the messages now arrive on their own, quietly. Once your desktop is connected, Foxl downloads recent chats in the background - one at a time, with a pause between each, starting a few seconds after connecting so it never competes with the chat you are actually having, and stopping immediately if the desktop goes away. Rows that are not downloaded yet carry a small cloud in the left margin; hovering it says why. How many chats to keep is yours to set in Settings > General > Offline chat history (off, 10, 20, 50, or all). It defaults to the 20 most recent rather than everything, because on a long history "all" is hundreds of round-trips to your own machine, on a phone, on cellular data.
- Word documents and slide decks now look like Word documents and slide decks. Opening a .docx in the workspace ran it through a converter that maps document STRUCTURE and throws presentation away, so every file arrived as the same unstyled web page - no page, no margins, no fonts, no headers. A .pptx was worse: the text was scraped out of the slide XML and printed as a bullet list, which tells you what a deck says and nothing about what it looks like. A macOS-only picture of page one papered over both, and showed nothing at all on Windows, Linux, or the web app. Both now render properly, in the browser, on every platform: a .docx as real pages at the document's own width with its styles, tables and headers, and a .pptx as real slides with the text, shapes, pictures, tables and gradients where the author put them.
- The + at the top right of a chat is now a workspace-files panel. That slot held a fourth way to start a new chat (Cmd+N, the sidebar +, and the Chat menu are the other three), while the files the agent had just written had no way in at all. It now opens a panel beside the conversation listing the files THIS chat produced, newest first, and previews any of them in place - so the deck and the conversation that asked for it are on screen together. On a phone it opens as a full page instead. New chat is unchanged everywhere it already lived.
- Tool calls now happen where the reply says they happen. An assistant turn drew every tool it used in one stack at the top of the message and then all of its prose underneath, so a reply that went "let me check disk usage" -> command -> "the volume is 93% full" -> command read as a wall of commands followed by text that had lost track of which command it was talking about. The cause was structural rather than cosmetic: a turn recorded the ORDER of its thinking and its tools, but its words were kept as one flat string with no position, so there was nothing to interleave them with. Prose is now an ordered block like the others - live and after a reload, since the ordering is persisted - and a turn renders as the sequence it actually was.
- A batch of commands is one line you can open, not fifteen rows. Consecutive tool calls collapse into a single quiet summary ("Ran commands - 3 steps") that expands on click, the way Codex and the Claude app do it. A run that is still executing opens itself so streaming output stays visible, and then stays however you left it. A lone tool call is still a lone row: wrapping one command in "1 step" would only add a click to reach what was already on screen. Prose between two batches keeps them separate, which is the point - each batch stays next to the sentence that explains it.
- The expand chevrons are hidden until you reach for them. On grouped commands, on individual tool rows and on thinking, the disclosure arrow is revealed on hover or keyboard focus instead of sitting there permanently, so the transcript reads as prose rather than as a column of widgets. The whole row is the click target, so nothing got harder to hit, and touch screens - which have no hover - keep the arrow visible.
- The assistant's reply is no longer in a bubble. Its own words are the content of the page, and a tinted capsule around a long answer interleaved with un-bubbled tool and thinking rows made the reply read as a quoted excerpt inside its own turn. It is now plain text at 80% of the column width - the measure does the job the bubble's edge used to do. Your messages keep their bubble; they are the ones being quoted back.
- The right-hand panel in Foxl Code is now what needs you, not a second copy of your task list. It opened on "In progress" and "Recent" task cards - the same rows, drawn by the same component, that the sidebar on the left was already showing, so it spent a whole column restating what you could see and hid its one unique thing (a plan's subtask board) one click deeper. It is now "Needs you": a queue of the decisions that are yours, each with the button that settles it - approve a plan, answer a question, merge a PR that is green and approved and waiting, look at a build that went red, at a merge GitHub refused, at a reviewer asking for changes. It reads across every connected repo, and when there is nothing it says so instead of showing you a list. The plan board is still there, one click from the plan row it belongs to.
- Two things that need you were unreachable, and now are not. A plan that stopped to ask for approval spawns nothing while it waits - which meant there was no task to select, and the approve button only existed inside a panel that required one. That plan is now a row in the queue with its cost estimate and a Confirm button, no selection required. And the whole queue also renders at the top of the Work page on every platform, so an iPhone - where the side panel has no room to exist - reaches the same rows from the notification that brought you there.
Fixes
- The Settings list is in an order you can predict. It had been sorted by guessed re-open frequency, which put General - theme, language, the version number - at the very BOTTOM of App on the theory that those are set once and left alone, filed Usage under a "Connect" heading next to tunnel pairing, and filed Advanced under "Diagnostics" next to two log viewers. Each of those was argued at length in the code and none of them survives contact with someone scanning the list: frequency is invisible until you already know the app, while category is visible immediately. App now runs broadest-scope-first - General, then Account with Usage directly beneath it (spend is something your account has, not a "connection"), then the panes that decide how the agent behaves, then Trash, and Advanced last, where every desktop platform puts the migration-and-experiments drawer. Opening Settings with no section named lands on General for the same reason. Connect is now only the two panes that wire Foxl to something outside itself, and Diagnostics is only the two log readers. Nothing was removed or renamed, and the phone list follows the same order as the desktop rail instead of leading with Notifications.
- The Usage Explorer sits in a column instead of running edge to edge. It was the one screen in Settings with no side padding at all on desktop (and 4px on a phone) and no width limit, so its text pressed against the pane border and on a wide display the four-up summary stretched to 1390px - far enough that a label stopped looking related to its number. It now uses the same gutter and column cap as the Usage dashboard it drills out of, and as Mobile/Web beside it.
- The daily chart can say a date again. Over a 30-day range it drew one MM-DD label per bar, but a label is wider than a bar at anything under a very large window, so all thirty clipped to "07-..." - a date axis that named no dates. It now labels about eight evenly spaced days, always including the most recent one, and hovering any bar still shows its full date and token count.
- A caption stopped shoving itself out of the page. "Token distribution across models" refused to give up any of its width, so between roughly 768 and 900px - where the Settings nav leaves the reading column narrow - it ran past the page edge. It now shortens with an ellipsis and keeps the full text on hover.
- Signing in to Foxl Notes now looks like signing in. Notes renders without an account (you can read the sample note signed out), so it had no login screen of its own - the signed-out desktop editor reused the same grey "No note selected" placeholder that appears when you simply have no note open: a 14px de-emphasised heading over 12px body text and a small dense button. The one screen standing between a new user and every feature of the product was set two type steps smaller than the equivalent screen in Foxl Code. It now uses Code's sign-in typography exactly - a round bordered icon, a 20px semibold heading, 14px body, full-size button - and the heading names the product ("Sign in to Foxl Notes") instead of just the company, which in a shell hosting three products never said which one you were signing in to. Translated in all 10 languages. The empty-note placeholder keeps its original quiet styling, and nothing changes once signed in.
- The Notes header stops offering buttons that do nothing. With no note open it showed five controls in its top-right corner, two of which could not work there. The transcript toggle was one: the panel it opens only renders for a recording in progress or a note with a transcript, so on the empty screen clicking it changed nothing on the page while still flipping its own label from "Show transcript" to "Hide transcript" - announcing to a screen reader that it had opened a panel that does not exist. The other was the house icon, which clears the selection and the editor and goes to Notes: all three already true on that screen, with no editor even mounted to clear. Both now appear only where they do something - open a note and they are back, because there the house is how you get to a fresh one, and it is also the way back to the editor from Notes Settings. It also draws a plus now: its tooltip has always read "New note" in every language, so the house was promising a different action than the label underneath it. And the "Live panel" button moved up beside Start Recording, where it belongs - it is the other half of recording a meeting, and it had been sitting after the view toggles wearing the only box border in the row, which made a secondary action look heavier than the primary one next to it.
- Two rows in the Foxl Code sidebar no longer say the same word in Korean. Tasks and Work were both "작업" - adjacent rows under one heading, differing only by icon, and because the header title reads from the same string, moving between the two pages changed nothing on screen. Work is now "이슈/PR", which is what the page holds (this repo's open issues and pull requests) and what its own tabs already say. The page heading comes from a second dictionary that had the same collision independently, so that was fixed too - otherwise the duplicate would simply have moved from the sidebar into the title. Portuguese had the same defect in the tool preset picker, where "Default" and "Standard" were both "Padrão": two identical options in a list of five.
- The Inbox row is translated. It was the one nav destination with no translation key at all, in any of the ten languages, so the sidebar fell back to the hardcoded English "Inbox" while the page it opened was translated - a Korean user saw "Inbox" in the list and "받은 알림" once they got there. All ten locales now name it, and a check asserts the row and the page it opens keep agreeing.
- Foxl Code reads in your language, not half of it. The Code pages carry their own dictionary, separate from the shell's, and it shipped with English and Korean only - so a Japanese user got a translated sidebar above a page whose title, tabs, buttons and error messages were all English. That dictionary now ships the same ten locales as the rest of the app.
- A failed code preview says what happened instead of printing its own name. The error state asked for a string that no dictionary defined, in any language, and the fallback for a missing key is the key itself - so when a preview could not render, the panel read "chat.previewError". It now says so in words, in all ten languages.
- The live terminal in Foxl Code follows your colour theme. It was a fixed dark palette - a hardcoded near-black pane with hardcoded ANSI colours - so with the app in light theme it sat in the middle of a white screen as the one surface that ignored the setting, next to two panels directly above it that had always used the theme. Turning only the background white would have been worse than leaving it: the terminal's default text colour scores 1.48:1 against white and its brightest white scores 1.00:1, i.e. invisible, so the whole sixteen-colour set changes with the theme now. Light mode uses a GitHub-Light-derived palette where every colour clears the 4.5:1 contrast bar on white (yellow becomes a brown - a terminal yellow cannot be read on white, and the agent uses it for budget warnings); dark mode keeps the colours it always had, moved onto the app's own card surface so it matches the panels above it. Text selection now has a colour in both themes - it had none, and the built-in default is white, which was invisible the moment the pane went light. Switching theme with the terminal open repaints it in place, keeping the scrollback and the live connection. The "session stopped" card over a settled terminal was also a hardcoded black fill behind theme-coloured text, so in light mode it was near-black ink on a near-black card; it uses the theme now too.
- code.foxl.ai serves Foxl Code and nothing else. That host is the Code product alone, but five addresses still reached the Agent super-app's Integrations screen -
/skills,/tools,/channels,/systemand/customeach kept its URL and rendered a page full of controls for software that host does not run. The router recognised those five names before it checked which host it was on, so the check that sends every other foreign path to Tasks never got a turn. It now runs first, which also means the next address added cannot slip past it. Three more doors are shut with it: a foreign address's trailing part is no longer adopted as a task id (/chat/<conversation>became a task URL naming a conversation, and/billing/successa task called "success"), Cmd+N in Foxl Code starts a new task instead of jumping to an Agent chat, and the fully-qualified spelling of the host (code.foxl.ai., with the trailing dot, which really does resolve) is recognised as the Code host - it was not, so that one address served the entire Agent+Notes app, product switcher and all, and stopped passing GitHub's webhooks through to the orchestrator. - The + at the bottom of the sidebar makes the thing you are looking at. In Foxl Code it created a chat instead of a task, and in Foxl Notes it threw you out of Notes into a chat - one control, hardwired to the Agent product, in all three. It now starts a task in Code, a note in Notes, and a conversation in Agent, which is what Cmd+N already did; the button and the keyboard had disagreed, and the button is the one you can find. Its tooltip says which of the three it will do, so a screen reader no longer announces "New chat" on a control that makes tasks. Pressing it from Repos, Files or Runtimes lands on the empty task composer rather than doing nothing. One of those doors was a CLICK rather than an address, which is why trying URLs never found it: opening a notification about a schedule, a chat or a finished agent put the Agent page for it on screen, because a notification's destination comes from a table that maps most kinds to Agent pages. Every in-app navigation now refuses a destination this host does not serve, so a control nobody has thought of yet cannot leak either.
- code.foxl.ai no longer warns you that a desktop you may not own is offline. The sidebar header carried the relay-tunnel status dot, and its popover said "Desktop Offline - Chat-only mode. Connect desktop for full features - Go to Settings". None of that describes Foxl Code: it runs its work in AgentCore through the orchestrator, never calls the desktop tunnel, and has no chat-only mode - so the warning was permanent, about unrelated software, and its one action opened a pane that cannot pair anything from that host. The dot and its popover are gone there; app.foxl.ai, where the tunnel is real, keeps both unchanged.
- A Foxl Code tab says it is Foxl Code. One bundle serves both app.foxl.ai and code.foxl.ai, and the page title was the static "Foxl" both got - so with both open there were two identical tabs, two identical window-switcher entries, and bookmarks that could not be told apart. The Code host now titles itself "Foxl Code", including on the sign-in screen.
- The chat menu no longer comes up as a grey slab, and the "..." now turns INTO it. Two things were wrong with the menu behind the round button in the top-right of a phone chat. It sometimes rendered dark - a flat grey panel instead of glass - and it depended on your PHONE's Light/Dark setting rather than the app's, which is why it looked random: the chip and the rows were hosted in a native glass container, and that container was the one surface never told which appearance to draw for, so it followed iOS while everything inside it followed Foxl. Same build, same app, only the OS setting changed: the panel measured 151-159 grey with iOS in dark mode and 243-253 with it in light, over a white page. It also left the round chip sitting on the panel's corner the whole time it was open, as a small grey hump. Opening now MORPHS: the circle dissolves as the square panel grows out of the same corner, and closing runs it backwards - the panel shrinks back into the circle's place and the circle returns. One shape at a time, and the material is the app's own in either theme.
- The Logs console showed its own HTTP traffic and almost nothing else. It now shows what the server is actually doing. Three separate causes, each measured against a running server:
Every request the app makes to itself was logged at the same level as real output, and the buffer held 1000 lines. Ordinary background polling was enough to fill it: after a few hundred routine reads the buffer measured 100% access logs and zero lines from anything else - every boot, database, scheduler and skills line evicted by traffic nobody asked to see. Routine reads are now recorded as
debug, so they no longer decide what survives, and the buffer holds 5000 lines. Nothing is hidden: a new Debug filter shows them, with counts. The capture that feeds the console installed part-way through the server's startup, so every module that logged while initialising was lost.[DB] SQLite database initializedwas verified reaching the terminal on startup and never the console, one line above a line that did arrive. Capture now installs before anything else loads, and that line is in the console. The agent SDK's own logging was discarded before it reached us. Its default logger definesdebugandinfoas empty functions, which silently dropped 58 places where it reports what it is doing - loading skills, offloading tool results, evicting context, model and session internals. It is now wired to ours and appears under aStrandssource you can filter to or ignore. Also in the console: Info and Debug filters (it offered only All / Errors / Warnings, while counting info lines it never displayed), aDBGlabel instead of debug lines mislabelling themselvesINF, source chips built from what has actually arrived rather than a one-shot probe taken on open (so a source that first logs later gets a chip, and none are dropped past the eighth), and batched rendering with a row cap so a chatty agent no longer re-renders the whole console once per line. - Settings no longer draws a box inside a box. Appearance and Language each had a full-width bordered panel of their own whose entire content was one small control, so the General pane opened on two large mostly-empty boxes, each holding a smaller box. They are now two rows of a single "Display" panel, with the name and its explanation on the left and the control on the right - the layout the Notes settings have used all along. The Light/Dark/System switch also stops stretching: it was written as a block-level flex row, so its track ran the full width of the panel while the three buttons huddled at the left edge. It now hugs its own labels, and its selected segment is the raised light chip on a tinted track that the product switcher and every filter bar in the app already use, instead of a filled button that looked like it came from a different design. On a phone each control still takes its own full-width line with 44px targets. Sweeping the rest of Settings for the same shape turned up three more: Task Budget was a 608px box holding one 128px dropdown pinned to its right edge (it printed its own name twice, and removing the duplicate had left the row's left half literally empty) - it is now a normal row with its name and explanation; the Chrome extension panel drew an empty bordered strip once the extension connected, because its only content was the install steps it no longer needed to show, so the box now goes away with them; and Notes' "Live translation" panel titled itself and its first row with the same words in seven of ten languages, while its auto-update row was the one setting name on that page rendered grey - the same colour that page uses to mean "disabled" - next to a live switch.
- The Foxl Code sidebar says which product you are in. The tab title was the only place that name appeared. code.foxl.ai serves one product, so it does not draw the Agent/Notes/Code switcher - and that switcher was the only thing in the header naming what you were looking at, which left a bare fox mark and chrome indistinguishable from app.foxl.ai's. "Code" now sits beside the mark, as part of the same Home button rather than a label next to it, so the whole thing is one target and both halves take you home. The collapsed icon rail, where there is no room for a word, shows the mark alone.
- Dropdowns on a phone could open taller than the screen with no way to scroll them. Every Select and every long-press context menu in the app capped its height through a Tailwind v3 spelling of a raw CSS variable, and v4 compiles that to an invalid value the browser throws away - so the cap was not merely wrong, it was absent. The list then grew to fit all of its options, which also stopped the
overflow-y-autobeside it from ever engaging: measured on an iPhone with 21 options, the menu ran 221px below the fold, seven options sat off-screen, and the list could not be scrolled at all. Six more components carried the same mistake, including the chart legend, where it was killing the swatch colour. The same spelling in comments and docs was ALSO compiling into the stylesheet - v4 scans file text, so writing the broken form down was enough to ship it. - Menu and dropdown rows are now a real touch target. Options in the Foxl Code model pickers, and every row of a long-pressed context menu, were 32px tall - 12px under Apple's minimum - on the controls that choose which model runs your coding tasks and, on Repos rows, the only path to "View on GitHub" and "Copy clone URL". They are 44px on a touch device and unchanged with a mouse.
- The task header on a phone hid its own controls off the side of the screen. Open a task with a red build, or one with a pull request and an issue, and the header row grew past the viewport: Conversation/Terminal, the PR and Issue links, and the Cancel / Retry / Delete / Reset-session menu were all beyond the right edge, with nothing that could bring them back - so a phone could not cancel a running task, and Terminal, the only view of what the agent is actually doing, was unreachable on exactly the tasks you open in order to look at it. The row now scrolls sideways and reaches its end, the task's name no longer collapses to nothing to make room for status chips, and every control in it is 44px.
- Inbox rows can settle the thing they are about. A row that said a pull request was waiting on you offered only "Open PR", which moves the work to GitHub rather than doing it - you left, merged there, and came back to a row that still looked unresolved. A row for a PR the agent opened now carries Merge itself, using the same merge the Needs you queue and the Work page use, so the three surfaces cannot disagree about what merging does. It takes two presses, because merging writes to a default branch and this is a list you scroll and swipe through; the armed state relaxes after a few seconds. Rows whose event never carried a PR number keep the link rather than guessing which pull request to merge, and a repo you no longer have installed shows no button at all.
- Foxl Code pages start at the top of the screen. Every contained Code page (Work, Repos, Runtimes, Settings, Account) had up to 40px of empty space stacked on top of the header the shell already draws, so the title read as floating in the middle rather than beginning the page - most of a phone's first screen went to nothing. The gutter at the sides and the bottom home-indicator inset are unchanged, and so is every type size.
- The Repos header lines up with its own buttons. The title sat 4px low on a phone against the Sync and Connect buttons beside it, because a heading carries more leading than a 36px button and the row aligned their box tops instead of their centres.
- Repos does not lead with a paragraph about tokens. The GitHub-App design (a fresh repo-scoped token per task, no personal access tokens) was a bordered panel above the repo list, and before that a copy of the same text on every repo card. It is true and it never changes, which is exactly why it does not need restating on every visit ahead of the list the page exists for.
- Inbox puts "Read all" and "Clear all" on the title row. They sat on the filter row opposite the Needs-you / All toggle, which reads as though they apply to the filter you are looking at. They do not - both act on the whole feed - so they now sit with the page title, with Clear all last.
- The Needs you panel can be reopened on a narrow window. Its reopen control used to appear only above 768px, while dismissing the panel below that width was remembered across sessions - so a small window could lose it with no way back.
- Foxl Code has an Inbox: one screen for every repo. Work has always been per-repo by construction - it needs a repo selected and refuses without one, because the GitHub token it borrows is scoped to exactly that repo - so "what needs me right now" could only be asked one repo at a time, by changing the picker and re-reading three lists. Inbox answers it once, across all of them: every PR waiting on you, red build, budget warning and hard-capped agent, each row naming its repo, with a Needs-you filter separating the things stuck on a person from the things that merely happened. It opens on the sidebar next to Work, and old
/activitylinks land here now - that URL used to go to Runtimes, which only lists agents that are still running and so could never show you anything that had already finished. It also costs nothing to load: the history was already on the server, so the page reads it back rather than asking GitHub again, which is what makes it safe to open on a phone on cellular. If a push notification arrives while the app is closed, the event is here when you open it. - The Settings list has its icons back. They were removed on the reasoning that fifteen glyphs in a narrow rail competed with the labels for the same glance; in use the rail reads as a list of places, and the leading glyph is how a row is found without reading it - which is also what the phone's grouped list does, so keeping them means the two sizes agree instead of differing by breakpoint. One thing the removal had noticed is kept: General and Web Access were sharing the same globe, so two rows could not be told apart by their icon. Web Access has its own now.
- The Notes screen on a phone drops two controls that were not controls. The word "Notes" at the top sat inside a filled grey pill, because the header's Notes / Background / Report tab row is desktop-only in its other two entries - leaving the phone a "tab bar" of exactly one tab, whose selected state was advertising a choice you could never move. It is plain text now, like every other page name on a phone. The house icon next to Search is gone from that screen too: it clears the selection and returns to Notes, all of which the home screen already is, so tapping it did nothing while holding one of four slots in the row your thumb reaches first. It stays for an open note, where it is the way back. Two things that were quietly broken behind that tab came out with it - tapping "Notes" on an open sample note now really opens the editor instead of re-showing the report, and "Add context for better AI" opens a Background screen (with a Back button) instead of being a tap with no effect at all.
- Foxl Code's sidebar highlights one thing at a time. Opening a task lit up both the task and the "Tasks" heading above it, so the sidebar showed two selections and neither one told you where you were. Now picking a task moves the highlight onto that task and the heading steps back - the same way Foxl Agent has always behaved when you open a conversation under Chat. Clicking "Tasks" still takes you back to the new-task screen and takes the highlight with it.
- The "1" on Chat now tells you WHICH chat. When a reply landed in a conversation you were not looking at, the sidebar's Chat row put a number on itself and stopped there - so you knew something had finished but not what, and the only way to find it was to open chats one at a time until the number dropped. The conversation that got the reply now carries a dot of its own, in the empty gutter at the left of its row, and clicking it clears both. The count and the dots are the same underlying set read two ways, so they cannot disagree. Also fixed alongside it: replies produced by finishing background agents never marked anything unread at all - the one kind of completion you could not have witnessed was the one that left no trace - and deleting or archiving an unread chat left its marker behind forever, counting toward a badge with no row left to click.
- The empty chat on a phone is the suggestions, centered, and nothing else. It opened with three lines of text nobody asked for above the part you actually tap: a headline ("Ready to dive back in?"), a label announcing the cards underneath it ("Try asking something like:"), and a legal notice, with the whole stack pinned to the top and a screen's worth of blank space below it. The headline was the worst of them - it was written by the model on every open, so the largest text in the product was a different sentence each time and none of them told you anything; the desktop had already stopped generating one for that exact reason. All three are gone, the cards now sit in the middle of the free space between the buttons and the composer, and they line up with the composer's edges instead of being inset further than everything else. The AI disclosure moved to Account, where it stays put - on the zero state it vanished the moment you typed, which is the whole conversation it was describing.
- The Settings sheet's close button is now a glass button you can actually see. It already carried the shared glass chip recipe - byte-for-byte the same blur, tint, rim and shadow as the round buttons in the chat header - and was still effectively invisible: measured on an iPhone 15 Pro viewport it stood 2.5 luminance levels off the panel behind it, where Apple's own round system button stands about 25. The reason is that glass is defined by what it refracts, and this one sits on the sheet's own near-flat surface, so there was nothing behind it to lens; the chat buttons look right because on iOS they are swapped for a real system material, which a control inside a sheet cannot use. It now has a recipe meant for a button sitting on a surface rather than floating over the page, keeping the same shape, rim and depth while taking its fill from the text colour, so it reads in both light and dark mode - 22.7 and 28.8 levels measured - and deepens instead of fading when pressed.
- The Foxl Code message bar sits where Foxl Agent's does, and its two pickers read as two controls. Three separate things on that one bar. The card sat lower than Agent's because Agent's composer pays the home-indicator inset (
max(1rem, safe-area)) and Code's paid a flat 16px - so on a phone that reserves 34px, Code's bar was inside the system gesture strip. The model name was clipped to "So..." whenever a long repo was selected, because the two pickers competed for width as equals while the repo trigger's name refuses to shrink: measured at 393px with a long repository name selected, the repo control took 209px of a 359px row and left the model 30px for text that needs 59. And the repo name did not merely clip - it painted 52px outside its own button, over the control next to it. Now the model name never pays first, it falls back to a labelled icon (keeping its name in the tooltip) only when the row is genuinely too narrow for any two names, and each picker sits on its own surface so the eye can tell where one ends and the next begins. - A Foxl Code task on a phone says its name once, at the top. The header showed the section word "Tasks" and the strip below it repeated the task's own name, so the first 104px of the screen spent a full row on a word that never changes and squeezed the status, the Conversation/Terminal switch and the task menu into a 48px band under it - where the status chip was already truncating to "T..". The task name moved up into the header at the header's own size and the strip keeps just the controls. Desktop is unchanged: there the two rows read as breadcrumb-then-controls and there is width for both.
- Connecting GitHub from the iPhone app no longer dead-ends. Pressing Connect took the app itself to the sign-in handshake, which meant leaving the app with no address bar and no back button - and because the app does not share Safari's session, most people landed on a GitHub login screen they could not get past or escape from, which read as "Connect goes to code.foxl.ai and nothing happens". It now opens in the system browser, the way signing in to Foxl already did, so your existing GitHub session is there and the app is still behind you when you finish.
- The repo you are working in is no longer abbreviated away. The repo button clipped from the right, which is the half that names the repo - so several repos in one organization all showed as the same truncated string, and the control could not answer the only question it exists to answer. It now keeps the repo name whole and gives up the organization prefix first, and the list you pick from shows full names instead of trimming them too.
- Repos you use most are at the top. The picker was alphabetical, so a repo you had not touched in a year outranked the one you were in five minutes ago. Recently used ones now sort first, under their own short "Recent" group, and the rest stay alphabetical for when you are hunting a name. If you lose access to the selected repo, Foxl falls back to your most recent one rather than to whatever sorts first in the alphabet.
- Less chrome above the thing you came for on mobile. Work opened with a decorative icon over the word "Workspace" - the name of the sidebar group it sits in - above the title "Work", and Repos opened with "Connections" above "Repos"; both then repeated the page name a second time in the header bar. Those are gone, and Work's refresh button sits beside its title instead of across the screen in the corner. The last row of every Code page also clears the iPhone's home-indicator strip now, instead of sitting underneath it.
- The GitHub App installation row shows the GitHub mark. Small enough to be worth checking: at the sizes used inline the outline glyph reads better, so the filled Octocat is used only in the one slot large enough for it to be recognizable.
- A dialog on a phone could be taller than the phone. The Schedules window measured 904px inside a 659px screen and was centred on its own height, so it hung off the top AND the bottom at once: "Create Schedule" sat above the top edge, Cancel and Create below the bottom one, and nothing inside was scrollable - so the form could be filled in but neither identified nor submitted, at any scroll position. Every dialog in all three products now caps its height against the visible viewport and scrolls its own overflow. 26 of the 33 dialogs in the app passed no height limit of their own, so this was a property of the shared component rather than of that one window.
- Foxl Code printed the page name three times. On a phone, Work showed "Work" in the app header, "WORKSPACE" as an all-caps eyebrow, and "Work" again as the page's own heading - so half the first screenful restated where you already were. Repos and Runtimes did the same. The Agent side had solved this a while ago and the Code pages were simply not on the list; they are now, they share one header component instead of three hand-rolled copies, and the eyebrow is desktop-only where there is room for it.
- Sections on a phone sat further apart than they should have. Schedules and Agents were spending desktop-sized padding between groups on a 393px column, and the hero's buttons had their own line - which put them between a heading and its own subtitle and read as a floating toolbar over an empty half-row. The buttons now sit on the heading's line where the heading's own size does the separating, and the padding is trimmed for the narrow column. Counters move below the summary line on a phone rather than competing with the title and the buttons for the same 393px.
- Workspace told you to select a file when there were no files. The empty workspace showed "Select a file to view and edit" - and on a phone the file list is the whole screen when nothing is open, so the only thing on screen was an instruction you could not follow. It says what is actually true now.
- One line in Settings was tighter than the app's own readability floor. The "model does not support task budgets" note was set at 1.43 line-height where prose requires 1.5.
- The Foxl Code chat scrolls on a phone. Its transcript could not be dragged through history on a touch screen - and on desktop it was fine, which is why it survived. The two chats had grown two different transcripts: Foxl Agent's chat owns its scroller and stops auto-following the moment you scroll UP, whichever way you scrolled; Foxl Code's went through a stick-to-bottom library where a finger cannot get out of "keep pinned to the newest message" while a reply is streaming - one of its two escape hatches needs a mouse wheel, and the other is switched off on exactly the frames where the answer is growing. So the view was dragged back to the bottom on every reflow and history was unreachable. Foxl Code now renders the same transcript component as Foxl Agent - one implementation, not two that look alike - so scrolling, following the stream, releasing at the bottom, and the keyboard behave identically in both products. A regression test drives a real touch drag through both chats so this cannot come back.
- The two chats are now the same chat. Beyond the transcript, the message bubbles, the tool-call rows, the image viewer and the composer were each two near-identical copies, and the copy that got a fix was not always the copy the product rendered - which is how the scroll bug survived in the first place. They are one implementation each now. Two fixes crossed over as a result: Foxl Code's Stop button works on a phone (iOS drops the click when the same tap dismisses the keyboard, so it needs the touch path Foxl Agent already had), and a Foxl Code reply containing an html, svg or mermaid block now previews it instead of printing the source. Foxl Agent keeps everything it had, including the live streamed output of an exec tool and the auto-expanded row when a coding agent starts - both of which came the other way, from Foxl Code.
- Opening Foxl Code on a phone no longer throws the keyboard up. Every time you opened Code it put the cursor in the chat box, so iOS raised the keyboard over half the screen before you had decided to type anything - on the screen you came to read, with no gesture to dismiss it other than tapping away. Foxl Agent's composer has skipped that on touch devices since the mobile pass; the Code composer was forked before that landed and kept taking focus on arrival, on every thread switch, and again each time a reply finished. It now waits for you to tap it, which is also the gesture iOS honours most reliably. Desktop is unchanged - the cursor is still in the box when the page opens, so you can start typing immediately. An iPad was affected twice over, because iPadOS Safari reports a desktop Mac browser string and fell through to the desktop path; it is now detected by its touchscreen.
- Foxl Code's Save button follows you down the settings page again. Almost everything on that screen - instant spawn, auto-merge and its options, the autonomous loop and its whole sub-tree, the budget fields, custom instructions, the MCP connectors - is held locally until you press Save, and the button had been moved into the normal flow of a page that is about eleven hundred pixels tall on a phone. So you would flip a switch near the top, the confirmation would be several screens below, and a flipped switch that has not been saved looks exactly like one that has. It is pinned to the bottom of the page again, on every screen size, without the two problems that got it unpinned: it no longer stretches past the page's margins (which had left its top edge stopping short on wide windows) and it no longer adds its own gap above the home indicator on top of the one the settings sheet already adds. The notification switches on the same page still save the moment you tap them - those go to a different service and never needed the button.
- The round glass buttons on iPhone are real glass again. The circular controls at the top of the screen have been drawing themselves in CSS since v0.5.8 instead of using the actual iOS material, which is why they stopped looking like the rest of the system. It was not a performance decision and nothing was turned off on purpose: a build change made to fix an unrelated CI failure left the app asking for the native glass plugin by a name the web view cannot resolve, so the request failed every single time and the app quietly used its fallback. That fallback is meant to exist - it is what an older iPhone or the web app gets - so a broken plugin and an absent one looked identical from the outside, which is how this survived two releases. The build now ships the plugin properly, and a test reads the built app and fails if the bad name ever comes back, because this is not a bug you can see by looking at the screen.
Accessibility
- Asking for less transparency now turns the frosted surfaces off. The app had no handling for this at all: chips, the message bar and every sheet stayed see-through with a live blur behind them, which is precisely what those settings exist to prevent. They now switch to a solid surface, keeping their shape, border and shadow so a control over a plain white page is still visible as a control - which is what iOS itself does, measured on Apple's own round buttons. On iPhone and iPad the trigger is Increase Contrast rather than Reduce Transparency, because Safari does not report the latter to a web page; the controls drawn by the real iOS material already respond to both on their own.
- Settings' Logs and Activity pages had no margins at all. Both rendered flush against the divider that separates them from the section list, while every other page in Settings sat in a proper column - so clicking down the list made the text's left edge jump from a wide indent to nothing and back. They now use the same column as the other full-width pages in Settings (Usage, Mobile/Web), which also means the log console and the event list finally scroll on a narrow window instead of being cut off below the fold. Opening an event from Activity no longer shifts the text sideways either.
Changes
- Settings > Diagnostics > Activity is gone. It was a flat, reverse-chronological table of raw agent events -
tool_start,tool_end,thinking- behind a time-range picker, and stripped of which run had asked for them those rows were data rather than an answer. The same events are still recorded and still readable where they mean something: the Agents page groups them by session with each run's status, and opening an agent replays them as a transcript beside the messages that caused them. The endpoint that only this pane called (GET /api/agent-events, which it polled every 5 seconds while open, itself a contributor to the log flood below) is removed with it; the per-session endpoints are untouched. Diagnostics is now Logs and Advanced. - Settings' section list is ordered by what you actually open. Model & provider leads instead of General: every expired sign-in, API key and reasoning setting lives there, whereas appearance and language are set once and never revisited. General moves to the end of App, Usage leads Connect (it is a dashboard you read, not a setting you change), and Foxl Code comes before Foxl Notes.
- The three pages you only open when something is wrong now have their own group. Activity, Logs and Advanced moved out of App into a Diagnostics group at the bottom, so the everyday preferences are not padded by three pages you hope never to need.
- Settings' section list has no icons. Fifteen small glyphs down a narrow column competed with the words for the same glance, and two of them were the same glyph (General and Web Access both showed a globe), so they were not even a reliable way to tell rows apart. The list reads as a list of names now. The phone's Settings keeps its icons, where the rows are tall and the icon is what you aim at.
- "Chats" in Settings is now called "Trash." The pane restores chats you deleted, but "Chats" sitting in a settings list - in an app whose sidebar is already a list of chats - read as "your chats" rather than "the ones you deleted". Every language already used its own word for Trash in the notice that links here, so the two now agree.
- Settings on code.foxl.ai now only offers the settings that host can change. That site serves the Foxl Code product, but its Settings screen was the whole super-app's: the desktop agent's model and provider, Heartbeat, tool approval, deleted-chat restore, Integrations, Mobile/Web, Advanced, and the entire Foxl Notes screen were all listed, none of which configure anything reachable from there. The list was not even stable - it was the short version only while your desktop app was closed, so signing in from a machine running Foxl made nine more screens appear, on the same site, for the same account. Settings there is now Code, Account and General: the product, plus the two screens that genuinely apply everywhere (sign-in and plan; appearance, language and About). Nothing was removed from app.foxl.ai or the desktop and mobile apps, which is where the other products live. The three Foxl Code notification switches stay on Code's own screen, so they are still one click away.
- A settings link on code.foxl.ai now opens the screen it names.
/settings/accountthere opened the Code screen instead: the address was read correctly and then discarded, so no Settings screen on that host could be linked, bookmarked, or reloaded back to. The phone layout already got this right, so the same address meant two different things depending on the window size. - Opening a settings link on code.foxl.ai from a phone no longer puts the chat screen behind it. On a phone Settings slides up over the page you were on, and that page keeps showing through and is where closing it returns you. Opening a settings address directly - from a link or a bookmark, with no previous page to go back to - put Foxl Agent's chat home back there, which that site does not serve, so the sheet showed through onto the wrong product and closing it landed there. It now falls back to Tasks.
- The Settings button now says what it does. On the phone, Settings opens as a sheet with one round control in its header, and that control was a back arrow in both of its states - including at the top-level section list, where there is no previous screen to go back to and the only thing left to do is close the sheet. It is an X there now, and stays a chevron while you are drilled into a section, which is the one place it really does pop a level.
- That button is made of the same glass as the rest of the app. It carried its own private copy of the liquid-glass recipe rather than the shared one, so it was a thinner, flatter material than every other round chip - and it silently missed the tier that only phones get (a stronger frost, on the reasoning that the iOS web view renders it fully), plus the automatic de-frost while the keyboard or the drawer is animating. It now uses the shared recipe, so it matches the composer and header chips and picks up all of that by construction.
- "Usage today" on For You loads quickly, and says so while it loads. The card shows three numbers, and it was fetching them from the endpoint that builds the whole Overview dashboard - about fifteen SQLite aggregations plus process and OS telemetry, on a driver that blocks the server while it runs. Measured on a real 57 MB database, the work the card actually needed took 0.06 ms and the work it threw away took 19.2 ms. Two things were wrong underneath: the two heaviest queries group tool history by name, and the query planner chose to walk the whole table rather than seek the 24 hours asked for - which matters because those rows carry entire tool payloads, 7.5 KB on average and up to 2 MB each. Both now seek a covering index (340x faster, same results, with tie-breaking pinned so equal counts no longer reshuffle between polls), and the card reads a small endpoint of its own that returns 68 bytes instead of 758. Separately, whenever a refresh does take a moment, a small spinner now appears beside the card's title: the card used to display last-known numbers with no sign it was working, because the only progress indicator was gated on having nothing to show at all. It waits 400 ms before appearing, so a fast refresh no longer flickers.
- For You names itself, on every screen size. The page had no title of its own, so a status line ("All caught up") was the largest text on it, and on a phone the page name appeared nowhere at all - the shell header hides its copy on narrow screens for pages that print their own heading, and this was the one page in that list that never did. The title is now in the page, beside the sidebar toggle, with the status line reading as supporting text next to it.
- "All caught up" is capitalized like the heading it is. It read "all caught up" in English and five other locales.
- Quieter empty states in the For You inbox. The "No items yet" panel led with a decorative AI sparkle that repeated nothing the heading did not already say, and the empty Inbox and Archive views each drew the same icon as the tab the user had just clicked. All three are text-only now.
Features
- Foxl Code tells you when it is waiting on you. It could already say a pull request had opened and that one had merged, and nothing in between - so the states where the work is actually stuck on you were the ones that never reached your phone. A PR that is green and approved but not merged (the common case, since auto-merge is off by default), a merge attempt that was refused and now needs a person, a red build, and a reviewer asking for changes all send a notification now, each naming the repo and PR and opening straight onto the diff. Each thing notifies once, not once per webhook, and a merged PR stops asking - so this adds the notifications you were missing without adding noise.
- Foxl Code tells you when it files an issue. The autonomous loop could survey a repo overnight, decide on a dozen things worth doing, and file them - and the only surface that ever learned about it was a browser tab you had left open. Nothing was wrong with push delivery (a registered iPhone and a successful send were both on record); there was simply no sender for that event, so an issue arriving was an event with no notification attached to it. Now filing one pushes to your phone with the issue title and the one-line reason the loop picked it, so the decision is reviewable from a lock screen instead of only from a tab. It is a category of its own rather than part of "task results": that one fires when work you started finishes, this one when the loop chooses what to start, and folding them together would mean giving up merge notifications to quiet backlog chatter. Only the loop's own issues notify - an issue you asked for in chat is one you are already watching.
- Notification settings inside Foxl Code's own settings. The three Code categories - issues it files, questions it stops to ask, and task results - now have switches in Code's settings, next to the model and budget defaults they belong with, and they save the moment you flip them. They are the same preferences as the ones in the app's Notifications screen (one store, so the two can never disagree); this is just the place people look first. The card also states how many devices are registered for push, because with none registered every switch is correct and nothing can arrive - which is indistinguishable from a category being turned off, and is what made the missing notification hard to see in the first place.
- A long paste now stays where you put it in the sentence. Pasting something big into the composer turns it into an attachment card, and until now that card always went to the top of the message - so a prompt like "compare this log against this config" ended up as both pastes stacked above the sentence, with nothing saying which was which. The paste now leaves a marker at your cursor, right where you pasted (
[#1 server.log, 240 lines]), and you keep typing around it. When the message is sent, each paste is placed at its own marker, so the model reads it exactly where you meant it - and the sent message reads back the same way instead of front-loading every attachment. The card above the composer stays, numbered to match: click it to highlight its marker in your draft, click the marker and the card opens. Removing the card removes its marker, and if you delete a marker by hand the card says "not placed" rather than quietly looking the same as a positioned one - it is still sent, just without a position. Short pastes are untouched; they go straight into the text as always. - A pasted attachment could be silently dropped when sending from a phone. On mobile the composer only reports what you have typed when the field loses focus, and tapping send does not do that - so a message with both typed text and a pasted attachment took a code path that sent the raw text and never attached the paste. The attachment stayed visible in the composer the whole time, so there was nothing to notice: the model just never saw the pasted content. Both are now always sent together.
- The sidebar no longer casts a curtain of light under the conversation list. The chat and task lists in the sidebar are capped in height and fade at the bottom to show there is more below. That fade was painted on as a band of solid sidebar colour - but the sidebar is not solid: on the desktop app it is glass, and the wallpaper behind it supplies about a quarter of every pixel. So the band was painting the un-tinted colour over a surface the desktop had already darkened, and what came out was a bright wedge fanning up from the bottom edge, most obvious over a dark background. The fade now dims the rows themselves instead of covering them, so whatever is behind the list - glass, wallpaper, a solid panel - comes through untouched, in light mode and dark. It also measures the list rather than counting rows, so scrolling to the end clears the fade instead of leaving it to dissolve the last conversation you were looking at.
- A long paste now stays where you put it in the sentence. Pasting something big into the composer turns it into an attachment card, and until now that card always went to the top of the message - so a prompt like "compare this log against this config" ended up as both pastes stacked above the sentence, with nothing saying which was which. The paste now leaves a marker at your cursor, right where you pasted (
[#1 server.log, 240 lines]), and you keep typing around it. When the message is sent, each paste is placed at its own marker, so the model reads it exactly where you meant it - and the sent message reads back the same way instead of front-loading every attachment. The card above the composer stays, numbered to match: click it to highlight its marker in your draft, click the marker and the card opens. Removing the card removes its marker, and if you delete a marker by hand the card says "not placed" rather than quietly looking the same as a positioned one - it is still sent, just without a position. Short pastes are untouched; they go straight into the text as always.
Improvements
- The phone got its own shape. Corners on mobile came from two unrelated places:
--radius(8px) generated only the small/medium/large steps, whilerounded-xl/2xl/3xlwere Tailwind's own defaults, so half the scale could not move with the other half. One screen could show 6px, 8px, 12px, 16px and 28px corners at once, and the Settings sheet nested all five inside each other. There is now a single four-role scale - sheet, card, panel, chip - that steps up on a phone (28/20/14/10px) and stays exactly where it was on desktop (20/12/10/8px), so nested corners follow the rule that an inner radius is the outer one minus the gap between them. Desktop is pixel-identical. - Bottom sheets are one component again. Settings, the model picker, conversation search, notifications, the Notes AI panel and the Schedules filters were five different sheets: 28px all round, 28px on top only, 16px on top only, and - for notifications - an opaque square panel running edge to edge, with two grabber opacities and three ways to dismiss. They now share the inset, radius, frosted surface and grabber, and differ only in what they list.
- Dialogs are no longer square on a phone. The shared dialog carried
sm:rounded-lg, which does not apply below 640px, so the Notes onboarding, the EULA and Connect-desktop all rendered with hard square corners on iOS. Fixed for every dialog in all three products. - The chat home screen reads as one design. The suggestions under the greeting were hairline-divided rows with the smallest radius in the app, sitting between a heavily rounded composer and two circular chips. They are now cards in the composer's own shape, and message bubbles follow it too.
- Tasks is a phone screen, not a squeezed table. A five-column table on a 393px display gave a third of the width to the ID column and left two selects fighting over the rest. It is now a card per task, with sort controls that the phone previously had no access to at all (they lived in the table header).
- Everything you tap on a phone is now at least 44px, in all three products. Measured rather than eyeballed, and the results were worse than they looked: in the sidebar EVERY row was under the floor (nav rows 40px, the product switcher and the logo/Home button 24px, the account row 32px, New chat 28px), the chat composer's controls were 32-36px, and Notes' header controls were 28px. Buttons, inputs and selects now carry the floor in the SHARED components, so Agent, Code and Notes inherit it instead of each page fixing its own. Desktop keeps its denser sizes - a cursor is precise, a thumb is not.
- Typing in Foxl Code no longer zooms the whole app. Its composer was 14px, and below 16px iOS zooms the page when a field takes focus - so starting a task on a phone left you pinching back out to read the reply. The Agent composer has been 16px for this reason since the mobile pass; Code never got it. Its composer also ran under the iOS home indicator, where the send button was.
- Fewer rules, bigger targets. Pages built on the shared hero drew a divider and then their own, stacking three or four hairlines down a narrow screen, and the header repeated the page's own heading right above it. Both are gone on mobile. Header chips were five different sizes across five places (28/36/40/44px) - the agent view's back button was the smallest tap target in the app and its header was 12px shorter than the bar it replaces - and are now uniformly 44px. The Notes recording pill sat under the iOS home indicator; it now clears it.
Fixes
- A stopped server now restarts itself, and a failed restart says why. When the desktop app lost its local server it put up a panel with a Restart button and then waited - forever, if nobody was at the machine, which for a 24/7 agent is most of the time. Pressing that button often looked like it did nothing, and there were three separate reasons for it. The app was fighting itself: stopping the server made its own crash-watcher think the server had died, so the crash-watcher started one copy while the restart started another, and in a real log one press produced start, stop, start again - occasionally killing the healthy server it had just brought up. The button also could not tell you how it went, because it reported success the moment it had *scheduled* a start rather than when the server actually answered. And if the old server was somehow still holding the port, the new one quietly moved to a different port and reported itself healthy while the app kept talking to the old one, so the panel could never clear. All three are fixed: one restart owner instead of two racing ones, a result that means the server really is up, and a pinned port that fails loudly instead of relocating. The panel now retries by itself - three times, spaced further apart each time - tells you which attempt it is on, and if it still cannot recover it says what went wrong (the server never reported ready, exited on startup, or could not be launched) instead of re-enabling the button in silence.
- Foxl Code's message bar sits at the bottom of the chat again. Opening a task put the input bar directly underneath the message bubble, floating in the middle of the screen, instead of docked at the bottom the way Foxl Agent and every other chat in the product do. A task seeds its transcript with the prompt that started it, rendered as a real message bubble, and the "centered greeting" empty state was being applied to that bubble - so the two stacked in the middle of an empty canvas. Centering is now only for the new-chat greeting, and only on desktop, both of which is what Foxl Agent already did. The transcript also measures the composer now instead of assuming one line of text, so a long draft or a pasted block no longer covers the message you are replying to.
- The Work tab paints instantly on return instead of showing four skeletons. Issues and pull requests are cached per repo and refreshed behind the rows you are already looking at, so leaving the page and coming back no longer costs a full reload. The 20-second auto-refresh now pauses while the tab is in the background and catches up when you come back to it - a tab left open was refreshing 180 times an hour for nobody. Server-side, one request now mints one GitHub token instead of three, cutting six round-trips to four.
- Foxl Code looks for its own work by default. Foxl has been able to survey a repo it has worked in, open a GitHub issue for something worth doing, and start an agent on it - but the switch was off unless you found it in Settings, so for most people the loop simply went quiet whenever the queue emptied. It is on for new accounts now. It only ever surveys a repo you have already run work in, on a 6-hour cadence, stops while its own issues are unread, and stays out of anything risky (no dependency major versions, migrations, auth or billing changes). If you had already turned it off, it stays off. The composer also no longer promises to "draft an issue" when what it actually does is open a pull request.
- A notification that arrives on your phone now stays in the app. Every push the relay sends on its own - a task finishing, a question, a Notes transcript, and the new issue-filed one - arrived as a banner and left no trace: miss the banner, open Foxl, and the Notification Center said "Nothing here". The only thing writing to it on the phone was a frame relayed from your desktop, so it needed your Mac awake to record anything at all. Pushes that arrive while the app is open are now filed like any other notification, with the same Open button pointing where the banner would have taken you. (A push that arrives while Foxl is closed is still the OS's to hold - tapping it opens the right screen, as before.)
- Foxl Code's settings no longer collapse into one line of text when its server is unreachable. A response that arrived without a body - which is what a missed route looks like, since both hosts answer unmatched paths with the app shell and a 200 - was read as if the settings were present, and the resulting error took the whole pane down: no cards, no switches, no save button, just a sentence. It now says what happened and keeps the notification switches usable, since those come from a different service and have nothing to do with whether Code's server answered.
- The save bar at the bottom of Code's settings is no longer a floating strip. It was pinned to the bottom of the window with a full-bleed border sized for one specific layout, so on the other two it stopped short at both ends and read as something pasted over the page - and on iOS it added a second home-indicator inset on top of the one the settings sheet already applies, leaving a dead band under the button. The action now sits in its own panel and scrolls with the rest of the page, the way every other settings control in the app does. It is also disabled until something actually changes, instead of permanently offering to save a page nobody had touched.
Features
- Notifications you can actually read on your phone. Every notification the app raised on iOS or the web went into the store and bumped the home-screen badge, and then had nowhere to be read: the notification bell only ever existed in the macOS titlebar and the Windows header, and the phone has neither. The badge could say 12 with no way to see what the 12 were. There is now a Notification Center on those builds, opened from the account row at the bottom of the sidebar - which carries the unread count, so the badge has somewhere to lead. Rows swipe the way they do in Mail: left to delete, right to mark read, and right again to mark it back to unread, because a one-way gesture turns "keep this for later" into a trap. Inbox and Archive are both there (archiving has existed in the app for months with no button on the phone to reach it), items group under Today / Yesterday / Earlier, and the gear in the corner goes straight to your push settings. The desktop bell is unchanged.
- code.foxl.ai is now the same app as app.foxl.ai, so signing in with a password works there too. Foxl Code had its own separate front-end. Only the page bodies were shared with the main app; everything around them - the sidebar, the chat surface, the header, the sign-in screen - was a second copy, and the two drifted apart in small ways that were hard to name but easy to feel: nav items in a different order, a chat that looked subtly unlike the one in the app, and a sign-in page that only ever offered GitHub, Google, Apple, and a magic link. Setting a password in Settings did nothing for code.foxl.ai, because that page had no field to type it into. The second front-end is gone. code.foxl.ai now serves the app itself, opened directly into Foxl Code, so the password option (and anything else that lands on the sign-in page in future) is simply there. Everything you had keeps working: the same links (
/tasks,/repos, and links to individual tasks), the same GitHub connection, the same sign-in session, and older links like/filesand/activitystill resolve. The ONLY difference from app.foxl.ai is that the Agent/Notes product switcher is not in the sidebar, since this host serves one product; every other screen is the same code. - Staging pages now say they are staging. The yellow "this is not production" bar existed on stg.code.foxl.ai but never on stg.app.foxl.ai, which was indistinguishable from the real thing. Both show it now, naming the host you are actually on.
- Foxl Code has a Work tab: every open issue and pull request in one place, with the two buttons that close the loop. Foxl Code could run agents and open pull requests, but the work going IN (an open issue) and the work coming OUT (a pull request waiting on you) were only visible on github.com - so the story that begins "your agent works while you sleep" ended with you opening a browser at both ends, and the state that actually matters ("three of these are green and waiting on me, two issues have nobody on them") was not shown anywhere. Work lists the repo's open issues, its open pull requests, and what recently merged, each row joined with what Foxl knows about it: which agent is on it, whether the build passed, whether the reviewer approved. Open issues is the tab you land on, because that is the work that still needs a person. On any issue nobody has picked up, Solve puts an agent on it in one press - the issue text is re-read from GitHub at that moment rather than trusted from the page, the agent gets its own branch, and a comment goes on the issue so anyone reading it on github.com can see work started. An issue that already has an agent shows that agent instead of a second Solve button, so one issue never gets two competing pull requests.
- You can now see what changed and merge it, from the phone, without opening GitHub. Every pull request row has a diff view - per file, per line, additions and deletions - and a Merge button. A merge notification used to be a dead end: it said "PR merged" with no indication of what moved, and tapping it did nothing but bring the app to the front on whatever screen you left it. Notifications now carry the shape of the change ("acme/web #41 - +42 -8 across 3 files"), which is often the whole answer, and tapping one opens that pull request's diff with Merge next to it. None of that costs an extra request: the numbers were already in the GitHub event Foxl receives and were simply being discarded.
- Auto-merge, off by default and on your terms. The default is unchanged and is the recommendation: you read the pull request and press Merge. Turn auto-merge on (Settings -> Auto-merge) and a pull request lands by itself, but only when BOTH gates pass - the build reports green AND the reviewer agent approved it. Neither one alone merges anything, and your own branch protection still applies on top. Both gates are checked against the exact commit that would be merged, not just as a yes/no: a build that went green on an earlier commit does not count for a later one, so a push landing mid-decision cannot slip in ungraded - the pull request simply says the green build was for an older commit and waits for the new one. A pull request whose required checks have not all reported is treated as not ready rather than merged-and-refused. When GitHub does refuse a merge (a conflict, a check Foxl cannot see) that is recorded and shown on the row rather than retried in a loop, and every pull request that looks green but has not merged says which gate it is still waiting on - so the setting can never look silently broken. Merges are logged with whether a person or the loop decided, because GitHub reports the same bot account for both and only that record can tell you afterwards. In a shared organisation install, any member can retry a merge that was refused and every member sees the same reason it was refused.
- Approve a pull request and an adversarial reviewer decides whether it merges - yours, a teammate's, or one Foxl never touched. Approving is the cheapest thing you can do on GitHub and reading a diff properly is one of the most expensive, so this splits them: you press Approve to say "I want this in", and a reviewer that has actually read the change decides whether it goes in, comments either way, and merges when it agrees. Two things had to be built for that, because neither existed. Nothing in Foxl was listening for an approval at all - the GitHub event that fires when you submit a review reached no code in the product, so pressing Approve on github.com did precisely nothing here. And the reviewer could only ever see Foxl's own work: it gave up immediately on any branch its agents had not created, then required a matching Foxl task, so a pull request a person pushed by hand failed both tests and there was nowhere to even record that it had been reviewed. Both are fixed, which is what makes this work on a repo where people and agents commit side by side. Your approval is treated as a request, not as the verdict - the reviewer is told, in as many words, that an existing approval is not evidence the code is correct and that it must not defer to one, because a reviewer that agreed with every approval would be theatre and here a passing verdict can merge. If it finds the change does not do what the pull request claims, it says so and refuses to merge. A verdict has to name the commit it read, and the merge is pinned to that commit: pushing while a review runs blocks the merge instead of landing a commit nobody graded, and a verdict that names no commit at all is refused rather than trusted, because a missing answer is not a passing one. A draft, a conflict, a required check that has not reported yet, or a mergeability answer GitHub has not finished computing each stop it with a comment saying which - "no conflicts" and "the checks passed" are different questions and both get asked. Nothing here can block a merge you could otherwise do by hand: every refusal leaves the pull request open and yours, and your branch protection still applies on top of all of it. Off by default in two separate switches (Settings -> Review on approval): reviewing on approval spends a model call whenever anyone approves, and merging on the reviewer's verdict writes to your default branch, and wanting the first without the second is a reasonable place to stop.
- Foxl Code can now find its own work instead of going quiet when yours runs out. The autonomous loop only ever advanced work you had already queued, and the way it was woken made that a hard limit rather than a design choice: it looked for users with a task in flight or a plan in progress, so the moment the last agent landed and the last plan completed, it stopped being woken at all. Not idle - gone. It could not notice a build that went red an hour later, a dependency drifting behind, or an unfinished follow-up from its own pull request, because nothing was running to notice with. The tool for filing an issue had been there since the first release and no unattended run had ever called it; every issue in the repo came from someone asking in chat. There is now a third way to be woken: with your queue empty, the loop surveys the repo on a slower schedule of its own, and when it finds something worth doing it opens a GitHub issue explaining what and why, then starts an agent for it. An issue is the unit deliberately - it is reviewable, closable, and visible to someone who never opens the app, which silent work is not. It is off until you turn it on, under Settings -> Autonomous loop, because unlike the rest of the loop this one chooses work rather than doing what you asked. It stops surveying while it already has its own issues open, so closing them is what invites it to look again; it stays out of anything risky (no dependency major versions, migrations, auth or billing changes, no deleting features - it can describe those in an issue but will not start them); and finding nothing worth doing is a normal outcome that files nothing, since a made-up task is the one result that would make this worse than silence.
- The window glass now settles back when Foxl is not the app you are using. A real material goes quiet when its window is not in front, and that behaviour is a large part of what makes the window read as a pane of glass rather than a panel with a tint on it. It was not happening: nothing in the app was watching the window's focus, and the two places that could have done it for free are both dead ends - at the tint that keeps the sidebar legible the material only owns about a quarter of the pixel, so macOS dimming what it owns is barely perceptible, and on macOS older than 26 the glass fallback pins itself active, which switches the system behaviour off outright. Switching away now drains the key hue out of the canvas, sidebar and titlebar over the same 420ms the app already uses when it finishes launching, and switching back restores it. The transparency itself does not change, which is deliberate: that is what holds the measured contrast floor for small sidebar labels over a dark wallpaper, so the colour moves and the alpha does not - which is also what the system does, since an inactive macOS window goes flat, not dark. The content card is untouched.
- Your chat history stays readable when the desktop is offline. On the web app and the phone, the conversation list and every transcript came from your desktop over the relay, so the moment it went to sleep the whole history disappeared: an empty sidebar and a chat that would not open. Conversations you have opened are now kept on the device, encrypted, and are what you see in that grey state - the list, the full transcript, search and copy all work. The saved copy is read-only, and says so in place of the message box: replying needs the desktop, because it is the desktop that holds your files and tools, and answering without them would be a different assistant pretending to be the same one. The offline copy is not kept on our servers - it is a copy of your own data, on your own device.
- What is kept on the device is kept per person, and encrypted. Only conversations you actually opened are saved (there is no background download of everything), and attachments are never copied - the text is kept and the file is named. Deleting or archiving a chat, or renaming it, reaches the saved copy too, so a chat you threw away does not stay readable offline.
- Foxl Code can stop and ask you something, and you can answer from a locked phone. The loop had only one way to raise a question that survived being unread: a plan parked for confirmation, which is the rarest path it takes. Everything it actually needs to ask about day to day - two repos match the name you gave, this step will force-push, the change is bigger than one pull request - came out as a sentence in a reply, and a sentence in a reply is seen by an open tab and by nothing else. Phone locked and laptop shut, the run simply stopped, nobody was told, and the loop stopped looking at you at all, so it could not even wait properly. Questions are now kept as real, durable items: they reach you as a notification you can type the answer straight into, without unlocking anything or opening the app, and a matching banner on the desktop. The loop picks the answer up on its next pass and carries on from where it stopped. If nothing can reach you the question waits in the app instead of being lost, and if it goes unanswered for a week it lapses rather than waiting forever - lapsing is never read as "you approved". These notifications are opt-out under Settings -> Notifications, next to the other Foxl Code ones.
Changes
- Activity and Logs moved into Settings; For You is now just the feed. The For You page had three tabs across the top - For You, Activities, Logs - all sharing one URL. Activity (the agent event log) and Logs (the server console) are things you read when something looks wrong, not every day, so they now live in Settings next to the rest of what you inspect, each with its own row and its own deep link. For You keeps its place in the sidebar and drops the tab bar, so the sidebar entry and the page are finally the same thing. Nothing was removed: both views are the same code they always were, and the command palette finds them by name ("logs", "events", "agent log") instead of dropping you on Advanced.
Fixes
- A file path an agent was given could point outside its own workspace, and one tenant's agent could write into another tenant's files. Every file an agent reads or writes goes through one containment check, and that check trusted a shortcut: it resolved the part of the path that already existed and then re-attached the rest by arithmetic. A symbolic link - a pointer from one path to another - broke the arithmetic, and a link pointing at a file that does not exist YET broke it in the worst direction, reporting a path outside the workspace as inside it. Anything then written landed wherever the link pointed. This did not need a tool call to set up: a link committed in a repository arrives with an ordinary
git clone, so simply asking an agent to work on a repo was enough to plant one. Reproduced on Linux at the real layout: six of eight planted links produced a write outside the workspace, two of them into another user's SSH keys and npm credentials. The check no longer takes shortcuts - it walks the path one name at a time from the workspace root, resolves every link it meets before deciding anything, and refuses on any error rather than guessing. Ordinary symbolic links inside a workspace keep working, because repositories legitimately contain them. Also fixed: the test that was supposed to catch this passed on macOS and failed on Linux for reasons peculiar to macOS temp directories, and it had never run in CI at all - it now runs on Linux on every pull request. - Foxl Code's request for a decision could never reach you. The agent gained the ability to stop and ask a question in the previous change, and the server-side list of calls a running agent is allowed to make was tightened in this one - but the new question call was not on the list, so every attempt would have been refused. Nothing would have been shown: the agent receives a plain error and carries on, so a question would simply never arrive. It is on the list now, for asking only - answering stays with you.
- On staging, pressing Connect sent you to the production site. The GitHub connection flow worked out which address to return to from a setting that is only present on one of the two paths through it; on the other path it fell back to the production address, spelled out in the code. From staging that meant landing on the real site, which could not make sense of a staging request, with no way back. It now reads the address of whichever site you are actually on.
- On the phone and the web app, the Notification Center was always empty. Every notification the desktop raises - a schedule finishing, an agent completing or failing, a heartbeat result, a feed item - reached the desktop and stopped there. The relay knew how to pass those on and the phone knew how to display them, but the desktop never put them on the wire: the part of it that feeds the relay forwarded only terminal events, so nothing was ever sent. The result was a notifications screen that could only ever say "Nothing here", and a home-screen badge with nothing behind it, on exactly the devices that have no other place to read a notification. The desktop now forwards them, so they arrive on app.foxl.ai and on iPhone as they happen, land in the Notification Center to be read later, and count toward the badge. This is also what finally makes the "Schedules" push toggle do something - a 6am job can now reach a phone in a pocket instead of notifying a Mac nobody is sitting at. Muting a type in Settings still silences its banner and still keeps the entry readable, exactly as on the desktop, and the desktop's own notifications are unchanged.
- Foxl Code pages other than Tasks no longer fail to open. On the old code.foxl.ai, /runtimes threw
useTaskSelection must be used inside a TaskSelectionProviderand rendered nothing - the old front-end supplied that provider only around its Tasks routes, while Runtimes (and the task plan panel and command palette) all need it. Serving the main app fixes it structurally: there, one provider wraps every Code page. - Staging talked to the production relay. Every automatic staging deploy built the app without telling it which relay to use, and the only rule it had left was "this is a production build, so use the production relay" - which is true of a staging build too. So the staging versions of both the app and Foxl Code were signing in against real accounts and spending real credits, when the entire point of staging is that it cannot touch any of that. Staging pages now recognise themselves by their own address and use the staging relay, so this holds however the site is deployed rather than only when someone remembers to pass the setting. The desktop and iOS apps are unaffected and still use production.
- A failed GitHub connection said nothing at all. After connecting the GitHub App, GitHub sends you back to Foxl Code with the outcome attached to the address - either "connected" or the specific reason it did not work (you are not a member of that organization, the request expired, and so on). Foxl Code was dropping that part of the address before any page could read it, so a connection that failed looked exactly like one that had never been attempted: no message, no reason, nothing to act on. The result is read again, so a success confirms itself and a failure tells you what went wrong. The address is tidied afterwards, so reloading the page does not show a stale message.
- The Work tab opened Tasks instead. Foxl Code's short web addresses are spelled out one per page, and Work - added at the same time - had no entry, so code.foxl.ai/work quietly fell back to the Tasks page. Links to Work, including the one in a merge notification, land on Work. Adding a Foxl Code page without its address is now a build error rather than something that only shows up when someone follows the link.
- Foxl Code no longer shows an error screen when it cannot reach its server. Tasks, Repos, and the task plan panel each read a list from the server and used it without checking one had arrived, so a reply that carried no list took the whole page down with "Something went wrong" - two error boxes at once, in the sidebar and the main pane. It reads as a broken product when the honest answer is "nothing to show yet". Those screens now render their normal empty state.
- The web app could only be built on one particular machine. It depends on the iOS-only glass plugin, which lives outside this project and is found by counting directories upwards - so it resolved on the laptop it was written on and nowhere else, failing the build outright anywhere the folder layout differed, including on the build servers. The plugin is now declared as something supplied at runtime rather than compiled in, which is what the code already assumed: both places that use it load it on demand behind an "are we on a real device" check and fall back to the CSS glass when it is not there. On the web that fallback is the intended path, and on iOS the real plugin is still loaded. A second cause of the same symptom is fixed too: two shared internal libraries listed none of the packages they actually use, and had been getting away with it because whatever happened to be installed nearby satisfied them. On a clean install nothing did, and the build stopped on a missing package. Both now declare what they need.
- Refreshing mid-reply showed a dead "..." and could prefix the answer with it. While a reply was being generated the app saved a placeholder "..." into the chat as the assistant's actual text, because the draft is created as soon as the model starts thinking or uses a tool, before it has written anything. Reloading the page then read that placeholder back as a real answer: the animated typing indicator was replaced by three dots that never moved, and when the reply resumed it was appended to them, so the finished answer began "...". The draft now starts empty, and chats already saved with the placeholder are corrected when they load.
- A refresh could leave a reply that was still being written looking finished. Reattaching to a reply in progress happens over a single request made as the page loads, and if that request failed - which it does when the app is reloaded faster than its local server can answer - nothing tried again. The reply kept being written but the window never showed another word of it until it was reloaded by hand. It now retries while the server comes up.
- A connection that died without saying so was never noticed. After the machine slept, or wifi dropped, both ends could be left holding a connection that looks open and carries nothing. The app went on believing it was connected and stayed silent. Connections are now checked, so a dead one is closed and reconnected.
- The app stopped trying to reconnect in several situations. Reconnection was attempted only when a connection closed cleanly, at a fixed two-second interval that never gave up, and a page navigation could leave old attempts running that fought with the new ones. It now backs off when the server is genuinely down, reconnects immediately when the app is brought back to the foreground or the network returns, and no longer leaves stale attempts behind.
- Conversation search sorted by date, so the result you meant was rarely at the top. Searching ordered matches by last activity, which meant a conversation actually titled what you typed lost to any chat that merely mentioned the word more recently. Results are now ranked by how well they match - a title match first, then how many of your words were found, then how often - with recency only deciding between comparable matches. Ranking happens before results are paginated, so scrolling for more keeps the order intact.
- Search results now show when each conversation was last active. The desktop titlebar dropdown showed no date at all. Both search surfaces now show one at the right edge, which matters more than before: results are ordered by relevance, so position no longer tells you how recent a match is.
- On the web and mobile app, search ignored conversation titles entirely. It only looked inside messages, so a conversation whose title was exactly what you typed did not appear, and the "Titles" filter was permanently empty there. Multi-word queries also only matched when the words were adjacent, while the desktop app found them apart. Both now behave the same way in every shell.
- The match count beside a search result counted words, not messages. A single line containing "relay timeout" showed "2" - one per word - implying two places to look when there was one. It now counts the messages the query actually hit.
- Retrying a coding task carried the failed attempt's changes into the new pull request. A retry deliberately reuses the original run's machine so the checked-out code and installed packages do not have to be fetched again, but nothing reset the code back to the branch being worked from. The retry therefore began on top of the attempt that had just failed, and the pull request it opened contained that attempt's commits as well as its own. A retry now starts from the current state of the target branch, which also means it picks up anything merged in the meantime, while still reusing the installed packages that made reuse worthwhile. All four coding backends were affected.
- Signing out now clears your data from the browser, not just your tokens. Sign-out had five separate implementations across Foxl, Notes and Code and none of them shared a cleanup step, so on a shared computer the next person to sign in inherited the previous person's chat history, notification text, meeting recordings, saved workspace paths, profile photo, the tools they had permanently approved for the agent, and their own Anthropic API key - which was still usable. Every sign-out route now runs one teardown, and signing in as a different person clears what the previous one left behind before anything is shown. Device settings you would not expect to lose - theme, language, panel sizes - are deliberately kept.
- Regenerate and Edit no longer appear on a transcript you cannot reply to. They were still offered on a deleted chat and on an offline saved copy, where pressing them either failed or would have quietly continued the conversation somewhere it did not belong.
- Deleting or renaming a chat while the desktop is asleep no longer looks like it worked. The web app was answering its own delete, rename and archive requests as successes when there was nothing to send them to, so a row would leave the sidebar or a title would change and then come back on the next sync - and "Delete all chats" in that state cleared the copies saved on your device while leaving every chat on the desktop untouched. Those actions now say the desktop is needed instead of pretending.
Improvements
- The typing dots actually move now. They previously only dimmed in place, which read as a flicker rather than as progress. They now rise and swell in sequence as a single wave. The travel is removed for anyone who has asked their system to reduce motion, and the dots stay visible.
- Foxl Code starts coding the moment you ask. Asking for a code change used to get you a question back - "I'll start an agent in your repo. OK?" - and only after you answered did anything begin. Every task cost a round-trip before the first agent existed. Now a coding request turns into running agents in the same reply: Foxl tells you what it started instead of asking permission, and several agents fan out at once when the work splits into separate pull requests. It only stops to ask when it genuinely cannot proceed - no repo selected, a target that does not exist, or work that is hard to undo. Details it can settle by reading your repo (which file, your naming conventions, how your tests run) are the agent's job to find, not a reason to interrupt you.
- Wide work still shows its cost first. A request that splits into more pull requests than your per-turn allowance (three by default) publishes a plan with an estimated cost and one approval button, so a large refactor never starts spending before you have seen the number. Both the switch and the allowance live in Settings under "Instant spawn"; turning it off restores approving every task.
- A starting agent looks like one. A spawning agent used to render as a collapsed grey line labelled with an internal tool name, and its result as raw JSON. It now shows the task it is working on, opens as soon as it appears, and every agent in a fan-out lands in your task list immediately instead of waiting on the next refresh.
Fixes
- A billing hole let frontier models be charged at the cheapest model's rate. Model names are normalised before use, so a request could name a model with a harmless-looking suffix, pass the plan check on the real model, be served that model, and then be priced by a lookup that fell back to matching any cheaper name inside the string. Measured against the live price table, Fable 5 output could bill at 1/83rd of its rate. Billing now always uses the model the request actually resolved to, the guessing fallback in the price lookup is gone, and a model with no price row bills at the highest rate rather than a mid-range one.
- Windows updates were installed without checking who signed them. The updater does verify signatures, but only when it is told which publisher to expect - and it was not, so the check silently passed on every Windows update. Now configured, so an installer that is not ours is refused. macOS was never affected: the operating system verifies our notarized signature there regardless.
- A page you visited could read the desktop app's local access key. The app's local server checked which sites may READ its responses, which browsers enforce, but never checked which address the request claimed to be for. A site pointing its own domain at your machine therefore looked same-origin to the browser and could fetch the page that carries the key - and with it the whole local API. The server now refuses requests that do not arrive as localhost.
- A coding-agent task could reach every repository the Foxl app was installed on. Each task was given a GitHub token covering the whole installation, and that token sits in the environment of a shell running with permissions checks disabled, on a repository whose contents are not ours. Anything that could influence the agent could therefore have pushed to any of those repositories. Each task now gets a token for its own repository only; GitHub refuses everything else at its end. Verified against live GitHub: with the scope, write access to the other repositories returns 403 and 404.
- The credential given to a coding-agent task could act as your whole account. Foxl Code hands each task a short-lived token so it can call the model. That token was also accepted by every other signed-in endpoint, so anything that could influence the agent - a crafted prompt, or content in the repository it was working on - could have read the account, changed its password, unpaired the desktop, or deleted the account outright. The token is now restricted to the model endpoints and refused everywhere else. Verified against a running relay in both directions.
- Any web page you visited could take control of your browser through Foxl. The desktop app listens on a local port for the Foxl Chrome extension, and that one path accepted connections without any check. WebSocket connections are not covered by the browser's usual cross-site protections, so a page in another tab could connect and switch on the tool that drives your real, logged-in Chrome - navigating, clicking and typing as you. The path now only accepts connections that genuinely come from a browser extension, which a web page cannot pretend to be. Verified against a running server: a page origin is now refused, the extension still connects.
- The incident kill switch did not stop two of three background jobs. Turning the service off stopped every interactive request but left the per-minute job that mints GitHub tokens running, along with the one that can cancel in-flight tasks. The switch is now checked once where the jobs are launched, so it covers all of them, including any added later.
- A Google OAuth client secret had been committed to the repository since May and was still accepted by Google when checked. Nothing used it. Removed, with the file pattern blocked so it cannot return.
- On iPhone, the "answering" spinner sat on top of the chat title in the sidebar. The spinner overlaps by design and is normally moved out of the way by hovering, which touch cannot do. The title now leaves room for it, and only while a reply is actually arriving.
Features
- Read a deleted chat before deciding to restore it. Clicking a chat in the deleted list now opens it in the normal chat view, rendered by the same components as any other conversation, with the composer replaced by a line saying the chat is deleted and where to restore it. Reading does not restore: browsing four deleted chats to find the right one leaves all four deleted. The list itself is a card with its own scroll and paging, so a long list can no longer push the controls below it off the screen.
- Restore a chat you deleted. Deleting a chat has always kept it for seven days before removing it for good, but nothing in the app could see into that window, so a chat deleted by mistake was gone as far as you could tell. Settings now has a Chats section listing what you deleted, how many days each has left, and a Restore button. You can also delete one permanently right away, or empty the whole list, instead of waiting the week out. The recovery endpoints had in fact been written some time ago and never worked: the listing was registered after the route that fetches a single chat by id, so the web server read the word "trash" as a chat id and always answered "Conversation not found". The feature was unreachable rather than missing. One thing restore does not bring back, and the panel says so plainly: the entries your chat left in the memory log. Those are removed the moment you delete, which is the point of the next item.
Fixes
- Deleting a chat now also removes what you said from the memory log, immediately. Alongside the database, Foxl keeps a day-by-day memory file containing your actual turns - your words and the reply, verbatim - and reads it back as context on later turns. Nothing connected those entries to the chat they came from, so deleting a chat could never remove them: they stayed on disk and kept being read back. Each entry now records which conversation it belongs to, and deleting a chat strips its entries out at once rather than at the end of the seven-day window, because the memory log is not part of what restore brings back and there is no reason to keep it waiting. Entries written before this change carry no such marker, so they cannot be attributed to a chat and are left alone. What you deliberately asked Foxl to remember - its identity, your notes, your topics - is never touched by any of this.
- The deleted-chat notice ran past the transcript on both sides, because it had no width of its own inside a bar that spans the window. It now sits in the same column as the message box, narrower and quieter, and "Settings > Chats" in it is a link that opens that pane instead of an instruction to go find it. Checked at desktop, iPhone 17 Pro and iPhone SE widths.
- A deleted chat appeared in the sidebar and stayed there. Opening a deleted chat to read it added it to the sidebar's chat list, so it looked un-deleted: the row survived clicking through to other conversations and only disappeared after a reload. Reading a chat from the trash no longer touches the sidebar. Clicking a different chat also left
?deleted=1on the address bar, which would have sent a later reload of that URL down the trash path for a live conversation; the address now updates properly. - The Foxl logo had a brown eye on two screens. The mark is duplicated as inline SVG in two places that cannot load an asset file - the page shown after signing in with Google, Apple or GitHub on desktop and mobile, and the screen Foxl shows if it fails to start. Both had the eye recoloured from blue to brown in v0.5.1 and it shipped in every release since. Restored to the canonical blue, taken from the logo file itself rather than retyped, and a test now compares every inline copy against that one source.
- "Signed in. AWS credentials are ready." was shown even when they were refused. Signing in with AWS SSO proves who you are; it does not grant access to an account. The two come apart routinely, and when they did the app showed a green success message next to its own "No access" error in the same panel, then failed the next chat with a permission error that looked unrelated. The success message now appears only when credentials actually work, and when they do not you get the real reason.
- Being told to request access you already have. When an SSO sign-in turns out to grant no accounts at all, Foxl now checks whether another profile on your machine works and names it, instead of only advising you to ask an administrator. On the machine where this was reported two profiles for the very same AWS account were working the whole time.
- The AWS settings panel took 13 seconds to load. Diagnosing the sign-in problem above meant asking AWS what your credentials can reach, and the first version did that one profile at a time, on every refresh of the panel. Those checks now run together and their results are cached, bringing the panel back to well under a second.
- Deleting a chat did not delete what you said in it. Nine tables hold pieces of a conversation and only one of them was set up to clean itself out, so removing a chat removed the chat and left the rest on disk - including a table that stores the text of the instructions you gave, word for word. On this machine that was 342 leftover rows from chats that had been deleted, some months ago, still holding their prompts. That is not what deletion should mean. Deletion now clears every table that belongs to the conversation, both delete paths go through the same code so they cannot disagree about what "deleted" means, and rows left behind by earlier deletes are swept up automatically. Memory needed care rather than a blanket wipe. The memory store holds two different kinds of thing: what you asked the agent to remember across sessions - its name, your project notes, your channel settings - and leftover run-state entries from a feature that no longer exists, whose entry NAME was your prompt. Only the second kind is removed. Your actual memories are untouched.
- Chat errors were being replaced with a guess, and the guess sent people to the billing page for problems money cannot fix. Any failure whose text contained "403" was rewritten as "This model is not included in your current plan. Upgrade in Account." A Pro user signed in to their own AWS account hit that, and on that path a 403 is almost never about a Foxl plan - it is an expired sign-in, a role without permission to call the model, or a model not enabled in that region. All three are fixable in a minute by the person reading the message, and all three were replaced with an upsell. Errors now keep the original text and add a hint above it, so you can read, search, or paste what actually happened. AWS failures get AWS advice.
- The app said "SSO session expired" while the session was valid for another fifty minutes. The check that looks for a live AWS sign-in was written with a call that does not exist in this part of the codebase, so it failed every single time - and because the failure was caught and treated as "no session found", the app confidently reported the opposite of the truth. You signed in, the browser confirmed it, and Foxl told you that you had not. Two more places had the same mistake: the system report crashed for anyone with an audit log, and a tool-caching helper would have crashed the first time it was used. A check now runs on every build so this class cannot return.
- The app now tells you which AWS accounts you can actually use, instead of letting you pick one that was never going to work. A profile in your AWS config is a request, not a permission: it names an account and a role, and the account grants that separately. Foxl was asking you to choose a profile and finding out the hard way, several layers later, that the choice was refused - and then blaming your Foxl plan for it. It now asks AWS the same question the AWS CLI asks: which accounts and roles are assigned to you. Profiles you cannot use are marked, and if the answer is none at all, it says so plainly rather than leaving you to guess why everything fails. That last case is what actually happened: a valid sign-in with zero account assignments.
- A profile that had been deleted from your AWS config was still being used. If you picked a profile months ago and later replaced your AWS setup, Foxl kept using the old name - which resolves to nothing, so it also ignored credentials that WERE working. It now notices the profile is gone, says so, and falls back to your default credentials instead of dead-ending.
- "Ready" no longer means "we found a token somewhere". Signing in to AWS proves who you are; it does not prove the account has granted you the role. Foxl was reporting ready in that case and letting every request fail downstream. It now tries to actually obtain credentials and, when the account refuses, says that the role is not assigned to you rather than blaming your plan.
Fixes
- On the phone, swiping a chat to rename or delete it kept closing the sidebar instead. Two leftward swipes shared the same screen: one closes the sidebar, one reveals Rename and Delete on a chat row. The closing gesture listened everywhere and triggered after a shorter drag than a row needs, so it won every time and the row actions were effectively unreachable. Closing now only works when the swipe starts on the covered content next to the sidebar, which is where you would reach anyway to push it back. Swipes that begin on the sidebar itself belong to the sidebar.
- Bring your own Bedrock key was impossible to set up, so users kept paying us instead of AWS. The "SSO Login" button in Settings had never worked: it posted to an address on the local server that was never built, so the request failed, the code checked a field that was not there, and the error was thrown away. The spinner flashed and nothing happened - no message, nothing to act on. A user reported that pressing SSO login did nothing, and that their requests were running on Foxl's account instead of their own. They were right, and a broken bring-your-own-key path bills us for inference someone was trying to pay for themselves. The sign-in now actually runs, opens your browser, waits for you to finish, and tells you what went wrong when it does not - a missing AWS CLI, a profile that is not an SSO profile, or a sign-in you did not complete in time. The same screen was also lying to them. It showed "Ready" beside AWS Bedrock whenever an SSO profile merely existed in the AWS config file, which says nothing about whether you are signed in: the config entry is written once, while the actual credential is a token that expires every few hours. On this machine that meant 25 cached files, of which 14 were not credentials at all and 11 were expired, all reading as "Ready". It now checks for a live session and, when there is not one, says the session expired and points at the button that fixes it.
- The privacy policy now explains how content sent to hosted models is handled. The version published that morning stated that conversations, notes and code "are not used to train Foxl or any provider model". The account is configured for provider data sharing, in both regions, since June. It was enabled because one of the models we offer requires it - but the setting applies to the whole account, not to that one model, so it covers every request to a hosted model regardless of which you pick. The page now says: Foxl trains nothing, and content sent to a hosted model may be shared with that model's provider under their terms. Anyone who would rather it were not can use their own provider key, which bypasses our account entirely.
- Stored passwords now use the full recommended hashing strength. A code comment said the platform capped password hashing at 100,000 rounds and that nothing stronger was available, so that is what shipped. The cap is per call, not per password: chaining six calls reaches the 600,000 the current security guidance asks for, and costs 68 milliseconds. Every new password now uses the full strength, and any password set before this is upgraded automatically the next time you sign in, with no interruption. This only matters if our database were ever stolen, which is exactly the scenario the number exists for.
- The record of failed sign-in attempts could be turned back into a list of email addresses. Attempts are counted against a scrambled form of the address rather than the account, so that guessing at an address that has no account behaves identically to guessing at one that does - otherwise eight attempts would reveal who has an account. The scrambling used a plain hash, which for something as predictable as an email address is barely scrambling at all: forty-nine guesses recovered a real address in a millisecond. It is now scrambled with a server-side key, so the record cannot be read back by anyone who does not already hold that key.
- The same password could be rejected depending on which keyboard typed it. Accented characters have two valid encodings, and the two produce different hashes. Someone could set a password on one device and be unable to sign in on another, with no explanation available to them or to us. Both are now treated as the same password.
- Deleting your account left your email preferences behind. Two tables that key on your account - your email subscription settings and the record of marketing mail sent to you - were not in the deletion list. They are now. The unsubscribe suppression list is deliberately kept, so a deleted and recreated address does not start receiving mail it had opted out of.
- A free user could pick a model their plan cannot run, and be told nothing. Locked models were greyed out and genuinely unclickable, so tapping Opus 5 did precisely nothing - no explanation, no way forward, at the exact moment someone has decided they want the paid thing. They now open a short prompt naming the model and offering to show the plans. Every locked row also carried the same sentence, "Upgrade to Pro to use Opus", so GPT-5.6 Sol and Fable 5 both claimed to be Opus; each row now names itself. Worse, a free account could be SITTING on Opus 5 with every message failing: the check that snaps your selection back to something available only asked whether the model still exists, not whether your plan can run it. It now checks both and falls back to the best model your plan includes - and it waits until it knows which plan you are on before deciding, because running that check while your account was still loading would have quietly demoted a Pro user's Opus choice to Sonnet and remembered it.
- Asking for help was a dead end on the screen where things break. The inline error in chat offered only a dismiss X, while the crash screen and the Settings row each had their own differently-styled Discord link. There is now one support affordance, with the real Discord mark, in all three places - and on the phone it opens in the system browser instead of a login wall inside the app.
- Dialogs no longer fly in from the top-left corner. EULA, License, GitHub, Discord and Docs all threw their panel diagonally across half the screen on open, which matched nothing else in the product - sheets rise, the command palette scales in place, toasts settle upward. They now rise into position and settle.
- Two flaws in the password sign-in shipped hours earlier, found by auditing it rather than by a user hitting them. The lockout counter never decayed, so once an account had eight lifetime wrong guesses, every single later typo re-locked it for fifteen minutes, forever, with no way out but a successful sign-in the lock prevented. Failures now expire after thirty minutes, so a burst still locks and scattered typos never accumulate. And the lock was recorded against the account, which meant only real accounts could lock - so eight attempts told an attacker whether an address was registered, defeating the deliberately identical error message. It is now recorded against a one-way hash of the address, so an unknown address locks the same way and reveals nothing. Response times were also equalized for an account that exists without a password.
- Terms, Privacy and Refunds are back, and rewritten to be true. All three pages had been returning "not found" since mid-May, when the marketing site moved to a new framework and the routes were not carried across. Nothing pointed this out because the pages were still listed in the file we hand to search engines, and the only visible links were on the sign-in screen, in the app, and at the bottom of every documentation page - so the agreement every new user saw linked to pages that did not load, in all ten languages, and Apple requires a working privacy policy link inside the app. The old text was recovered rather than rewritten from scratch, then checked against what Foxl actually does, which turned up two statements that needed correcting: it said conversations are never kept on our servers (Foxl Code keeps them, because a coding task runs for hours and has to survive you closing the app) and that your own provider keys never reach our servers (they pass through to reach the provider; they are not stored). Both are corrected. The new pages describe each product separately, name the transcription service meeting audio is sent to, list every company involved in running the service, and say plainly that we do not sell your data, and do not train on your content. The in-app agreement also described Foxl as running entirely on your device; that is gone too.
- You can set a password now, if you want one. Sign-in was email links and Google, Apple or GitHub only. That is a good default, but it left no way to hand someone a credential they can type - which App Store review requires for the account they test with - and no second route in when email is slow or you are on a device without your inbox. A password is optional and additive: you set it in Settings once you are already signed in, so it can only ever be attached to an address you have already proven, and forgetting it needs no reset flow because the email link already does that job. Minimum twelve characters, a short memorable phrase rather than a short jumble. After eight wrong guesses password sign-in pauses for fifteen minutes while email links and connected accounts keep working, so someone guessing at your account cannot lock you out of it.
- The iOS app was carrying several things App Review would have stopped, one of which crashed it. Setting a profile picture, or attaching an image to a chat or note, opens the system file picker, and choosing "Take Photo" starts the camera - which iOS refuses to do without a stated reason, terminating the app instead. There was no camera reason string, so the first reviewer to set a profile picture would have watched Foxl quit. The app also shipped no privacy manifest, which Apple has required since May 2024 and which has to name the system features bundled libraries touch. Three purchase-shaped controls were present on the phone: a credit top-up card with three price buttons, an Upgrade button in the out-of-credits banner, and a checkout helper in the Notes client. All three were dead - they pointed at an endpoint the server does not have - so they did nothing, said nothing, and would have read as either a broken app or a purchase flow outside the App Store. Billing is now read-only on the phone with a single link out to the web, and the buttons that looked like purchases either manage an existing plan or are gone. The out-of-credits banner previously offered an Upgrade that silently failed for everyone, on every platform. On iPad, and on an iPhone held sideways, the notification settings disappeared entirely, so there was no way to turn any notification off. The AI disclosure sat in a line that is hidden on phones, so the iOS build shipped without one; it now appears in the empty chat where there is room for it. The end-user agreement described Foxl as running entirely on your device, which does not fit the web, phone, Notes, or Code experiences - it now describes what actually happens and points at the privacy policy. The iPhone app also offered a macOS installer as its main button, and a leftover shop image contradicted our answer that the in-app game has nothing to buy.
- Search engines were being told the wrong thing about nearly every URL we publish. Google Search Console reported 108 pages redirecting, 38 not found, and a page both blocked and indexed at once; tracing each bucket to its source turned up bugs rather than noise. Old versioned docs URLs all collapsed onto the generic docs hub even though 147 of them had an exact current equivalent, so a decision to reorganise the docs quietly discarded the reputation of every page it moved.
foxl.ai/llms-full.txthad grown to 359KB by concatenating the docs corpus with the blog corpus, and because it carried no directive it was fully indexable - including 220KB of blog prose we had deliberately marked as not-for-indexing, laundered into an indexable file.changelog.mdserved a 342KB copy of/changelogthe same way. Every one of the 41 markdown twins on the docs site was in the same state, and docs had no mechanism to set a response header at all, because a Next.js static export silently ignores header config. Requests for a page that does not exist were given a redirect first and a 404 second, so one dead address was counted twice. The error page itself answered 200./docs/desktopand/docs/referencewere listed in the sidebar but had no page, so 18 pages advertised a breadcrumb trail through a dead link.app.foxl.aiforbade crawling AND asked not to be indexed, which cannot work: a crawler that is turned away never reads the second request, so the address stayed in the index with nothing in it. Seven blog posts existed only behind a click and so were invisible to any crawler. All of it is fixed, and the checks that run on every build now fail when a sitemap advertises a page that no longer exists - the gap that let three deleted pages be recommended to Google for two months. - Broadcast notifications can now reach a large audience safely. Sending to everyone used to happen in a single request that opened one connection per phone, held every device in memory, and recorded nothing - so past a few hundred devices it would be cut off partway through with no way to tell where it stopped, and retrying would notify everyone who had already been reached a second time. A broadcast is now a job that advances in bounded batches, remembers its position, and resumes on its own if it is interrupted. Each phone is sent to at most once, even across a retry, because that is recorded before the send rather than after. A send in progress can also be cancelled, which matters because a notification cannot be taken back once delivered.
- The second half of the push fix: the app now actually receives its notification token. v0.5.4 corrected the notification environment, which let iOS issue a token for the first time - and then the app dropped it, because the native code that hands the token to the notification plugin was missing entirely. So no device ever finished registering and the server still had nobody to send to. Confirmed by watching the server while the app ran: it made every other call it should and never once asked to register the device. Registration failures are now reported too, so a signing problem can be told apart from someone simply declining notifications.
Fixes
- Going back also takes the sidebar back. Switching from Agent to Notes and then pressing Back returned the page you were on but left the sidebar showing Notes, so the app disagreed with itself about which product you were in. It only got that right for three specific pages; every other one - Workspace, Agents, Schedules, For You - was missed. The product a page belongs to is now derived from the navigation itself, so it cannot go stale, and the choice is saved too - previously a reload right after going back would silently put you back in the product you had just left. Opening Settings still leaves your product alone, since it sits over whichever one you were in.
- A schedule run shows one back arrow, and says which run you are looking at. On the Mac there were two identical back arrows side by side, because the window header already has one. The title now names the run instead of repeating where the back button goes.
- Schedules and agents now notify your phone, not just your desktop. A schedule set for 6am told the desktop it had finished and nothing else - the phone stayed silent, even though the Notifications screen has had a Schedules toggle since it shipped. The toggle was real but nothing ever read it: the desktop broadcasts one notification event for schedule runs, finished agents, heartbeat results and feed items, and that event was never forwarded to the phone. It is now, under the toggle you already had, and failures come through under the same one - a scheduled job that quietly fails is worse than one that tells you. Tapping opens the conversation it came from, in the app.
- Notification taps stay inside the app. Tapping a notification that pointed at a Foxl screen used to leave the app and open the same screen in Safari, as a separate signed-in copy. Links to genuinely external pages - the changelog, docs, pricing - still open in the browser, which is what they should do.
- Dark mode is no longer flat black. The page, cards and dialogs were all the same near-black value, so nothing had any depth and only borders separated a card from the canvas behind it - and it sat next to a sidebar that was already blue-grey, so the seam between them was visible. Dark surfaces now share one hue with a step for each layer: page, card, dialog. Pure black against near-white text is also tiring to read for long stretches, so the canvas is lifted slightly; measured contrast stays well inside the accessibility standard (18.1:1 for body text, 7.5:1 for secondary text). Applies to desktop, web, iOS and the Notes app.
- Launching no longer stalls on the boot screen and then shows the server-log page. A healthy launch could sit on the loading animation and hand you the diagnostics screen - server log, restart button, "restarts 0/3" - about seven seconds in, even though the server was up and answering the whole time. The boot screen polls until the server is healthy and then navigates to the app, but it also checked that the window was still showing the boot page, and that check read an empty address while the boot page was still being committed. An empty address is not "the user navigated away", it just means "not attached yet" - so the poll stopped for good, and the only thing left that could change the screen was the boot page's twelve-second escape hatch to the diagnostics view. Measured: the address usually commits in about 100ms but was seen taking 794ms on a cold first run, so this was an intermittent race that got worse the slower the machine. Versions before the boot screen existed could not hit it, because they waited for the server and then opened the app directly.
- Cmd+Shift+F in Foxl Notes no longer opens two search surfaces at once. The same bug was fixed for Chat previously, but the Notes branch was missed, so on the Mac desktop the recordings palette and the title-bar search dropdown both opened stacked on one keypress. Notes keeps the palette everywhere the title bar is not already showing a search field, which is web, iOS and Windows.
- "Open HUD" appears once in the Notes header, not twice. In a narrow window the action moved into the overflow menu but the standalone button stayed, so the same action was offered twice in one row.
- Screen readers announce the right thing when closing things in Notes. The buttons that close the meeting HUD window, the HUD's AI panel and the Notes settings page all announced "Close transcript", because they reused the transcript's label.
- The floating "Back to Notes" recording pill is translated. Its four strings were the last hardcoded English in Notes navigation, in an app that ships ten languages.
- Push notifications on iPhone can work at all now. Every TestFlight build so far, including the most recent one, was signed for the notification sandbox rather than for distribution, so iOS never issued the app a notification token and the server had nowhere to send anything. No push of any kind - a finished chat, a Code task, a Notes summary - has ever been able to reach a phone. Nothing in the build or upload process could reveal it: the build uploaded normally and Apple marked it valid, because that check looks at the app package rather than at whether notifications function. Three things had to be corrected: the notification environment was declared as sandbox, the project pinned the Release build to a development signing certificate, and the account had no distribution certificate at all. The shipped app is now verified to carry the production notification environment and a distribution signature before it is uploaded. This needs one real device to confirm end to end, since a simulator never issues a notification token.
Fixes
- The window can be made smaller. Its minimum was 800x600, but on a 14" Mac with Accessibility > Larger Text turned on the screen only leaves about 560px of height once the menu bar and Dock are accounted for - less than the minimum - so the window could not be shrunk to fit and its bottom edge, including the composer and send button, sat under the Dock with no way to reach it. The minimum is now 640x480.
- The app stops draining your battery while it sits idle. macOS listed Foxl under "using significant energy" even when Activity Monitor showed almost no CPU, because the conversation list's loading spinner animated forever whenever there were more chats to load - which, with a long list, is always. An endless animation makes the window recalculate its styles every single frame, and that steady per-frame work is exactly what macOS counts as energy. Measured on an idle window: 1196 style recalculations per 10 seconds before, 0 after, and main-thread busy time dropped from 9.6% to 0.0%. The spinner now only spins while a page is genuinely loading.
- Upgraded the agent SDK to 1.11.2, which includes an upstream fix (contributed from this project) so a failed model stream surfaces a real error instead of finishing as an empty successful answer. Context-limit failures from Bedrock Mantle are now classified correctly and trigger context reduction rather than a silent empty reply.
- The phone stops burning battery when the desktop is offline. Two status dots pulsed forever whenever the desktop tunnel was disconnected - which on a phone is the normal state - and an endless animation makes the screen recalculate every frame. They are static now; the colour already said what the motion was repeating. Measured on a real iPhone: one infinite animation before, zero after.
- The Foxl mark on dark screens is a soft grey rather than the near-white it briefly became, so it reads as a logo instead of the brightest thing on the screen.
- Onboarding no longer appears in the iOS app. It existed to explain the desktop agent and offer a download, neither of which applies once you are holding the app - sign-in is the first screen now. The web app still shows it, where the download matters.
- Onboarding buttons picked up the app's rounded shape.
- The sidebar collapse button moved up into the window titlebar, beside the traffic lights, and a back arrow took its place in the page header - each control now sits in the bar it acts on. The sidebar header also has more room around it, so the logo, product tabs and navigation read as three groups instead of one crowded block. On phones and the web app the sidebar button stays where it was: there is no titlebar to move it to, and the drawer is the primary navigation there.
- The desktop search bar is a command palette now. Alongside conversations it searches your pages, every Settings pane, and your workspace files, so "where is the notification setting" is one query instead of a hunt - picking a settings result opens that exact pane. The filter is a set of checkboxes (Titles, Messages, Workspace, Commands) rather than a single choice, so you can narrow to two sources at once.
- Search finds individual settings, not just the page they live on. Typing "only when in background" now returns "Notifications > Only when in background" and takes you straight there - 51 individual settings across 12 panes are searchable, each shown with the pane that contains it so you can see where it lives before you click. You can search a setting's explanation as well as its name, so "not focused" finds the same toggle. Every one of them is searchable in all 10 languages, because the index stores which setting it is rather than its English text.
- Cmd+Shift+F opened BOTH the titlebar search and the popup palette on the Mac desktop, stacking two search boxes for one keypress. The titlebar field owns the shortcut there now; web and iOS keep the popup, which is their only search surface.
- A crashed screen can now report itself: "Report on Discord" copies the error, the screen it happened on, and your build to the clipboard, then opens the Foxl Discord so there is something to paste. Nothing is uploaded automatically.
- The header's duplicate "search all conversations" button is gone on the Mac desktop, where the titlebar already holds a search field. It stays on web, Windows and mobile, and comes back if you switch the titlebar to the status HUD.
- The boot screen is just the Foxl mark and a progress line now - the wordmark under it was set in a display style that appears nowhere else in the app, so the first thing you saw looked like a different product than the one it opened into. The mark is also legible on a dark desktop now (it was a near-black shape that vanished into a dark wallpaper behind the glass, leaving only a small blue sliver).
Fixes
- Light / Dark / System in Settings works. Picking a theme did nothing on the desktop app - it always snapped back to whatever macOS was set to, so on a light Mac the app stayed white no matter what you chose. The theme preference now has a single owner instead of one copy per screen, so the choice sticks, survives leaving and reopening Settings, and "System" still follows the OS.
- The Foxl mark is visible in dark mode. It is a near-black shape, so on a dark background it measured 1.1-1.5:1 (3:1 is the minimum for a graphic) and all you could see was the small blue wedge floating in the dark. The sidebar, sign-in, onboarding and Settings now use a dark-surface version of the SAME artwork - identical shape, same blue, just a body light enough to see. This was always broken in dark mode; the Appearance fix above is what made it visible.
- Two unreadable labels in the Foxl Den (a "last seen" timestamp and the dismiss hint on a rare-critter reveal) were faded to 2.3-3.2:1 against their background, under the 4.5:1 minimum for small text. Both are full-strength now.
- The titlebar HUD's "streaming" label no longer uses the brand accent colour or all-caps: the accent is reserved for things you can click, and all-caps reads slower.
- Secondary text is legible everywhere, not just on white. The grey used for every hint and description was tuned against a white page, so on the tinted sidebar and on selected rows it fell under the readability minimum. It is now a shade darker, verified against every light surface it can land on.
- Small print in Settings is easier to read. Descriptions and helper notes were set at a line spacing meant for single-line labels, which made the ones that wrap to two or three lines hard to track. Settings, Notifications and the error screen now use proper body spacing.
- Toggles are easier to hit. Switches look the same but now have a full 44px touch target instead of 20px, and the sidebar's sign-in and account rows were under the minimum too.
Features
- The desktop window is real frosted glass now. On macOS 26+ the app's outer chrome - the canvas the sidebar sits on - is a native NSGlassEffectView, so your desktop shows through it the way it does in Outlook and Codex. The inner content card stays opaque, because that is what you read on. It degrades to exactly today's opaque window on Windows, Linux and older macOS.
- Starting the app shows you something. The packaged app used to wait up to 30 seconds for its local server with NO WINDOW ON SCREEN at all - a Dock bounce and then nothing. There is now a glass boot window from the first moment, which hands over to the app the instant the server answers, and offers the log/restart diagnostics if boot is genuinely stuck. Mobile and the web app got the same treatment for the gap before the bundle mounts.
- The glass firms up once the app is up. While loading it is genuinely see-through, because there is nothing to read yet; once real UI is on screen the surface steps up so small labels stay legible over any wallpaper.
- A key colour, and it is not blue-by-accident any more. Royal blue and gold, sampled from the plush Foxl artwork, with the surfaces carrying a pale blue-grey hint of the same hue on desktop AND on iOS. Every value was checked for contrast on every surface it can land on rather than picked by eye.
- Date dividers in the conversation list. Scrolling reveals a rounded date pill between the rows - Today, Yesterday, then dated days for the past week, then by month - and hovering keeps them up so they do not flicker. The space collapses when they hide, so a still list has no gaps. Phones keep the floating pill instead, since touch has no pointer to rest on the list.
- The date groups are now mutually exclusive. "Previous 30 days" and "June" could both be true for the same conversation, so which divider it appeared under depended on ordering rather than on its date.
- Appearance moved into Settings > General, and works everywhere. It had been placed inside an Electron-only block, so the theme switch did not exist at all on iOS or the web app - and its labels were showing as raw keys. Launch-at-login and the titlebar HUD are now under their own Desktop heading rather than filed under Updates.
- The sidebar has its own error boundary. The one that existed wrapped only the page content, so a crash in the sidebar unmounted the whole app and left a blank window with no error card - which is the failure that boundary exists to prevent.
- Search remembers what you opened. An empty search box now lists the conversations you last opened from it, newest first, instead of a line of instructions - kept on the device, since a recents list that followed you between machines would surface work you did somewhere else. There is also a filter for narrowing to title or message matches; it is limited to what the search endpoint can actually answer rather than pretending to more.
- The sidebar reads as navigation, not as a toolbar. The leading icons are gone from the nav rows - a label was already there, so the icon was decoration - while Settings and the account row keep theirs, because those are rows you hunt for rather than read. The collapsed icon rail is unaffected.
- One selection at a time. The Chat row and the open conversation were both highlighted, which read as two selections; Chat now defers to the conversation and is only highlighted when it IS the destination. The selected row also has a shade you can actually see - measured, the old one was 1.002:1 against the new sidebar surface, i.e. invisible, which is why font weight was doing all the work.
- The theme switch moved out of the sidebar footer into Settings > Appearance as three labelled choices. That footer slot is always visible, so it now holds New Chat - the frequent action - rather than a preference you set once.
- The titlebar search opens downward, like Outlook's. A real field - bigger type and a taller box - that expands on focus and unrolls its results beneath it, with arrow keys and Enter. The centred command palette stays exactly as it was, because the web app and iOS have no titlebar to put a field in and still need it; the header's search icon keeps opening that.
- One surface token, so nothing can mismatch. The sidebar, the reveal drawer and the swipeable chat rows all derive from the same value now. They did not before: the drawer and the rows painted
--background, which read as a white block sitting on a tinted sidebar in both light and dark. - The loading screen is translucent on a glass window instead of flat white, so the material is visible at the moment there is nothing else to look at.
- The titlebar centre is a search bar. That is the most-looked-at space in the window, and it was spending it on a status readout. The live agent HUD is now a setting; status itself moved next to the notification bell, so it is still one glance away.
Fixes
npm run devactually starts the app. It brought up the agent server but not the web server, so unless you separately remembered to run Vite the window opened on a blank page with a connection error.- Text that was too faint to read is readable. 75 labels were drawing
muted-foregroundat reduced opacity, which measures 1.96:1 to 3.23:1 against white - the floor for text under 18px is 4.5:1. De-emphasis now comes from size and weight, which is what it is for. - Things you have to click are big enough to click. Measured on the real rendered app, the desktop had 53 tap targets under 24px; the conversation delete button was a 16px square and the connection dot an 8px one. Now 2 remain and both are deliberate (a full-width row and the full-height sidebar drag rail).
- Raised 94 labels that were 9-10px to an 11px floor and 9 icon buttons from 20-24px to 28px. Pixel-art surfaces in the game are deliberately exempt.
- Dropped the "For You" group heading that sat directly above a nav item also called "For You", and stopped the mobile suggestions label shouting in all-caps.
- The game is a real game now: a home screen, a collection, and it saves to the server. It opens on HOME - who lives with you, what you hold, what to do next - and the summon becomes somewhere you go from there rather than the screen you land on. FOXLS is the collection: every character has a card, and the ones you have not met are still shown as silhouettes, because the gaps are the point.
- Nine plush-doll characters, each with its own pixel version. A patchwork ragdoll, a stitched fox, two bunnies, three cats, a puppy, a husky and a top-hat bear. Every one has a hand-drawn illustration for the summon and the collection card, plus a 16x16 pixel version OF THAT SAME DOLL for walking around the den - so the thing you pull is visibly the thing that moves in. Their names and lines are translated into all ten languages.
- Your collection survives losing your browser. The game used to live entirely in local storage, so clearing site data destroyed a collection built from weeks of real agent work, a new phone started from nothing, and a reinstall quietly re-granted the paid-plan gems. It now syncs to the server, and the merge is careful in the way that matters: what you have collected is unioned so nothing is ever lost, and currency is never added across devices, so owning two phones cannot mint gems.
- A pixel mini-game, where Quests used to be a dead tile. Your Foxls pop up one at a time and you tap them before they wander off - thirty seconds, no fail state. Catching them raises your bond with the ones you have neglected, which is the one thing in the game that cannot be bought or rushed. Only characters you have actually summoned appear.
- The den can tell you when someone wanders in. At most once a week, off by default, and only if you have actually played - tapping it opens the game. It is the second notification category you have to opt into, alongside promotions, because nobody asked for it.
- Nothing in the game is for sale, and both currencies are earned by working. Sparks come from your agents' tool calls, as before. Gems now come from your actual token usage - roughly one per 250,000 tokens, capped at a few a day - instead of arriving with a paid plan, and the shop is gone entirely. There is no way to buy either currency and no way to turn credits into pulls, in either direction. Home has a plain explainer that says so, and the pull odds are still published in-app.
- The den is a real room. An arched window with the moon behind it, a wooden floor in perspective, a rug, swaying lanterns, sakura - and everyone you have ever met wanders it at once, pausing and turning to face where they are going. Tap one to spend time with it; the bond it builds is the one thing in the game nothing can buy.
- The game no longer takes the Agents page away from you. Opening it used to unmount the real page, so anyone with agents running lost the list, the run bar and the live state - and got them rebuilt from scratch on the way out. It is a layer over the page now, and the page keeps running underneath.
- The game is off by default. It was on for everyone, which made it not an experiment: a game-controller chip sat in the header of a tool that bills real inference credits, with no way to have opted in. Turn it on in Settings > Experiments.
- "Promotions and tips" now actually does something, at most once a month. The toggle existed with nothing behind it. If - and only if - you have turned it on, you may now hear from us about the parts of Foxl you use, no more than once every 30 days, and never in your first week. Which message you get is based on counts and dates (your tier, when you joined, whether you use Notes or Code), not on the contents of your messages, transcripts or files. It remains the only notification category that is off until you ask for it.
- Foxl Notes tells you when the summary and the report are done, not just the transcript. Those two are the slowest things Notes does - they read the whole transcript - and they usually run unattended at the end of a recording, so they were the two most worth hearing about and the only ones that stayed silent. A summary you watched appear does not notify you; one that landed while you were elsewhere does.
Fixes
- The For You headline shows its number again, in every language. It was built by gluing a count in front of a translated fragment, which silently forces English word order on all ten locales - and Korean attaches its counter suffix to the numeral, so it came out as a bare "개 항목이 대기 중입니다" with no number in front of it at all. One of the strings was passed no count whatsoever, so even English read "items waiting for you". Every hero string is now a whole sentence that carries its own number.
- The sidebar drawer stops re-frosting the whole screen while it slides. A backdrop-filter re-samples its backdrop every frame, and the composer's frost was paying that for the entire 360ms of the reveal animation - the most expensive per-frame work there is in a web view, and the reason the drawer stuttered on a phone but looked fine in a simulator. It now mattes for the transition and re-frosts at settle, which is the same thing the keyboard dock has always done.
- The "..." menu opens in one continuous motion. Its liquid growth was measuring the panel with a method that returns the *scaled* box, while the panel was running its own scale animation - so the easing was applied twice over and the shape sat nearly still for the first 60ms before lurching. It now measures the untransformed size, and sends half as many messages to the native layer per frame.
- The game no longer draws over the Settings sheet. Both were at the same stacking level, so which won came down to which mounted last - and the game, being portaled, always did. It sits below anything you deliberately opened now.
- The portal glow is translucent, and its opacity control works at all. The pulse animation hardcoded its own opacity, and an animated property overrides the element's own - so every attempt to dim the portal was silently ignored (the markup said 0.14 while the browser computed 0.88). The peak now comes from a variable the caller sets.
- The collection screen is symmetric. The title ribbon was centred in the space left over beside the back button rather than on the screen, and the sort control was stealing width from the four rarity filters, which left the whole row sitting left of the grid beneath it.
- Two dead-end "it's quiet" screens are gone. An empty den now goes straight to the summon rather than showing a screen whose only content was a signpost - and which drew an animal that is no longer in the game. The summon's own empty state got a readable plate instead of thin text over the brightest part of the portal.
- The game opens on the first tap. Tapping the chip before the game had finished loading did nothing - and left it convinced the game was already open, so the next tap closed it again. The first tap now works whenever you make it.
- Escape, Android back, and the iOS edge swipe all leave the game. Previously the only way out was to find the small close button.
- The game clears the desktop title bar. Its top row - level, sparks, the close button - was drawn underneath the macOS title bar, where it could be neither read nor clicked.
- Sparks accumulate while you are looking at them. The loop that mints them skipped running whenever you were on the Agents page, handing off to a foreground loop that no longer existed - so the currency froze on precisely the screen that spends it.
- Presentations and documents show a real rendered page, not just their text. Opening a .pptx or .docx gave you its text content, which is genuinely useful and stays - but it could not show you what the file actually looks like. On macOS the desktop app now renders the real page (the same renderer Finder uses for spacebar preview) and shows it above the text. No extra download and no new dependency; on other platforms the text view is unchanged.
Fixes
- Images and Office files open in the desktop app. Every image, PDF and Office file failed to display in a released desktop build while working perfectly in development. Production builds protect the local server with a token that the app attaches to its own requests - but an image tag cannot attach anything, so every one of those requests was rejected. They now carry the token a way a tag can.
- A file that cannot be displayed says so. It used to show a spinner forever, which is why the problem above went unnoticed for so long: a rejected file and a slow one looked identical. A failure now explains itself and offers to open or download the file instead.
Features
- Foxl Notes: importing a recording now shows its progress. Picking an audio file used to give no sign that anything was happening - transcription runs at the speed of the audio, so a long file looked like the app had simply ignored you. There is now a progress bar with the file name and a live percentage, an explanation that it takes about as long as the recording, and a confirmation at the end naming the note it created (with its length and segment count) plus a shortcut to the folder on desktop.
- Foxl Notes: you can import a recording on a phone. Importing previously needed either drag-and-drop or the desktop File menu, so it was unreachable on mobile even though the transcription itself worked there. There is now an "Import a recording" row on the Notes home screen.
- The Agents game is a real game screen now. Flipping the game switch takes over the whole screen instead of showing a small panel under the form: a summon view with your level and currencies along the top, the character you pulled on a light burst with its rarity and star rating, its own line of dialogue, and a six-tab game nav along the bottom. Pulling again is animated - the character lands with an overshoot, the stars snap in one by one, petals fall. Three original Foxl characters at different rarities. The switch itself moved out of the button row and onto a glass chip in the header row - the same place, size and material as the chat menu's chip, and real iOS glass rather than a CSS imitation. (Presentation only: level, gems and your collection are kept on this device, pull odds are published on the screen, and pulls cannot be bought - there is no purchase path and nothing is charged or synced.)
- Foxl Notes can notify your phone when it finishes. Notes was the only product without notifications, and the one that needed them most: transcribing an imported file takes about as long as the audio, so the natural thing is to start it and put the phone down. A "Notes transcripts" toggle joins the others under Notifications (on by default), and a finished import now reaches you even if you have looked away.
Fixes
- Workspace: PNG, DOCX and PPTX open on the web app. They spun forever while the exact same files opened fine from the desktop, because the tunnel sent the text
"null"as a request body for every file fetch - which the desktop server rejected as malformed JSON and answered 500 to, before the file route ever ran. Verified end to end: all three now arrive byte-valid, including files in folders with spaces. - Menu text is readable in dark mode. The native menu rows and the "..." glyph were drawn in the system's label colour rather than the app's, so in dark mode they came out near-black on dark glass.
- The search palette has no stray close button. It had nowhere to sit that was not on top of the search field; Escape and a click outside already dismiss it.
- Notes sidebar rows are no longer clipped under the selection.
- Push notifications can be delivered at all. No device had ever registered, so every notification - chat, Code and Notes alike - was silently going nowhere. The device token arrives from Apple once per install, almost always before you have signed in, and it was being discarded in that case and never offered again. It is now kept and uploaded as soon as sign-in happens.
- An idle app no longer burns through the request budget. Two open clients could disconnect each other in a tight loop, and because each connection briefly succeeded the retry backoff reset every time and never backed off at all - tens of thousands of requests a day with nobody using the app. Backoff now only resets for a connection that stays up.
- The chat menu opens below the button in a browser. It overlapped the button it came from, so the click that opened it landed on the first menu row. On iOS the overlap is kept deliberately - that is what makes the menu and the button read as one piece of glass.
- Header chips fade out with a sheet instead of blinking away. They disappeared instantly while the sheet was still sliding in, which is what made the transition noticeable; they now dissolve on the same timing the sheet arrives with.
- A dialog close button no longer floats below the search field.
- The Code-tasks notification toggle actually saves now. It was sent under a name the server did not recognise, so switching it off appeared to work and quietly reverted the next time the screen opened.
- Two open clients no longer knock each other offline in a loop. Every web client identified itself to the relay with the same hardcoded name, and the relay keeps one connection per name - so a second tab (or the phone alongside a tab) disconnected the first, which reconnected and disconnected it back, forever. That was the constant network traffic visible in an idle app. Each client now has its own identity, so a reconnect only ever replaces its own connection.
- Provider and model names are readable on a phone. Settings showed "foxl..." and "Opus..." because the status badge beside the name kept its full width while the name itself collapsed. The name is now the last thing to give way.
- Workspace: images, slides and other binary files open instead of loading forever. A PNG or PPTX preview span forever and then reported "The transfer from your desktop stalled", on the web app as well as the desktop. The desktop server had no 404 for an unknown
/api/*path at all - it left the request open, so nothing downstream ever learned the request had failed: the tunnel waited on a reply that would never come, the relay held an already-accepted empty response for ten minutes, and the viewer sat on a spinner until its own timeout blamed the transfer. Unknown routes now answer immediately, and the tunnel's streaming path has the same first-response deadline its non-streaming sibling always had (long-lived subscriptions are unaffected). - Conversation search is the same bottom sheet as everything else on phones. It was a top overlay unlike Settings and the model picker; it now rises from the bottom as the same floating card, and can be dragged up to full screen for long result lists.
- The chat menu's opening animation matches the rest of the app. It had its own springy curve plus a second overshoot in its keyframes, so it felt rubbery next to the sidebar and the sheets. One easing now describes all of them.
- The whole menu row is tappable again, not just its text. Hiding each row's icon also removed that part of the row from touch handling, so the left third was dead.
- The desktop really does stop repeating "Web client connected securely". The earlier fix deduplicated by device, but the secure-handshake path reported an id derived from a fresh key on every reconnect - so an idle tab looked like an endless stream of new devices. Measured: 240 reconnects over two hours now produce one notification, and a genuinely new device is still announced.
- The chat menu's items are clickable again (iOS). "Find in this chat", "Search conversations" and "New chat" all did nothing when tapped. Two independent causes: the menu's rows were being hidden with
visibility, which removes them from touch handling as well as from view, and the native glass container was claiming every touch inside the region it covered rather than only the ones its own controls wanted. - The chat menu no longer closes the instant you open it. On phones the panel was positioned far enough up to sit under the finger that opened it, so the same tap landed on a menu row - the menu opened, silently ran "Search conversations", and shut again. Measured the safe range with a real touch and the panel now stops short of it.
- The chat menu opens as one glass shape with its chip, and lets go again. The merge was a chip joined by an empty spacer to a separately-styled panel, with a visible seam where the two met; the panel is now part of the same shape, so it grows out of the chip and retracts back into it. The web hamburger icon no longer flashes underneath as the menu closes.
- The in-chat "Find" bar has its own row on phones. It was a small pill in the top-right corner, overlapping the title on one side and sliding under the menu chip on the other. It now sits below the header at full width, with touch-sized buttons.
- Search and dialogs clear the status bar on phones. The conversation search sheet opened with its field partly behind the clock, and a dialog's close button was a 16-point target inside the status bar - too small and too high to press. Both now respect the safe area, and close buttons are full-size touch targets.
- Foxl Notes: importing a file always creates the note. A recording that read fine but contained no recognized speech - a silent stretch, music only, or audio in a different language than the transcription setting - produced a message and nothing else: no note, no kept audio, no way to retry without picking the file again. The note is now always created with its audio attached, so an empty transcript is something you can edit or re-run instead of a dead end.
- The desktop stops announcing the same web client over and over. A browser tab or phone left open reconnects on its own for ordinary reasons, and each reconnect produced another "Web client connected securely" notification, so notifications kept arriving while nobody was doing anything. A device is now announced once, and its reconnects are silent.
- Foxl Code settings: the save bar matches the panel it sits in. It was painted pure white, which on the mobile Settings sheet read as a strip pasted across a differently-tinted surface, and it now also keeps clear of the home indicator.
- Foxl Notes: a file with no speech says so. "Could not read the file" and "the file was fine but nobody spoke" were reported as the same failure, and a silent or music-only recording therefore looked like a broken import. They are now separate messages, and the one for no speech suggests what to check.
- iPhone: the header buttons stop disappearing when you open a chat. Entering a conversation, or following a link into one, made the sidebar and menu buttons vanish - and only in Foxl Agent, which is what made it look random. Moving between screens inside the app looked like a page reload to the glass layer, so it threw the buttons away while the app still believed it had them, leaving an empty gap where each control was. It now tells a real reload apart from moving around inside the app, so the buttons survive both.
- iPhone: one set of buttons, not two overlapping. On the Foxl Code Tasks screen the old CSS imitation was still being drawn underneath the real iOS material, so the buttons showed as two stacked shapes. Both surfaces now go quiet the moment the real material takes over, in every product.
- iPhone: the chat menu grows out of its button as one shape. The menu and the button it came from now fuse into a single piece of glass, the way iOS menus do, and the menu's labels stay perfectly readable. Previously the shape sat offset from the menu it belonged to and left an empty ring where the button was.
- iPhone: swipes work in both directions. The sidebar could only be swiped open and the terminal only swiped closed, so the other half of each pair needed a button. Now: swipe in from the left edge to open the sidebar, swipe left to close it, and swipe in from the right edge to open the terminal.
- The sidebar shows five and a half conversations. Half a row stays clipped at the fold, so it is visible that the list continues.
- Foxl Code: the regenerate and edit buttons are gone from replies. They were drawn on every message but did nothing when tapped, because Foxl Code has no re-run or edit-and-resend behind them. They will return when it does.
- Foxl Code stops hanging on "Loading..." when its server is unreachable. Requests had no deadline, so a server that accepted the connection and then went quiet left every screen spinning with nothing to report. Requests now give up after 30 seconds and say what went wrong, and cancelling still cancels immediately.
- iPhone: the app uses the whole screen. The top and bottom strips used to be native chrome the page could not draw into, so backgrounds and sheets stopped short of the physical edges and left a flat band along the home indicator. The page now owns the full display corner to corner and keeps its own clearance for the Dynamic Island and the home indicator, so everything runs to the edges like any other iOS app.
- iPhone: bottom sheets meet the screen properly. The model picker and Settings drew their side edges and square bottom corners inside the screen, so a sheet looked like a slab pasted over the app instead of a panel floating on it, with a bright band left under it along the home indicator. Sheets are now rounded on all four corners, lifted clear of the bottom edge, and genuinely frosted, and the strip below them follows the sheet instead of the page. The section headings inside the model list no longer paint white bars across the frosted surface, and iOS no longer draws a stray blue outline around the sheet or the selected row.
- iPhone: the header buttons no longer flicker or shift. They used to swap between the real iOS material and a CSS imitation whenever a menu, sheet or the sidebar was open, and the two treatments do not look alike - that swap was the shimmer and the little jump. The buttons now keep one presentation at all times. They also carry a hairline edge, so the shape stays visible over a white page, where glass has nothing to refract, and they follow light and dark mode properly instead of flashing bright.
- iPhone: the sidebar button is a sidebar icon, the same one the desktop app uses for it, and the chat menu sits at the right edge of the header again.
- The conversation title no longer overlaps the chat on a phone. The mobile header is transparent so the transcript scrolls under it, which left the title printed on top of the message text. It is gone on phones (the desktop header has its own surface to sit on and keeps it).
- Two more messages fit on screen, in Foxl Agent and Foxl Code. Both transcripts padded the top against a transparent header they already scroll beneath, and over-reserved at the bottom for the floating message box - wasted height on desktop and mobile alike.
- iPhone: the chat menu opens smoothly. The
...menu sprang from a point much smaller than the button and animated a blur on a frosted surface, which made it judder on open; it now unfolds from the button itself using only compositor-friendly motion, with a softer directional shadow. - Foxl Code: the chat inside a task scrolls again. Open a task, let the conversation run long, and the transcript was simply cut off with no way to scroll to it - and the message box would not stay at the bottom of the screen where it belongs. Both came from the same layout mistake, and both are fixed. The scrolling transcript is now literally the same component Foxl Agent uses rather than a second copy of it, so the two products can no longer drift apart like this.
- Errors arrive as a reply, not a red bar. Running out of credits showed you
402 {"error":"Credits exhausted","remaining":0}in a detached red strip while the conversation itself went blank, as if nothing had happened. Every failure in Foxl Code now ends the turn inside the conversation with a plain sentence and a next step ("Your credits are used up... Add credits or wait for your monthly refill in Account"), keeping any partial output that had already streamed. Foxl Agent already did this; both products now use the same code for it. - Foxl Code: the first bubble on a task is the right width. The prompt that seeds a task page rendered edge to edge across the column instead of sitting in a normal user bubble like every message under it, which is what made Foxl Code chat look wider than Foxl Agent. It was skipping the shared message wrapper that applies the width, so it also failed to line up with the real turns below it.
- Foxl Code: task status lives in the top bar, not in popups. Cancelling a task, retrying it, resuming it, or marking it done each threw a toast over the app - and a toast saying "cancelled" could sit next to a header still reading "Running". Those eleven popups are gone. The outcome now appears next to the status pill it describes and fades on its own, so the top bar is the single place that tells you where a task stands. The header also no longer claims a task is running Opus 4.8 while its real model is still loading.
- Foxl Code: Cmd+N starts a new task. It used to throw you out of Foxl Code and open a new Foxl Agent chat instead. Find and Search from the File menu now reach Foxl Code's own search too.
- Korean greetings no longer read like machine translation. The greeting on an empty chat is written fresh by a model each time, and it had been translating the English phrasing word for word, which produced stiff results in Korean. It now writes original copy in your language.
- Foxl Code: New task actually clears the chat. If you were already on a fresh chat (not inside a task), pressing New task left the whole previous conversation and any error on screen - the cursor moved to the message box and nothing else happened. It now empties the conversation the way New conversation does in Foxl Agent.
- Web search is now Web Access, in Settings. The globe in the message bar was labeled "Web search" but actually switched Foxl's control of your Chrome browser on and off - a standing permission sitting in a per-message spot. It moves to Settings > Web Access, which gathers everything in one place for the first time: browser control, fetching pages by URL, the Chrome extension (including how to install it, which the app never told you), and the list of domains Foxl is allowed to visit.
- You can remove a domain from the allowed list. The list only ever grew. Removing an entry took it off the screen but left the site reachable, because an allowed domain always won over the blocked list. Removal now actually removes.
- Workspace opens every kind of file, in a real code editor. Only markdown could be opened before - anything else was handed off to Finder, which on a phone meant tapping a file did nothing at all. Now images, PDFs, audio, video, Word documents and spreadsheets all open in the app, and text files open in Monaco, the same editor that powers VS Code: syntax highlighting for 80+ languages, find and replace, folding, multiple cursors. On a phone it is tuned rather than shrunk - larger type, wrapped lines so nothing scrolls sideways, and no minimap eating the screen.
- Agents, Schedules and For You lost the giant number. Each page opened with a 60-pixel digit that was usually 0, under a shouty repeat of the page name that the header already showed, with the same counts printed again right beside it. On the Agents screen the word "Agents" appeared three times. All three now open with one compact line, so the thing you came for is on screen instead of below it, and a count of zero simply is not shown.
- Foxl Code and Foxl Agent now share their tool and message code. The two products had separate copies of the code that decides a tool's icon, title, and output formatting, and separate copies of the message shapes underneath the chat. The copies had quietly diverged, and each difference was a real defect: a live "progress" readout that only Foxl Code could show, and message block types that only Foxl Agent actually type-checked. There is now one implementation of each, so a fix to one product is a fix to both.
Features
- iPhone: the header buttons are real iOS 26 Liquid Glass. The hamburger, the chat menu, and the scroll-to-bottom button are now genuine UIGlassEffect rather than a CSS imitation, so they refract the page behind them and react to touch exactly like the system's own controls, with their icons drawn crisply on the glass. The message box deliberately keeps its CSS glass: native glass refracts everything inside its own bounds, so the placeholder, the model picker and the send button would have been smeared along with the background. Glass also steps aside automatically whenever a menu, a sheet or the sidebar drawer is open, so nothing can float on top of them.
- Claude Opus 5 is here, and it is the new default. Anthropic's most intelligent model is available across Foxl Agent, Foxl Code, and Foxl Notes from day one. It matches or beats Fable 5 on agentic coding and professional knowledge work at half the price, so it takes over as the default everywhere Opus 4.8 used to be - same $5/$25 rate, materially stronger results, no action needed on your side. 1M context, 128K output, all five reasoning effort levels, and reasoning is now on by default: Opus 5 decides for itself how long to think on each turn. Every earlier model stays available in the picker.
- Model pickers show the current generation, not the archive. Superseded models (Opus 4.7 and 4.6, Sonnet 4.6, GPT-5.4 and older, Gemini 2.0) are now hidden by default across all four model pickers - chat, Settings, Foxl Notes, and Foxl Code. Nothing was removed: "Show older model versions" in Settings > Model & provider brings them all back, and every picker has the same one-tap row at the bottom of its list. A model you have selected or favorited is never hidden, and searching still finds everything, so typing "4.6" turns up Sonnet 4.6 with the setting off. Foxl Notes and Foxl Code settings carry the same switch, so wherever a list is shortened you can widen it on the spot.
- Foxl Code: your starred models stop disappearing. Foxl Code and Foxl Agent share one favorites list, but stored them in two different formats, so opening Agent chat once silently unstarred every model you had favorited in Code. New Foxl Code chats also started on Sonnet 4.6 while the send path assumed Sonnet 5; both now agree on Sonnet 5.
- Gemini CLI actually works now. Replies came back empty every time: Foxl read the CLI's stream in a format it has never emitted, so every line of the answer was discarded. Errors were worse than silent - a quota or sign-in failure was indistinguishable from success, so you got an empty reply with no explanation. Both are fixed, the current Gemini 3 models are selectable, and signing in with
geminiis now detected (Foxl only looked for an API key, so a signed-in CLI still showed as not configured). - Fixes to model identity that were quietly costing you. Picking the short "Claude Code Sonnet" option ran Sonnet 4.6 long after Sonnet 5 shipped. Six other model IDs resolved to nothing internally, which made Foxl treat a 1M-context model as 256K - compacting your conversation about five times earlier than needed - and record its cost as zero. GPT models over a ChatGPT subscription were assumed to hold 1M tokens when the service actually serves 272K, so long sessions failed upstream instead of compacting in time. A GPT-5.3 option that OpenAI does not serve at all has been removed.
- Settings: a Refresh button next to Save Provider Settings. After running
claude /loginorcodex loginoutside the app, Foxl kept showing the old "not configured" state until you restarted it. Refresh re-reads provider credentials and model lists on the spot. - Chat: starter prompts on mobile actually work now. The tappable "try asking something like" rows under the mobile greeting had never been able to show anything; they do now, and your last greeting and prompts are remembered so they appear instantly on a cold start instead of a few seconds later. The desktop empty state is unchanged (greeting and composer, no prompt list). The composer no longer repeats the question already asked above it.
- Sidebar: switching product closes the mobile drawer, like every other destination in it, so you land on the screen you tapped instead of dismissing a panel first. The product switcher is also reachable by keyboard and screen reader for the first time.
- Foxl Code: AgentCore compute is now actually billed. A task costs two things - the model tokens and the machine it runs on - and the machine half was never charged on relay-routed tasks, because finalize treated the two as alternatives and kept only the larger. Both are now recorded, and a task's reported cost is the real total. Pre-flight cost estimates also no longer price a model at zero just because it was missing from an internal table.
- Foxl Code: budget settings that actually do something. The Budget section had four knobs, and two of them did nothing: an "Account-wide budget cap" that promised to reject new tasks (nothing enforced it) and a "Hard cap fraction" the server ignored. Both are gone, along with the per-task multiplier, leaving one number - max spend per task - which the relay really does enforce. The daily spend cap also could not be saved at its own default value; its limit now matches the server's.
- Foxl Code: Runtimes shows real live spend. The spend bar read $0.000 for the entire time a task was running, because that figure is only written when the task finishes. It now shows the running total the relay is metering. The fake mini-terminal preview, which could never display agent output, is gone.
- Foxl Notes: an AI summary can no longer land on the wrong note. If you clicked a different note while a summary was still being written, the finished summary replaced THAT note's contents and renamed it. The summary now always goes to the note it was started for, and it no longer overwrites whatever you happen to be reading.
- Foxl Notes: import a recording you already have. Drag a wav, mp3, m4a, or mp4 onto Notes - or use File > Import Recording... - and it becomes a new note with a full transcript, speaker labels, and the same AI summary, title, and export you get from a live recording. It runs through the exact same transcription path as recording, so an imported note behaves like any other note; the audio is kept too, so clicking a line still plays that moment.
- Foxl Code: one chat, like Foxl Agent. Sending the first message no longer jumps you to a separate task screen with what looked like a copy of your conversation. You stay in the same chat, the reply keeps streaming, and the new task appears in the left sidebar. Picking a task from the sidebar swaps that task's thread in place and reveals its status, plan, PR link, and live terminal above the same chat; picking nothing puts you back on a fresh chat. The composer no longer jumps from the middle of the screen to the bottom either - it is the same composer, so a half-typed message and its attachments survive your first send. The old "Clear chat" link is now "Reset session" in the task menu, next to Retry and Cancel.
- Chat: a marker when the model changes mid-conversation. Switching the model in the middle of a chat now drops a subtle "Switched to <model>" divider into the transcript, so the record shows which model answered which turns. It only appears on an actual change (consecutive same-model turns add nothing) and is saved with the conversation on app.foxl.ai and mobile, so it survives a reload or a second device. (On the desktop app the marker shows for the session; the divider is not yet persisted to the local chat database.)
Features
- Foxl Code: the loop closes itself. A batch of loop-engineering capabilities so a task drives from prompt to verified PR with less hand-holding:
- PR reviewer (maker-checker). When a coding agent opens a pull request, an independent reviewer agent fetches the diff, grades it against the original task, and posts a real GitHub review (approve or request changes with a structured assessment). On "request changes" the coding agent is automatically resumed with the feedback, up to two rounds.
- CI-aware self-heal. Foxl now ingests GitHub check/workflow results: a task shows a CI status chip, and a red run feeds the failing check back to the agent to fix instead of sitting silently.
- Verify gate. After a coding agent finishes, its repo's own test suite runs; a red suite blocks the PR and marks the task failed rather than "ready for review".
- Scheduled tasks. Set a task to run on a cadence (every N hours or a daily UTC time on chosen weekdays), from Settings or by asking the agent. Scheduled runs respect the same budget and beta gates as manual ones.
- Per-repo memory + custom instructions. Tasks start warm with a short brief distilled from prior work on the repo, plus account-level custom instructions and per-user MCP connectors.
- Cross-device chat history. Foxl Code chat threads are mirrored server-side, so a task's conversation is there when you reopen it on another device.
- Push notifications when a task is ready for review, merged, or fails.
- Foxl Code: more coding agents. Codex (default model GPT-5.6 Sol), Kiro, and OpenCode backends are enabled alongside Claude Code, and mid-run steering (read the agent's screen, send input, resume) now routes to each backend's own runtime instead of only Claude Code's.
Fixes
- Notes: transcript sentences no longer land out of order. With system audio + mic captured together (two transcription pipelines) or across the periodic socket rotation, a late-arriving sentence could be appended to the bottom of the live transcript - and stay there in the saved note - instead of slotting in where it was actually said. Segments are now kept in absolute audio order as they stream in, the transcript view sorts defensively, and previously saved notes are repaired on load (fixes copy, summaries, and send-to-notes built from those notes too).
Features
- Foxl Code: per-task conversations. Every task now has its own chat thread alongside the live terminal (Conversation | Terminal toggle in the task header, next to the status). The home composer starts a task and drops you into its thread; follow-ups there steer the same coding agent instead of starting a new one. Clear chat now clears only the thread you are in, and the autonomous heartbeat's updates get their own activity feed on the Tasks home page.
- Foxl Code: one chat UI everywhere. The Tasks home and a task thread now render the exact same chat surface (the glass-composer, rich reasoning + tool-call timeline). Previously the two used different code and looked unrelated. Each task also has its own address (/code-tasks/:id, like the Agent's /chat/:id); /code-tasks is the "new chat" home.
- Foxl Code: the "Tasks" title is New Chat. Clicking the Tasks title in the Code header (from anywhere, including inside a task) returns to the empty composer home and starts a fresh chat, mirroring the Agent header.
- One Settings for all three products (desktop). Opening Settings from Notes or Code now lands in the same two-pane Settings view the Agent product uses, drilled to that product's section - instead of each product showing its own standalone settings page. Every setting is reachable from every product, and the mobile sheet already worked this way.
Fixes
- Code Settings opens again. After viewing any task, clicking Settings in the Code sidebar footer kept showing the task instead of Settings: the task-selection sync replayed the remembered task over the fresh settings route on every remount. The sync now only drives task routes, and the desktop Settings entry renders the unified Settings directly.
- Code Settings coding-agent cards read properly. Inside the shared Settings column the coding-assistant picker used a 3-column grid meant for the wide standalone shell, so each card squeezed to ~200px and every label wrapped one word per line. The cards are now full-width rows, and product settings (Notes/Code) get a wider column than the plain preferences list.
- Code "New task" button works from anywhere. The in-shell New task button did nothing while a task detail page was open (only the Tasks page listened for its event); it now clears the selection and opens the composer from any Code page.
- One language setting for the whole app. The Code sidebar could show Korean labels while the rest of the app was English: its nav labels were missing from the shared locale files, and Notes kept its own UI-language picker in its own store. The language picker in Settings > General is now the single source of truth - it drives Agent, Notes (including the HUD window and AI output language), and Code together, and the Code nav labels are translated in all 10 locales.
- Foxl Code task view polish. A spawned task's prompt now shows as a proper user message bubble (it used to render as a washed-out grey box); the task header is a single tidy row; and a stray vertical scrollbar that appeared even on short pages is gone.
- Foxl Code: "Tasks" title now actually leaves a task. Clicking Tasks while viewing a task changed the address bar but left the task on screen; it now returns to the composer home.
- iOS: the top and bottom safe-area strips match the app. In dark mode the strips around the clock and home indicator showed pure black against the app's slightly-grey background (and could even show the opposite colour when the phone's system appearance differed); they now paint the same colour as the app in both themes.
Marketing
- The Foxl Code landing hero is now a live recording. foxl.ai/code plays a real screen capture of app.foxl.ai/code (typing a task, browsing the Task Plan) in a browser frame - retina-crisp, autoplaying muted loop with a play/pause control, a scroll scale-up entrance, and a poster fallback that respects reduced-motion preferences.
Features
- The mobile terminal has a reconnect button. Next to the new-tab chip, the refresh chip does what the desktop terminal's refresh does: tears the session's connection down and reconnects, re-hydrating the scrollback.
Design
- Glass everywhere it floats. The chat's scroll-to-bottom arrow is now a frosted glass chip like the header buttons, and the mobile terminal's bottom bar matches: quick keys and arrows as translucent glass pills on the dark surface, and the command box restyled as a frosted glass card with the same specular rim and lift as the message bar.
Fixes
- Spawning a terminal from the web app no longer shows two tabs. Starting a terminal on app.foxl.ai created one real session but two tabs (both looking selected): the desktop's "terminal appeared" push and the spawn request's own response both added the same session. The session list now merges by id, so one session is always one tab.
- Rolled back native iOS glass. v0.4.18's native Liquid Glass darkened the top and bottom of the app on real devices and the glass never showed: an iOS app is fullscreen, so unlike a transparent macOS window there is nothing behind the web view for glass to sample - making the web view transparent only exposed the app's black container. The header chips and message bar are back on the proven CSS glass everywhere.
- The mobile terminal now covers the whole screen. It slid in under the header (sidebar/title/menu chips stayed visible) because the animated app shell turns
position: fixedinto shell-relative positioning; the terminal page now renders outside the shell, so it truly covers everything, header included.
Fixes
- Desktop terminals appear the moment the app opens. On web and iOS the terminal list was fetched once at launch - before the desktop connection was up - so it came back empty and only a terminal opened *after* that point would show. The list now re-syncs as soon as the desktop comes online and on every app resume, so terminals already open on the desktop are there immediately.
Design
- Real Liquid Glass on iOS 26+. The header chips and the message bar now render actual system glass - native UIGlassEffect views tracked behind the web content via our new @foxl/capacitor-liquid-glass plugin (the electron-liquid-glass architecture, adapted to Capacitor) - instead of a CSS imitation. Older iOS, Android, and the web keep the CSS glass.
- Cmd+T shows and hides the terminal. One shortcut flips the chat's terminal view open and closed, from anywhere in the app (desktop menu accelerator + in-page shortcut on the web).
- The mobile terminal is a full page now, not a bottom split. Tapping the terminal in the message bar pushes a full-screen terminal in from the right (the iOS navigation push), so the PTY and its command input get the whole screen instead of fighting the chat composer, quick keys, and keyboard in one cramped stack. Swipe right from the left edge - or tap the round back chip - to return to the chat. Desktop keeps the bottom panel.
- Mobile header, reworked. The three round header buttons grew to a full 44px touch size, and search + new chat merged into one menu button: tap it and an iOS-style menu drops out of the corner (with the springy water-drop spread) holding Find in this chat, Search conversations, and New chat.
- Mobile sheets match the shell's roundness. The Settings sheet and the model selector sheet now use the same 28px corners as the main screen card when the sidebar drawer is open, so all lifted surfaces read as one family.
Features
- GPT-5.6 Luna joins the free tier. Free accounts can now chat with GPT-5.6 Luna (the fast, light GPT-5.6 tier) alongside Haiku 4.5, Sonnet 4.6, and Sonnet 5. Sol and Terra remain Pro+.
- Locked models sink to the bottom of the model picker. Models your plan can't use no longer sit greyed-out between usable ones - they collect in a "Requires upgrade" group at the end of the list.
Fixes
- Stop responds instantly on mobile. Two bugs stacked up: the web app's tunnel routing dropped the abort signal, so tapping Stop cancelled nothing - the reply kept streaming until the desktop finished; and on iOS the tap itself could be swallowed when it coincided with the keyboard dismissing. Stop now aborts on touch-down (with a haptic tick) and the abort reaches the stream and the desktop agent immediately.
- A failed reply now always answers back. Credits exhausted, a model not on your plan, permission or rate-limit errors used to vanish - no toast, no banner, no bubble. Every failed turn now ends with a clear in-conversation reply (a calm red-tinted message that persists in history) explaining what happened and what to do next, on desktop, web, and mobile alike.
- Tool activity chips stopped swapping identities for good. The tool name now rides the authoritative SDK event (not a lookup that could miss), and every pairing path - live stream, tunnel, and mid-stream reconnect replay - refuses to attach a result to a different tool's chip. Shell commands no longer render as "file read" or "web search".
- Model and provider names no longer clip in Settings on phones. Wide pickers (Notes AI model, translate model/language, save format) drop to their own full-width row on small screens instead of squeezing into an ellipsis next to the label.
Design
- Selects match the app's roundness. Dropdown triggers, menus, and rows across Settings now use the same softly-rounded corners as the chat model selector (rounded-lg triggers, rounded-xl menus) instead of the sharper stock corners.
Fixes
- CRITICAL: replies work again on mobile and app.foxl.ai without the desktop connected. Since v0.4.13, chats on the relay-only path rode a relay-internal
conversationIdfield (for chat-complete push deep links) that the relay forwarded verbatim to the model provider. Bedrock rejects unknown fields ("Extra inputs are not permitted"), so every model returned an empty reply with no message bubble. The relay now strips relay-internal metadata before any upstream forward, with a regression test that sends exactly what the apps send. - Tool activity chips no longer mislabel each other's work. When results arrived for interleaved tools (for example a web fetch and a shell command running in the same turn), a result that missed its id match was stapled onto whichever chip was last running - showing "Web search completed" over a python command, duplicated across rows. Results now carry the tool name and only ever pair with a chip of the same tool.
- Mobile header buttons line up with the message bar. The phone header's glass chips sat on a slightly narrower margin (px-3) than the composer strip (px-4), so the top row looked subtly off against the message bar. Both now share the same horizontal edge.
- Workspace is friendlier to touch. File and folder rows get taller tap targets on touch devices, the mobile back button is a proper 36px target, Save grows to a touch-sized button, and the editor uses 16px text on phones so iOS no longer zooms in when you tap it.
- Every recent blog post has its own cover. Four posts (v0.4.10, v0.4.12, v0.4.15, and the AirPods deep-dive) shared the v0.4.7 sessions thumbnail; each now has a cover drawn from its own story.
Fixes
- Skills, Channels, and custom tools (MCP) are reachable again. When Integrations moved from the sidebar into Settings, its five-tab bar (Integrations / Skills / Channels / System / Custom) was left behind in the old page header - so Skills, Channels, and the System/Custom tool pages (including custom MCP servers) silently disappeared from the UI. Settings > Integrations now carries all five tabs inside the section as a segmented control, on desktop and mobile.
- The Integrations section scrolls on mobile. The Settings sheet expects each section to own its scrolling; Integrations didn't, so the section was frozen at the top on phones. The new hub owns its scroll container.
- Integrations dropped its gradient hero for a quiet prompt strip. The rotating full-color gradient carousel is gone; in its place a single flat row shows one featured integration with a real example prompt and a "Try in chat" button - tap the row to see the next example. Less visual noise, zero idle animation cost (the carousel was a steady compositor load on phones), and the page now reads like the rest of Settings.
- Usage scrolls (and loads fast) on the phone. The Usage section didn't own its scrolling inside the Settings sheet, so it was frozen at the top on mobile - fixed. Its dashboard also caches to durable storage now, so reopening the app paints the last numbers instantly and refreshes in the background instead of holding a spinner through a full tunnel round trip. The headline metric scales down on small screens instead of overflowing.
- Workspace opens instantly on the phone. The file tree now persists to durable storage: relaunching the app paints the last known tree immediately and refreshes in the background, instead of spending seconds on a spinner while the tree crosses the tunnel. (Demo data shown while the desktop is disconnected is never persisted.)
- Your name no longer gets stuck as "..." in the sidebar. Opening the app after being away could leave the account footer showing "..." even though you were signed in: the profile lookup sent the expired session token, got rejected, and never retried - on the web a manual refresh papered over it, but the app has no refresh gesture. The lookup now refreshes the token first, re-runs automatically when a refresh happens or the app returns to the foreground, and keeps showing the cached name instead of blanking to "..." while it revalidates.
- The Skills page dropped its gradient hero too. Same treatment as Integrations: the rotating gradient carousel is replaced by a flat prompt strip (tap to see the next example) - no ambient animation left anywhere in Settings.
- Usage Breakdown folds on the phone. The per-model chart in Account is collapsed behind its headline total on mobile - tap to expand. The number you check stays visible; the dozen bar rows no longer push everything else off screen.
- A tall message bar no longer covers the conversation. The chat's bottom scroll room was sized for the short one-line composer, so a multi-line draft or an attachment card sat on top of the last messages with no way to scroll them clear. The scroll area now tracks the composer's real height - as the bar grows, the conversation gains exactly that much extra room, and if you're reading the bottom it stays pinned above the bar.
- Attachment chips show their remove button on the phone. The X to remove a pasted-text block, image, or document from the message bar only appeared on hover - a concept touch screens don't have, so on mobile there was no visible way to remove an attachment. On touch devices the X is now always visible as a quiet gray chip (and slightly larger for the finger); desktop keeps the hover reveal, now in the same quiet gray instead of alarm red - removing a draft attachment is routine, not destructive.
Features
- Share from the iPhone app. Every chat reply now has a share button that opens the iOS share sheet (Messages, Mail, AirDrop, Notes...), and Notes exports (.md / .docx) go through the share sheet too - previously the browser-style download simply vanished on iOS, so exporting from the phone didn't work at all.
- The app icon shows an unread badge. When replies finish while you're away, the home-screen icon carries a count that matches the in-app unread state and clears as you read. Chat-finished pushes also set the badge, and opening the app sweeps its delivered notifications out of Notification Center instead of letting them pile up.
- Home-screen quick actions. Long-press the Foxl icon for New Chat and New Recording - New Recording jumps straight into Notes and starts recording.
- foxl:// links now navigate the iPhone app. Links like foxl://chat/{id} (the sidebar's "Copy link") and foxl://chat/new open the right conversation on the phone instead of just launching the app; they work from a cold start too.
- The status bar matches the app theme on iPhone. Switching Foxl between light and dark now flips the clock/battery icons to stay legible, instead of leaving them at whatever the system default was.
- Unread tracking works on the phone. A reply that finishes in a background conversation now marks it unread (sidebar dot + icon badge) on the mobile app, matching desktop behavior.
- Cmd+1 / Cmd+2 / Cmd+3 switch between Foxl Agent, Notes, and Code. The product switcher now has first-class keyboard shortcuts on desktop, listed in the View menu so they're discoverable like any native app.
- "New Recording" in the menu-bar tray. Right under New Chat: starts a Notes recording immediately and brings up only the floating meeting panel - the main window stays wherever it was, so you can capture a meeting without switching context.
- The floating meeting panel opens instantly. It used to build its window from scratch on every open (and closing destroyed it), which took visible seconds. The panel is now pre-warmed hidden at startup and hides instead of closing, so opening it - from the tray, from Notes, or automatically when a recording starts - is immediate.
- Bottom sheets on the phone now swipe down to close. The model picker and the Settings modal follow your finger 1:1 on a downward drag and dismiss past the threshold (or on a quick flick), springing back otherwise - the standard iOS sheet gesture the grab handle always implied. Scrolling inside a sheet still works: the drag only takes over when the content is at its top. Both sheets also float with a slim gutter on each side instead of running edge-to-edge. (Follow-up during staging: the gesture now attaches at the document level so the portal-mounted model sheet actually receives it, and a dismissed sheet slides straight off instead of replaying its exit animation from the top - the brief "bounce back up" glitch.)
- Key actions on the phone now give haptic feedback. Opening the sidebar, starting a new chat, opening Settings, sending a message, and picking a model or reasoning effort each give a light native tick (a firmer one for send). Phone app only - web and desktop are unchanged.
- Notes recordings keep going in the background on iPhone. Starting a recording and switching apps (or locking the screen) no longer kills it. iOS suspends web-view microphone capture the moment an app leaves the foreground, so the iPhone app now records through a native audio engine instead - paired with the audio background mode, the capture and live transcription continue with the system's recording indicator showing. Phone calls interrupt and resume cleanly, and switching to or from AirPods mid-recording re-anchors the capture instead of going silent.
Features
- Mobile notifications now have per-category controls. Settings > Notifications on the phone splits into individual toggles - chat replies, scheduled tasks, product updates, and promotions & tips - like a proper app, instead of one on/off. Each toggle is stored on the relay (the thing that actually sends the push), so a change takes effect immediately across your devices. Promotions are off by default and only ever sent to people who turn them on.
- "Open Settings" jumps straight to the system notification screen. When iOS or Android has notifications turned off for Foxl, the settings screen now has a button that opens the OS app-settings page directly - the standard way to re-enable them, since no in-app toggle can grant the system permission itself. A "System notification settings" row is always available too.
Fixes
- Chat-finished notifications now actually arrive on the phone. The chat-complete push was only wired into the desktop tunnel path, so a reply sent straight from the phone (or app.foxl.ai) finished silently with no notification when the app was backgrounded. The relay now fires the push on the mobile chat path too, and keeps the reply generating to completion in the background even after the app is backgrounded or locked. The iOS app also declares the remote-notification background mode so the system can wake it to deliver.
Features
- See which chats are still answering, right in the sidebar. Every conversation with a reply in progress now shows a small right-aligned spinner next to its name - whether that chat is open in front of you or generating in the background. Replies already keep running when you switch to another chat; now the sidebar makes that visible so you know at a glance what's still working. On desktop the spinner steps aside for the delete button on hover (same slot, no layout jump); on mobile it stays put.
- The phone has its own notification settings. Settings > Notifications on mobile is no longer the desktop's notification page: it now shows the phone's push controls - whether iOS has allowed notifications for Foxl (with a one-tap request, or a pointer to system Settings if previously denied), and per-kind toggles for chat-reply and scheduled-task pushes. The toggles are stored on the relay, which is what actually sends the push, so turning one off takes effect immediately for every registered device. Desktop notification settings are unchanged and stay on the desktop.
Fixes
- Notes recordings now capture the meeting's audio, not just your mic. Recording with headphones or AirPods produced an empty or one-sided transcript: the other participants' voices played inside your headphones and never reached the microphone, and system-audio capture only ran when live translation was armed. Every recording on desktop now captures system audio (the sound this Mac is playing) and mixes it with your microphone - both in the transcript and in the saved audio file. A new toggle in Settings > Recording turns the capture off. This needs macOS's "System Audio Recording Only" permission, which macOS never prompts for on its own - it just hands over a working-looking but silent capture - so Foxl now proves the capture end-to-end instead of trusting it: a new onboarding step and a test button in Settings > Recording play a short inaudible tone and verify it comes back through the capture, with a one-click "Open Settings" jump straight to the right privacy pane when it doesn't. The same self-test runs at the start of every recording; if the capture is dead, a standing warning appears in Settings until it's fixed. On macOS older than 14.2, where the system can't provide loopback audio at all, it tells you up front that the recording is microphone-only.
- A background chat's tool activity no longer bleeds into the chat you're reading. When a reply that uses tools kept running in one conversation and you opened another, the first chat's "running tool" chips and status could appear at the bottom of the new chat - pure display bleed, nothing was actually shared. Tool status is now tracked per conversation on every path (desktop stream, WebSocket events, relay web), and a background turn can no longer paint its bubbles or tool chips into whichever chat is on screen.
- A single
~no longer strikes through your text. Chat and Notes render Markdown, and a lone tilde used as a range ("rank 0~7, rank 8~15") was being paired with the next tilde and struck through everything between them - so a perfectly normal sentence showed up with a line through it. Strikethrough now requires the standard double tilde (~~like this~~); single tildes are left as plain text. - The keyboard animation no longer reflows the app every frame. Docking the composer on the rising keyboard animated the shell's height, and height is a layout property - every frame of the 250ms transition forced a full relayout of the app, which stayed visibly choppy no matter how much paint work was removed. The composer now rides the keyboard on a compositor-only transform and the real layout change commits exactly once, at the moment the keyboard settles - the standard technique for smooth keyboard docking in embedded web views.
Fixes
- The keyboard animation is smooth on mobile. While the app shrank to dock the composer on the rising keyboard, every animation frame re-rendered the glass surfaces' backdrop blur - the most expensive per-frame job in the iOS web view, and the source of the stuttery keyboard feel. During the 250ms docking transition the glass now switches to a near-opaque matte and the frost returns the moment it settles; the swap is imperceptible, the dropped frames are gone.
- Sidebar text no longer peeks out while the keyboard opens. The reveal drawer sits at full screen height behind the app shell, so when the shell shrank for the keyboard, drawer rows ("For You") showed through the strip between the shell and the keyboard. The closed drawer is now fully hidden, with the hide delayed past the close animation so it never vanishes mid-slide.
- Glass looks closer to native iOS material on phones. Touch devices with backdrop-filter support now get a more translucent tint with stronger blur and saturation on the header buttons and composer - nearer the real iOS 26 material in the native app - while desktop keeps its subtler treatment.
- The content panel border is back to its v0.4.1 weight. The recent full-opacity border on the desktop inset shell read too heavy; restored the original softer hairline.
Features
- Get a notification when your chat finishes on mobile. Send a message from the phone, switch apps or lock the screen, and Foxl now delivers a system push when the response is ready - tapping it opens that conversation. The push only fires when the app actually stopped watching the stream mid-turn; foreground chats never notify.
- The product switcher is now three tabs. The sidebar's "Foxl Agent" dropdown is replaced by a segmented Agent / Notes / Code control on both desktop and mobile - one tap to switch, and the active product is always visible.
- Swipe to manage chats on mobile. Conversation rows in the mobile sidebar now swipe left to reveal Rename and Delete, replacing the long-press menu. The drag tracks your finger and settles with a spring; tapping an open row closes it. Desktop keeps the right-click menu and hover actions.
- Settings is a native mobile sheet, and all three products now share it. On the phone, Settings slides up as a glass sheet over the app (the sidebar stays put beneath it, iOS-style) with a single round back button - no title bar, no divider - and sections push in from the right and pop back like a native settings app. Your Account, Integrations, Mobile/Web, and Usage all moved inside it, and Foxl Notes and Foxl Code settings are sections here too, so everything lives in one place. Tapping your avatar on mobile opens Settings straight to Account. Each section loads on demand, so the sheet opens instantly. Desktop keeps its familiar two-pane Settings page unchanged.
Fixes
- A dead desktop connection no longer causes a burst of repeated Gateway Timeouts. When the desktop's tunnel socket died silently (sleep/wake, network switch - no close event ever arrives), the relay kept writing every request into the dead socket for up to two minutes: each one waited its full 10 seconds and failed with a 504 while the dashboard still showed green. A live desktop always answers within 8 seconds, so the relay now treats one full request timeout as proof the socket is dead: it closes it and flips the desktop offline immediately. The desktop redials within about a second, so the next request goes through instead of joining the timeout storm.
- The chat composer now rides the keyboard smoothly on mobile. Tapping the input used to stutter as the composer rose: the layout transition ran on a different curve than the iOS keyboard, and every animation frame fired scroll events that re-rendered the chat mid-animation. The shell now animates on the keyboard's own timing curve and scroll-state updates pause until the keyboard settles, then reconcile once.
- Mobile chat is redesigned to mobile norms. The empty state drops the centered logo for a large left-aligned greeting, and suggestions become quiet full-width rows instead of centered pill buttons. Message text is 15px with relaxed line height (was 14px), the input is 16px (which also stops iOS from zooming the page on focus), sidebar rows grow to 40px touch targets with 14px labels, composer buttons grow to 36px, the disclaimer line under the composer is hidden on phones, and tap-highlight flashes are gone.
- The mobile chat header follows the round-button pattern. The hamburger and the header actions are now round soft-filled buttons (like the Claude and ChatGPT apps), the header grows to a comfortable 48px, and the two search buttons collapse into one on phones - the conversation search palette covers both finding a chat and finding within it.
- The message composer floats on a soft shadow. On desktop and mobile the input card now carries a subtle diffuse elevation that deepens slightly while typing, instead of sitting flat on the page. The border is thinner and the edge definition comes from a tight shadow fade hugging the card.
- Free users with fresh monthly credits can chat again. One oversized agent turn could overdraw the internal balance by more than a month's grant; that debt silently carried across months, so every later request failed with "Credits exhausted" while the Account page still showed 10 credits available. Monthly free credits are use-it-or-lose-it, so the refill now also clears any carried overdraft, and affected accounts were reset.
- Chat errors are visible again. A regression dead-wired the persistent error banner, so a failed send (out of credits, plan-gated model, relay errors) produced no feedback at all - the reply just never came. The banner is rewired: credits/plan issues show the amber upgrade prompt, other errors show the alert with the real message.
- The chat header is now translucent glass. Content scrolls beneath a blurred, semi-transparent header (same treatment as the foxl.ai site), and tapping the Foxl logo in the sidebar returns home (new chat / Notes / Code tasks) on desktop and mobile.
- Scrolling the chat while touching a message bubble works again. A containment rule applied to every scrollable element stopped touch gestures from reaching the transcript when they started on a nested scroller (code panes, text blocks); containment is now scoped to the top-level scrollers.
- A request that lands exactly on a dead connection recovers by itself. The relay heals a silently-dead desktop link the moment one request times out, but that first probe request still surfaced as a Gateway Timeout in the app. Read requests now retry once after the desktop's ~1s redial, so the healing is invisible instead of an error flash.
- Fixed an accessibility violation when the sidebar opened over a focused chat input on mobile (focus retained under aria-hidden). The composer no longer steals focus on phones - the keyboard appears when you tap the input, not when the app decides.
- Vertical scrolling no longer freezes intermittently on mobile. A legacy iOS scrolling hint forced the chat list onto a deprecated scroll path where streaming content could stall it until the next touch; removed.
- Dropdowns inside the mobile Settings sheet open again. Selects, popovers, and menus were rendering behind the sheet (a stacking-order regression), so tapping the language picker or any Settings dropdown did nothing. They now layer above the sheet.
- The chat follows a long answer as it streams again. When a single reply or thinking block grew tall, the view stopped scrolling with it - you had to keep tapping "scroll to bottom." Auto-scroll now tracks the content as it grows (not just when a new message arrives), and still hands control back the moment you scroll up, exactly like before. This restores the v0.3.x stick-to-bottom behavior.
- The message bar has a crisp, defined edge again. The glass composer's border was washed out by the blur and nearly black in dark mode; it now has a clear hairline (like Codex), a soft gray card in dark mode instead of near-black, and a symmetric shadow that lifts the top and bottom edges evenly instead of pooling at the bottom. Foxl Code's composer matches. The inset content panel and the mobile sidebar drawer also get a defined border.
- Removed the "AI can make mistakes" line under the composer in both Foxl Agent and Foxl Code - it added a row of clutter on every screen.
Fixes
- Remote access is stable again: no more connecting-then-dropping, and chat is fast. Three tunnel regressions from v0.4.7's connection-fencing rework are fixed, restoring the v0.3.x behavior.
- A phone or browser no longer multiplies into many device rows on the dashboard. The relay was dropping the client fingerprint when routing a web connection to its per-user hub, so every reconnect from the same device looked brand-new and piled up a fresh connection on every network blip, token refresh, or app resume. The fingerprint is now forwarded and the hub keeps exactly one live socket per client, closing the stale one.
- A desktop reconnect no longer drops in-flight requests. A reconnect (sleep/wake, network change) used to abort every request in flight with a "connection was replaced" error; because the web client also cycled its status socket on every token refresh, this fired constantly and looked like "connected for about ten seconds, then everything drops and chat gets slow." In-flight requests now survive a reconnect and complete from the original reply.
- The web app stops needlessly cycling its status connection. It used to tear down and reopen the status WebSocket on every token refresh and app resume even when the socket was healthy; an open tunnel socket stays valid across a refresh, so it now stays put and only reconnects when it is actually down.
- The desktop no longer shows two or three "Web client connected" pop-ups for a single connection. A phone or browser opens a few tunnel sockets at once (presence, chat, terminal sync) and each one, plus the chat socket's own encryption handshake, fired its own notification. The desktop now coalesces them into one notification (and one in-app toast) per device.
Fixes
- Mobile/web tunnel requests no longer hang for 10 seconds and then fail with a Gateway Timeout. When the desktop's machine ran out of local network ports (a socket-exhaustion storm that also breaks other apps), the desktop's loopback call to its own server could stall with no error and never reply, so the relay waited out its full request timeout and returned a 504 while the desktop still showed as connected. The desktop now bounds that local call and returns a real error instead of silence, and the relay always matches a desktop reply to its pending request - even if the desktop reconnected while the request was in flight - so a live desktop stops surfacing phantom timeouts.
Features
- Sessions on the Account page now reflect real devices. Every Foxl installation and browser profile mints a stable client identity, so the session list groups by actual device instead of by browser version string. Old duplicate rows (the same Safari appearing many times) collapse into one entry, and revoking a session signs out exactly that installation.
- Per-provider usage breakdown on the Account page. The 30-day usage table now separates the same model served by different providers (AWS Bedrock vs OpenAI OAuth), shows month-to-date credits from the immutable usage ledger, and prices them consistently at the credit rate.
Fixes
- Foxl Desktop now starts without internet. When the machine was offline (DNS unresolvable), macOS proxy auto-discovery failures made even the local
127.0.0.1app page fail withERR_ADDRESS_INVALID, so the app never got past the startup screen. Loopback now bypasses any system proxy, and subframe or embed failures no longer knock a healthy app page back to the startup splash - which also removes the rapid splash/app flashing loop seen while offline. - The startup screen matches the app's light theme. The splash was a dark-only page with an inverted monochrome logo; it now uses the light palette and the brand-color logo, so launching no longer flashes a black screen on light-mode systems.
- Signing in on two app surfaces at once no longer logs you out. When the renderer and the Electron shell refreshed the same session within a few seconds of each other, the relay treated the second refresh as token theft and revoked the whole session family. Concurrent refreshes are now idempotent: both callers get the same replacement token, while replays outside the short concurrency window still revoke the family.
- A reconnecting desktop can no longer be marked offline by its own old connection. Tunnel connections are now fenced by a connection id, so a delayed close event from a previous WebSocket cannot flip the replacement connection to offline. Wake-from-sleep reconnects collapse into a single jittered backoff owned by the tunnel client instead of three racing timers.
- Mobile/web tunnel status is push-first. The always-on HTTP status polling loop is gone; status arrives over the push channel and HTTP is only used as a bounded recovery probe, which also cuts steady-state relay reads.
- Credit balances update on activity instead of polling every 15 seconds. The sidebar and Account balances refresh when a chat turn completes, when the app resumes, or on manual refresh, removing a constant background request loop on every open Foxl surface.
- Model favorites are provider-aware. Starring a model on one provider no longer stars the same model id on every provider; existing favorites are migrated in place.
- Foxl Code's collapsed desktop sidebar now keeps long task histories contained. Pressing Command-B no longer expands every task avatar down the icon rail and pushes the remaining navigation away. The task section now matches code.foxl.ai with a bounded, independently scrolling list and a clipped bottom edge that indicates more tasks.
Fixes
- GPT tool runs no longer stop with an empty answer. Bedrock can report a terminal Responses API failure after a long tool run. Strands 1.9 ignored that event and finalized the turn as a successful but empty response. Foxl now turns it into a model error so transient failures can retry and final failures appear through the same error toast used by other models.
- Bedrock GPT context limits now match the actual 272K window. GPT-5.6 Sol/Terra/Luna, GPT-5.5, and GPT-5.4 were shown and configured as 1M-context models even though Amazon Bedrock Mantle rejects prompts above 278,528 tokens. The AWS and Foxl relay paths now advertise and configure the real limit, and the chat context meter uses it. Direct OpenAI and ChatGPT OAuth keep their 1M windows.
Features
- Launch at login. Foxl now starts automatically when you sign in to your computer, so your 24/7 agent is always running. Enabled by default; toggle it off under Settings -> About.
Fixes
- Offline behaves like a normal desktop app now. Losing internet used to flash a retrying error panel on and off (the reconnect ticker strobed the overlay). The connection-lost screen was redesigned into one calm panel that distinguishes "you're offline" (just waits and auto-reconnects, no blinking) from "the local agent server stopped" (offers Restart), and both edges are debounced so a flaky network can't make it flicker. Sending a chat while offline now shows a plain "You're offline" message instead of a raw "Failed to fetch", and the app recovers on its own when the network returns.
- GPT-5.6 on AWS: a transient hiccup mid-conversation no longer makes the agent quit tool-calling or go silent. GPT-5.6 (Sol/Terra/Luna) runs on the Amazon Bedrock Mantle OpenAI Responses API, which surfaces transient server errors (503/500/502) in the OpenAI SDK's error shape (a plain
status), not the AWS shape our retry logic recognized ($metadata). So a brief Bedrock blip during a long GPT-5.6 tool loop was treated as fatal instead of retried, and the turn stopped mid-way or returned nothing. The retry policy now recognizes both error shapes (plus connection/timeout errors), so these blips are retried with backoff on every GPT-5.6 path. Verified end-to-end against real Bedrock: single and multi-round tool loops complete cleanly. - Favoriting a model no longer shows it (and a lit star) twice. A favorited model was rendered both in the pinned Favorites group and again in its provider group, so a single favorite looked like two selected stars. Favorited models now appear only in the Favorites group.
- GPT-5.6 Sol, Terra, and Luna now read distinctly in the model picker. All three tiers showed the same "Advanced reasoning" subtitle; they now describe their actual role - Sol for flagship reasoning, Terra for balanced performance at half the cost, Luna for fast, cost-efficient inference. The Claude model subtitles were also refreshed to match Anthropic's current descriptions.
- No more "Tool 'workspace_memory_save' not found in registry". The system prompt always told the model to use the workspace-memory tools, but some setups (Claude Code subscription provider, or memory tools disabled in Settings) run without them - so the model called a tool that wasn't there and the turn errored. The prompt is now generated from the tools actually available for the turn: it only mentions memory, subagents, exec, and scheduling when those tools are present, on every agent path (chat, subagents, channels, scheduled runs, heartbeat).
- Foxl Code: per-task budget is a hard cap under concurrency. A coding task's budget was checked by reading spend that is only written after a response finishes, so several requests running at once could all pass the check and blow past the budget (and the account's credits). Each request now atomically reserves its worst-case cost before the model runs and settles to the real cost afterward, so parallel requests can't collectively exceed the cap.
Changes
- Upgraded the Strands Agent SDK to v1.9.0 (from 1.7.0 on desktop, 1.5.0 on the Forge orchestrator). Picks up the fix for tool-use metadata in streamed
contentBlockDeltaon non-standard models (GPT-5.x / GLM / Kimi routed through the SDK), tool usage after reasoning content, and durable message identifiers. No API changes on our side - all the SDK symbols Foxl uses are unchanged, and the one breaking rename (LocalMemoryStore -> TestMemoryStore) is a store we don't use.
Features
- OpenAI GPT-5.6 Sol, Terra, and Luna - day-one support. OpenAI's newest model family (GA on Amazon Bedrock today) is available across Foxl: the chat model picker on desktop / app.foxl.ai / Foxl Notes, and as Codex coding-agent models in Foxl Code. Sol is the flagship reasoner ($5/$30 per 1M tokens), Terra the everyday workhorse ($2.50/$15), Luna the fast, affordable tier ($1/$6) - Pro plans and up, priced at OpenAI first-party rates. All three support reasoning effort up to the new
maxlevel. Available two ways: on your Foxl credits via Amazon Bedrock, or on your own ChatGPT Plus/Pro subscription through the OpenAI (OAuth) provider - no API key needed. - Accurate prompt-cache billing for GPT models. GPT-5.6 introduces billed cache writes (1.25x input) and discounted cache reads (90% off); the relay meter now decomposes OpenAI's combined input-token count into plain input, cache reads, and cache writes, so cached GPT traffic is billed at the discounted rates instead of full input price.
Fixes
- Chat no longer fails with "Invalid or expired token" while the sidebar still shows you signed in. The relay access token expires every 12 hours; the sidebar and account surfaces silently refresh it, but sending a chat message hit the relay with the stale token and treated the 401 as a dead session - wiping both tokens instead of refreshing. The message path now refreshes the token (sharing the same in-flight refresh as the rest of the app) and retries the send once; you only get signed out when the refresh token itself is no longer valid.
- AWS provider: GPT-5.6 listed once and actually works. The desktop AWS provider briefly listed each GPT-5.6 tier twice (once under Bedrock, once under OpenAI-on-Bedrock); the Bedrock-routed copy failed with "The provided model identifier is invalid" because these models are served only by the Mantle Responses endpoint. The provider split is now derived from the catalog (any
openai.*Bedrock id is Mantle-only), and a stale saved selection self-heals onto the right route instead of erroring. - Images stay part of the conversation. Attached images used to reach the model only in the turn you sent them; after the app restarted (or the agent was rebuilt), later turns saw just a file-path hint - so asking "read that image again" got "I don't see an image". Following the standard ChatGPT/Claude conversation model, image attachments are now part of the durable conversation record and are rehydrated into real vision blocks when history is restored (newest 10 images; older ones fall back to the path hint), so the model can keep referring to what you showed it.
- Pasted screenshots stay readable. Chat image attachments over the API size limit were converted to JPEG with quality walked down as far as 30% (and dimensions halved as a last resort), which smeared screenshot text - the model would sometimes answer that the image resolution was too low. Oversized images now try lossless PNG first, then WebP, with a gentler quality floor and a 0.75x (not 0.5x) fallback downscale; the raw size cap is also corrected to fit the API's 5MB base64 limit (a ~4MB paste used to slip through unmodified and get rejected).
- Signing in from Foxl Notes no longer lands you in Foxl Chat. The desktop deep-link login (and one web OAuth fallback path) hardcoded the post-login destination to Chat, so the sidebar said Notes while the content pane showed Chat. Every sign-in path now returns to the product you were in - Notes stays Notes, Code stays Code - and history navigation keeps the sidebar product and the content pane in lockstep.
Fixes
- Foxl Notes: duplicate transcriptions are structurally impossible now. Live-translate mode used to run TWO parallel transcription streams (your microphone + the meeting's system audio); on speaker setups the mic re-heard the remote party, so the same sentence landed twice - and the text-similarity filter that tried to catch this was unreliable. The two captures are now MIXED into a single stream before transcription, so every utterance reaches the transcriber exactly once. This also removes the phantom "Remote N" speaker label space, and the saved audio recording now includes the remote party (it was mic-only before).
- Foxl Notes: fewer phantom speakers. The speaker label for a line is now the majority vote across the line's words instead of the first word's label, so a single misattributed word no longer spawns a new "Speaker N"; single-stream capture also halves the label spaces (no more parallel Speaker/Remote numbering for the same voices).
- Foxl Notes: in-progress (italic) lines are readable again - they keep the italic style but drop the hard-to-read faint gray in both the transcript panel and the live glass panel.
Fixes
- Foxl Notes: no more duplicate transcriptions. On speaker (non-headphone) setups the microphone re-heard the remote party, so the same utterance could appear twice - once as "Remote N" (system audio) and once as "Speaker N" (mic). The mic now captures with echo cancellation, and a cross-feed duplicate filter drops the echo copy when both still slip through.
- Foxl Notes: the live panel accents are back to the classic yellow (the blue accent experiment is reverted) in both dark and light themes.
- Foxl Notes: the live panel's Notes tab is the real editor. Same rich editor as the main window - toolbar, headings, lists, task lists, tables, code blocks, undo/redo - instead of a plain-text box, with edits syncing live in both directions.
- Foxl Notes: "Open saved file" in the note's right-click menu opens the auto-saved Word/Markdown export directly (or the save folder if the file isn't there yet).
- Foxl Notes: full editor toolbar everywhere. The live panel's Notes tab and the mobile editor now carry the complete formatting toolbar (headings, emphasis, lists, quotes, code, tables, images, alignment) scrolling horizontally, instead of an 8-button subset; the panel toolbar wears the glass styling.
- Foxl Notes: better live translations. Once a sentence finishes, it is re-translated with the surrounding dialogue as context and the rough in-progress translation is replaced in one shot; the "translating..." placeholder is gone - translations simply appear as they stream.
- Foxl Notes: honest sign-in messaging. Recording and transcription need a (free) Foxl account; the empty screen, mobile home, and onboarding now say so up front - the onboarding sign-in step carries a "Required for recording" badge and the start button reads "Sign in" when signed out instead of a Start Recording button that silently did nothing.
Features
- Foxl Notes: click a transcript line to hear it. Recordings now keep their audio on disk (desktop), and clicking any line in a saved note's transcript plays the recording from that exact moment - the line under the playhead stays highlighted, and clicking it again pauses. Timestamps stay accurate across long recordings (they previously reset every few minutes internally), and deleting a note removes its audio file too.
- Foxl Notes: light and dark glass panel. The floating meeting panel now follows the app theme automatically, with an override (Auto / Dark / Light) in its settings menu. Accents moved from yellow to Foxl blue.
- Foxl Notes: mini mode is a real caption strip. No recording dot or timer - just the latest lines, with the visible row count adapting to however tall you drag the window (newest bright at the bottom, older lines dimmed). Your mini size is remembered. The expand button stays visible.
Fixes
- Foxl Notes: clear error when credits run out. Starting (or continuing) a recording with exhausted credits now shows the actual reason instead of silently doing nothing; a mid-recording denial stops the recording with a message.
- Foxl Notes: one unified sign-in. Signing in from Notes (including onboarding) now returns to this app via foxl:// - it previously deep-linked to the retired standalone Notes app (foxlnotes://), which could open the wrong window and land you on Chat.
- Foxl Notes: transcript playback highlights exactly one line - previously the last line of every earlier speaker group lit up too.
- Foxl Notes: settings dropdown no longer clips its values at the panel edge.
Features
- Foxl Notes: floating meeting HUD (glass panel). Starting a recording on the desktop now opens a compact always-on-top companion window with the live transcript, translations, timer, and stop/pause controls - so you can follow the meeting while other apps are full screen. On macOS 26+ it renders with the native liquid-glass material. Toggle in Notes Settings > Recording.
- Foxl Notes: meeting coaching report. A new Report tab analyzes your meeting after it ends: overall score, speaking share and pace, a skill breakdown (language use / fluency / grammar), sentence-level feedback with suggested phrasing, action items, and expressions to learn. Turn on "Report for every meeting" in Settings to generate one automatically after each recording.
- Foxl Notes: sample report on first run. New users see a complete sample meeting note with a finished coaching report before their first recording.
- Foxl Notes: first-run onboarding. Opening Notes for the first time now walks through language, sign-in, and microphone setup; replay it any time from Settings > Show guide.
- Google profile photo as your default avatar. Signing in with Google now uses your Google profile picture across Foxl and Foxl Notes; you can replace or reset it from the Account page.
Improvements
- Foxl Notes: live translation now translates complete sentences. Instead of translating each speech fragment as it arrived (choppy half-sentence output), the transcriber's fragments are stitched into full sentences before translation, with a short flush timeout so trailing fragments still arrive.
- Foxl Notes: turning on live translation picks a sensible target language automatically (your UI language) instead of staying inert until a second setting was found and set.
- Foxl Notes: Settings reorganized into clear sections - Recording and transcription, AI features, Live translation, Auto-save and export, General, About and updates - matching the Foxl Agent settings layout.
Fixes
- Foxl Notes: the Start button works with live translation on. Recording with live translation captures the other party's system audio; the desktop app was missing the screen/audio capture handler, so the presigned capture request failed instantly and the Start button appeared dead. Both dev and production Electron builds now register the handler (with loopback system audio on macOS/Windows).
- Foxl Notes: recording no longer fails with "Failed to execute 'start' on 'MediaRecorder'". System-audio (live translation) and some virtual audio devices reject the local audio-copy recorder; that copy is optional (it was never saved to disk), so the error is now non-fatal and transcription proceeds normally.
- Foxl Notes: exports now default to a "Foxl Notes" folder inside Documents instead of scattering files in the Documents root. Still configurable in Settings > Auto-save location (an existing custom folder choice is respected).
- Foxl Notes: HUD transparency slider in Settings > Recording controls how see-through the floating meeting panel is, updating live while it is open.
- Foxl Notes: the live panel grew into a full meeting companion. Live / Notes / Background tabs (notes are editable right in the panel, markdown supported), an AI chat with message bubbles and one-tap reply suggestions, a hamburger menu (transparency, fully-transparent ghost mode, text size, live translation, suggestions, always-on-top), and a mini mode that shrinks the panel to a tiny caption pill for screen sharing. The panel stays open after Stop so it works across back-to-back meetings; auto-open on record start is a setting. Live captions auto-scroll but pause when you scroll up (jump back with the Latest button).
- Foxl Notes: translation keeps up with continuous speech. In-progress (italic) captions now translate in rolling chunks instead of waiting for the sentence to finish; Transcribe partial-results stabilization makes finals land in smaller, faster units; filler-only fragments ("I", "um") are dropped instead of translated; and the translator never replies with meta commentary ("I cannot translate...") anymore.
- Foxl Notes: personal AI context in Settings > AI features - tell the assistant who you are and what your meetings are about, and HUD answers and reply suggestions take it into account.
- Foxl Notes: auto title works independently of auto summary, and auto-saved files are named after the generated title (never "New Transcript"), prefixed with the date:
2026-07-10 - Title.docx. - Foxl Notes: speakers are diarized again ("Speaker 1/2", system audio as "Remote 1/2") instead of everything being labeled ME.
Features
- Find any past conversation from the agent. A new conversation search lets the assistant look back through your earlier chats by keyword (full-text search), so it can recall what was actually discussed instead of only what was saved to memory. The chat search box is faster and more accurate too.
- Foxl Notes: live translation. Turn on live translation in Notes settings, pick a target language, and each incoming line of the other party's speech is translated on the spot as the meeting happens - built for following meetings in a language that is not your first. Uses a fast model by default.
Improvements
- Sidebar shows the current chat's title in the header instead of a generic "Chat" label.
- Scroll date overlay on the chat and Notes lists shows the exact date of each session (Today / Yesterday, then the real date) as you scroll, so it is clear which conversation happened when.
- Notes controls pack cleanly in small windows - buttons collapse to icons and an overflow menu instead of overlapping.
Fixes
- Foxl Notes no longer crashes to an error screen when switching between Notes and Chat while a summary or transcript is loading. A tiptap editor teardown race ("Cannot read properties of null") is now guarded.
Fixes
- Chat no longer loses earlier messages from the model's memory on long or interrupted conversations. The conversation the model remembered could drift from what the chat showed on screen: a long chat silently dropped its opening turns, a stopped turn left a phantom "Cancelled by user" reply the model learned to imitate, and a turn interrupted by a crash could vanish from the model's view while still showing in the chat. The app now rebuilds the model's memory directly from the same messages the chat displays every time a conversation is resumed, so what you see is always what the model sees. Prompt caching and tool calling are unchanged.
- Foxl Notes no longer crashes to an error screen while an AI summary is streaming in. A timing race during editor teardown could throw "Cannot read properties of null (reading 'cached')" and blank the Notes screen when a summary arrived as the editor was being replaced. The editor now guards against that teardown window.
- Foxl Code task icons now line up vertically when the sidebar is collapsed. In the collapsed icon rail, the Foxl Code task list kept its full-width left-aligned rows, so the task avatars sat off to the left instead of centering in the narrow rail like the nav icons above them. Collapsed rows now show a single centered agent avatar (matching the Chat conversation list), and the expanded list is unchanged.
Fixes
- Long thinking-enabled conversations no longer break with an "Invalid signature in thinking block" error. After the move to structured conversation persistence, resuming a long conversation (especially across an app restart or a model switch) could fail with a Bedrock 400 (
Invalid signature in thinking block). Extended-thinking blocks carry a cryptographic signature tied to the exact moment and model that produced them; replaying those historical blocks verbatim made the provider reject the whole request. Foxl now drops prior turns' thinking blocks when restoring a conversation for the model (the current turn still thinks normally), which is the provider-recommended behavior and verified against real Bedrock. No loss of functionality: reasoning still streams live, it just isn't replayed from history. The relay now applies the same guard on its Bedrock path as defense-in-depth, so older desktop builds and other clients are protected too.
Fixes
- Opus 4.8 now reliably runs tools instead of printing them as text. In longer conversations Opus 4.8 could reply with a literal
[Tool: ...]line instead of actually running the tool. Root cause: prior turns' tool calls were replayed to the model as a TEXT summary glued onto the assistant's message, and 4.8 (the most instruction-following model) copied that shape as its own output. Foxl now persists and restores the full STRUCTURED conversation (real tool-use / tool-result blocks) via the Strands SessionManager, backed by our existing local database, so the model sees past tools as typed actions - not text to imitate. Existing conversations are upgraded automatically the first time they're opened, and conversations now survive an app restart mid-thread. - Type-ahead message queue no longer double-sends or fragments (desktop). When you type follow-up messages while Foxl is working, they queue and splice into the running turn at the next tool boundary (Claude Code style). A dual-path race between the client-side drain and the server-side boundary flush could enqueue the same message twice, or send queued messages one-at-a-time instead of merging them into a single follow-up. Each queued message now has a single owner from the moment you send it, so it is delivered exactly once and always merged with its siblings.
- Same queue hardening on mobile + web (app.foxl.ai, iOS). The relay-mode chat used by the mobile and web apps had the same class of race: a rapid burst of follow-ups could launch concurrent sends (duplicate messages/bubbles), and the queue drain ran its send inside a React state updater, which double-fires under StrictMode. Both now go through one synchronous in-flight latch and drain the whole queue as a single merged turn - delivered exactly once.
- Conversation snapshots no longer duplicate your first message. The structured-persistence upgrade could store the first message of a turn twice (it was written by the app before streaming and appended again by the agent), permanently doubling it in the model's memory of the conversation.
- Memory and skill updates now reach ongoing conversations. Restored conversations were frozen on the system prompt captured when they were first saved, so new memories, skills, and workspace changes never reached them. Snapshots no longer store the system prompt - it is rebuilt fresh every turn.
- Editing or deleting a message now really removes it from the model's context. Edit, regenerate, reset, and single-message delete previously left a stale conversation snapshot behind, so the model could still "remember" turns you had deleted. All four flows now invalidate the snapshot, which is rebuilt from the message history.
- Restored conversations can no longer hit a Bedrock validation error. Snapshots could contain empty text blocks (a side effect of streaming), which Bedrock rejects when the conversation is restored after a restart. They are now filtered out on save and restore.
- Removed a wasteful no-op compaction step. Long conversations triggered a paid "context compaction" model call that operated on a text copy of history the model no longer reads - it reduced nothing while showing a "Context compacted" notice. Context is now bounded by the agent runtime itself (sliding window + automatic overflow recovery).
- Foxl Notes: AI summaries are now sanitized before rendering. A crafted meeting transcript could smuggle active HTML through the AI summary into the editor. Summaries and AI-generated markdown are now sanitized (DOMPurify) with no change to how markdown renders.
- Web/mobile chat storage survives quota pressure. If browser storage filled up (large pasted images/files), conversation saving silently stopped for every conversation. On quota errors Foxl now strips attachment payloads from local history and keeps the newest conversations instead of dropping everything.
Fixes
- Claude Fable 5 works reliably again. Amazon Bedrock flipped which inference profile serves Fable 5: the
global.profile Foxl used since launch now returns server errors, while the standardus.profile (the same kind Opus and Sonnet use) now works from every region. Foxl switched Fable to theus.profile and removed the special us-east-1 routing it needed at launch. Fable now runs through the normal region like every other model, so the intermittent failures are gone. No action needed on your part.
Features
- New model: Claude Sonnet 5. Anthropic's most capable Sonnet - near-Opus 4.8 intelligence at the same Sonnet price ($3/$15 per million tokens), with a 1M-token context window and 128K max output. It is a drop-in successor to Sonnet 4.6: same adaptive thinking, same everything, just smarter. Sonnet 5 is now the default model for chat and the autonomous code orchestrator (Opus 4.8 remains the default for the coding agents and the desktop app), and it is available on the free tier alongside Sonnet 4.6 and Haiku 4.5. Adjustable reasoning effort (low through max) is supported, defaulting to medium - the best speed/quality tradeoff for everyday work. Pick it from the model selector on desktop, app.foxl.ai, Foxl Code, and Foxl Notes.
Features
- Type a follow-up while Foxl is working and it queues, then sends at the next natural break - just like Claude Code. Previously a second message sent mid-response either waited until the whole turn finished or cut the running turn off entirely. Now it is held and spliced in at the next tool-call boundary: the current tool finishes cleanly, your queued message lands as its own turn, and Foxl responds to it - without restarting the work. Queue several and they merge in order into a single follow-up. Press Esc (or Stop) to interrupt immediately instead of waiting. This works on the desktop app and on remote-connected desktops (via the relay tunnel); the cloud-only chat at app.foxl.ai keeps its end-of-turn queue since it has no tool loop to break at. Verified end-to-end against real Bedrock (the queued message is provably consumed only after a completed tool call, never mid-tool) and in a real browser (the queued text renders as its own message and gets its own reply).
Internal
- Upgraded the Strands agent SDK to v1.7.0. The mid-turn queue is built on the SDK's tool-boundary hooks (
AfterToolsEvent/AfterInvocationEvent), using only public APIs - no SDK patching.
Features
- Message action buttons (copy, edit, regenerate) now appear on tap on mobile. On desktop they were already shown on hover. On mobile they were always visible, cluttering every message. Now they start hidden and appear when you tap the message bubble - tap again to hide.
Fixes
- Attaching files with the AWS (Bedrock) provider no longer fails with "The model returned the following errors: ...content.N.type: Field required". Root cause (found via real end-to-end reproduction against Bedrock): with prompt caching on, the agent SDK appends a cache marker to the end of your latest message, and Bedrock rejects that marker when the block right before it is a non-PDF document - which is exactly how a pasted .txt/.csv/.md file lands. (PDFs and images coexist with the cache marker fine.) Foxl now suppresses prompt caching only for a message that carries a non-PDF document attachment, so PDF and image turns keep their cache savings, and the conversation is re-used correctly afterward. Verified end-to-end on the real desktop AWS-provider path (the exact failing request now succeeds, PDFs still cache).
- The relay path is also hardened against malformed attachment blocks. Two related causes were fixed for chats that go through the relay (app.foxl.ai, mobile, relay-routed desktop): (1) some attachments reached the model as a content block missing its
typefield, which the Anthropic API rejects; (2) non-PDF documents (txt, csv, md, json, docx, ...) were sent as native document blocks, but Bedrock's Claude only accepts PDF that way. Non-PDF files are now inlined as text (their contents still reach the model), PDFs stay document blocks, and the relay defensively repairs any malformed block before it reaches Bedrock. Verified end-to-end against real Bedrock. - Attaching two files with the same (or non-Latin) name no longer errors. Bedrock rejects messages with duplicate document names, and the name sanitizer collapsed non-Latin filenames (e.g. Korean) to the same fallback name. Document names are now de-duplicated before sending.
Fixes
- Agent-created terminals now appear in the UI. Terminals opened by the AI agent were invisible in the desktop app: the terminal panel never opened and the tab never appeared. Root cause: the internal WebSocket that listens for terminal spawn/exit events was not sending the connection security token, so the server immediately closed it (code 4003) in production builds. The token is now attached, the connection stays open, and agent-spawned terminals show up and stream live as expected.
- Web/mobile app no longer refreshes when your desktop connects. On app.foxl.ai (and the mobile app) the app starts in offline mode and used to do a full page reload the moment your desktop came online - a jarring refresh that interrupted whatever you were doing. Now the switch to live desktop data is seamless: the chat list and open conversation refresh in place (an in-progress reply is never dropped), and a small "Desktop connected" note appears instead of a reload. Coming back to the app after it was in the background no longer risks a surprise refresh either.
Fixes
- Terminals now sync live everywhere, no matter who opened them. A terminal that appears on your desktop - opened by the AI agent (its terminal tool), a background task, or the desktop UI itself - now shows up and streams its output live on every connected surface: the desktop window AND the web/mobile app (app.foxl.ai). Before, an agent-created terminal could be added to the tab bar without ever becoming the active tab (so it never connected and showed no output), and the phone never learned about a terminal it didn't open itself. Now the desktop forwards every terminal it opens to your connected phone/web, and each surface auto-selects the new terminal so it streams immediately.
Changes
- GLM 5 and Kimi K2.5 are no longer offered on Foxl relay credits. Their results did not meet our requirements for hosted models, so they've been removed from the model picker on app.foxl.ai, mobile, and the web app. They remain available on the desktop app if you connect your own AWS Bedrock account (Settings -> Providers), where they run on your AWS bill rather than Foxl credits and stream natively.
Fixes
- Remote access status is now instant and always accurate. The Mobile/Web page could show your desktop green ("connected") while chat, the channel list, and remote actions all failed with "Desktop is offline" - and even when correct, it could lag up to ~10s behind the real state. Two fixes: (1) the live relay tunnel is now the single source of truth - the desktop's background heartbeat only updates "last seen", while online/offline is owned by the tunnel itself, so the badge can't disagree with whether remote features actually work; (2) the desktop coming online or dropping is now pushed to the web/phone instantly over a live connection instead of being discovered by polling, so the status flips the moment it changes. Even a desktop that dies ungracefully (crash, power loss, network drop with no clean disconnect) is now detected - previously that left the badge stuck green while every request silently timed out; now the connection's missing heartbeats are noticed and the status flips to offline within ~2 minutes (instantly if you try to do something, which fails fast as "offline" instead of hanging). This was also re-built to stay well within free-tier infrastructure limits as usage grows (status rides a near-free idle socket and the heartbeat write is coalesced, instead of every open tab polling on a timer).
- Mobile/Web page: tidied the device controls. The row of unlabeled icon buttons (refresh / check for updates / restart / unpair) is now a single "⋯" menu with clear labels, so it's obvious what each action does. The remote-access on/off switch stays where it was.
- Model selector always reflects what's actually available now. It could keep showing a stale selection cached from a previous session or from when the desktop was connected (e.g. a desktop-only model after the desktop went offline). The list now refreshes the instant the desktop connects or disconnects, and if your selected model is no longer offered it snaps to an available one instead of showing a dead choice.
- Mobile terminal: reverted the iOS keyboard rework that broke typing. The recent change that let you type straight into the terminal on iOS (with a keyboard accessory bar) regressed the experience - tapping the terminal made the keyboard flicker up and down, and Korean/CJK still split into separate jamo. The terminal is back to the previous keyboard behavior on mobile: a dedicated command box that composes Korean correctly, with the quick-key row (Tab/esc/^C/arrows) below it. The terminal chrome redesign and the rotation/resize fixes are kept.
- Stopping a reply now also stops the "Thinking…" shimmer. When you cancelled a response mid-thought, the reasoning header kept its animated "Thinking…" shimmer forever because the cancel path never marked the reasoning block as finished. Cancelling now ends the reasoning block (it switches to "Thought for N seconds") in chat and in the relay/web app, and also tears down a re-attached background stream so it can't restart the animation. (The underlying generation and any in-flight tool were already stopped server-side; this was a display-only leak.)
- Terminal tab status now updates live. A terminal tab's status dot stayed green even after its process had ended - the dot only changed when you deleted the tab by hand, so a shell you exited (typed
exit, the process died, or an agent-spawned command finished) kept looking like it was still running. The dot now turns gray the instant the process exits, in the desktop app and over remote access (Mobile/Web), and dead tabs are cleared when you open a new one. - Terminal: reconnect button + auto-reconnect on resume. Next to the fit-to-width button in the terminal toolbar there's now a reconnect (refresh) button that tears down and re-establishes the connection for the current terminal, re-loading its scrollback - handy when a session looks wedged or shows "[Disconnected]". On top of that, the terminal now reconnects automatically when you bring Foxl back to the foreground: backgrounding the app (especially on mobile) can let the OS drop the connection, and instead of sitting on a dead "[Disconnected]" terminal until you tap reconnect, it re-establishes itself the moment the app resumes (only when the connection was actually lost, so an active session is left untouched).
Changes
- Free credits now refill on your own monthly anniversary. Instead of every free account refilling on the 1st (a date that had nothing to do with when you joined), your 10 monthly credits now top up on your sign-up day each month. If you joined on the 31st, months without a 31st refill you on their last day (Feb 28/29, Apr 30, etc). The Account page shows your exact next refill date (now displayed correctly in all time zones - it previously could read one day early west of UTC). Your welcome credits remain permanent (no expiry) as before.
- Foxl Code: one-tap "Connect GitHub". The connect flow was redesigned to a single button. Instead of choosing between "open GitHub install", typing a GitHub login to adopt, and a dead-end "configure" screen, you now click "Connect GitHub" once, authorize on GitHub, and every organization and account you can access is connected automatically (repos synced, membership granted with your real org role). If your Foxl account had no GitHub identity yet, the authorize step links it. No more guessing which button connects your repos.
Fixes
- Mobile search palette (Cmd/Ctrl+Shift+F) now docks above the keyboard. On phones the global search palette (shared by chat conversations, Notes recordings, and Foxl Code tasks) opened as a full-screen sheet whose results list ran behind the on-screen keyboard - so the list could not be scrolled and the keyboard could not be dismissed without closing the palette. The palette now shrinks to the real visible height when the keyboard is up (the list always keeps a scrollable area above it), and dragging the list retracts the keyboard. Desktop keeps the centered command card.
- Conversation search (Cmd/Ctrl+Shift+F) reads more clearly and focuses the chat you pick. Results now show each conversation's last-activity date instead of a repeated message icon, and stay sorted newest-active first. Opening a result selects it in the left sidebar and scrolls that row into view, even for an older chat that wasn't yet loaded in the list.
- Foxl Code repos list is calmer on mobile. Every repo row used to show a full "Start task" button, repeated down the whole list. On phones each row now shows a single compact chevron; desktop keeps the hover-revealed "Start task" button.
- iOS terminal: Korean (and other IME) input works. Typing Hangul straight into the on-device terminal previously produced broken jamo because the terminal's built-in text field can't commit IME composition inside the iOS web view. The terminal now routes keystrokes through a dedicated invisible composition field and sends only completed characters to the shell - so Korean/Japanese/Chinese type correctly while still feeling like typing directly into the terminal (no separate command box).
- Mobile terminal reflows on rotation. On phones the terminal width was pinned to its initial value, so rotating the device (or showing/hiding the keyboard) left the columns wrong and text clipped. It now recomputes its size on orientation and viewport changes.
- Rate limiting can no longer be burst past under load. The free-tier daily request quota used a check-then-record sequence that two simultaneous requests could both slip through; admission is now a single atomic step, so the quota holds exactly even under concurrent traffic.
- Subscription credit recovery is now once-per-period. A safety net that re-grants a paid subscriber's monthly credits if a renewal webhook is missed could, in some cases, re-grant the full allotment every few minutes once the balance hit zero. Recovery is now locked to exactly one grant per billing period (and correctly ignores already-expired credits), so paid balances refill on the real billing cycle and never double up.
Security
- Foxl Code: stricter input validation on team-member admin actions. The endpoints that remove a member or change their role now validate the target account id format before touching the database - defense-in-depth hardening on the org/team management surface added in v0.3.15.
Security
- Foxl Code: membership is now proven and revocable. Connecting a GitHub organization or account to Foxl Code now requires proving you personally have GitHub access to it (a GitHub authorization step), instead of trusting a typed login. Membership is also continuously re-verified: if you leave a GitHub org, or an admin removes you, your access is revoked and your running tasks for that install are stopped. The Repos page gained a "Who can use this install" panel so you can see exactly which Foxl accounts can act on your repos, with admin controls to change roles or remove members. This closes a cross-tenant access hole and adds the offboarding lifecycle (departures, role changes, team moves).
Fixes
- iOS terminal types directly, like a real terminal. Opening the terminal from the chat bar on iPhone/iPad no longer shows a separate command box below the keyboard. You now tap the terminal and type straight into it, exactly like on desktop, with the quick keys (Tab/Esc/Ctrl-C/arrows) riding on the keyboard itself. This removes the duplicate input surface and makes the on-device terminal feel native.
- Foxl Code: tapping a repo no longer jumps to chat. On mobile, tapping a repo row in the Repos list used to fling you into the new-task composer just from browsing. Repos now only start a task from an explicit "Start task" button (always visible on mobile, hover-revealed on desktop).
- Foxl Code: stop auto-syncing repos on every tab switch. The Repos page used to re-sync (and flash "Synced N repos") every time the tab regained focus. It now only syncs after you actually visit GitHub to change an install, and that implicit sync is silent.
- Foxl Code: disconnect / leave an installation. Each install's access panel now has a gear menu with "Manage on GitHub", "Change repo access", and "Disconnect / leave" - so you can relinquish your own access (and, if you are the last member, fully disconnect the install from Foxl) without uninstalling the GitHub App.
- Foxl Code: back from a runtime returns to Runtimes, not chat. Opening a task from the Runtimes page and pressing back used to drop you on the chat composer. Back now returns to wherever you opened the task from.
- Foxl Code: redesigned repo picker. The repo selector now matches the model picker - a searchable list with a Favorites group on desktop, and a full bottom sheet with tall touch rows + a search box on mobile.
- Account & Notes-settings pages scroll again. Inside Foxl Code (and Foxl Notes) the Account page and the Notes settings page were clipped with no way to scroll to the lower content (usage, billing, delete account). Both now own their vertical scroll inside the shell.
Features
- Terminal redesigned for the new app shell. The terminal panel no longer has its top row clipped when it opens inside the rounded app window, and fullscreen now fills the content area cleanly instead of overlapping the header. The tabs, buttons, and resize handle were restyled to match the rest of the app (rounded controls, consistent hover, smooth motion). On phones the command bar is cleaner and docks right above the keyboard, with bigger, evenly sized quick keys (Tab/Esc/Ctrl-C/arrows) and a proper send button. On iOS those quick keys now ride ON the keyboard itself (a native accessory bar that appears only while the terminal input is focused), so they move perfectly in step with the keyboard like a real terminal app.
- Edit and scroll pasted text in the composer. When you paste a long block of text it collapses into an attachment chip so the input stays tidy. You can now expand that chip to scroll through the whole thing (no more 2,000- character preview cutoff) and edit it inline before sending - trim it, fix a typo, or clear it to drop the attachment. Large pastes stay smooth: only the on-screen portion is rendered, so editing a huge paste no longer lags.
Fixes
- Refreshing during a long reply no longer drops the beginning. When you reloaded the page while the assistant was streaming a long answer, the recovered message could come back missing its opening - only the tail survived. The live recovery buffer is capped to bound memory, and a very long reply overflowed it. Recovery now reads from a separate uncapped record of the in-flight turn, so the whole reply (text, reasoning, and tool calls) comes back intact no matter how long it is. Reconnecting also targets the exact in-flight message, so a follow-up turn can never get glued onto the previous answer.
- Switching chats mid-reply and back now resumes the live stream. If you left a chat while it was still answering, read another conversation, then came back, the reply used to look frozen at wherever it was when you left (it kept generating on the server, but the screen stopped following it until a full reload). Coming back now re-attaches to the live stream the same way a page refresh does, so the answer keeps flowing in. Leaving it running in the background and finishing there still works too - it is marked unread and floats to the top of the list when done.
- Failed scheduled tasks now show as failed. A scheduled task that errored out was still recorded as "completed", which also meant a repeatedly-failing schedule never auto-disabled itself. Failures are now recorded as failed (with the error message), count toward the auto-disable threshold, and the run is still openable as a chat so you can see where it stopped.
Changes
- Personal Brain removed. The For You dashboard's "Today brief" and "Personal Brain" cards and the foxl-brain skill that fed them have been pulled out. For You now shows your upcoming schedules and today's usage. No data you created elsewhere is affected.
Features
- Open any background run as a chat. Scheduled tasks, the Feed Generator heartbeat, and chat subagents now save their full run as a conversation - every step the agent took, the tools it called, and what each tool returned. Click a run in Schedules or Activities (or "Open as chat" on a subagent in Agents) and it opens in the normal chat view with the same tool bubbles a live chat shows. This makes it obvious why a scheduled task did what it did (for example, whether it actually read a skill or where it got blocked), instead of only showing a one-line summary. These run conversations are kept out of your normal chat list and are reached only from those run views, and they are pruned automatically so they never grow without bound.
Fixes
- Deleting a conversation now fully removes it. Foreign-key enforcement is on, so removing a conversation also clears its messages, tool calls, and reasoning instead of leaving orphaned rows behind.
- Subagent and scheduled-run transcripts are faithful and cache-friendly. A forked subagent inherits its parent's conversation so repeated requests reuse the prompt cache (faster, cheaper); the saved transcript now shows only that subagent's own work instead of replaying the parent's. The inherited context is no longer truncated before the model sees it, so the cache is actually reused on longer conversations.
- Mobile: repository names use the full row width. In Foxl Code on a phone, the Repos list no longer clips long owner/name titles behind an invisible button; the name spans the whole row and the row itself taps to start a task.
- Mobile: workspace search fills the screen. The search-all-conversations palette (Cmd+Shift+F, or the header search button on a phone) opens as a full-height sheet on phones instead of a small centered card, so the input is reachable and results use the whole screen. On desktop it stays the centered dialog.
Improvements
- Schedule runs open straight to their transcript. In Schedules, a run with a saved transcript opens as a chat in one click (no expand, no extra button), and a slim "Back to Schedules" replaces the header title while you read it.
- Cleaner run + subagent status. Schedule run rows and the sidebar subagent list now use a single quiet status dot (running, done, failed) instead of competing full-color icons, matching the rest of the app.
- Clearer schedule details. The schedule detail dialog leads with the type, status, and cadence, then lists last run, next run, run count, timeout, and created time as full, untruncated values.
Fixes
- Model responses no longer cut off mid-answer. The relay was parsing Amazon Bedrock's binary streaming format as if it were text, which let a random checksum byte silently swallow the rest of a long response. The stream is now parsed by its real binary framing, so long answers, tool-heavy turns, and code blocks always stream to completion. Verified against a real captured stream that previously dropped 70 of 119 events.
- Mobile chat keeps following new messages. Opening the keyboard or growing the composer no longer turns off auto-scroll, so replies keep scrolling into view without tapping the scroll-to-bottom button. Auto-scroll now only pauses on a deliberate upward scroll and resumes when you return to the bottom or send a new message.
- Foxl Notes mobile home fits the screen. The Record-a-meeting screen no longer overflows sideways: the Start Recording button and recent-note cards stay within the viewport, recent-note previews show clean text instead of raw HTML tags, and the duplicate bottom Start button is gone. Note summaries are now stored as markdown so titles and previews stay readable everywhere.
Improvements
- Settings is scoped to each product. Opening Settings inside Foxl Agent now shows only agent settings; Foxl Notes and Foxl Code each have their own Settings within their product. No more cross-product settings mixed into one list.
Features
- For You dashboard. The Feed page is now "For You": an at-a-glance dashboard with a Today brief, your personal knowledge brain (people, companies, meetings and recent pages), upcoming schedules, and today's usage, with the suggestions inbox below. The sidebar item and all languages follow the new name.
- Personal Brain (beta). Foxl can now maintain a personal knowledge brain as plain markdown in your workspace: people, companies, meetings, concepts, and your own original ideas, cross-linked and consolidated nightly by an opt-in dream cycle. Ask Foxl about anyone you have met and it answers from your own notes, with sources cited and gaps called out. Powered by the new foxl-brain skill; the For You page shows the brain at a glance.
- Account deletion and data export. Delete your account (with a data purge) directly from the Account page, and download your data as JSON or your usage history as CSV at any time.
- Billing lifecycle emails. Welcome email on signup, usage alerts at 80% and 100% of your credits, and a heads-up email if a subscription payment fails, with a banner in the app until it is resolved.
Improvements
- Cold start is much lighter. The main bundle dropped by about 360 kB and the Notes page by about 650 kB (the editor and sub-agent chat view now load on demand), so the app paints noticeably faster on first open.
- Fairer plan changes. Downgrading a subscription now keeps your current credits until the end of the paid period instead of dropping them immediately; refunds claw back only the matching top-up.
- Abuse protection. Per-minute rate limits on the relay, burn-rate monitoring, and welcome credits sized by signup method keep shared capacity safe without affecting normal use.
Fixes
- Sign-in deep links are now CSRF-protected. The desktop and Notes apps reject any sign-in callback they did not initiate, closing a session-fixation vector. Transcription metering is now bound to the recording session server-side.
- Chat streaming cleanup. Fixed a timer leak in the streaming batcher that could fire after leaving the page, and capped the page cache so very long sessions no longer grow memory without bound.
- TypeScript board cleared. Removed seven dead Notes components and fixed all five long-standing type errors; the web app now typechecks clean.
Features
- AI-first Foxl Notes on mobile. The phone experience is redesigned around the AI: a hero Start-recording screen with your recent notes, a full-height live transcript while recording (no more duplicated half-screens), and a new Summary | Transcript | Notes view switcher that lands you on a streaming, read-only AI summary the moment the recording stops. Ask AI is now a labeled button with suggestion chips during the meeting, and the editor becomes an explicit edit mode with a slimmed-down mobile toolbar.
- One motion system across the app. Page and section switches, list items, cards, sidebars, and buttons now animate on a single set of durations and easing curves (the chat language), including press feedback on every button and restored accordion animations. Respects reduced-motion preferences.
Improvements
- Pages load dramatically faster. The statistics dashboard, Workspace, Account, Agents, Settings, Schedules, Activities, Logs, Skills, and Integrations pages now render instantly from cache on revisit and refresh in the background instead of blanking behind spinners. Server-side, the dashboard, workspace tree, workspace search, skills scan, and agent-session queries were rewritten or cached - the worst offenders were full-database aggregations and per-file disk scans running on every poll.
- Chat streaming is smoother. Streaming tokens are batched into far fewer screen updates, completed messages no longer re-render while new ones stream, and auto-scroll is frame-synced.
- Build identity everywhere. Every About/version display now shows the exact build as version + git commit (for example 0.3.10 (dd21869)), and the iOS build number is now the commit count, so TestFlight re-uploads no longer masquerade as a different version.
Fixes
- The 30-day usage chart on the Account page now actually shows 30 days of real data (it silently fell back to 24 hours and dropped every row of the model breakdown).
- Accordion sections animate again (the open/close animation was lost in the Tailwind v4 migration and content has been snapping since).
Fixes
- Opening the sidebar no longer crashes the app. The first v0.3.9 build could blank the whole app (black overlay on mobile, white screen in Foxl Code) the moment the sidebar rendered a non-empty Code task list: the task rows were wired to a sidebar context from the wrong component library, which threw on mount and took the app down with it. The rows now use the shell's own sidebar primitives. A second crash path - an unexpected repo-list response wiping the repo cache and crashing every repo consumer - is also hardened. The over-aggressive document pin (
body { position: fixed }) that fought the sidebar drawer's scroll lock is removed; push-up protection is fully carried by scoped auto-scrolling, the scroll-reset guard, and the native web-view pin. - The mobile app no longer gets pushed up off-screen during recording. On iOS, starting a recording in Foxl Notes (or any streaming/keyboard-heavy screen) could shove the whole app upward so the navigation bar disappeared and never came back. The cause was
scrollIntoViewand focus calls scrolling the entire app shell - and the keyboard plugin snapping the web view to the wrong resting position. Auto-scroll and focus everywhere are now scoped to their own scroll container, a scroll-reset guard snaps any stray document offset back, and the iOS shell pins the web view to its correct resting offset, so the push-up can no longer happen. - The chat usage HUD shows the real prompt size. "Input tokens" now counts the full prompt the model read (uncached input plus cache-read and cache-write tokens) with a "Cached" breakdown, instead of showing only the few uncached tokens - which made a large skill+system prompt read as a nonsensical "2". All numbers come straight from the model's reported usage.
Changes
- Foxl Code Repos is a clean list. The repos page is now a list (with a grid toggle) that leads with the repo name, branch, language, and description, instead of repeating "Connected / Installation #... / tokens are minted per task" and an inline task form on every card. "Start task" routes to the Tasks page; describing a task lives there now.
- One place for the task budget. The per-repo and per-task budget inputs are gone - the default task budget is a single setting in Foxl Code Settings.
- Right-click menus across Foxl Code. Task rows, repo rows, and the task list all have right-click context menus (open, open on GitHub, copy id/branch, resume, cancel, delete, delete all). The always-visible "Delete all" button is gone - deleting is behind right-click now, matching Foxl chat.
Features
- The sidebar conversation list reorders live, with a smooth animation. Sending a message (or a background conversation finishing its reply) now floats that conversation to the top of the sidebar immediately - no reload needed - and rows glide to their new position instead of snapping.
- Foxl Code's model picker now matches the chat one. The composer model picker in Foxl Code (code.foxl.ai and in-app) gains search, sticky provider section headers, right-click favorites pinned to a Favorites group, a bottom sheet on mobile, and live models from the Foxl catalog with Pro-only models badged - the same selector experience as Foxl chat.
- Foxl Notes got a real mobile layout. On a phone, Notes no longer renders the squeezed desktop chrome (header buttons overlapped the tabs, the side transcript dock left a sliver of editor, and picking a note from the sidebar appeared to do nothing). Mobile now has a thumb-reachable bottom action bar (record/stop + timer + pause, AI, summarize, transcript), the transcript opens as a portrait half-split under the editor, the AI assistant opens as a bottom sheet over the editor, and tapping a note closes the sidebar overlay and shows the note.
- The app shell got the Codex-style curve. On desktop the content area now floats as a rounded panel over the sidebar surface - the sidebar blends into the window chrome and curves into the content instead of meeting it at a hard border line. The sidebar drag-resize indicator also stops before the curve instead of running the full window height.
- Dashboard pages share one column width. Usage, Agents, Schedules, Feed, Logs, and Mobile/Web all use the same max width (some were wider or narrower), and the last fully-circular action buttons (Channels/Integrations connect buttons, Feed back button, onboarding close) moved to the standard rounded shape.
- Settings is now a two-pane surface. A left nav with search (flat, borderless style) and consolidated sections - General, Model & provider, Heartbeat, Notifications, Safety, Advanced - plus a Products group that embeds Foxl Notes and Foxl Code settings, so all three products configure from one place.
- The HUD shows per-chat statistics. With a chat open, the title-bar popover shows that conversation's exact input/output/cache tokens and caching-aware cost ("This chat"); otherwise app-wide last-24h totals. Historical $0 costs were backfilled from catalog rates, and the metrics render as label/value rows. All HUD text is localized.
- The app detects a dead local server and restarts it cleanly. If the desktop's agent server stops responding, a quiet overlay offers one Restart button: the app frees the server port (killing any orphaned process tree holding it) and relaunches the server as its own child, identical to a normal boot.
- Refreshing mid-reply no longer loses the streaming answer. The desktop now saves the in-progress reply continuously (not just at tool boundaries), and reconnecting after a refresh resumes from the fuller of the saved draft and the live stream snapshot - including the case where the reply had not started yet (no more gluing new text onto the previous answer).
- "Relay" is now "Mobile/Web" (and "Desktop" when viewed from the web/mobile app). The page header shows a compact status row instead of a giant Online/Offline headline, and the legacy local gateway (self-hosted LAN server) was removed - the Foxl relay is the only remote-access path.
- Settings looks like a modern settings screen. Each section is now one flat panel with hairline-divided rows instead of a stack of floating cards.
- The colorful Integrations and Skills heroes are back. The crossfading per-item gradient backdrops returned behind the sample-prompt cards.
- Buttons and inputs share one shape language. Pill-shaped (fully round) buttons, search fields, selects, and segmented filters across Agents, Schedules, Tools, Skills, Channels, Activities, Logs, Integrations, and the remote-access page now use the standard slightly-rounded shape; status dots stay round. The Agents Run button also dropped its paper-plane icon.
- The status HUD in the title bar is cleaner and stays in sync. Regular UI type in a soft pill instead of terminal-style monospace, and the "Running: tool" / thinking line now resets reliably when a reply finishes (it could previously stick after a reconnect).
- Every page now speaks the chat design language. Skills, Tools, and Channels dropped their centered marketing-style titles for the same left-aligned header Settings and Integrations use; the Skills hero lost its hardcoded gradient (which broke in dark mode) for the flat panel Integrations has; pill-shaped search fields and CTAs became the standard rounded inputs/buttons; and Account, Notification Settings, and Notes Settings now sit in the same centered column as Settings instead of pinned to the left edge.
Fixes
- The agent now splits long shell commands instead of failing silently. The agent's instructions tell it to never inline large content into one exec call (such commands can fail with no output at all) and to build big files in small appended chunks across multiple calls, retrying any silent no-output failure as smaller steps.
- Foxl models and your local AWS provider no longer mix in the model picker. Models served on Foxl credits were labeled by their upstream infrastructure ("AWS"), which split them into duplicate sections and merged them with models from your own local AWS (Bedrock) credentials. All Foxl-served models now group under one "Foxl" section; "AWS" is reserved for the local provider. Within every section models are ordered Claude first, then GPT, then open-weight.
Fixes
- The agent's shell tool no longer silently stalls on long replies. When a model on the Foxl relay produced a long response (for example writing a big file in one command), the relay could drop a piece of the streamed response at a network boundary, so the tool call arrived incomplete and ran nothing with no error. The relay now reassembles split stream frames correctly, so long commands and long answers come through whole.
- The shell tool reports an error instead of hanging on an oversized command. A command longer than the operating system's limit used to fail with no result at all. It now returns a clear error explaining the limit and suggesting writing large content incrementally.
Features
- The model picker groups models by provider with a sticky header. As you scroll the model list, the provider name (AWS, OpenAI, ...) stays pinned at the top so you always know whose model you are looking at. Favorites pin to the top of the list.
- Right-click a model to favorite it. Favorited models pin to a Favorites group at the top of the picker (a star also appears on hover).
- Fable 5 is marked Pro in the picker (like Opus), so it is clear which models the free tier cannot run. The Pro gate is now derived from the relay's tier rules, not hardcoded model names.
- Task Budget moved to Settings. The reasoning toggle and per-model effort stay in the message bar, but the advanced Task Budget control now lives in Settings so it does not clutter the quick picker. Reasoning settings share one source of truth between Settings and the picker, so they can never disagree.
Foxl Code
- "Delete all" is now a visible action at the top of the task list (not only in the right-click menu). Tasks that are still running are kept; only finished tasks are removed.
Design
- Settings and Integrations match the rest of the app. Both pages dropped the centered marketing-style headers, oversized width, and gradient hero in favor of the same flat, left-aligned layout the chat surface uses.
Mobile
- The model picker is a smooth bottom sheet on phones. Instead of a small popup that flipped up from the bottom and crowded the keyboard, tapping the model name now slides up a proper bottom sheet with large tap targets and one-tap effort pills.
Features
- Reasoning controls live in the message bar now. The reasoning toggle, per-model effort levels (Low through Max), and the task budget moved from Settings into the model selector next to the send button, so you can tune reasoning per model right where you pick it. Each model shows exactly the effort levels it supports, picking an effort turns reasoning on, and your choice applies immediately to the next message. The selected effort now shows inline in the bar (for example "Sonnet 4.6 Low") instead of a generic "Thinking" badge, and the menu itself is a tighter, lighter design with the effort levels tucked behind an "Effort" row.
- Search the model list. The model selector now has a search box - type a model name or provider to filter the list instead of scrolling.
Removed
- The "Auto" model option is gone. Auto-routing picked a model by guessing the message's complexity and did not work reliably. You now always know exactly which model answers: pick one and it stays. Anyone previously on Auto is moved to their default model.
Foxl Code
- The send button works as you type on mobile. In Foxl Code on phones (and the iOS app), text you typed was treated as empty until the input lost focus, so the send button stayed disabled and a tap sent nothing. The composer now registers what you type immediately, exactly like Foxl Agent, so send enables the moment there is text and always sends what is on screen.
- No more blank gap under Tasks in the Foxl Code sidebar. On the desktop app, when you had no tasks (or were signed out) the Foxl Code sidebar showed an empty stretch between Tasks and Repos where placeholder rows were reserved. An empty task list now collapses to nothing, matching the Foxl Agent conversation list.
Models
- Fable 5 reasoning is now correct for Foxl Code's autonomous agents too. The Foxl Code orchestrator picked each model's thinking mode by matching on the model name, which could send a new model the wrong shape (Fable 5 only accepts adaptive thinking and rejects the older budgeted shape). It now reads the thinking mode from the same shared model catalog the rest of Foxl uses, so any model added to the catalog gets the right reasoning behavior with no code change.
Security
- Closed two command-injection paths in the local desktop server. The "reveal in Finder/Explorer" and "open folder" actions, and external skill installs, now pass paths and package names as arguments instead of building a shell command string, so a crafted path or skill name can no longer run arbitrary commands.
- Background and channel agents now obey approval gates. Agent runs started by a connected channel (e.g. Telegram), a scheduled task, or the browser extension now go through the same permission deny-rules and approval prompts as the main chat, instead of running tools ungated.
- Sign-in links can no longer be forged on desktop. The desktop only accepts a
foxl://sign-in callback when you actually started a sign-in, so a malicious link cannot silently swap your account. - The local dev server binds to localhost only. In development the API and WebSocket are no longer exposed to your local network by default.
- Closed a WebSocket auth bypass. The browser-extension WebSocket path was matched by a loose substring, so a crafted URL containing "/extension" could skip the connection-token check. The check now matches the exact path.
Fixes
- Windows downloads and auto-update work again. The v0.3.4 release went out with macOS files only, which broke the fixed Windows download links on foxl.ai and docs.foxl.ai and silently stopped auto-update for existing Windows installs. The Windows installer, portable ZIP, and update manifest are back on the latest release, and the release script now carries Windows files forward automatically and refuses to finish if any download link would break.
- Model pricing reconciled. GLM-5 and GPT-4o were priced inconsistently in different places, and Kimi K2.5 had no pricing row on the staging backend (where it failed as "unknown model"). All three are now consistent.
- Sign-in is rate-limited everywhere. The token-refresh endpoint now has the same per-IP rate limit as the other sign-in endpoints.
- foxl.ai shows the current model lineup. The pricing and demo screens named retired models; they now show Claude Fable 5, Opus 4.8, and GPT-5.5.
Foxl Code
- Settings sits at the bottom of the sidebar again. In the Foxl Code workspace, Settings was rendered directly under Runtimes with a large blank gap beneath it. It now pins to the bottom of the sidebar (above your account), matching the Foxl Agent layout, while Tasks / Repos / Files / Runtimes stay grouped at the top. Applies to both the in-app Foxl Code and code.foxl.ai.
Foxl App (mobile)
- Swipe from the left edge to open the sidebar. On the iOS app you can now drag in from the left edge of the screen to slide the sidebar open, the same way native apps do. Tapping outside still closes it. Desktop and web are unchanged.
Fixes
- Reasoning toggle now shows correctly for every foxl.ai model. The model list served by foxl.ai did not carry each model's reasoning capability, so Settings wrongly said "This model does not support adjustable reasoning" for models that do (including Fable 5). The model list now carries the reasoning spec, and the chat path picks the correct reasoning mode from the shared model catalog instead of matching model names, so newly added models work without a code change.
Security
- Google sign-in now requires a verified email. The Google login path did not check Google's email-verified flag before matching an existing account, unlike the GitHub and Apple paths. It now rejects unverified Google emails, closing an account-takeover vector.
- Relay CORS fails closed. When the allowed-origins list was unset the relay reflected any caller's origin together with credentials; it now serves a credential-less public CORS posture in that case (the relay uses header auth, not cookies, so nothing was exploitable, but this is the correct default).
- Desktop no longer exposes the process environment to the web layer. The unused
get-envbridge (which would have carried AWS credentials) was removed from both Foxl Desktop and Foxl Notes, and the standalone Notes window now blocks navigation to external origins. - Foxl Code agents validate repo and branch names before using them in git commands, preventing argument-injection from repository metadata.
Models
- Claude Fable 5 is now available. Anthropic's new state-of-the-art model is selectable across Foxl App, Foxl Code, and Foxl Notes. Fable 5 is built for ambitious, long-running work with advanced vision and is top-tier on most benchmarks. It is a Pro/Ultra model (excluded from the free tier like the Opus tiers). Opus 4.8 remains the default; pick Fable 5 from the model selector when you want the most capable model. Pricing is $10 / $50 per million input / output tokens. Fable 5 is also available through your Claude Pro/Max subscription (Claude Code OAuth) on the desktop.
Foxl App
- Sign in on mobile now finishes cleanly. On iPhone, after signing in through the in-app browser the sign-in sheet stayed open on top of the app showing an "Open Foxl" button that did nothing (the app behind it was already signed in). The sheet now closes by itself the moment sign-in completes, so you land straight in the app. The unhelpful "Copy link" button is gone on mobile.
Foxl Code / Foxl App
- Fixed "Sign in with Apple" failing on the first try. Apple periodically rotates its signing keys; when it did, the next Apple sign-in failed once and only worked on a retry. Sign-in now refreshes Apple's keys and retries automatically, so it works the first time across a key rotation.
Foxl Code
- The task list now sits directly under Tasks in the sidebar, and loads instantly. In the in-app Foxl Code, the left sidebar task list used to drop below the Settings row and take a few seconds to appear (while the right rail was instant). It now renders right under the Tasks nav item, matching code.foxl.ai, and the list starts loading the moment you open Foxl Code (with a brief skeleton instead of a blank gap) rather than waiting for the page to finish loading.
- Editable per-task budget. Settings now exposes the default per-task budget in dollars, so you can set the absolute spend ceiling a single task runs under (previously this was an internal fixed value and only the multiplier was adjustable). The per-task override on the new-task dialog still wins.
- More coding agents. The coding-agent runtime was rebuilt on the AWS AgentCore interactive-shell model, adding Cursor, Hermes, and OpenCode alongside Claude Code, Kiro, and Codex. Each runs in its own isolated microVM and opens a pull request the same way. Cursor brings its own key like Kiro; Hermes and OpenCode run on Bedrock.
Foxl App
- Onboarding logo renders correctly in dark mode. The welcome screen logo was color-inverted in dark mode, which flipped its colors; it now shows the correct mark on any theme.
- Onboarding is fully translated. The "Get the Desktop App" step on the web app was English-only; it now follows your app language in all 10 supported languages.
Foxl Code
- Fixed code.foxl.ai rendering with square corners and wrong spacing. After the Foxl Code product moved into a shared package, the standalone code.foxl.ai stopped generating the styling used only by that product, so the composer, tool rows, and message bar lost their rounded corners and padding. They now render the same rounded, properly spaced UI as the in-app Foxl Code and the desktop app.
- The repo name in the message bar no longer overflows. A long owner/repo name now truncates with an ellipsis inside the composer instead of pushing past the edge, matching the model picker next to it.
- The Files page fills the window. The workspace file browser rendered short with empty white space below it; it now uses the full height in every shell (web, desktop, and in-app).
- Sign-in nudge when you are not signed in. Like Foxl Notes, starting a Foxl Code task now prompts you to sign in (with a one-click sign-in action) instead of the button quietly doing nothing, since Foxl Code runs on your Foxl account and credits.
Site & Docs
- docs.foxl.ai home now lists Foxl Notes. The documentation home page added Foxl Notes alongside Foxl Desktop and Foxl Code, both as a product card and in the browse-by-section grid, so all three products are discoverable from the landing.
- foxl.ai/code refreshed for the in-app launch. The Foxl Code marketing page now reflects that Foxl Code runs inside the Foxl app (web, desktop, and phone) in addition to code.foxl.ai, and a broken docs link was corrected.
Foxl Code
- Foxl Code is now built into the Foxl app. The coding-agent product that runs at code.foxl.ai is now available as a third product inside Foxl, next to Foxl Agent and Foxl Notes. Pick "Foxl Code" from the product switcher to see your tasks, repos, files, and runtimes, open a task to watch its live agent terminal, and start new coding tasks - all without leaving the app, signed in with the same account. The standalone code.foxl.ai keeps working as before.
- A failing screen no longer blanks the whole app. The app now wraps each product view in an error boundary, so if one screen hits an error it shows a recoverable message with a way back to Chat instead of a blank window.
- In-app Foxl Code polish. The Task Plan side panel and chat now read in your app language instead of showing internal text labels; the message bar keeps its send button visible and shortens a long model name instead of pushing the button off-screen; the Task Plan panel gained a close button (with a header toggle to reopen it); and the Runtimes screen no longer scrolls sideways on a phone when it shows a long status message.
Foxl Mobile
- Mobile layout respects the notch and home indicator. On iOS the WebView insets its content for the Dynamic Island / status bar and the home indicator, so headers and the bottom composer clear them. (The earlier attempt to add a CSS-level
viewport-fit=coverinset on top of that was reverted - combining it with the WebView inset desynced render and touch coordinates, so taps landed in the wrong place.) - Foxl Code mobile polish. Agent icons (Claude Code / Kiro / Codex) now load correctly; the content pages (Repos, Runtimes, Settings, Account) get the same page gutter as code.foxl.ai instead of sitting flush against the screen edge; and the Code header is decluttered on phones (the repo picker, which also lives in the composer, is hidden in the header on narrow screens).
- Keyboard-docked message bar on iOS. Tapping the chat box now behaves like the Claude / ChatGPT mobile apps: the keyboard slides up and the message bar rides up to sit directly on top of it, the conversation above shrinks to fit, and the header stays put - no more page scrolling or the input getting hidden behind the keyboard. Applies to both Foxl Agent and Foxl Code chats.
- Foundation for Foxl on iOS and Android. Groundwork for a native mobile app that wraps the Foxl web experience (Agent chat, Notes, and Code) with native sign-in, microphone recording for Notes, and push notifications. Billing on mobile is read-only with an external link to manage your plan on the web. The mobile app is not yet in the App Store or Google Play; this release lays the technical foundation.
Foxl Notes
- Fixed "Start Recording" doing nothing (the actual cause). Recording opens a secure WebSocket to the transcription service, but the production app's content-security policy allowed
https:connections without also allowing secure WebSockets (wss:), so the transcription socket was blocked and recording never started - in production only, while development builds (which have no such policy) worked. The policy now permits the secure WebSocket, so Start Recording connects and transcribes as expected. Production builds also now mirror renderer errors into the app log so issues like this are diagnosable without a debugger. - Fixed the Notes header overlapping on narrow windows. On small or mobile-width windows the Notes/Background tabs and the recording controls could overlap. The recording controls now keep their own space and the tabs shrink, so the header stays readable and tappable at any width.
- Notes now follows your app language, in 10 languages. The Foxl Notes interface used to render in your browser's default language regardless of the language you picked for the app; it now stays in sync with the app's language selector. Added Russian and Arabic translations (Arabic also switches the interface to right-to-left), so Notes is now fully translated in every language the app supports.
Foxl Desktop
- Fixed the sidebar and main view disagreeing after a restart. On a fresh launch the sidebar could show Foxl Notes while the main area still showed the Agent chat (or the reverse). The app now restores both the sidebar and the content to the same product you used last.
Site & Docs
- docs.foxl.ai model and tool pages refreshed. The Models page now lists Kimi K2.5 and shows that GPT-5.5 / GPT-5.4 run on Foxl relay credits (not only via a ChatGPT subscription), and the Agent Tools page tool-profile counts were corrected to match the app.
Foxl Notes
- Fixed "Start Recording" doing nothing (for real this time). The previous release added the microphone permission handling but the production build did not pick up the microphone usage description, so on a signed, hardened build macOS still silently refused mic access and Start Recording did nothing - while development builds worked. The production build now ships the correct microphone usage string, and Foxl asks for microphone access before the first recording (with a clear message pointing you to System Settings if access is blocked). Recording now starts as expected.
Site & Docs
- foxl.ai/note refreshed. Tighter hero copy focused on what Notes does (transcription, AI summaries, action items, any language), and the product mockup now matches the real Foxl Desktop app - the product switcher and recordings live in one shared sidebar, with the recording controls in the app header.
- docs.foxl.ai navigation matches across pages. The documentation pages now use the same top-bar order as the docs home: the section links sit next to the brand, with the search box on the right.
Foxl Desktop
- Fixed GPT-5.5 / GPT-5.4 returning an error on your Foxl account. Picking a GPT-5.x model while signed in with your Foxl account still failed with "Model gpt-5.5 is an OpenAI Responses-API model" in the main chat. The previous release routed most paths correctly, but the primary streaming-chat path still sent GPT-5.x to the Claude-style endpoint, which these models reject. That path now uses the same single routing helper as everywhere else, so GPT-5.5 / GPT-5.4 stream correctly on your Foxl account, in the desktop app and at app.foxl.ai. Claude, GLM, Kimi, and Gemini are unchanged.
Foxl Notes
- Fixed "Start Recording" doing nothing. When Foxl Notes moved into the unified Foxl Desktop app, the microphone permission setup did not come with it, so on a fresh install clicking Start Recording silently failed - the app was never allowed to open the mic. Foxl now requests microphone access correctly (with the proper macOS permission prompt and entitlement), so recording starts and the system asks for mic access the first time, as expected.
Site & Docs
- foxl.ai/note redesigned for the unified app. The Foxl Notes page now reflects that Notes ships inside the Foxl Desktop app - every download points at the single Foxl Desktop installer instead of a separate Notes download, and the standalone-only release notes were removed. One download, one account, one balance of credits.
- Docs top navigation no longer wraps to two lines. Adding the Foxl Notes tab pushed the docs.foxl.ai header wide enough to wrap the section labels; the nav now keeps every label on a single clean row.
Foxl Desktop
- Fixed duplicate messages and empty replies when sending quickly. Firing several messages in a row (or re-sending after a slow turn) could duplicate your message, leave blank assistant bubbles, and bind replies to the wrong message. The send path gated new turns on React state that updates asynchronously, so a rapid burst slipped through and started several streams at once. Turn-start is now serialized with a synchronous per-conversation latch, so a burst becomes one turn plus the rest queued into a single follow-up. The fix is keyed by conversation only - it is model- and provider-agnostic.
- Reasoning controls now adapt to the selected model. The thinking/effort setting was a single fixed list (low/medium/high/max) that did not match what each model actually accepts, and the effort never reached OpenAI-on-Bedrock (GPT-5.5/5.4) at all. Each model now declares its reasoning style and supported effort levels in one place (the model catalog), and both the server request and the Settings UI are driven from it: GPT-5.5/5.4 expose none/low/medium/high/xhigh and now actually send their reasoning effort; Claude Opus exposes low through max (plus task budget); Claude Sonnet exposes low through max; Haiku and GLM/Gemini show a simple on/off; models without reasoning hide the control entirely. Switching models clamps the effort to one the new model supports. GPT-5.x reasoning summaries are not shown on Bedrock yet (a known upstream limitation); the UI says so rather than showing an empty trace, and will surface them automatically once available.
- Fixed GPT-5.5 / GPT-5.4 repeating their answers. Picking a GPT-5.x model (on AWS or through your Foxl account) and asking anything with reasoning on produced an answer that restated itself 3-8 times, growing each time. The cause is upstream: the hosted endpoint streams GPT-5.x as several message chunks where each new chunk repeats everything said so far. Foxl now collapses those repeats back into a single clean response - both as it streams and in the saved note - at the point where Foxl talks to Bedrock, so every surface (desktop, app.foxl.ai, Foxl Notes) is fixed at once. GPT-5.4 and Claude were unaffected, and the fix turns itself off automatically once the platform issue is resolved.
- GPT-5.5 / GPT-5.4 now work when routed through your Foxl account. Selecting a GPT-5.x model while signed in to Foxl (rather than using your own AWS keys) failed with "Model gpt-5.5 is an OpenAI Responses-API model." The desktop always sent chat through the Claude-style endpoint, which these models reject. Foxl now detects GPT-5.x and routes it to the correct OpenAI-style endpoint automatically; Claude, GLM, Kimi, and Gemini are unchanged.
Foxl Notes
- Foxl Notes AI summaries support GPT-5.5 / GPT-5.4. Notes shares the same fixed GPT-5.x routing and de-duplication, so picking a GPT-5.x model for a meeting summary produces a clean, single summary instead of a repeated one.
Foxl Desktop
- GPT-5.5 / GPT-5.4 work again when selected directly on AWS. Picking GPT-5.5 or GPT-5.4 with the AWS (Bedrock) provider in the desktop app returned "The provided model identifier is invalid." These models are served only through the native OpenAI Responses API on Bedrock, but the desktop chat path had no branch for the OpenAI-on-Bedrock provider, so it fell through to the Claude Bedrock path and sent the request to the Converse API, which does not recognize the OpenAI model id. The chat model builder now routes the OpenAI-on-Bedrock provider to the Responses endpoint (SigV4, no API key), matching how the relay (app.foxl.ai) already handled it. The relay path was unaffected.
Foxl Code (code.foxl.ai)
- Kiro backend gated off until it has working auth. The Kiro coding-agent backend never had a working headless auth path (no non-interactive sign-in was available for it in the sandbox), so a Kiro task would stall on an interactive browser-login prompt inside the sandbox and end in a confusing failure. Kiro is now disabled at the environment level unless explicitly enabled, the Settings picker greys it out, and starting a Kiro task returns a clear error instead of launching the broken path. Bring-your-own-key scaffolding (paste a Kiro/Q API key in Settings, stored encrypted) is wired in for when the backend is turned on; Kiro runs on your own Kiro/Q account, not Foxl LLM credits.
Foxl Desktop + Foxl Code
- GPT-5.5 / GPT-5.4 streaming fixed on the relay. OpenAI-on-Bedrock models are served through the native Responses API; the relay's streaming proxy could throw an uncaught error and drop the stream when a client disconnected mid-response (the normal case for the Codex CLI and browsers). The passthrough now handles client disconnects cleanly and always meters the tokens it observed, so streaming GPT responses are reliable.
- GPT-on-Bedrock now shows under AWS. In the desktop model picker, GPT-5.5 / GPT-5.4 are badged "AWS" (they run on Amazon Bedrock, like the Claude models) instead of an internal provider name.
- Open-weight gpt-oss models removed. Foxl exposes the frontier GPT-5.5 / GPT-5.4 only; the gpt-oss-20b / gpt-oss-120b entries were dropped from the catalog, pricing, and routing.
Foxl Desktop
- Update "Relaunch" banner now appears on first launch. The "Updated to vX / Relaunch" prompt sometimes only showed up after a manual reload (Cmd-R). The preload cleaned up IPC listeners with
removeAllListeners, so any component unmounting (e.g. leaving the Settings page) silently tore down every other subscriber to the same channel - including the update banner - and the next "update ready" push reached no one. Each subscription now removes only its own handler, and the main process re-emits the ready state on every page load so the banner surfaces deterministically.
Docs (docs.foxl.ai)
- Fixed blank article body and rebuilt the layout. The documentation article column had been rendering blank under the new top section-tabs (a tab bar stretched over the article and painted an opaque panel over the text). Moved docs to a full-width top bar with the section tabs, search, version selector, and a light/dark theme toggle, and put Home / App / Download in a proper page footer that no longer covers the sidebar.
- Foxl Code docs expanded. The Foxl Code section grew from a single page into Overview, How it works, Tasks, Coding agents, GitHub, Budgets and tiers, Autonomous loop, and Resume from review.
- Themed, not just gray. Added Foxl brand blue for links and active navigation, tinted info/warning callouts with their own accent color, and gave code blocks a crisper surface - all correct in both light and dark mode.
Foxl Code (code.foxl.ai)
- Autonomous multi-PR runs. One command now goes all the way: the orchestrator publishes a structured plan (one checkbox = one PR), you confirm ONCE, and from there the autonomous loop fans out a coding agent per checkbox, tracks each PR, retries failures, and marks the plan complete - no babysitting. The confirm button now wakes the loop immediately (it used to dead-end until your next chat turn), a plan carries its own repo + installation so the loop can start it with no live chat, and the heartbeat tick performs the initial fan-out for any confirmed-but-unstarted plan. Autonomy is on by default for every Foxl Code user.
- OpenAI Codex backend (GPT-5.5/5.4 on Amazon Bedrock). A third coding-agent backend alongside Claude Code and Kiro. The orchestrator runs the OpenAI Codex CLI in an isolated AgentCore microVM with all model inference routed Bedrock-direct via the container IAM role (no API key, AWS SDK credential chain). Say "use codex" on a task, or set Codex as your default coding assistant in Settings and pick GPT-5.5 (most capable) or GPT-5.4 (best price-performance). New
forge/agent-codexruntime,agent_backend='codex'end to end. - Per-family coding-assistant settings. Settings now lets you choose a default coding-assistant family (Claude Code / Kiro / Codex) and the model within the Codex family. Tasks with no explicit backend use your default; you can still name a backend per task and the orchestrator honors that. Backends not provisioned in your environment are greyed out.
- Security: webhook task matching hardened. The pull_request webhook now matches a PR back to its task by exact 12-hex-char branch suffix (
substr(id,-12)=?) instead of aLIKEpattern, and rejects non-hex branch names. Closes a path where a crafted branch name on a shared org installation could flip another member's task. - Coding agent always opens its PR on the right branch. The agent re-derives the canonical
foxl/<task>branch at push time instead of trusting the working branch, so a mid-task branch switch never produces a self-referential PR or defeats the task matcher. - Stg now mirrors prod branding. The staging Foxl Code surface shows the real "Foxl Code" name + logo (it was previously white-labelled), so staging is a faithful dress rehearsal.
Foxl Desktop + Foxl Code
- Opus pricing corrected across estimates and docs. Cost estimates, the desktop pricing table, and the docs now all state Opus 4.6/4.7/4.8 at $5/$25 per MTok (cache read $0.50) - matching what the relay meter actually charges. Some estimate/doc surfaces had inherited a stale $15/$75; users were never overcharged (the meter was always correct), but pre-flight task estimates and budget gating were 3x high.
- Adaptive thinking kept on with task budgets (relay path). Enabling a Task Budget on the default relay transport no longer silently drops adaptive thinking; it now layers the budget on top, matching every other transport.
Docs (docs.foxl.ai)
- Claude-style top navigation. The docs site now has section tabs across the top (Get Started, Foxl Desktop, Foxl Code, Reference), each scoping the sidebar to its own tree, plus a refreshed landing page. Old page URLs 301-redirect to their new homes.
Foxl Desktop + Foxl Code
- Claude Opus 4.8 added across the stack. New Anthropic flagship: state-of-the-art coding (SWE-bench Pro 64.3%, SWE-bench Verified 87.6%, Terminal-Bench 2.0 69.4%), longer autonomous runs, lower output variance for enterprise workflows. 4.8 is now the default Opus tier in Foxl Desktop, Foxl Code (orchestrator + coding agents), and the relay model registry. Migration is a model-id swap; same adaptive-thinking shape, same 1M context, same
output_config.effortsemantics. Pricing matches 4.7 ($5/$25 per MTok, cache read $0.50/MTok, cache write $6.25/MTok). - Opus 4.7 stays in the catalog. Users on 4.7 can keep using it via the model picker. The legacy
claude-code/opusshort alias now points at 4.8 (current default Opus tier); the explicitclaude-code/claude-opus-4-7id keeps resolving to 4.7. - Default model bumped.
currentModeldefault in the desktop provider registry is nowclaude-opus-4-8; the model aliassmartandopusresolve to 4.8. - Forge defaults bumped. New users get Opus 4.8 as both
coding_agent_modelanddefault_modelfrom/api/settings. Existing users keep their persisted selection. - D1 migration
0024_opus_4_8_pricing.sql. Seedsmodel_pricingso the relay'smeter.canRequest()resolves 4.8 instead of returning "Unknown model" the way 4.7 did at launch. - Task budgets (beta). Settings page exposes a new
Task Budgetselector (off / 25K / 50K / 100K / 250K / 500K tokens). When enabled with thinking on Opus 4.7+, the desktop attachesoutput_config.task_budget = {type:'tokens', total:N}and thetask-budgets-2026-03-13beta header to the AnthropicModel-backed transports (Anthropic API direct + foxl relay). Bedrock Converse silently dropsoutput_configtoday, so the budget is a no-op on the direct-Bedrock path; we will switch to Bedrock Mantle Messages API later to fix that. - Sampling-param hardening for 4.7+. Anthropic provider's
complete()andstream()no longer sendtemperature: 0.7when the model id matches Opus/Sonnet/Haiku 4.7+. Those models reject non-defaulttemperature/top_p/top_kwith HTTP 400 per the field guide; Foxl now lets the API use its calibrated default. Older Claude/non-Claude paths are unchanged. resolveEffectiveContextWindowrecognizes 4.8. Like 4.7, Opus 4.8 reports the catalog's full 1M context on the Claude Code OAuth transport. Sonnet 4.6 and Haiku 4.5 are still capped at 200K on the subscription pool.- Account / Usage charts add 4.8. App.foxl.ai AccountPage and code.foxl.ai UsagePage label and color the new tier so the per-model bar charts don't fall back to "claude-opus-4-8" raw text.
Foxl Code (code.foxl.ai)
- Goal-first task rows. Both the left Tasks sidebar and the right Task plan rail now lead with the goal (title or prompt preview) instead of the repo name. The agent's avatar carries its lifecycle status as a dot, repo + timestamp drop to a muted second line. Three tasks in the same repo no longer read like the same row repeated.
- Account menu in the topbar. Sign-in / Sign-out, credits balance, Service status, and account links live in a dropdown under your avatar. The Orchestrator-degraded indicator surfaces here when
/healthreturns non-OK so you know new tasks may queue. - Right rail polish. "Open in full page", "Back to tasks", and a "Prompt" header on the task plan rail. Search bar inside the rail. Accessible Open/Close labels for screen readers.
- Edit your display name. Account page now lets you set the name shown across Foxl. Saves through the relay's new
PATCH /auth/meendpoint, so the name follows you to Foxl Desktop too. - Quieter Runtimes page. Removed the bottom "Recent activity" event log; the active-runtime grid stays. Each runtime card still shows its own mini-terminal preview of the last few events.
Foxl Desktop (app.foxl.ai)
- Display-name editing in Relay-Only mode. Profile edit now persists to the Foxl account on relay (not just local state). The new name carries across browsers, the Foxl Code SPA, and Foxl Desktop on macOS / Windows.
Relay
PATCH /auth/me. New authenticated endpoint to updatedisplayName(max 100 chars; passnullor empty to clear). CORS allow-list now includesPATCH.
Foxl Code (code.foxl.ai) - operational
- Default per-task budget floor raised to $500. Previously a 30-min Opus task auto-estimated at ~$1.30 and got killed mid-flight with
forge task budget exceededeven when the user had thousands of credits. The auto budget now floors to $500 (override + multiplier paths still respected); daily-cap default lifted from $0.50 to $500 with a $1000 ceiling.
Foxl Desktop
- Streaming-text shimmer restored to v0.2.30 timing. The Tailwind v3 -> v4 migration shipped in v0.2.41 lost the original keyframes; v0.2.42 wrote them back at 1/4 of the original travel range, which made the shimmer "tick" visibly at the seam every half-second. Keyframes now match the v0.2.30 config (200% -> -200%) - smooth, uni-directional sweep, no visible loop. Shared
@foxl/uiShimmer also now sets the duration on every variable name in use across the workspaces.
Foxl Code (code.foxl.ai)
- Cmd+Shift+F global task search. New CommandPalette +
GET /api/search/tasksendpoint. Match across title, repo full name, prompt body, and id; results scoped to the user via the relay JWT. Hard-capped at 50 results, 150 ms debounce. Press Enter (or click) to navigate to the matched task. - Cmd+F in-chat search. New ChatSearchBar mounted on TasksPage and TaskDetailPage. Walks text nodes inside the chat container, highlights matches via the CSS Custom Highlight API, and steps prev/next with Enter / Shift+Enter. Falls back gracefully on browsers without the API.
- Auto-refresh sidebars on task mutations. New
TASKS_CHANGED_EVENTwindow event fires after every cancel / set-status / retry / resume / delete / delete-all. AppSidebar inline list and TaskDocSidebar In-progress/Recent sections listen for it and refetch immediately, so right-rail and left-sidebar both stay in sync without waiting for the 5 s poll.
Foxl Code (code.foxl.ai)
- Kiro CLI as a peer coding-agent backend. New
forge/agent-kiroAgentCore Runtime container ships the AWS-distributed Kiro CLI (kiro-cli + kiro-cli-chat + kiro-cli-term). The orchestrator picks per task via the newagent_backendzod arg onspawn_agent, defaulting to Claude Code unless the user explicitly says "use kiro". Settings shows backend availability read-only; the orchestrator owns the per-task choice. Kiro auth (KIRO_API_KEY / SIGV4) is still pending upstream so Kiro tasks land at the login prompt today. - Per-task agent backend persisted on tasks rows. New
tasks.agent_backendD1 column captures which CLI ran each task. RuntimeCard + TaskDetailPage header render the backend icon (Claude Code orange mascot vs Kiro logo) so post-mortem context survives even if defaults change. - Bulk Delete-all from right-click context menu. New
DELETE /api/tasksendpoint wipes every terminal-state task (queued/running rows skipped, returned in the response). Right-click any task row in the AppSidebar inline list, or anywhere in the right-rail TaskDocSidebar list, to surface "Delete all". - Repos page connection flow. "Add another install" is now a dropdown with two paths: open-on-GitHub (the standard flow) and Connect-by-login (adopt an install Foxl never picked up). Each install card gets an "Add repo" button that jumps to GitHub's per-install Configure page; the Repos tab auto-syncs on focus when you come back. Manual-add escape hatch reachable even when installs already exist.
- One-click GitHub repo jump. The topbar repo picker now has an external-link button next to the trigger that opens the selected repo on github.com. Each row inside the dropdown also gets a hover-revealed open-on-GitHub action.
- Orchestrator session bumped v6 -> v8. Forces AgentCore to spin up fresh containers so the new
spawn_agentschema + Kiro-aware system prompt take effect immediately. - Relay proxy: strip Bedrock-incompatible beta fields. Claude Code 2.1.x sends
context_managementandoutput_configin every request body. Bedrock InvokeModel rejects them with 400 "Extra inputs are not permitted", which the SDK retried until the agent gave up. The relay now strips these fields before forwarding to Bedrock. - Agent API key prompt eliminated. Pre-seed the per-task JWT into Claude Code's
customApiKeyResponses.approvedso the "Detected a custom API key" interactive prompt never fires. Previously the agent stalled on this prompt every invocation. - Resume without alert. The "Resume" button no longer pops a text-input dialog. It flips the task back to running immediately and the user types directly in the live terminal.
- Resize-jiggle on mount and resume. The terminal sends a shrink-then-restore resize pair (two SIGWINCHes) on every page load and on resume, forcing Claude Code to do a full repaint. Fixes partial rendering on fresh loads.
- Deduplicated task events. Removed SSE backlog replay from the Durable Object subscriber. Events are now delivered once via the REST backlog, then live-only via SSE. Timestamps no longer mismatch.
- "live" badge restricted to running tasks. The sidebar badge now only shows on running/queued tasks, not review (where the terminal is idle).
- Compute usage metering. The agent container now emits
wall_clock_secondsandio_wait_pctin the finished event. The relay uses this to calculate and deduct AgentCore vCPU + memory credits alongside LLM token credits. - Expanded agent container toolbox. Added bash, vim, nano, jq, ripgrep, htop, tree, ping, dig, nc, gpg, ssh, rsync, and more to the agent Docker image.
- Telemetry isolation. Agent containers set
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1to turn off nonessential network traffic from Claude Code.
Foxl Desktop (app.foxl.ai)
- Shimmer effect restored. The streaming text shimmer animation (
animate-shimmer) was lost during the Tailwind v3-to-v4 migration. Keyframe and utility definition re-added to index.css.
Foxl Code (code.foxl.ai)
- Autonomous loop. Your coding agents now check back on running tasks automatically. Enable it in Settings - the orchestrator wakes up on a configurable interval (default 5 min), checks if anything has progressed since its last look, and follows up if needed. Quiet hours and a daily spend cap keep it from running up costs overnight.
- Per-task spend metering. Every LLM call a coding agent makes is now tracked in real time against the task's budget. You can see cumulative cost on the task detail page. When a task hits its budget ceiling the agent stops gracefully - no surprise charges.
- Custom budgets. Set a spending limit before launching a task. The composer now has a "Budget (USD)" field. Values below the auto-estimate are rejected; the system caps runaway spend at whatever you set.
- Resume from review. When a coding agent pauses for your review (e.g. waiting for approval on a risky change), you can now hit "Resume" to continue exactly where it left off - same container, same git state. If the container was reaped, the UI falls back to a retry automatically.
- Agent screen and input. The orchestrator can now read a running agent's terminal screen and send input to it. This is the foundation for multi-agent coordination - one agent can check on another and unblock it.
- Dual storage architecture. Two orchestrator runtimes: Session Storage (default, per-session physically isolated) and S3 Files (shared mount with prefix-based isolation). Pick in Settings.
- Stop button. Cancel streaming responses mid-flight via the composer's stop button.
- Thinking block interleaving. Multiple thinking blocks render independently with separate collapsible sections.
- Tool call shimmer fix. Tool result events now correctly stop the running animation.
- Workspace page file browser. Browse your agent's working directory - session storage or S3 Files mode detected from settings.
- Mobile: compact New Task button. The topbar "New Task" button collapses to a "+" icon on small screens so it no longer overflows.
Foxl Desktop
- Monorepo workspace fix. Independent deploy units (docs, site, agent) no longer block the shared workspace install. Speeds up
npm installand removes the linux-only platform error on macOS dev machines.
Infrastructure
- Per-task JWT replay window. Relay now checks the task's D1 status before honoring a per-task token. If the task is already in a terminal state (merged/failed/cancelled), the token is rejected even if it hasn't expired - prevents spend after completion.
- Heartbeat cron (1-min global trigger). A single Cloudflare cron fires every minute, prefilters eligible users from D1, and fan-outs to per-user HeartbeatDOs. The DO handles interval gating, quiet hours, daily cap, and event-sequence dedup so idle users cost nothing.
- Budget multiplier and daily cap columns. D1 migrations 0021-0022 add per-user budget_multiplier, heartbeat_interval_seconds, daily_cap_usd, and quiet-hours fields to forge_user_settings.
- Session storage orchestrator runtime. New AgentCore runtime with sessionStorage at /mnt/workspace (14-day idle expiry, per-session isolated).
- Terraform apply clean in stg workspace. IAM policy updated for new AP ARN.
Cross-product
- Foxl Desktop and Foxl Code now share one version line. Both products ship under the same v0.2.40 tag. Every workspace
package.jsoncarries the same"version". Per-product version drift removed. - Stg environment for every customer-facing surface.
stg.foxl.ai,stg.app.foxl.ai,stg.code.foxl.ai,stg.relay.foxl.ainow run the same source as prod with separated D1 database, JWT secrets, GitHub App, AgentCore Runtime, and S3 bucket. Stg cannot reach prod and vice versa. Eachwrangler.tomlexposes an[env.stg]block;--env stgflips the deploy. forge/web carries a yellowSTAGINGbanner only when built withVITE_FOXL_ENV=stg(dead-code-eliminated for prod). Marketing/docs has no stg. - Docs versioning starts at v0.2.39.
docs/scripts/snapshot-version.mjssnapshotscontent/docs/tocontent/docs/v<version>/before edits land for the next release. Old versions stay reachable atdocs.foxl.ai/v<version>/....
Security
- GitHub login account-takeover bypass closed. The relay's GitHub OAuth callback used to match the foxl user by email, so anyone who controlled a GitHub mailbox could log in as a foxl account that was created via magic link or another provider. Login now matches by GitHub's immutable numeric
id(stored in the newusers.github_user_idcolumn, migration 0017) and refuses to auto-link to a pre-existing email-only account. Affected accounts are asked to sign in with their original method first and connect GitHub from settings. - Cross-tenant install ownership transfer closed.
INSERT INTO github_installations ... ON CONFLICT(installation_id) DO UPDATEno longer touchesuser_id, and/api/github/setupnow refuses to write when the install is already owned by another foxl user (audit-logged ascross_tenant_denied). Combined with the existing/api/installations/adoptownership check this closes the "Foxl user A reclaims Foxl user B's install" path. FORGE_WEB_URLenv wired through OAuth callback. Three hardcodedhttps://code.foxl.ai/tasksredirects inrelay/src/auth.tsnow consultc.env.FORGE_WEB_URLfirst (default unchanged for prod). Stg setsFORGE_WEB_URL=https://stg.code.foxl.ai. Closes the leak where stg-originated GitHub OAuth would land tokens on prod code.foxl.ai.- Repo selection mode reclassified. Forcing foxl-bot installs to
repository_selection: "selected"was on the launch-block list; that conflicts with the multi-tenant SaaS model where each user installs on their own account/org and picks the mode at install time. Tenancy is enforced at thegithub_installations.user_idlayer (single owner per install, ON CONFLICT does not change owner, audit log on every mint). A user who picksallonly enables Foxl Code on their own repos under their own install. Removed from the launch checklist;forge/SECURITY.mdandforge/TODO.mdupdated.
Foxl Code (code.foxl.ai)
- Mobile layout pass on every page.
AppShellcontent padding drops frompx-6 py-8topx-4 py-6on phones (matches app.foxl.ai), so the 375px viewport stops cropping cards and headers. Page-level fixes: TaskDetailPageaction bar (Pull request / Issue / Cancel buttons) now wraps to a second row instead of overflowing on phones; the header collapses to a stacked layout, the meta + budget cards switch to a 2-up grid above the terminal on tablets and 1-up under the terminal on phones, and the terminal's fixed68vhshortens to60vhso soft keyboards don't push the composer offscreen.ReposPagerepo grid drops to one column on phones (was breaking atmd:only); the Sync + Connect buttons wrap when the heading is wide.RuntimesPageactivity rows wrap the repo name under the kind label on small screens; horizontal padding tightens.SettingsPagecard padding goesp-4 sm:p-6; the Save / Sign-out row wraps so neither button gets clipped.UsagePagestat cards switch to a 3-up grid atsm:(waslg:-only), and ledger rows wrap when the timestamp wouldn't fit.OnboardingPageouter padding drops topx-4 py-10and the heading scalestext-2xl sm:text-3xl.
Build
- Foxl Desktop is no longer hoisted into the same
node_modulesas Foxl Code.foxl/apps/webandfoxl/apps/electronwere removed from the rootworkspaceslist; they install their ownnode_modulesand pin Tailwind v3 again. Foxl Code stays on Tailwind v4 in the root workspaces tree. Stops the cross-product break where forge bumping Tailwind silently dragged the desktop CSS pipeline along. legacy-peer-deps=true+NODE_ENV=productionno longer silently skips devDependencies. A stale shellNODE_ENV=productionwas makingnpm installresolveomit=dev, which leftvite,@vitejs/plugin-react,@tailwindcss/vite,esbuild, and friends out ofnode_moduleseven though they were inpackage-lock.json. Builds (npx vite build,node bundle-server.mjs) then crashed withERR_MODULE_NOT_FOUND. The integrity issue is now resolved againstnode_modules/.- Removed the duplicate
site/landingentry in the rootpackage.jsonworkspaces list. npm tolerated it but it pollutednpm lsand slowed install resolution. scripts/release-all.shdocs deploy passes--project-name foxl-docsso wrangler 4.92+ does not fail with "Must specify a project name."
Fixes
- app.foxl.ai white screen fixed. A vite chunking quirk was bundling two copies of React into the relay-only build; the second copy hit the
__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADEsymbol mismatch on boot and rendered nothing. The build now dedupes React across the workspace symlink and lands all ofreact,react-dom, andreact/jsx-runtimein a singlevendor-reactchunk. Verified live: zeroCLIENT_INTERNALSreferences invendor-radix/vendor-ui/indexchunks. - Sidebar borders no longer render black, electron no longer starts in dark mode.
index.csswas using@import '@foxl/ui/styles.css'after@font-faceand@tailwinddirectives, which PostCSS silently drops. Every--background/--border/--sidebar-*HSL var was undefined; tailwind'sborder-borderresolved tohsl()(invalid) and the browser fell back to black. Tokens are inlined intoindex.cssagain so the rule order does not matter.@foxl/ui/styles.cssstays the canonical source for forge/web.
Cross-product
- Foxl Code (code.foxl.ai) shipped as a separate product on the same monorepo. Foxl Desktop and Foxl Code share
relay.foxl.aifor auth and the credit pool but version independently. SeeVERSIONING.mdat the monorepo root for the full strategy. Foxl Code release tags carry theforge-vprefix so the two products do not interfere. packages/uinow exposes shared layout primitives (AppShell,NavSidebar,TopBar,Breadcrumbs) consumed by Foxl Desktop and Foxl Code so the chrome stays in sync between the two products.- React bumped to 19.
foxl/apps/webandpackages/uinow agree onreact ^19.0.0andreact-dom ^19.0.0; recharts bumped to^3.8.1to keep peer-dep alignment. No user-visible UI change beyond the rendering fixes above.
Foxl Code (code.foxl.ai)
/tasksrebuilt around a bottom-pinned composer. Active tasks (queued/running/review) and recent five closed tasks render above the composer on the empty-state view, with an 8s background poll so status changes show up without a manual refresh. Pressing Enter now surfaces a clear inline error if no repo is connected or no paste is typed - it used to swallow the keystroke silently. Submit + topbar GitHub buttons flattened (no shadow / border)./repospopulates after install. The orchestrator gained a state-bound install URL handler, a manualPOST /api/installations/syncendpoint, anadopt-by-owner endpoint for the legacy install path, and webhook handlers forinstallation+installation_repositoriesso future installs sync without manual action. The Repos page auto-syncs once when installations exist with no repos and exposes a "Sync repos" button. Empty-install state shows both "Sync repos" and "Configure on GitHub".- Workspace page added at
/workspace. Per-user view of the shared S3 Files mount (/mnt/repos) - finder-style lazy tree, resizable sidebar, search across loaded files, context menu (Copy path), text / binary preview with a 1 MiB inline cap. Shape ported from Foxl Desktop's WorkspacePage, data layer swapped for the orchestrator's new/api/files(S3 ListObjectsV2 + GetObject via aws4fetch). Read-only - the AgentCore container owns writes. Tenant isolation is the bucket prefixusers/{user_id}/{org}/{repo}/...enforced server-side. - Terraform shared S3 Files mount enabled.
forge/infra/terraformnow provisions the VPC, NAT gateways, S3 bucket + S3 Files file system, mount targets per AZ, IAM service role, and the access point. AgentCore endpoint flipped from PUBLIC to VPC mode so the shared cache is reachable. Updated CLAUDE.md to reflect that Pro/Ultra share one mount with prefix-based tenancy (was previously documented as Enterprise-only).
Gateway "Enable remote access" actually works now
- Click was a no-op when no access token existed. The
tunnel-toggleIPC handler returned{ok: true}immediately and only kicked offconnectTunnel(at, rt, ...)ifatwas truthy. If the user wasn't signed in,atwas empty, the function silently bailed, and the button looked frozen forever. - Handler now
awaits the localStorage read, returns{ok: false, reason: 'no-access-token'}when the token is missing, and the renderer surfaces a "Sign in first (Account page)" message inline beneath the button. - For other failures the handler returns
{ok: false, reason: '<exception text>'}instead of pretending success. - Renderer polls
tunnelStatus()for up to 15 seconds after a successful start, refreshesfetchAll()once the WebSocket attaches, and shows a clear timeout message if it never does. - Loading state on the button - spinning Power icon + localized "Connecting…" copy + disabled while awaiting, so a click no longer looks like a no-op.
Gateway page i18n
- Gateway "No desktop" copy now resolves in every locale. v0.2.37 added new English strings (
relay_no_desktop_desc_v2,relay_turn_on_desktop,relay_desktop_not_connected,relay_desktop_not_connected_desc,relay_enable_remote_access) but didn't add them to the other 9 locale files - users on Korean / Japanese / Chinese / etc. saw raw key names. v0.2.38 ships translations for all 10 locales (en, ko, ja, zh, es, fr, de, pt, ru, ar) plus the new connecting/error strings.
Sidebar tooltips
- Collapsed sidebar (Cmd+B) now shows the conversation title as a dark tooltip on hover. Previously the title only rendered when expanded; with the sidebar collapsed to icons there was no way to read which conversation was which. Tooltip mirrors the Cmd+B nav-item style.
- Top-level nav items and the settings group also surface their label as a tooltip when collapsed - Chat, Workspace, Usage, Settings, Account. Same dark popover styling.
- Truncated rows show a hover tooltip with the full text in both the sidebar conversation list and the Workspace file/folder tree. The tooltip only opens when the inner span actually overflows (
scrollWidth > clientWidth); short titles don't trigger it. 700ms delay so it's not noisy.
Workspace polish
- Editor header reads
MEMORY.mdinstead ofWORKSPACE / MEMORY.md. The redundantWORKSPACE /crumb prefix was removed - the sidebar already says WORKSPACE, the breadcrumb just doubled the label. - File and folder rows restored to v0.2.15-era density (
text-sm/py-1.5). The earlier compaction totext-[13px]made the tree feel cramped against the rest of the app.
app.foxl.ai conversation pagination fix
- Sidebar conversation list now pages past the first 50. On app.foxl.ai (relay-only mode with desktop tunnel online) the IntersectionObserver attached to the conv scroll container saw
convScrollRef.current === nulleven after the list had rendered, so the "load more" sentinel never fired. Switched to a callback-ref + state pattern so the effect re-runs the moment the scroll element actually mounts, plus replaced the IntersectionObserver with a plainscrollevent listener for reliability inside the nested hidden-scrollbar container.
Gateway page "No desktop" actions
- Web (app.foxl.ai): replaced the lone Download button with two CTAs - "Turn on desktop" (deep-links to
foxl://opento launch the installed app) and "Download for macOS" (fallback if the app isn't installed yet). - Desktop: when looking at /gateway from inside the installed app, the page no longer suggests downloading the desktop app (you're already in it). Instead it surfaces an "Enable remote access" button that flips the tunnel toggle, with copy explaining what relay connection gets you.
max_tokens overhaul (Claude Code parity)
- Every Claude path now requests the model's full output capacity. Previously the desktop chat sent
max_tokens: 4096whenever thinking was off, the agent layer hard-coded8192for every provider, and the relay-only web app capped output at64000regardless of model. Long generations were silently truncated. Now Opus 4.7 / 4.6 ask for 128k, Sonnet 4.6 / Haiku 4.5 ask for 64k, matching what the Claude Code CLI sends. - Agent layer reads from the catalog instead of a hard-coded constant.
strands-agent.tsnow resolvesentry.maxOutputper model for Bedrock, Anthropic, OpenAI, OpenAI-OAuth, Claude Code OAuth, and the foxl relay path. - Claude Code OAuth catalog corrected. The 32k metadata was misleading - real requests already went out at the catalog max. Updated to 128k (Opus) / 64k (Sonnet) so
/contextpercentages and autocompaction triggers reflect actual behavior.
Relay billing fixes
- Opus 4.7 unblocked on the relay. D1
model_pricingwas missing a row forclaude-opus-4-7, someter.canRequest()rejected every request with "Unknown model" - even though the registry listed it. Migration0011_opus_4_7_pricing.sqladds the row. - Opus pricing corrected to Anthropic's published rates. Catalog and pricing previously inherited Opus 4.1's $15/$75 per MTok. Both Opus 4.7 and Opus 4.6 are $5/$25 per MTok. Updated
model-catalog.tsand the local D1 row.
Sidebar UX fixes
- Cmd+N (and the File → New Chat menu item) always opens a fresh chat. Previously, pressing Cmd+N from a non-chat page resurrected the previous conversation because
navigate('chat')re-pushed/chat/<oldId>from a stale closure value, and the popstate handler reloaded that conversation. - Clicking a different conversation actually opens that conversation. Selecting B from the sidebar after viewing A used to re-load A - same closure-staleness bug routed
/chat/<A>instead of/chat/<B>. Now the click goes throughnavigate('chat', { conversationId: id }), which uses the explicit clicked id. - A → B switching no longer flashes empty state. Conversation messages stay on screen during the fetch; the new conversation's messages swap in once they arrive. No suggestions/greeting flicker between selections.
- Conversations are no longer highlighted while you're on Workspace, Usage, or other non-chat pages. Sidebar conversation rows now check
activeNav === 'chat'before applying the active style. Clicking the top-level Chat nav from those pages opens a new chat instead of resurrecting the previously-selected one. - Infinite-scroll loader no longer spins forever when conversation pagination fails. On app.foxl.ai (relay-only mode) the desktop conversation list endpoint isn't reachable; the failed fetch used to leave the sentinel mounted, retriggering the IntersectionObserver in a loop. Now any non-OK response or thrown error sets
hasMoreConversations: falseand the spinner goes away.
foxl.ai migrated to Next.js SSG for SEO
- Google can now index foxl.ai. The landing page was a pure CSR React SPA - crawlers saw empty HTML. Migrated to Next.js 15 App Router with static export. Every page is pre-rendered as full HTML with proper meta tags, canonical URLs, and Open Graph data.
- JSON-LD structured data for sitelinks. Organization, WebSite (with SearchAction), SoftwareApplication, and SiteNavigationElement schema in root layout. Signals Google to show the site hierarchy (Blog, Pricing, Security, Changelog, Docs) as sitelinks beneath the main search result.
- sitemap.xml with 22 URLs. All static pages + 17 blog posts. robots.txt allows AI crawlers (GPTBot, ClaudeBot, PerplexityBot) and blocks training-only crawlers.
- worker.js simplified. Removed the entire SPA routing layer (HTMLRewriter meta injection). Next.js handles per-page metadata natively. Worker now only handles security headers, llms.txt proxy, and old .html redirects.
- Blog preserved exactly. Same thumbnail grid, pagination, category filters, search, and individual post layout as before.
Landing page redesign
- Pricing moved to dedicated /pricing page with detailed credit breakdown, BYOK explanation, local model info, and FAQ.
- Security section redesigned. Clean 3-column architecture diagram with vertical mobile connectors, prose-style feature descriptions replacing card grid.
- "What people ask" replaced with a differentiators section. 6 quote-heavy cards condensed to 3 focused differentiators: mobile coding, 24/7 background agent, multi-provider single interface.
- FAQ trimmed from 11 to 5. Ordered by user priority (features, competitors, pricing, privacy, mobile access). First item open by default. Links to docs/Discord for more.
Agents page bug fixes
- Running agents no longer flash as "completed" the moment the detail view opens. AgentChatView receives
initialStatusfrom the Agents page (source of truth) so it starts with the correct status the user already saw, eliminating the race where in-memory state clears before the detail view fetch resolves. - Assistant responses stop rendering twice.
broadcast()was double-recording every agent event to DB (once inside broadcast, once in the runAgent callback). Removed the redundant call. Also,runAgent()no longer emits intermediatemessageevents for no-tool turns - onlycompletecarries the final response. - New agents started from the Agents page now show their progress events. Session ID minted up-front so WS broadcasts and DB rows share one ID.
Relay, Schedules, Feed, Activities, Logs redesigned
- Unified hero-stat pattern across five pages. Each page now opens with a single headline answer ("12 active schedules", "Live: streaming to 2 clients", "9 unread items", "247 events", "1,248 lines streamed") plus three supporting stat cells — the same rhythm as Agents and Usage. Replaced the nested Card-in-Card chrome with flat sections separated by dividers.
- Relay (Gateway) rebuilt. Flat device topology with a single connected-desktop row, inline quick-actions (update / restart / unpair), web and mobile clients as tree branches off the bottom edge, and audit history in a collapsible scroll panel below. Tunnel "Remote access" is now a pill toggle next to Refresh instead of a standalone card. Legacy local gateway drops into one collapsible at the bottom for advanced users. Cleaned up dead code from the deleted pairing-code flow.
- Schedules stopped pretending to be a spreadsheet. Dense table became a divided list sorted enable-state-first, then by upcoming-run proximity. Each row leads with a status dot, the human-readable cron (raw expression lives in the tooltip), and prefers "next in 18m" over stale "last ran 3h ago". 7-day success rate and average runtime are now prominent hero stats. Recent Runs uses pill inputs and chip filters, grouped by day bucket. Heartbeat rows are labeled system-managed and can't be deleted.
- Feed reads like an inbox. Segmented pill toggle (Inbox / Archive) with per-view counts. Each item is a single clickable row — click archives, click again unarchives. Urgent dot goes amber, unread dot stays foreground, archived items fade. Hero leads with unread count and amber urgent subtext when applicable.
- Activities chip filter. Time range matches Agents' pill style; type filter is a horizontal chip bar derived from actual event frequencies so users can focus on tool_start vs thinking vs error without a dropdown. Outer Card wrapper removed so the list can breathe.
- Logs terminal has a frame that doesn't fight it. Hero shows stream state (live vs paused+buffered count) plus error/warning/info totals. Level filter is a segmented pill; source filter is a chip row behind the Filter icon. Console is one bordered rounded-xl panel instead of a Card wrapping another Card.
- UX ⇄ API alignment. Killed the duplicate "Connected Desktop" surfaces — the relay is now the single source of truth for devices and the local gateway is explicitly flagged as advanced/optional.
- Mobile. Every page is single-column on narrow viewports, pill inputs wrap cleanly, hero drops to stacked layout, toolbar icons stay tappable (min 32px hit targets), horizontal overflow killed with
overflow-x-hiddenat every shell. - i18n. 100+ new keys across all 10 locales (en / ko / ja / zh / es / fr / de / pt / ru / ar). Key parity check passes at 97–100% per locale.
UX polish pass
- Consistent semantic tones across hero stat blocks. Warning stats were mixing
text-foreground,text-yellow-*, andtext-amber-*across Feed, Activities, and Logs — every page now uses the samewarn=amber / danger=destructivepair, so a 2 next to "Warnings" reads the same wherever it appears. - Feed rows stop auto-archiving on a misclick. The whole row used to be an archive button with a stealth time→action crossfade on hover; now the row is a passive list item and an explicit "Archive" hover-only pill handles the action. Unread dot uses
bg-primaryinstead of pure foreground so it matches the brand. - Refresh / Auto collapsed into one control on Activities. The separate Refresh button next to the "Auto" pill was redundant — now the toolbar shows a live-pulse dot when auto-refresh is on (click to pause) and a Refresh icon when it's off. State change is explicit, not dual.
- Activity hero totals match what the list shows. Hero used
dbEventswhile the list renderedmergedEvents(db + live), so in-flight live events were invisible to the tally and the type chip tallies. Both now derive from the same unfiltered merged stream. - Logs source filter comes out of hiding. The source chip row used to live behind a separate Filter icon toggle — only discoverable via curiosity. It's inline now, rendered whenever the server reports sources. One less click, one less icon.
- Schedules filter rail simplified. Status is a segmented pill (the axis users actually filter on); Range / Type / Sort / Schedule-picker drop to auto-width dropdowns. Triple "shown of loaded of total" counter replaced with a single "N of M" that only shows when a filter is active.
- Destructive actions gate on confirm. Schedules detail dialog and row dropdown no longer delete on a single click — a confirm prompt names the schedule so users see what they're about to lose.
- Gateway audit rows stop showing a Clock icon next to every timestamp. Redundant with the time on the right side of the row. Dead
relayConnected/tunnelConnectedstate and an unusedWifiimport removed. - Schedules day-group labels respect locale. "Today / Yesterday / This week" were hardcoded English; now they go through
chat.today / yesterday / this_weekso they follow the UI language. - Overview "Top tools" aligned to 24h window. Hero counter is 24h but the top-tools list was pulling lifetime stats labeled "Most used" — both are now 24h so the page tells a single consistent story.
Workspace on mobile actually scrolls now
- Mobile Workspace stopped clipping the editor at ~50% of the viewport. The previous layout cut the internal
h-fullandoverflow-hiddenat the md breakpoint so the page could rubber-band on iOS, but the side-effect was that the frontmatter + editor textarea got pushed off-screen below the sidebar header. The page now clamps to100dvh - 2.75rem(app header) on every breakpoint and manages scroll internally — the tree scrolls inside the sidebar, the textarea scrolls inside the editor, and mobile gets the same full-viewport behavior as desktop.
Demo preview caught up with the Usage rename
- Demo/preview mode's "Connect your desktop to use Overview" card now says "Usage" (plus a fresh one-line description about token burn / cost / model breakdown). The rename in v0.2.32 only covered the live app; the preview copy still referred to the page by its old name. Updated across all ten locales.
Landing page redesign
- Demo sidebar now matches the real app exactly. Icons corrected to match navigation.ts (Plug for Integrations, Clock for Schedules, Activity for Feed, Settings gear, Users for Agents, BarChart3 for Usage). Every sidebar item is now interactive with dedicated mock content panels for Usage, Schedules, Feed, and Settings.
- Foxl blue brand color system. Added
--brandCSS variable (desaturated blue from the Foxl logo) with light/dark mode variants. Applied as a gradient accent on the hero headline and subtle radial glows behind the hero and CTA sections. - Real provider icons in demo. The integrations grid now shows actual Microsoft, Slack, GitHub, Google Workspace, Notion, and Obsidian icons instead of placeholder letters.
- Logo in demo uses
logo-title.svgwith correct size and spacing matching the actual app sidebar.
New tray icon
- macOS menu bar icon redesigned with clean inner line separation. The new 2-piece SVG clearly distinguishes the left wing from the right body with a visible gap. Sized to 80% of the tray canvas for proper macOS menu bar breathing room.
"Overview" is now "Usage"
- The sidebar, page title, breadcrumb, and every localized label switched from "Overview" to "Usage" across all ten translations (en, ko, ja, zh, es, fr, de, pt, ru, ar). The page was never really an overview - it was the place users went to see token burn, cost, and model usage. The new name says that out loud. The internal route key stays
overviewso existing bookmarks, localStorage entries, and deep-links keep working.
Agents page editorial redesign
- Agents leads with a headline number instead of admin chrome. The old header stacked a small
h2 Agent team+ subtitle + a row of badges (1 active / 2 done) that all competed for attention. The page now opens with one large tabular number for running agents ("2 agents running") plus an inline three-stat rail (Active / Completed / Failed), same uppercase-tracked labels as the Usage dashboard. - Run bar became a single pill input. Goal field is now a rounded-full search-style input with a leading Send glyph, Run sits as the primary action, and Stop-all + Pixel-office toggle collapse into rounded-full secondaries. No more cramped
h-8row stuck between the status badges and the list. - Session history dropped the per-row Card chrome and rebuilt as a
<ul>withdivide-yseparators and uppercase date group labels ("ACTIVE / TODAY / THIS WEEK"). Status filters light up withbg-mutedinstead of swapping badge variants on every click. iter / tools / duration / error counts usetabular-numseverywhere so the row doesn't jitter as numbers tick up. - Consistent gutters. Agents now uses
px-4 sm:px-8 max-w-6xl mx-auto, matching Usage / Settings / Skills / Integrations so mobile stops reading edge-to-edge. - Every hardcoded English string moved to i18n (
agents.starting,agents.agent_running_singular,agents.no_sessions,agents.err, etc.) and the translation table got filled out across all ten locales.
Workspace gets the editorial treatment
- Workspace page dropped the Card wrappers and now reads as one continuous surface: file tree on the left separated by a single border, editor on the right. Header uses the same uppercase-tracked label + tight title as Overview, file path renders in mono, and the save button sits inline. Frontmatter pills switched to compact
key valuebadges. - Workspace action icons moved to the app header, matching Chat's pattern. Search / Open folder / Refresh now sit in the top header bar on the right, so the sidebar owns a single editorial label row instead of two competing action strips. The empty-state panel lost its large folder glyph in favor of a tiny uppercase
WORKSPACEchip plus the hint copy, and the editor pane became edge-to-edge without border/ring chrome so it reads like a real Linear/Vercel writing surface. - Workspace tree now shows a spinner during the initial fetch instead of two bare border lines with a void between them. The spinner only fires before
treeLoadedflips true, so manual refreshes don't flash it over a populated tree.
Overview loads faster
- Dashboard query does fewer scans. The
/api/dashboardendpoint was running seven separateSELECT COUNT(*)statements acrossconversationsandmessages, most of which had no usable index for theirWHERE created_at >= ?/WHERE role = ?clauses. Replaced the per-metric counts with two CASE-sum aggregates (one per table) and addedidx_messages_created,idx_messages_role_created,idx_conversations_created, andidx_tool_history_name. On a 12K-message / 365MB database the overview request dropped from a visible pause to effectively instant. - Overview caches its last render. Navigating away and back used to show a spinner for every round trip. The page now reads from
sessionStorageon mount and refreshes silently in the background, so subsequent visits are immediate. - Removed the "Uptime 15m" badge from the hero row - it was visual noise next to the token total.
- Usage Explorer range chips no longer clip off the left edge.
Overview + Usage Explorer redesign
- Overview got a proper dashboard instead of four identical admin cards. The page now leads with a hero row - last-24h tokens as one large number plus cost, a live uptime dot, and a "View Usage Explorer" chevron - and demotes conversations / messages / tool calls into a compact three-column strip next to it. Activity, Model usage, and Top Tools became bare typographic sections separated by horizontal dividers; the bar chart and list rows have more room to breathe without card chrome eating 48px on every side.
- Usage Explorer uses the same editorial layout. Breadcrumb + refresh on one row, chip-style range picker under it, 2x2 summary stats on mobile and 4-col on desktop, per-model rows with an inline progress bar and a 4-up breakdown (input / output / cache write / cache read) that stays on 2 columns on small screens. Custom date range inputs now flex to full-width on mobile instead of spilling off-screen.
- Numbers use
tabular-numseverywhere so columns don't jitter when values change during live polling.
Custom tool env-vars editor now behaves like a real textarea
- Enter, Space, and blank lines work again in the MCP env-vars box. Editing an MCP tool's environment variables used to feel broken: pressing Enter did nothing, trailing spaces disappeared, and the cursor would jump every keystroke. Root cause: the textarea re-parsed the whole text on every keystroke, dropped the parsed map back into props, and the parent re-serialized it from scratch, which stripped newlines and whitespace. The editor now holds the raw text locally and only pushes the parsed map up, so typing feels normal. Comments (
# ...) are also preserved across saves.
Heartbeat can run on any schedule now
- Feed Generator frequency is no longer capped at 6 hours. Settings -> Feed Generator now shows preset chips (15m, 30m, 1h, 3h, 6h, 12h, Once a day) plus an "Other" option that takes hours + minutes directly, so you can pick 17h 30m, once every 2 hours, once a day, or anything up to 7 days. The preset chips replace the old single-select dropdown. Custom values are clamped to a minimum of 1 minute and a maximum of 7 days to keep the scheduler sane.
- "Once a day" and "12 hours" are now first-class presets. Users who just wanted a morning briefing had to fake it with
7am cronschedules; now they can leave the Feed Generator on Heartbeat and pick the interval that matches their actual cadence.
`exec` is back
execandprocessare now core tools again. Some users reported the agent refusing to run a simplegit statusand falling back to the heavier terminal PTY path every time. Root cause:execandprocesswere gated behind theexec-toolskill, and a singleenabled: falseline in a syncedSKILL.mdwas enough to silently delete both from the tool registry at startup. They are now unconditional built-ins alongsidecode_search,browser,browser_extension, andweb_fetch. Approval gating still applies. Only OAuth-backed integration tools (Outlook, Slack) remain skill-gated, since they genuinely require a connected account to work.
Critical hotfix (rebuild)
- Fixed: app would not start after install. A route-pattern change that shipped with the first v0.2.30 build used
/api/workspace/:filename(*)syntax, which is rejected by the Express 5 path parser at boot. Every launch crashed before the embedded server bound its port, so the app sat on a retry screen forever (Attempt 1, 2, 3…). The wildcard routes for workspace files and webhook triggers are back on the working*filename/*splatform. If you were stuck on the loading screen, updating to this build fixes it. - New startup screen. When the local server is still coming up or has crashed, the loading screen now shows phase, port, PID, the last server error line, a rolling log tail, and three buttons: Restart server, Open logs, Copy diagnostics. Replaces the previous "Attempt N…" spinner that gave no indication of what was wrong.
Faster search across all your conversations
- Cross-conversation search now loads as you scroll. Before, Cmd+Shift+F only ever returned 20 results - anything past that was silently dropped, which was especially painful on large archives. The sidebar and the mobile search overlay now fetch the next page automatically when you scroll near the bottom, no extra "Load more" tap needed, until there's nothing left to match.
More auto-update fixes
- Clicking "Install Now" on the macOS native notification no longer crashes the app. The notification's action handler was focusing the main window before applying the update, which raced with the server shutdown that runs during quitAndInstall. The install path now defers to the next tick and skips the focus step so the update applies cleanly.
Strands SDK 1.1.0
- Upgraded
@strands-agents/sdkfrom 1.0.0 to 1.1.0. Brings proactive context compression, interrupt support for human-in-the-loop workflows, per-tool timeouts, retry strategies with configurable backoff, and MCP server log surfacing. Agent behavior is unchanged for existing usage; the new features will roll out in follow-up versions.
Use Foxl in your language, on any screen
- Integrations, Skills, Channels, and Tools pages now speak your language. Every page under the Integrations tab - including the Skills library, Channels, System tools, and Custom tools - reads in all 10 supported languages instead of always showing English. Section headings, filter buttons, search boxes, connect dialogs, error messages, and OAuth permission lists are all translated. Settings page too.
- Mobile-friendly layout across the whole app. Pages used to overflow on phones - long tab rows cut off, filter buttons got squished, dialogs didn't fit the screen. Now the tab bar at the top scrolls sideways with a soft fade on the right edge (so you can tell there's more), filter pills scroll the same way instead of shrinking their text, dialogs fit inside narrow screens, and search + filter rows stack vertically when there isn't room side-by-side.
- Preview mode on app.foxl.ai now matches the real app pixel-for-pixel. When you sign in without a desktop running, the sidebar shows every page (Agents, Workspace, Schedules, Feed, Relay, etc.) instead of only Chat + Settings. Clicking any data page shows a simple "Install Foxl" panel. The Install button auto-detects Mac, Windows, or Linux and shows the matching platform button.
Notes for developers
- New i18n blocks in the locale files:
integrations,skills_page,channels_page,tools_page,settings_page,header_tabs. - Demo components live in
apps/web/src/components/demo/(ConnectDesktopProvider,DemoPage,DemoIntegrations) so preview surfaces stay separate from the real pages. - None of the preview-mode behavior runs in the Electron desktop build -
IS_RELAY_ONLYis compile-time false there.
Auto-update fixes
- Mac "Install Now" button actually works now. Clicking "Install Now" in the native macOS notification used to do nothing. Fixed.
- Stale "update ready" notification cleaned up after install. After Foxl auto-updated itself, the old "ready to install" row would hang around in the notification bell and the button did nothing when clicked. Now the notification disappears automatically once the update has been applied.
Onboarding polish
- Skill library count in onboarding replaced with "Extensible skill library". The skill count kept rotting (73 → 68 → 35) every time we trimmed the library. Removed the number so it stops going stale.
Small fixes
- Clicking "Manage tools & MCP servers" in the HUD now goes to the right tab. It used to land on an older Tools page without the top tabs visible.
- Workspace file rows click on Windows again. Left-clicking a file in the Workspace sidebar was broken on Windows; fixed.
Workspace: real folder tree
- Workspace sidebar is now a proper folder tree you can expand and collapse. Replaces the three fixed sections (Core / Daily Memory / Sessions). Folders sort before files, hidden files stay hidden, and the tree remembers what you had open when you come back. Non-markdown files open in Finder instead of the editor.
- Workspace remembers the last file you opened. Reopen Workspace and you land on the file you were editing, with the folders around it already expanded.
Cleaner System and Custom tools pages
- System and Custom tools pages redesigned to match Integrations and Skills. Centered title, pill-shaped search, and category-grouped rows instead of the old card grid. Built-in tools are now grouped by type (Memory, Files, Web, Browser, etc.) so the list reads at a glance.
- Tool preset is now a dropdown. The four big preset cards became a single compact dropdown next to the search bar.
Sidebar restructure
- Tools moved under the Integrations tab. "Built-in" and "Custom" tools now live as two tabs inside Integrations (next to Integrations, Skills, Channels) instead of having their own sidebar entry. URLs:
/systemand/custom. - Agents tab no longer shows sub-tabs. Agents used to have a Tools sub-tab next to it - that's gone.
Tray menu fixes
- Menu bar dropdown now shows Recent chats and 7-day usage in the packaged app. This worked in development but was silently blank in the installed version - fixed.
- Clicking the menu bar icon no longer pops the window open. It opens just the dropdown. Use "Open Foxl" in the dropdown to bring the window back.
- First click after launch no longer shows an empty menu while the recent-chats data is still loading.
Skills cleanup
- Removed the "Trigger" field. The
trigger: manual / schedule / webhookfield in skills never actually did anything (scheduling lives in the Schedules page, webhooks go through channels). Removed from the skill editor and from the UI.
app.foxl.ai URL fixes
- Cleaner URLs when you open Skills, Channels, System, or Custom directly. No more
#skills,#tools, etc. hanging off the URL. - Direct links to /agents, /integrations, /feed now work on app.foxl.ai. Before, refreshing on these pages would bounce you back to Chat.
Landing page demo mock updates
- Desktop and mobile mocks on foxl.ai match the current app. Updated sidebar groups, model selector label ("Opus 4.7 Thinking"), Integrations/Skills/Tools panels rebuilt.
- Subtle parallax tilt. The mocks lean toward your cursor when it's in the surrounding whitespace, snap flat when hovering over the mock itself.
v0.2.27 blog post
- Published the v0.2.27 release notes as a blog post: "Trimming the Sidebar, the Skill Library, and the Tray."
Misc
- Pricing and "Try it out" sections on the landing page now visually separate from the sections above and below.
- SEO metadata updated on app.foxl.ai and docs.foxl.ai for Claude Opus 4.7.
Integrations / Skills / Tools: cleaner separation
- Sidebar reordered: Integrations → Skills → Tools → Schedules. The flow now reads left-to-right: connect a service → what the agent can do → when it runs.
- Integrations page only shows real third-party services. Before, anything with a "requires" field showed up here - including local document processors (PDF, Excel, etc.) and developer tools (exec, git, browser). Those all moved to the Skills page. Integrations is now just the OAuth connectors (Microsoft 365, Slack) and external SaaS skills (Notion, GitHub, Google Workspace, Obsidian, Spotify, etc.).
- Git removed as a built-in tool. The dedicated git tool was redundant - the agent handles git fine through the shell (
exec) tool, which gives more flexibility for pipes and custom flags.
Integrations page polish
- Rotating hero at the top now shows skills too, not just OAuth connectors. Each row gets its own gradient and sample prompt (e.g. "Review my pull requests and flag regressions" for GitHub).
- Microsoft 365 and Slack open a proper connect dialog first. Before, clicking Connect immediately kicked you out to the browser. Now you see a preview with the permissions being requested (and Slack's workspace input) before the OAuth flow starts.
- Channel icons show up properly. Every channel row was showing two-letter initials instead of its real logo - fixed.
- Connected channels no longer show a redundant "+" button. Just Stop / Edit / Remove.
Slimmer skill library
- Skill library trimmed ~60%. Deleted 32 rarely-used skills (Apple Notes, 1Password, various specialty tools). 21 commonly-used skills (browser, code search, exec, Notion, GitHub, Google Workspace, Outlook, PDF, etc.) stay enabled by default. Everything else defaults to off so they don't clutter the agent's context.
Streamlined tray menu
- Menu bar dropdown trimmed to essentials. Clicking the Foxl icon in your menu bar now shows: 3 most recent chats (click to jump right to the conversation), 7-day usage summary, then New Chat / Open Foxl / Quit Foxl. Removed rarely-used toggles (Stop Agent, Dark Mode, Always on Top, etc.).
Pricing restored
- Pricing section back on foxl.ai. Pro ($20/mo) and Ultra ($200/mo) plans, Credit Top-up, and the upgrade card in Account are all visible again. The brief "billing disabled" freeze from April is over.
Credit progress in the sidebar
- Click your avatar to see your credit usage. Compact progress bar showing how much of your monthly credits you've used, with a Pro/Ultra tier badge. Bar turns amber above 80% and red above 95%. Free-tier users get an "Upgrade" shortcut.
Smaller fixes
- Logos and icons render at full opacity everywhere. Removed the various
opacity-50/opacity-60/opacity-70dimming on the Foxl logo, platform icons under the download buttons, and the landing page's channel logos. - Docs site refreshed. Model pages, FAQ, and credits pricing now reference Claude Opus 4.7 as the flagship.
- Landing page SEO refreshed. Updated titles, meta, and structured data to reflect the current product (Opus 4.7, Windows support, Pro/Ultra plans).
New Foxl app icon (macOS + Windows + extensions)
- New Apple-squircle brand mark. Replaced the orange polygonal fox with a dark Apple-style squircle (dark monochrome fox silhouette + blue crescent accent). Canvas/padding match the previous icon layout (100px margin inside 1024 canvas), so the app tile reads at the same size on the Dock and in Finder.
- Covered every surface:
icon.icns(macOS Dock),icon.ico(Windows NSIS + taskbar, multi-res 16/32/48/64/128/256),icon-256/512.png, Windows installerbuild/icons/*.png(16-512), Chrome extension toolbar icons (16/32/48/128), and the web PWAapple-touch-icon.png+icon-192/512.png. - macOS menubar tray now renders from a new
menubar.svg(background-removed wordmark) at 22x22 standard and 44x44 retina, sized at ~80% of canvas so the tray icon visually matches surrounding menu-bar glyphs instead of looking oversized. - Unified brand across favicons and sidebar logos. All favicon SVGs (
favicon.svg,favicon-home.svg), sidebar logo variants (logo-color/dark/light/title/tray.svg), web PNG favicons (favicon.png,favicon-16x16.png), and landing-page favicons now use the new transparent mark — web app, landing, and docs all share the same brand asset.
Message queue drains as a single turn
- Multiple queued messages now combine into one turn. When you piled up several messages while the assistant was streaming, the old drain logic pulled them off the queue one at a time and ran a separate end-to-end turn per message — so three quick "also", "and", "oh one more thing" messages meant the model answered your first message fully, then your second, then your third, each without seeing the others. Drain now takes the whole queue for the current conversation on each wake-up, joins the entries with a blank line, and sends them as a single user turn. Matches Claude Code's behavior where rapid follow-ups land as one message.
- Applied to all three chat hooks:
useStreamingChat(local),useRelayChat(relay-only / app.foxl.ai),useTunnelChat(remote tunnel).
Generated image context menu
- Copy Image and Save Image As now work. Right-clicking a generated image (either the inline thumbnail or the zoom modal) and choosing "Copy Image" or "Save Image As..." was silently failing before. Two root causes: (1) the renderer's
fetch('file://...')is blocked by the defaultwebSecurity: true, so the saved-to-disk path fallback rejected with a network error; (2) after our asyncfetch→createImageBitmap→canvas.toBlobround-trip, the browser had already dropped the user-activation window thatnavigator.clipboard.writerequires and the write rejected withSecurityError. Both paths now route through new Electron main-process IPC handlers (copy-image-from-path,copy-image-from-data-url,save-image-as) that usenativeImage.createFromPath+clipboard.writeImagefor copy anddialog.showSaveDialog+fs.copyFileSync/fs.writeFileSyncfor save. Browser-only builds still get anavigator.clipboard.write+ anchor-download fallback. - Removed "Copy Image Data URL". The menu item duplicated "Copy Image" for most users' mental model and produced huge base64 blobs when pasted into a normal text field.
- Explicit toast feedback. Copy and save outcomes now show a sonner toast on success/failure, so a silent
navigator.clipboard.writerejection can no longer look like "nothing happened".
Subagent recursion guard (the real one)
- Subagents can no longer spawn subagents. Previously fork children kept the full
sessions_*tool schema (for byte-identical prompt-cache prefixes) and relied on two guards to prevent recursion: aBeforeToolCallEventhook that was referenced in comments but never actually registered, and anisInForkChild()scan that looked at the main conversation agent's messages viagetParentMessagesFn/ a hardcoded'default'fallback — never the running child's own messages — so it always evaluated false. Net effect: a child that decided to "delegate search" could fan out another 5 children, each of which could fan out 5 more, etc. Tree depth was bounded only by the 6-concurrent-agent cap racing against new spawns. - New hard guard:
sessionsSpawn.callbacknow checksgetCurrentAgentId()(backed by a newAsyncLocalStoragecontext thatrunAgententers for each subagent) and rejects if the caller isn't the'default'main agent.runWithAgentId(agentId, () => runAgent(...))wraps the spawn site insubagent.ts. - Belt + suspenders: the
BeforeToolCallEventhook that comments claimed existed is now actually wired up instrands-agent.tsfor every subagent Agent instance (fork or not). It cancels anysessions_spawn / sessions_status / sessions_stop / sessions_messagecall at runtime, regardless of whether the tool schema was filtered out or left in for cache sharing. - Dead code removed:
isInForkChildimport and the two call sites that scanned the wrong message lists.parseForkResultwas imported but never used — also removed. - parentId lineage fix: spawned subagents now record the real spawner's
agentIdviagetCurrentAgentId()instead of a hardcoded'default', so long-running-watch messages and UI parent links point at the agent that actually asked for the work. (Recursion is blocked before this matters in practice, but the registry data is now correct instead of lying.) - System prompt guidance rewritten to match Claude Code's delegation model. The old "RESEARCH & WEB SEARCH" block told the agent to "Spawn 3-5 subagents in parallel with different search angles" and to poll with
exec sleep Nbetweensessions_statuscalls — which encouraged fan-out on every research query and wasted tool calls on sleeps the runtime doesn't need (results arrive automatically). Replaced with explicit delegate-vs-work-directly rules: delegate for multi-file changes / refactors / debugging / broad research / verification / context-flooding outputs, work directly for trivial ops. Brief each subagent as a cold teammate (goal + in/out scope + brevity). Launch independent subagents in a single turn, don't duplicate delegated work, don't poll, and explicitly: subagents cannot spawn further subagents. Matching update insystem-prompt.tsMulti-Agent System section.
Subagent result gathering matches Claude Code's Task-tool semantics
- Batch-complete gather. Before, every individual subagent completion notified the server to drain, so a fan-out of 5 parallel subagents could trigger 2–5 separate auto-continue passes on the same conversation — the parent would synthesize mid-batch, then get poked again with the stragglers.
onSubagentDoneinsubagent.tsnow counts peers that share the sameconversationIdandstatus === 'running', defers the drain notification until it's the last one reporting, and only then firesautoContinueFn. Results still land in the durable DB queue as they arrive (so no completion is lost if the lock is briefly held by a mid-flight drain), but the synthesis pass runs once per batch — matching Claude Code's Task-tool behavior where a batch of parallel sub-tasks returns as a singletool_resulton the parent's next turn. - Registry extended with
conversationId. Required to scope peer-running counts to the right conversation so two concurrent chats don't delay each other. - Consolidated message shape. The auto-continue prompt is now
"N subagents have returned. Synthesize their findings into a single response for the user. Do not delegate further; do not restate the mechanism."followed by labeled### Subagent i/N — <goal>sections separated by---, with failed ones carrying a[FAILED]tag. Previous boilerplate ("The following subagent results have arrived. Synthesize them into a clear, organized response...") encouraged the model to restate the mechanism back to the user. - Dead parser removed.
strands-agent.tshad a branch that rewrote the prompt if an injected message contained[SUBAGENT COMPLETED:/[SUBAGENT FAILED:, but those tokens haven't been produced anywhere since auto-continuation moved to the DB queue — the branch never fired. Dropped. - Tool + prompt docs synced.
sessions_spawntool description,strands-agent.tsAUTONOMOUS_AGENT_INSTRUCTIONS, andsystem-prompt.tsMulti-Agent System section now all describe the same batch-complete delivery shape instead of the old "[SUBAGENT COMPLETED] message arrives per agent" promise.
Notification popover cleanup
- Consolidated notification action buttons to a single "Open" per row. Previously each entry had a type-specific primary label ("Open Agent" / "View" / "Reply") plus a redundant "Dismiss" button; the action row could show "Open / Dismiss / Dismiss" when a notification was rehydrated with a stale secondary action. Now there's exactly one action button labeled "Open", and dismiss lives as a per-row X icon that appears on hover.
- Native macOS banner actions also collapsed to a single "Open" button. macOS's notification shell already provides a close affordance, so an explicit "Dismiss" button was duplicating the OS chrome.
Notifications: actions, deep-links, and a working Install Now
- Action buttons on every notification type. Native macOS banners now carry "Open Agent / View / Reply / Dismiss" for agent done/failed, schedule done/failed, chat/channel message, and feed events. Previously only the update-ready toast had actions; everything else rendered as an unactionable banner that did nothing when clicked.
- Notification body-click navigates to the event page AND deep-links to the specific resource. Clicking a "Schedule: daily-briefing" banner now opens
/schedules#{scheduleId}, an "Agent Done" banner opens/agents/{sessionId}, a Slack channel message opens/chat/{conversationId}, and a feed alert opens/activities. Before, body-click only focused the window and dropped the user on the default page. - Action button clicks carry meta through the full stack. Server broadcast → WS → renderer → Electron main → back to renderer — the originating event's
sessionId/conversationId/scheduleIdis preserved end-to-end so deep-link navigation works for both the body click AND the action button. - Install Now on the update-ready toast actually installs.
autoUpdater.quitAndInstallis now scheduled on the next tick (was racing with the notification dismiss on macOS, which is why the button looked like it did nothing), explicitly setsautoInstallOnAppQuit = trueas a belt, and falls back toapp.quit()if the native call throws. - Bell popover and native toast are consistent. The in-app bell popover shows the same action buttons as the OS toast, so the experience is uniform on Windows/Linux where native actions aren't available.
- Server-side meta added to every emission site.
subagent.tsnow attaches{agentId, sessionId, conversationId}to completion notifications.server.tsschedule emissions carry{scheduleId, scheduleName}. Channel message emissions carry{conversationId, channel, channelId}. Single-agent start/goal endpoints carry{sessionId: 'default'}.
Notifications Settings cleanup
- Settings test picker now goes through the real server broadcast path. The picker was using a
CustomEventshortcut that bypassed the WebSocket round-trip, which meant it could pass locally while production was broken. It now hitsPOST /api/test/notificationwhich broadcasts over WS the same way production agents do, so clicking "Send test" exercises the exact same pipeline as a real event. - Settings test scenarios now mirror actual server emissions. Added
channel_message_whatsappandchannel_message_webpickers (missing before). Droppedpet_expedition_return/pet_item_dropscenarios — no code ever emitted those types, so the pickers were dead UI. Also removed the matching pet toggles from the settings schema. - Test picker resolves deep-link IDs from the server. When you test an agent notification, the picker fetches your most recent agent session and uses its ID as
meta.sessionIdso the click actually lands on a concrete row instead of the bare list. Same for schedules and conversations.
Agents page
- Active agents now render in the list. The header "N active" badge read in-memory team state, but the list below it only showed DB-persisted sessions — so chat-driven runs and not-yet-persisted agents appeared in the badge count but were missing from the list entirely. Live members are now merged as synthetic rows in a pinned "Active" group at the top, and running sessions bypass the Today / 7 Days / 30 Days time filter so a long-running agent stays visible even when the selected window excludes its start time.
Tests
notifications-e2e.spec.tsgained 17 new tests: meta propagation (5), Settings scenarios mirror server emissions (11, one per real type), subagent completion shape (1, skipped when no provider configured).- New
notification-actions-ui-e2e.spec.tscovers the UI half: Settings picker hits the real endpoint, bell popover renders action buttons, each action's pushState observed via ahistory.pushStatespy for race-free deep-link verification.
Schedule timeout UI
- Schedule execution timeout is now visible and configurable in the create/edit/detail dialogs. Displayed in minutes (stored as seconds), default 10 min. Hidden for heartbeat type (managed by server).
Fixes
- Fenced code blocks without a language tag (triple backtick) were rendered as inline code, collapsing newlines into a single line. Now checks content for newlines to determine block vs inline rendering.
Strands SDK v1.0.0 + Express 5 upgrade
- Upgraded
@strands-agents/sdkfrom v1.0.0-rc.5 to stable v1.0.0. Concurrent tool execution enabled by default - the LLM decides when to run multiple tools in parallel within a single turn. - Added
BeforeInvocationEventandBeforeModelCallEventcancellation hooks (SDK v1.0.0 feature). Agent stop requests now prevent the next API call from firing, saving cost and reducing latency on user-initiated stops. - Refactored per-agent tool event routing from a global Map (
agentToolEventFns) to SDK-nativeinvocationState- eachagent.stream()call carries its own callback via the per-invocation state bag, eliminating shared mutable state. - Upgraded Express from v4.18 to v5.2 with
@types/expressv5. Migrated all wildcard route patterns to Express 5path-to-regexpsyntax (:param(*)to*param, unnamed*to*splat). Fixed wildcard param handling - Express 5 returns arrays for*captures, now joined with/for path reconstruction.
Fixes
- Workspace file read/write via nested paths (e.g.
memory/daily/2026-04-30.md) broken by Express 5 array params - fixed withArray.isArray()guard andjoin('/'). - Webhook trigger endpoint updated for Express 5 named wildcard (
*splat).
Tests
- Added
sdk-upgrade-e2e.spec.tswith 11 new Playwright tests covering Express 5 wildcard routes, chat stop/cancellation, server health, and provider/model endpoints.
Custom tools & MCP: servers now actually reach the agent
- Custom tools stored in the
custom_toolsDB (shell, http, file, script,mcp_local,mcp_remote) were never wrapped as Strands tools — the LLM literally couldn't see or call them. AddedbuildStrandsToolsFromCustom()inserver/tools/custom-tools.tsthat wraps every enabled custom tool as a proper Strandstool()and appended them togetEnabledTools(). Custom tools bypass the profile system — if the user enabled them, the agent gets them. - MCP tools now default to expand-all mode: one MCP custom tool exposes every tool the remote server advertises. Each remote tool becomes its own Strands tool named
<customName>__<remoteTool>(e.g.server_time__get_current_time,server_time__convert_time). Removed the stalemcpToolNamesingle-target plumbing that was silently misrouting calls. - JSON Schema → zod converter ports the MCP server's
inputSchema(types,required,enum,description) into the Strands tool. Fixes the bug where the agent saw an empty{}schema and had to guess argument names / required-ness. executeMcpLocal/executeMcpRemotenow honor a per-call__mcpToolNameoverride injected by the wrapper, so expand-all routes correctly to the right remote tool on every call.
Connection status tracking & auto-probe
- New
McpStatuscache +refreshMcpStatus(def)/refreshAllMcpStatuses()helpers. States:unknown | connecting | connected | error | disabled, withtoolCount,tools[] (name/description/inputSchema), anderror. - Probe is triggered automatically on: server boot (for every MCP tool in the DB), custom-tool create, update (including enable toggle), delete (cache pruned for missing ids). No manual step needed.
- New endpoints:
GET /api/tools/custom/status(id → status map) andPOST /api/tools/custom/:id/refresh(force re-check). Route ordering fixed so/statusmatches before the/:idcatch-all. inputSchemapreserved in the cached status payload so the tool builder can forward the real JSON Schema (includingrequired) to the agent. Without this the model couldn't tell thattimezonewas required onmcp-server-time.
HUD redesign: flat, obviously-clickable, with MCP status
- ElectronTitlebar HUD rebuilt in the shadcn/ui design language: flat borderless pill with
text-muted-foreground → text-foregroundhover, chevron down indicator, status dot on the left, optional MCP badge on the right. No more raised button edges. - Popover expanded to 320px with clear sections separated by
Separator: status header, metrics grid (Agents / Tool calls / Iteration), context usage bar, MCP servers list (per-server status dot + tool count or truncated error), recent tool calls, and a clickable footer row that navigates to the Tools page (amber alert icon when any MCP errored). - Trigger auto-fetches MCP statuses on mount and polls every 5s while the popover is open — the number-of-connected badge updates without a manual refresh.
Tools page: edit existing custom tools
- Each custom tool row is now fully clickable (hover background, keyboard focus) and opens an Edit dialog that pre-populates every field (name, description, type, config, parameters). For
mcp_localthe space-joinedcommand/argsfield is reconstructed so the UI round-trips cleanly. - Dedicated Pencil edit button next to Play / Delete / Refresh. Dialog header and save-button label switch between Create / Edit mode automatically. Saving an edited MCP tool triggers a re-probe immediately.
- Non-MCP rows keep the same inline controls; action buttons stop click propagation so they don't accidentally open the edit dialog.
Misc
image-viewer.tsxtightened to match the rest of the tool-flip UI (generated / viewed images render with consistent collapsed / expanded states and zoom controls).- Landing site: FAQ additions, About / Legal / Blog copy edits, v0.2.19 blog post polish, new
humans.txt, updatediphone-frame.svg, sitemap regen. site/worker.jsupdated alongside new static asset routes (.well-known/, blog hero images).- Docs regenerated from latest MDX (
docs/public/docs/{models,providers,tools}.md+llms-full.txt+ sitemap) — covers thegpt-image-2+ OpenAI OAuth changes shipped in v0.2.19. foxl/scripts/debug-codex.mjs,debug-image-tool.mjskept in-tree for future Codex / image-gen wire triage.
`generate_image` tool: gpt-image-2 through ChatGPT subscription
- New built-in
generate_imagetool that produces or edits raster images viagpt-image-2without an OpenAI API key. Powered entirely by the user's existing ChatGPT Plus/Pro OAuth session (~/.codex/auth.json/CODEX_HOME/CHATGPT_LOCAL_HOME); no per-image billing outside the $20/month subscription quota. The tool posts tochatgpt.com/backend-api/codex/responseswithmodel: "gpt-5.4"carryingtools: [{ type: "image_generation", model: "gpt-image-2" }]. - Tool is gated to accounts with ChatGPT OAuth: only registered when the credential file is discoverable at module load, skipped otherwise so non-OAuth users don't see an unusable affordance.
- Accepts multi-image input for edits and composition.
inputImages: string[](max 10 paths) switches gpt-image-2 from text-to-image into edit / compose mode — "이 사진 만화풍으로 바꿔", "이 두 이미지 합쳐줘", reference-guided generation, etc. - Token-efficient wire shape: only file paths cross the model's tool-call args, never base64. The tool reads each path from disk inside the server process and encodes it as
input_imagedata URIs directly on the Codex request. Return payload to the model is trimmed toSaved to: <path>+ a sharp-resized 768px JPEG preview (~100KB) — the full-resolution PNG stays on disk atoutPath. - Attached chat images auto-persist to
data/workspace/attachments/chat-<timestamp>-<rand>.<ext>and their absolute paths are injected into the user's text block as[Attached image paths: "..."]. The model therefore always knows the exact disk path to pass togenerate_image({ inputImages: [...] }), closing the loop from drag-and-drop → edit. - Saved outputs live at
data/workspace/generated/generated-<YYYY-MM-DD>-<prompt-slug>-<suffix>.png. Workspace root (SOUL/USER/MEMORY/TOOLS/AGENTS/HEARTBEAT/BOOTSTRAP.md) stays uncluttered; every generated image carries its date and a readable slug derived from the first six words of the prompt. data/workspace/generated/excluded from workspace file listing automatically (subfolder convention), accessible via the Open Folder button now on the Workspace page header.- ChatGPT-style UI: generated images render expanded by default directly in the chat stream (not tucked inside a collapsible tool flip), with the standard Task chevron for collapse and consistent sizing with other tool calls.
view_imagekeeps its original collapsed-by-default compact UX. The full-resolution preview modal offers click-to-zoom (25%–400%) and an Open Folder button that reveals the saved PNG in Finder / Explorer / xdg-open. - Tool-profile wiring: added
mediacategory (['generate_image']) totool-profiles.tsand included it indefault,standard, andfullprofiles.minimalomits it to preserve its token budget.
OpenAI OAuth: catalog + model availability
- Added
openai-oauth/gpt-5.5to the catalog (1M context, reasoning + streaming). Verified serving on the ChatGPT OAuth endpoint via live probe.gpt-5.5-codex,gpt-5.5-mini,gpt-5.5-proare all gated to API-key accounts (400 Bad Request: "not supported when using Codex with a ChatGPT account") and therefore excluded. - Final catalog:
gpt-5.5(1M),gpt-5.4(1M),gpt-5.4-mini(400K),gpt-5.3-codex(400K). - Removed
openai-oauth/gpt-5.4-codexandopenai-oauth/gpt-image-2as top-level language-model entries. The ChatGPT OAuth backend returns400 Bad Request: "The 'gpt-5.4-codex' model is not supported when using Codex with a ChatGPT account"(same forgpt-image-2) despite the OpenAI Developer Community announcement.gpt-image-2is still reachable, but through the newgenerate_imagetool above. - Wired up
imageModel()/image()oncreateOpenAIOAuthregardless, backed by@ai-sdk/openai/internalOpenAIImageModelreused through the same OAuth fetch. Ready to flip on the moment OpenAI enables raw image models on the ChatGPT OAuth endpoint.
Fix: `openai-oauth/gpt-5.4` was silently routed to gpt-4.1
shared/model-resolver.tshad a staleNAMESPACE_ALIASESentry mappingopenai-oauth/gpt-5.4→gpt-4.1(andopenai-oauth/gpt-5.4-codex→gpt-4.1). Any time the user selected the OAuth GPT-5.4,setModel → toCanonicalIdresolved the alias and storedgpt-4.1as the active model — which Codex then rejected with a bare400 Bad Requestbecause ChatGPT OAuth accounts don't servegpt-4.1either. Removed both aliases so the transport-prefixed id passes through untouched. Verified end-to-end:/api/providers/selectnow persistsopenai-oauth/gpt-5.4verbatim and the follow-up/api/chat/streamreturns reasoning + text deltas as expected.
Debug: surface real Codex upstream errors behind `FOXL_CODEX_DEBUG=1`
- Added an opt-in
FOXL_CODEX_DEBUG=1env flag inopenai-oauth/core/transport.tsthat clones and logs the response body + request body on any non-2xx fromchatgpt.com/backend-api/codex/*. Strands wraps upstream errors as"Language model stream error: Bad Request", which discards the real cause; this flag is the single switch that reveals it. Off by default (no logging overhead in production).
UX: Workspace page "Open Folder" button
- New folder-open icon button in the Workspace header (next to Search and Refresh) that opens
data/workspace/in Finder on macOS, Explorer on Windows, andxdg-openon Linux. Electron shell path viawindow.pilot.openPath; non-Electron falls back to newPOST /api/system/openendpoint.
Skills: remove duplicate image-gen skills from foxl-ai/skills
- Removed
openai-image-gen(OPENAI_API_KEY + Python script path) andnano-banana-pro(GEMINI_API_KEY + uv + Python) from the skills repo. Both are superseded by the nativegenerate_imagetool above. One canonical image path across the product.
Dependencies: Strands SDK → v1.0.0-rc.5
- Bumped
@strands-agents/sdkfrom^1.0.0-rc.3to^1.0.0-rc.5. Picks up: mid-execution cancellation (agent.cancel()/cancellationSignalviaAbortSignal.timeout()), agent-as-tool (agent.asTool()), multi-agent session persistence, Bedrock thinking+forced tool_choice conflict fix, Bedrock context window overflow detection matching the Python SDK, invocation lock leak fix on consumer stream break, AgentSkillsPlugin → AgentSkills rename,contextWindowLimitadded toBaseModelConfig, and OTEL JS SDK v2 upgrade. No call-site changes needed in Foxl.
Frontend hygiene: zero web typecheck errors
- Fixed 19 pre-existing TypeScript errors across the web codebase so
tsc --noEmitinapps/webis now green. Bumpedtarget/libfrom ES2020 → ES2023 and addedvite/clientto thetypesarray (unlocksArray.prototype.findLastIndex, stricterArrayBuffertyping, andimport.meta.envtyping). Deleted unusedFloatingLines.tsx(referenced a missingthreedep). Tightened cast sites inuseWebSocket.ts(WebSocketMessagehad an[key: string]: unknownindex signature that made field narrowing impossible),tunnel-crypto.ts(BufferSource / Uint8Array overloads), andsearch-bar.tsx(RefObject nullability). None of these were blocking the Vite build, but keepingtscgreen is a non-negotiable guardrail for future refactors.
Claude Code (OAuth): Opus 4.7 gets its 1M context back
- Opus 4.7 on the Claude Code OAuth transport now reports its true 1M context window. Since Opus 4.7 shipped in v0.2.11,
claude-code/opushad been hard-coded to 200K because the CC OAuth catalog predated the 1M rollout. The result:/contextusage percentages showed ~5× inflated values and auto-compaction kicked in five times earlier than it should have, effectively capping Opus 4.7 sessions at 200K. A live check with a 320K-token prompt confirmed Opus 4.7 on this transport accepts the full input with nocontext-1m-*beta header — 1M is the native default, the beta flag is only for back-compat with older models. - Sonnet 4.6 on the same CC OAuth transport stays at 200K. A parallel probe (identical shape, only
modelswapped) returned HTTP 429 "Extra usage is required for long context requests" — Anthropic routes Sonnet's long-context requests into the pay-as-you-go pool instead of the subscription pool. Haiku 4.5 is likewise kept at 200K. - Added
resolveEffectiveContextWindow(modelId)inshared/model-resolver.tsso UI context gauges (useStreamingChat.ts) and server-side auto-compaction (server/agent/compaction.ts) both see the transport-adjusted ceiling rather than blindly trusting the catalog entry. Catalog entries keep their paper-spec numbers (Sonnet 4.6 = 1M via Bedrock/BYOK) and the helper narrows them only for transports that impose a cap.
Claude Code (OAuth) model ids: full Anthropic name after the prefix
- The CC OAuth catalog now exposes
claude-code/claude-opus-4-7andclaude-code/claude-sonnet-4-6as the canonical ids. The legacy short-form ids (claude-code/opus,claude-code/sonnet,claude-code/haiku) are preserved as aliases inCLAUDE_CODE_MODEL_ALIASESand in the sharedNAMESPACE_ALIASESmap, so previously persisted user selections (localStoragefoxl-selected-model, relay/api/providers/selectstate) keep resolving correctly. Verified end-to-end with a live probe — all four id shapes (new/old × Opus/Sonnet) route to the expected Anthropic model withservice_tier: standard.
Fix: model switch was a no-op on foxl.ai provider
- Switching model mid-conversation on the foxl.ai provider (e.g. Kimi K2.5 → Opus 4.7) kept running the previous model because
conversationAgentscaches StrandsAgentinstances andAgentis constructed with a baked-in model + provider. The POST/api/chat/streamhandler already calledsetModel(newModel)from the request body, but the cached agent ignored it. Added a parallelconversationAgentModelsmap that records each cached agent's construction-time model, andhandleStreamingChat()now discards the cached agent as soon ascachedModel !== config.model. All 16 existingconversationAgents.delete(…)/.clear()sites were mirrored so the maps never drift.
Relay: prompt caching on the Bedrock forward path
relay/src/proxy.tsnow injects block-levelcache_control: { type: 'ephemeral' }breakpoints on every Anthropic-format/v1/messagesbody before it hands off to Bedrock InvokeModel. The tool list, the system prompt, and the last user turn each get one breakpoint (up to Bedrock's 4-breakpoint limit) sotools → system → messagesprefix caching kicks in automatically across turns. Bodies that already carry explicitcache_controlmarkers are left alone. Verified with a dedicated unit-test suite (relay/tests/09-cache-breakpoints.test.ts, 7 cases covering string/array system shapes, tool lists, multi-turn conversations, andtool_resultblocks).- Strands'
AnthropicModelconfig only exposes acacheConfigthatBedrockModelhonors —AnthropicModelitself doesn't auto-inject cache points, so the relay-side injection is where caching on the foxl relay path actually turns on. Bedrock InvokeModel does not honor the top-level automatic-caching shorthand described in Anthropic's API docs (that's Claude API + Azure AI Foundry only), which is why block-level markers are the right place to hook.
Site: foxl.ai gets a real dark mode
- Added a
.darkpalette tosite/landing/src/index.css(background/foreground/card/muted/border/ring/accent all defined) and an inline pre-paint script inindex.htmlthat applies the saved or system theme before first paint so there's no FOUC on hard refresh. A newThemeTogglecomponent (site/landing/src/components/landing/ThemeToggle.tsx) sits in the Navbar next to the Download button on desktop and next to the hamburger on mobile, persisting the user's choice underlocalStorage['foxl-theme']and falling back toprefers-color-schemewhen unset. - Swept landing components for hardcoded light palette:
Security.tsxcards switched frombg-whiteto the semanticbg-card, and the LegalPage changelog version badge switched frombg-zinc-200 text-zinc-700tobg-muted text-muted-foreground. The only remaining hardcoded colors are intentional (the iPhone notch inMobileDemo.tsxstaysbg-black, the toggle knob inDesktopDemo.tsxstaysbg-white).
Revert: Claude Code (OAuth) compat layer is back on
- v0.2.17 disabled the Claude Code (OAuth) compat-mode tool rewriter based on raw
/v1/messagesprobes that appeared to show the compat layer was no longer needed. In production users immediately hit "Language model stream error: You're out of extra usage" — the raw probes did not reproduce the shape that Strands + Vercel AI SDK put on the wire in a real agent loop, so the requests were billed as extra usage. - Reverted:
strands-agent.tsandserver/api/server.tscallbuildCompatTools()again forproviderType === 'claude-code', the tool-adapter banner is back to its v0.2.16 wording, andclaude-code/haikuis excluded from the model catalog again (it was re-added in v0.2.17 based on the same faulty probes). - Compat mode returns to being the supported Claude Code (OAuth) path. Investigation to capture a real failing body and validate an end-to-end bypass is tracked in TODO.md; the probe scripts stay on disk as regression guards for the compat path.
Auto-update notification actions
- Clicking "Install Now" (or the notification body) on the "Foxl update ready" toast now actually installs the update and restarts the app. Two separate notifications used to race on download completion: a renderer-side rich notification with action buttons and an actionless main-process Notification. The main-process toast usually won, its
on('click')handler only focused the window, and the user saw "Install Now" do nothing. Removed the duplicate toast so the renderer's action-bearing notification is the only one the user sees. show-notificationnative-toast click handler now treatstype: 'app_update'as an install affordance rather than a focus-only click, so clicking the toast body (on any platform) installs the update the same way the explicit "Install Now" action does.
Claude Code (OAuth): full native tool registry
- Claude Code (OAuth) now sees Foxl's full native tool registry (memory, workspace memory, subagents, schedule, channel send, browser, view_image, etc.) — everything that was dropped by v0.2.16's compat-mode tool adapter. The Bash/Read/Grep/WebFetch shim layer is no longer used in
strands-agent.tsandserver/api/server.ts. Covered by two new probe scripts. server/providers/claude-code-oauth/compat/tool-adapter.tsis kept on disk (no longer imported) so it can be restored if needed.compat/message-rewriter.tsis still wired up — Foxl still relocates persona/context fromsystemto a<foxl-context>prefix on the first user turn.- Re-added
claude-code/haiku(Haiku 4.5) to the Claude Code (OAuth) catalog. The 2026-04-22 probe sweep showed Haiku now routes cleanly across the full native tool set — the instability that caused it to be excluded in v0.2.16 no longer reproduces.
Claude Code (OAuth) probe scripts
scripts/test-claude-code-oauth-compat-probe.mjs— 3×3 matrix (Opus/Sonnet/Haiku × no-tools/single-tool/full-CC-set) verifying subscription-pool routing against the CC-shape rewrite.scripts/test-claude-code-oauth-native-tools-probe.mjs— 3×3 matrix using Foxl-native tool names (exec, file_read, code_search, web_fetch, memory_save, sessions_spawn) to prove the CC-shape rewrite is no longer required.scripts/test-claude-code-oauth-roundtrip-probe.mjs— drives a full tool_use → tool_result → follow-up turn with Foxl-native names and asserts subscription routing on both turns.scripts/test-claude-code-oauth-claims-probe.mjs— checks Claude Code (OAuth) transport behavior against the live API:service_tier: autoandstandard_onlywork,cache_controlis a no-op over OAuth,context-1m-2025-08-07beta is rejected on OAuth tokens,claude -pCLI still runs, adaptive thinking plumbing returnsthinkingcontent blocks.
Notification click/action routing
- Notification bell items now actually navigate to the relevant page when clicked. Previously, any notification that carried action buttons (Install / Later on "update ready", or anything with explicit actions) swallowed the body click and stayed on the current page. Agent-complete, feed, schedule, and channel notifications now route to their owning page on click and close the popover afterwards.
- Action buttons whose id is not a special case (
install-update,dismiss-update) now fall back to navigating to the notification's navTarget, so "Open Agents" / "View Feed" style buttons in test notifications and future richer actions work without extra wiring. - Native OS notification clicks now route for
agent_complete,agent_error,feed,feed_urgent, andheartbeattypes as well (previously only chat / schedules were handled; everything else just focused the window). - Deep-link resolution extended: navigating to
chatwithmeta.conversationIdnow callschat.loadConversationand updates the URL; navigating toschedulesoractivitieswithmeta.scheduleId/meta.feedIdwrites the id into the URL hash so the target page can scroll or expand the relevant row.
Settings: interactive Test notifications
- The Test card in Settings > Notifications is now a working end-to-end test instead of a preview-only helper. Picking a scenario and hitting Send inserts a live rich notification (with an "Open" action) directly into the bell popover via a CustomEvent bridge, so you can verify click and action routing without waiting for a real event.
- Each scenario resolves a real deep-link target: agent scenarios fetch the latest
/api/agent-sessionsand route clicks to that session's detail page; schedule scenarios use the first/api/schedulesrow; channel_message scenarios use the most recent conversation. When no rows exist, the placeholder id still exercises the deep-link plumbing. - New "Also fire native OS notification" checkbox now calls
pilot.showNotificationdirectly from the renderer so the actions array reaches the Electron main process and the native banner renders the same "Open" button. Previously the test went through/api/test/notificationwhich stripped actions and also inserted a duplicate row in the bell. - Dismiss action removed from the test notifications — macOS notifications have a built-in close and the bell popover closes on outside click, so a second dismiss button was redundant. The action label is now just "Open" across all scenarios, localized in all 10 locales.
Claude Code (OAuth) compatibility mode
- Re-enabled the "Claude Code (OAuth)" provider with Opus 4.7 and Sonnet 4.6 entries. Haiku stays excluded.
- Added a transport-level rewrite layer (
server/providers/claude-code-oauth/compat/) that adapts Foxl's agent requests for the Claude Code (OAuth) transport. Two transforms run on every/v1/messagescall: message-rewriter.tsmoves Foxl's persona/workspace context out ofsystemand onto a<foxl-context>prefix on the first user turn, leavingsystemas a single preamble block.tool-adapter.tswraps each supported Foxl tool in a compatibility shim (exec->Bash,file_read->Read,code_search->Grep,web_fetch->WebFetch). Wrappers translate the CC-shape input back to Foxl-shape before delegating to the underlying Foxl tool, so Strands' agent loop keeps running existing callbacks unchanged.- Foxl-exclusive tools with no CC counterpart (memory, workspace memory, subagents, schedules, channel send, view image, browser extension, ...) are dropped from the tool list in compat mode - the model never sees them and cannot call them. First-time selection surfaces an AlertDialog explaining the trade-off (translated into all 10 supported locales).
- Docs: restored the Claude Code (OAuth) sections in
docs/content/docs/models.mdxandproviders.mdxwith compat-mode caveats.
Empty-chat layout
- When the terminal pane is open, the empty-state greeting + input no longer try to vertically center themselves over the terminal. The content now sits top-aligned above the terminal so both are fully visible.
Claude Code (OAuth) temporarily disabled
- Hidden the "Claude Code (OAuth)" provider and its Opus/Sonnet/Haiku entries from the model picker, settings page, and
/api/providersresponse. The transport, credential loader, and Strands wiring are kept in the codebase so this can be re-enabled later. - Why: Requests from Foxl's agent through this provider were billed as Extra usage instead of against the Pro/Max subscription, without users realizing it.
- Investigation also updated the OAuth transport's request headers and message format. Those changes stay in the tree.
- Workaround for users: use Anthropic API key (BYOK) or the foxl.ai relay for Claude access.
Empty-chat redesign (desktop + web app)
- New chats open with a Codex/Claude-style centered layout: a single "What should we work on?" greeting directly above the input box, vertically centered in the viewport. As soon as the first message is sent the input snaps back to the normal bottom dock.
- Dropped the six hardcoded prompt cards (Web Search / File / Debug / Code / Terminal / Analysis). They were generic enough to be noise. Pill-style AI suggestions still render directly under the input when
/api/suggestions/generatereturns any. - Foxl logo no longer prints in the empty state.
- Mobile keeps the earlier v0.2.11 layout (top-aligned logo + greeting + bottom-docked input) so the on-screen keyboard does not fight the centered overlay.
Fixes
- Suggestions fetch used an
AbortControllerwhose cleanup fired during React StrictMode's double-invoke effect, cancelling the inflight request so pills never appeared in dev. Switched to a cancelled-flag pattern - the request completes and the cache is warmed, results are just ignored if the component unmounted first. - app.foxl.ai (relay-only mode) now pulls greeting + suggestions from the connected desktop via the tunnel API (
/tunnel/api->/api/suggestions/generate), so mobile web users see the same cached AI-generated pills their desktop already produced. Previously mobile only showed the greeting because relay-only short-circuited the suggestions fetch. - Desktop UI no longer calls
/api/suggestions/generateon its own and no longer renders the "Try asking something like:" label. Suggestions are mobile-only now - the desktop empty state is just the centered greeting + input.
Changes
- Sidebar icon label renamed from "Config" to "Settings" (English only; other locales already said "Settings"/"설정"/"設定").
Site
- Added v0.2.13 blog post with pixel-office hero image; registered in
blog.tsx, worker SPA meta, and sitemap. Post is marked featured so it pins to the top of /blog.
Pixel Office — full redesign pass
- New cozy startup aesthetic: warm cream walls with wainscot trim, light marble-tile floor (6x3 staggered slabs with veining), wood-framed windows with sills, wall decorations (framed picture, clock, cork pinboard), and slowly-rotating ceiling fans. Ambient golden light beams with dithered edges and drifting dust motes near windows.
- Harmonized furniture palette: every piece now draws from the same ~18-color palette. Desks have warm oak tops with a single centered accessory (coffee mug, paper stack, or desk plant - deterministic per position). Chairs are backless 2-wide terracotta stools so a pet clearly perches on the cushion. Plants, lamps, shelves, whiteboards, and the water cooler all use coordinated wood + terracotta + sage tones.
- 2.5D object sprites: tall items (floor lamp 1x2, floor plant 1x2, bookshelf 3x1 drawn 2 tiles tall, whiteboard 4x1 drawn 2 tiles tall) protrude upward beyond their grid footprint without colliding with surrounding furniture. No more "floating head" plants or clipped shelves at the wall edge.
- Balanced layout: 4 workstations (left), meeting room with whiteboard + 3x3 rug + table + 2 chairs (center), lounge with rug + 2 cushions + tall lamp + tall plant (right), kitchenette with water cooler + bookshelf + pet feeder/bowl/cushion (far right). Mix of 1x1 and 1x2 items, perimeter plants and lamps anchor each zone.
- Agent-to-pet assignment is randomized: earlier the leftmost free pet and leftmost free seat always got picked, so the same pet always worked. Now random pick means workstations rotate.
- Clickable agent popover when a working pet is selected: compact 320px card with status dot, pet name, current task, live tool indicator with animated dots, last error, top-used tools, iteration/tool/elapsed stats, and Stop + Open Full actions. Much cleaner than the old cramped popover.
- Real-time pet-position persistence: pet positions (plus direction and state) now save to localStorage every 3 seconds and on tab blur / window close. Returning to the Agents page keeps every pet exactly where it was. Writes are batched so there is only one localStorage set per cycle.
- Notifications are deep-linkable: agent-completion notifications now carry the session id in their payload. Clicking "Agent Done" in the bell popover jumps straight into that agent's detail page. Works across the in-app bell, the Electron titlebar bell, and the Windows header bell.
Pixel Office - earlier in v0.2.13
- Claude-Code-inspired rare encounter journal (18 critters across 5 tiers, seasonal/night/agent-completion gates).
- Welcome-back summary modal with sparks/items/sightings earned while away.
- Pets replace human agent sprites; each walks to a chair and "works" with an animated monitor.
- Background pet simulation always runs when the Pixel Office is enabled (no separate opt-in).
- Wall-clock catch-up simulation so pet stats and rare rolls progress accurately after long absences.
- Server-side state backup via
/api/pixel-office/state(single-row blob store, overwrites in place - no history accumulation). - Visitor system retired and unified under the rare-encounter journal (sightings-only).
- Inventory now surfaces only placeable items; starter seed is a single comfy cushion.
- Auto-forage removed; pets stay home.
Fixes
- Feed sidebar black dot that couldn't be dismissed (legacy Activities-era code).
- Goal-started agents now appear as separate rows in the history list (each run mints its own session id).
- Agent popover used to show 2 running agents for 1 goal because the in-memory "default" row and the fresh session row both appeared - now deduped.
- Sidebar label "Agent Team" simplified to "Agents" across all 10 locales.
- i18n interpolation accepts both
{var}and{{var}}placeholder styles. - Monitor flicker on working pet's desk now aligns to the desk's centered monitor and refreshes at a subtle 2 fps instead of strobing.
- Wall-anchored tall items (whiteboard, shelf) previously got clipped or hidden when placed near the wall seam - render order fixed.
- Settings showed a stray "Background Pet Simulation" toggle even though the feature is always on - removed.
- Notifications now support action buttons. Previously the in-app bell dropdown only showed title + body - there was no way to trigger "Install", "Dismiss", etc. - so the new-version notification in particular had no actionable path. The Electron native OS notification also gains action buttons (macOS) and opens the bell popover when clicked (Windows/Linux), bringing the in-app action chips to every platform.
- "Update ready" notification now posts to the in-app notification center with Install Now / Later buttons, not just a silent system toast. Dedupes across multiple download cycles via a fixed notification id.
- Fix tunnel "restart desktop" and update-install restart paths leaking the spawned Node server subprocess. Previously
app.exit(0)/quitAndInstallskipped thebefore-quitlifecycle, so the server kept running on port 13847 and the relaunched app could not bind the port - making restart worse for users who were trying to recover from a stuck state. Restart now explicitly tears down the server subprocess and tunnel client before handing off to the updater / relaunch. - Fix Claude Code OAuth credential detection on Windows. The previous code path tried to read tokens from Windows Credential Manager via the community
Get-StoredCredential/New-StoredCredentialcmdlets, which are NOT installed by default on Windows - the shell-out silently failed for every Windows user and then fell through to the file fallback. Claude Code on Windows actually stores tokens in%USERPROFILE%\.claude\.credentials.json(matches upstream openclaw / pi-ai reference behavior), so we now read/write that file directly with no PowerShell spawn and no module dependency. Token refresh writes back to the same fileclaude loginuses. - Fix Feed Generator interval changes not applying. Changing "Frequency" in Settings → Feed Generator from 5 minutes to 1 hour updated only the heartbeat-runner but left the scheduler's paired
Heartbeatschedule spinning its ownsetIntervalat the old interval forever. Execution is now owned exclusively by the heartbeat-runner; theHeartbeatentry in the Schedules UI is display-only (scheduler skips attaching a timer for the auto-seeded entry). Settings ↔ Schedules UI are kept in sync both directions: interval/enabled changes from Settings mirror to the schedule row, and toggles/interval edits from the Schedules UI mirror back to HEARTBEAT.md + the runner.
Changes
- Feed Generator is now the single Heartbeat schedule. Users can no longer create additional heartbeat-type schedules from the Schedules UI - that type is removed from the create dialog, and
POST /api/schedulesrejectstype: "heartbeat"requests. Use Cron instead for custom periodic schedules.
Features
- New OpenAI (OAuth) provider: use your ChatGPT Plus/Pro subscription directly — no API key needed. Foxl reads
~/.codex/auth.json(created bynpx @openai/codex login), auto-refreshes the OAuth token, and calls OpenAI's Codex Responses API directly through Strands' VercelModel adapter. No local CLI subprocess, no proxy server. Tool use, reasoning/thinking blocks, and streaming all flow through the normal Strands agent loop. Models: GPT-5.4, GPT-5.4 Codex. - Claude Code (OAuth) rewritten on Vercel AI SDK: drops the
claudeCLI subprocess. Foxl now reads the user's Claude Code OAuth tokens (macOS Keychain, Windows Credential Manager, or~/.claude/.credentials.json) plus long-lived API keys fromclaude setup-token, auto-refreshes OAuth tokens, and callsapi.anthropic.com/v1/messagesdirectly through Strands' VercelModel adapter. Foxl's full tool registry, thinking/reasoning blocks, and streaming now work end-to-end on Claude Pro/Max subscriptions — same path as the OpenAI OAuth integration. - Settings > Providers list now groups each OAuth login right under its API-key counterpart (OpenAI (OAuth) under OpenAI, Claude Code (OAuth) under Anthropic, Gemini CLI under Google) with the provider's own icon.
Changes
- Renamed the Claude Code provider surface from "SSO" to "OAuth" everywhere (UI labels, status field
ssoConfigured->oauthConfigured, docs). The underlying auth mechanism is unchanged — just more accurate terminology. - Removed the legacy Codex CLI provider (subprocess-based). Replaced by OpenAI (OAuth), which talks to OpenAI's servers directly using the same
~/.codex/auth.jsoncredentials created bycodex login. - Removed the legacy CLI-subprocess Claude Code provider.
@anthropic-ai/claude-codeis no longer a runtime requirement — Foxl just reuses whichever credentials Claude Code already stored (keychain entry or~/.claude/.credentials.json). - Settings > Providers help text for Claude Code now points users to
claude /login/claude setup-tokeninstead of asking them to install the CLI. - Subscription-OAuth providers (OpenAI, Claude Code, Gemini CLI) now show a one-line disclaimer in Settings clarifying that they are unofficial community integrations using local subscription credentials — use at your own risk and never share the auth file.
Fixes
- Fix scheduler (cron + heartbeat) + several helper endpoints that would throw
openai-oauth requires async model creation/claude-code requires async model creationwhen those providers were the active default. All internalcreateModel()call sites now usecreateModelAsync()so OAuth-backed providers work everywhere, not just chat.
Features
- New Feed page (replaces Activities): For You tab for AI-curated items, Activities tab for agent event stream, Logs tab with live SSE log viewer. Persists selected tab per user.
- New Feed Generator (was "Heartbeat" in settings): a background agent that periodically surfaces items in the For You feed. Most runs stay quiet; only items marked urgent trigger system notifications, so it can run hourly without spamming you.
- New
feed_addtool exclusive to the Feed Generator executor (not exposed to chat or subagents). Accepts title, body, priority (quiet/urgent), category. - Feed items support Archive / Unarchive / Clear with a clean Inbox/Archive view toggle. Hover anywhere on the row to archive in one click.
- HEARTBEAT.md is the single source of truth for the Feed Generator prompt. Edit it in Settings or in the workspace; both refresh the runner immediately.
- Windows taskbar overlay icon now renders the unread count (16x16 SVG) for parity with the macOS Dock badge.
Improvements
- Sidebar restructured: Chat / Overview / Workspace in the top group; new "Extend" group with Agents, Tools, Skills, Schedules; Connect (Relay, Integrations); Feed.
- Page header uses i18n via
nav.<id>keys (was a static English NAV_TITLES lookup). - Schedules page Recent Runs gets a full filter bar: search, Status, Type (All / Excluding heartbeat / Cron / Heartbeat only / Webhook), Schedule, Time range, Sort. Grouped by Today / Yesterday / This week with relative timestamps.
- Skills page: Enable/Disable-all toolbar button removed, replaced by a subtle counter pill ("3/12 on") with Enable all / Disable all / Invert actions. Per-skill right-click context menu with Enable, Open in Finder, Delete.
- Notification settings redesigned: Behavior (Only in background / Sound) merged into the master toggle card at top; new Feed section with separate urgent/quiet toggles; test scenarios collapsed into a single dropdown plus Send Test button with a live preview card that shows the notification action chips.
- Heartbeat-type schedules no longer emit the "Schedule: ..." system notification or bump the sidebar badge. They only surface via explicit
feed_addcalls. - Feed Generator default interval changed from 5 minutes to 1 hour (recommended). Interval options are now 15m / 30m / 1h / 3h / 6h, with 5m kept for debugging only.
- Settings → Feed Generator card compacted: inline status strip, Frequency and Quiet Hours side-by-side, Instructions collapsed by default. Save button disabled unless there are unsaved changes; a Revert action discards local edits.
Removed
- Live Logs section removed from Config page. Use the Feed page's Logs tab instead (same SSE stream).
Fixes
- Fix black screen on app relaunch: retry loadURL up to 10 times on connection refused instead of showing error page immediately.
- Error recovery page now probes multiple ports (13847-13851) to find server after EADDRINUSE fallback.
- Fix relay model tier check rejecting prefixed model IDs (e.g. global.anthropic.claude-sonnet-4-6) for free tier users.
- Fix crash in Feed Generator settings when
activeHoursis null in the heartbeat runner state.
Features
- Merge Channels and Integrations into a single "Integrations" tab (sidebar Connect section)
- Slack OAuth workspace selector: enter workspace name (e.g. "mycompany") to connect a specific workspace directly
- Slack App registered (OAuth V2, user-token scopes, any workspace installable)
- Relay Slack exchange endpoint deployed with client_id/client_secret secrets
Fixes
- Fix OAuth loopback server blocking on repeated Connect clicks (async close + explicit cancel of previous flow)
- Fix Connect button staying disabled after first click (busy state now clears immediately)
- Auto-register/unregister integration tools (slack, outlook) on connect/disconnect without server restart
Features
- New Integrations page (sidebar → Connect → Integrations) for connecting Microsoft 365 and Slack via one-click OAuth
- New
outlooktool (21 actions): email (inbox/read/send/reply/forward/search/folders/drafts/attachments/contacts/move/categories/update), calendar (view/meeting/availability/room booking/search/shared list), and Microsoft To-Do (lists/tasks/checklist) via Microsoft Graph API - New
slacktool (16 actions) using the user's OAuth token: search_messages, whoami, get_recent_messages, channels_list, conversations_history/replies/add_message/open/members, check_replies_batch, users_lookup/profile_get, attachment_get_data, reactions_add/remove, file_upload - Both tools are skill-gated: only registered after the user connects the corresponding account (no noisy tool schema otherwise)
- Microsoft OAuth uses PKCE + loopback (public client, no shared secret). Slack OAuth exchanges the auth code through relay.foxl.ai so the Slack client_secret is never bundled in the desktop app.
- Deep-link fallback (
foxl://integrations/callback) for environments where the loopback port is blocked - Electron
openExternalIPC exposed for renderer → browser navigation (http/https only)
Changes
- Existing
outlook-webskill (browser-extension based) marked as legacy/disabled - superseded by the nativeoutlooktool - Existing
slackskill rewritten from bot-token stub to real user-token tool
Infrastructure
- New
foxl/server/integrations/module: shared OAuth loopback, token store (agent_memory-backed), Microsoft Graph wrapper (auto-refresh on 401), Slack Web API wrapper - New relay endpoint
POST /integrations/slack/exchangeholds the Slack client_secret - Skill eligibility now honors
requires: [integration:<provider>]- auto-hides tools until connected
Improvements
- Migrate to SDK-native cooperative cancellation (agent.cancel()) for faster, more reliable stop
- Stop button now cancels at SDK checkpoint (between model events and before tool execution) instead of polling flags
- Subagent stop also uses SDK cancel
- Strands SDK updated to 1.0.0-rc.3, Bedrock SDK to 3.1030
Fixes
- Fix Opus 4.7 thinking not displaying: Opus 4.7 defaults thinking.display to "omitted" (empty text, signature only). Now explicitly sets display:"summarized" to restore thinking content in responses.
Fixes
- Fix context usage percentage showing inflated values for Opus 4.7 (was using 200K instead of 1M as context window)
- Context window size now reads from shared model catalog instead of hardcoded string matching
- Future models automatically get correct context % without code changes
- Fix Opus 4.7 thinking error: "reasoning content format incorrect" - Bedrock SDK updated to 3.1030 for new thinking block format (thinking field + signature)
Infrastructure
- Add @shared Vite alias for frontend access to shared model catalog
- Strands SDK updated to 1.0.0-rc.3
New Model
- Claude Opus 4.7 support - Anthropic's most capable model, available on AWS Bedrock (us.anthropic.claude-opus-4-7)
- Opus 4.7 set as default model and routing target for expert-level tasks
- Opus 4.6 retained in catalog for backward compatibility
Fixes
- Fix Opus 4.7 thinking error: "thinking.type.enabled is not supported" - now correctly uses adaptive thinking for all Opus/Sonnet 4.6+ models
- Fix Electron EPIPE crash when tunnel log writes to closed pipe (uncaughtException handler)
Fixes
- Fix context compaction triggering at 180K tokens instead of model's actual limit (Opus/Sonnet now compact at 900K, was 180K)
- Fix scheduler cron times interpreted in system timezone instead of user's configured timezone
- Fix a hardcoded timezone in schedule display (now reads from USER.md)
- Fix heartbeat active hours check using wrong timezone
Improvements
- Context compaction now stays in the same conversation (no more "Continued:" new chats)
- Compaction inserts a visible divider message so users know it happened
- Context usage percentage resets after compaction
- Sidebar conversation list now supports infinite scroll (was limited to 50)
Fixes
- Fix model ID resolution in agent core: canonical IDs now correctly converted to provider-specific ARNs via catalog (was passing
claude-opus-4-6directly to Bedrock instead ofglobal.anthropic.claude-opus-4-6-v1) - Fix subagent model routing: subagents now resolve models through the same catalog as parent agent
- Fix GLM-5 and Kimi K2.5 not receiving
reasoning_configon Bedrock (string-match detection replaced with catalog family lookup) - Fix navbar hash links navigating to wrong page from blog (
#security->/#security)
SEO
- docs.foxl.ai: favicon (SVG), robots.txt, sitemap.xml (21 pages), OG/Twitter meta, canonical URLs per page
- foxl.ai: BreadcrumbList JSON-LD replaces SiteNavigationElement (fixes Google breadcrumb display)
- app.foxl.ai: SVG-only favicon (remove PNG fallback)
Blog
- New post: Foxl v0.2.2 release notes
- New post: What Breaks When Your AI Agent Runs on a Real Desktop
- Blog posts split into individual files with lazy loading (main bundle -28KB)
Build
- foxl.ai: Vite plugin auto-generates sitemap.xml on build
- docs.foxl.ai:
npm run buildauto-generates llms.txt + sitemap.xml from MDX sources
Model Registry
- Unified model catalog: single source of truth for all models across desktop, relay, and providers
- Model IDs normalized to canonical short form (e.g.
claude-opus-4-6instead ofglobal.anthropic.claude-opus-4-6-v1) - Adding a new model now requires editing 1 file instead of 5+
- Usage tracking shows clean canonical names (no more duplicate model entries)
- Relay derives model list from shared catalog
Settings
- Moved Logs from sidebar to Settings > Live Logs (collapsible card)
- System Report: download diagnostic file with system info, conversations, audit trail, and noise-filtered server logs
- Reports generated server-side for speed and richer data (audit.jsonl, DB conversations)
Chat
- Edit messages with attachment management: remove images/documents via X button before regenerating
- Save & Regenerate works even without text changes (useful for re-running with removed attachments)
- Auto-focus chat input on conversation switch (click sidebar conversation or new chat)
Sidebar
- Click "Chat" nav to start a new conversation (when already on chat page)
- Right-click "Chat" context menu: New Chat, Search, Delete All (all i18n)
- Right-click conversation context menu items now fully localized
Relay
- Non-Claude Bedrock models (GLM-5, Kimi K2.5) routed via Converse API instead of Anthropic InvokeModel
- Full tool support and streaming SSE translation for non-Claude models
Browser
- Dedicated Foxl browser profile (separate from personal Chrome)
- Login state persists across sessions within the dedicated profile
SEO
- docs.foxl.ai: add favicon (SVG), robots.txt, sitemap.xml (21 pages), OG/Twitter meta, canonical URLs
- docs.foxl.ai: per-page OG title/description/URL for all docs pages
- foxl.ai: replace SiteNavigationElement with BreadcrumbList JSON-LD (fixes Google showing all nav links as breadcrumb)
- foxl.ai: per-route BreadcrumbList via Worker (blog posts get Foxl > Blog > Title)
- app.foxl.ai: remove PNG favicon references, SVG-only favicon
Dev
RELAY_URL=http://localhost:4200for local dev with foxl relay mode
Skills
- Install skills from [skills.sh](https://skills.sh) registry directly in the Skills page
Scheduler
- Fix cron weekday schedules firing on wrong days after laptop sleep/wake
Overview
- Redesigned dashboard: today-focused metrics, cleaner layout, reduced polling
- Token usage by model with provider labels (Bedrock, Ollama, etc.)
- Usage Explorer shows which provider handled each model request
- Local data disclaimer in Usage Explorer
Search
- In-chat search (Cmd+F): find text within current conversation with persistent yellow highlights
- Cross-conversation search (Cmd+Shift+F): search across all conversations from sidebar
- Multi-word search: "hello world" finds messages containing both words
- Match navigation with up/down arrows and match counter (N/M)
- Click sidebar search result to navigate to exact message with highlights
- Korean and multi-byte text search support
UI
- Increase button spacing in prompt input toolbar for mobile
- Protocol-level WebSocket keepalive for more reliable connections
Multi-Agent
- DB-backed auto-continuation queue — replaces two competing in-memory queues that caused duplicate agent spawns (3 agents becoming 6)
- SQLite lock table serializes drain execution — atomic INSERT OR IGNORE mutex, stale lock cleanup
- Remove injectMessage for subagent completion — fixes raw [SUBAGENT COMPLETED] text appearing in chat during auto-continuation
- Sidebar agent list redesign: elapsed timer, stop button (hover), shadcn Badge for collapsed mode
- AgentChatView: group consecutive thinking+tool items into single Message block (matches main chat spacing)
- AgentChatView: fix thinking blocks not displaying — each DB event rendered as separate timeline item
- Per-agent tool event callbacks — each agent's tool calls scoped to its own instance (no cross-agent leaking)
- Subagent thinking capture — model reasoning blocks (reasoningContentDelta/thinking_delta) recorded to DB
- Auto-continuation triggers per-completion — each agent result delivered independently (no 30s batching)
- Parent breaks after spawning subagents — waits for auto-continuation instead of re-prompting
- Fork children keep full tool list for prompt cache sharing — spawn blocked at hook level
- Block subagent spawning during auto-continuation turn (DB lock = spawn guard)
- Remove goal-based dedup guard (Claude Code doesn't do this)
- AgentChatView fully DB-driven timeline — survives WS disconnect, complete/error events rendered
- Remove duplicate goal message bubble + duplicate result rendering
- Completed agent goal display — merge DB goal into in-memory state
- Remove all subagent result/tool truncation (was 1000-5000 chars)
- Remove duplicate active agents section from Agents page (fork tags sanitized)
Tool Approval
- "Always Allow" auto-approves remaining parallel pending tool calls matching new permission rule
- Load DB permission rules at server startup — "auto approve all tools" was silently ignored (ESM require fix)
Channels
- Auto-reconnect channels on server restart (Telegram, Signal)
Scheduler
- Fix cron weekday field parsing — was completely ignored, causing schedules to run on wrong days
- Support ranges (1-5), lists (1,3,5), and mixed weekday expressions
UI
- Message queue redesign: accent background, line-clamp, hover-reveal delete button
- Terminal session count sync: fix stale closure in WS handler, sessions refresh on spawn/exit events
Skills
- Fix YAML folded scalar (
>) and literal (|) block parsing in skill frontmatter - Multiline description fields now correctly joined instead of showing
>literal
Build
- Fix esbuild banner variable collision (
_cr->__foxl_cr) — prevented production app from starting - Fix 6 pre-existing TS errors: GoogleModel import, ProviderType ('foxl'), PermissionSource ('user'), SQLInputValue
Relay Dashboard
- New unified Relay card on gateway page with connection topology tree
- Desktop node shows online/offline status, platform, connection time
- Web client branches display browser, OS, and connection duration
- Remote restart: restart desktop app from any device via tunnel
- Remote update check: trigger auto-update remotely
- Force disconnect individual web clients by fingerprint
- Session history timeline with audit log (deduplicated, last 10 entries)
- Tunnel toggle integrated into dashboard header (desktop mode)
- Account email and relay connection status in card description
- 15s auto-refresh with visibility-aware polling
- Full i18n support across 10 languages (27 new keys)
Tunnel Cost Optimization
- On-demand heartbeat: idle 5min, active 30s (was 24/7 30s)
- HTTP heartbeat bypasses Durable Object entirely (zero DO request cost)
- Slow/fast heartbeat switching on web client connect/disconnect
- Dead connection detection maintained via HTTP liveness check
- Estimated tunnel capacity: ~630 DAU on $5/mo Cloudflare plan (was ~115)
Mobile Terminal
- Compact quick keys: smaller buttons prevent horizontal overflow
- Scroll-to-bottom button in quick keys bar
- Auto scroll-to-bottom after terminal resize (prevents mobile scroll jump)
Foxl Notes Landing
- White/light theme redesign for foxl.ai/note
- Pricing section removed
- Modernized mockup styling
Landing Page
- "Products" renamed to "Projects" (portfolio tone)
- FAQ rewritten: free project, Claude Code/Dispatch comparison, mobile access, privacy
- Hero subtitle rewritten
- CTA: "Try it out" with "No account required"
- Footer: project credit line (was copyright notice)
- Refund link removed from footer
- Billing/subscription sections of Terms and Privacy updated while billing was paused
- Legal entity reference updated on legal pages
Fixes
- Model selector: foxl relay models now appear first when tunnel connected
- Discord bot: pricing-disabled instruction prevents outdated billing answers
- Terminal scroll position preserved across resize events
Tunnel Stability
- Fix DO hibernate state loss: persist userId/deviceId to durable storage, restore on wake
- Fix tunnel status: check is_online flag for instant disconnect detection (was only using stale last_seen_at)
Tunnel Cost Optimization
- Durable Object Hibernatable WebSocket API: DO sleeps when idle, wakes on message
- Client-driven heartbeat: desktop sends ping every 30s (no more server-side setInterval)
- Chat delta batching: 100ms window reduces DO wake-ups by ~90%
- Estimated DO cost reduction: $8.38/mo to ~$0.41/mo per 2 tunnel users
Subagent Fork
- Fork subagent: children inherit parent's full conversation as byte-identical prefix for prompt cache sharing
- Identical system prompt + tool definitions across fork children (Claude Code pattern)
- Anti-spawn via fork directive prompt (soft guard) + isInForkChild() code check (hard guard)
Terminal Reopen Fix
- Terminal panel loads scrollback on reopen (no more blank black screen)
- Works for both running and restored sessions
Mobile Chat Copy
- "Copy Entire Text" works on app.foxl.ai (reads from localStorage in relay-only mode)
- Message copy/edit/regenerate buttons always visible on mobile (no hover needed)
Fixes
- Fixed auto-update "Relaunch" button only hiding window instead of restarting on macOS
- Fixed 10+ TypeScript type errors across App, AgentEvent, ImageAttachment, ConversationItem, ScheduleExecution
Native 1M Context Window
- Opus 4.6 and Sonnet 4.6 now have native 1M context window (no beta header needed)
- Removed separate "(1M)" model variants -- all Opus/Sonnet 4.6 are 1M by default
- Simplified model selector: single entry per model instead of two
Adaptive Thinking Effort
- New effort level selector: Low, Medium, High, Max (replaces token budget)
- Adaptive thinking with effort parameter sent via Bedrock
output_config - Max effort is Opus 4.6 exclusive (other models fall back to High)
- Default effort level: Medium
Tool Approval
- Claude Code-style permission prompts inline with tool calls: Allow, Always allow, Deny
- Pattern-based trust: "Always allow" on
exec lscreatesexec(ls*)rule - Permission rules persist to DB across restarts, with
*wildcard as default - Settings page: toggle auto-approve-all, add/remove patterns manually
- Built-in safety: destructive commands (
rm -rf /,mkfs,dd) are denied by built-in rules
Agent Core v2
- Context compaction: auto-summarize long conversations to stay within context window
- Error retry with exponential backoff for transient failures
- Hook system: BeforeToolCall / AfterToolCall lifecycle for permission checks and plugins
- Fork subagent: spawn child agents from parent conversation context
- System prompt token optimization (34K to 19K chars, 44% reduction)
GLM 5 + Kimi K2.5
- GLM 5 (Z.AI) available on Bedrock + relay with reasoning_config thinking support
- Kimi K2.5 (Moonshot AI) with 256K context, vision, and tool use
Context Usage in HUD
- Context window usage percentage displayed in macOS titlebar HUD
- Per-conversation tracking from actual token metrics
- Real-time updates during streaming, persists across conversation switches
Claude Code SSO Fixes
- Fixed double text output and shimmer stuck during streaming
- Rewrote CLI stream parser for reliable tool result handling
File Attachments
- Drag & drop files onto chat area with visual drop zone overlay
- Accept any file type via paste or file picker (json, yaml, py, ts, etc.)
- Unsupported Bedrock formats (json, xml, yaml) mapped to txt server-side
- Document attachment pill constrained to message bubble (no overflow)
Subagents
- Removed execution timeout — agents run until completion (no more premature stops)
- Auto-continuation max-wait safety timer (30s) for result synthesis
Settings Persistence
- AWS profile, region, and thinking effort persist across server restarts
- Saved to server-config.json in data directory
Schedule Reliability
- Schedules auto-disable after 3 consecutive failures (including stuck task timeouts)
- Prevents infinite retry loops for broken schedules
Large Text Paste
- Virtualized text viewer for attached text blocks (handles 1M+ chars without freezing)
- indexOf-based parser replaces regex (no backtracking on huge content)
- Copy button still copies full original content
Provider Detection
- Bedrock provider correctly reports unconfigured when no AWS credentials exist
- foxl.ai relay models listed above BYOK/bedrock models in model selector
Update Banner
- "Updated to vX.X.X" with Relaunch button in sidebar when auto-update completes
Landing Page
- Animated SoftAurora background with mouse interaction and fade-in
- Redesigned Security section with CSS Grid layout
- Discord button, pricing display, license URL fixes
Electron
- Electron 41, electron-builder v26
- Bundled Node.js runtime for non-developer users
- Source map protection (never ship .map files)
Fixes
- Model/provider sent in chat stream request body (fixes race condition)
- Fixed tunnel double-connection on sleep/wake reconnect
- Fixed production terminal, schedule persistence, provider switching
- Auto-close terminal panel when last session killed
- Fixed spinner stuck after stream completion (agentRunning:false broadcast)
- OS-aware download button in navbar
- Sidebar refresh after OAuth login
Claude Code SSO
- Use your Claude Pro/Max subscription directly in Foxl -no API key needed
- Auto-detects credentials from macOS Keychain or ~/.claude/.credentials.json
- Just run "claude auth login" once, then select Claude Code (SSO) in Settings
- Token-level streaming with thinking/reasoning separation
- Available models: Opus 4.6, Sonnet 4.6, Haiku 4.5 via your subscription
BYOK Relay Passthrough
- Use your own Anthropic API key through app.foxl.ai -zero Foxl credits consumed
- Relay acts as a stateless proxy and does not store your key
- Usage tracked for analytics only (cost: $0)
Terminal Relay Interface
- Built-in terminal in Chat UI -spawn PTY sessions, tabs, split view, resize
- JetBrains Mono Nerd Font bundled (Ghostty-style zero config)
- Remote monitoring via relay tunnel -view desktop terminals from mobile
- Terminal tool: agent can spawn, write, read, kill sessions programmatically
- ANSI strip filter for clean LLM output
Chrome Extension Multi-Tab
- Multi-tab browser control -switch between tracked tabs with labels
- New commands: switch_tab, list_contexts for tab management
- Sidepanel tab bar UI with chips and 3s polling
Bedrock Prompt Caching
- Automatic prompt caching via cacheConfig strategy for Opus/Sonnet/Haiku
- Applied across server, agent, and provider layers
Relay
- Ultra tier upgraded to 10,000 credits/month
- Free tier Opus access blocked (Haiku + Sonnet only)
- Tunnel pending request cap (50) + chat stream cap (10) for stability
Async Subagents
- Auto-continuation: when all subagents complete, main agent auto-synthesizes results
- Completion queue prevents concurrent auto-continuations on same conversation
- Schedule persistence across app restarts
Agents UX
- Terminal fullscreen mode in chat panel
- Suggestion cards on empty chat screen
- AI-generated suggestions with structured defaults
Skills Sync
- Auto-sync skills from foxl-ai/skills repo on first install
- Skills sync button in SkillsPage UI
- Local edits preserved via content comparison during sync
Mobile
- Terminal persistence, mobile IME fix, mobile terminal UI
- Mobile terminal return icon and Del key
Windows Support
- Native Windows desktop app -NSIS installer + portable exe
- CRLF line ending normalization for skills parsing
- PowerShell terminal with smart shell detection (pwsh.exe, powershell.exe)
- Native Windows title bar, portable Node.js detection
- Code signing with self-signed certificate
Auto-Update Fix
- Universal build targets -single DMG/ZIP works on both Intel and Apple Silicon
- Fixed latest-mac.yml referencing non-existent arch-specific files
Discord Integration
- Discord Q&A bot with /ask slash command (Cloudflare Worker)
- Gateway bot with presence detection and auto-respond in channels
- Relay auth with KV token persistence for bot sessions
Release Automation
- Changelog automation pipeline: CHANGELOG.md as single source of truth
- Release scripts:
release.sh(full desktop release),sync-changelog.sh(changelog-only deploy) - Generated changelog surfaces: foxl.ai/#changelog, foxl.ai/changelog.md, GitHub Release notes
Fixes
- Enable AI suggestions in relay-only mode via tunnel
- Terminal mobile return button visibility and light theme text color
- app.foxl.ai: relay-only sidebar now correctly shows only Chat and Account pages
- Message copy handler preserves hyperlinks as "text (url)"
- Gateway page i18n -hardcoded strings replaced with translations
- Terminal line ending normalization for cross-platform PTY compatibility
- Terminal tool: backspace character processing for clean AI output
- Terminal tool: literal \n escape handling for reliable command execution
- Schedule execution prevConvId not defined error
- esbuild-bundle server to fix 5+ minute NSIS install time (16K to 420 files)
- NSIS installer auto-closes running Foxl before install
- Windows taskbar icon uses exe embedded icon for proper size
- 800+ translation keys across 10 locales (en, ko, ja, zh, es, fr, de, pt, ru, ar)
Auto-Update
- VSCode-style silent auto-update -download in background, notify when ready
- Settings toggle to enable/disable auto-update
Tunnel: Login = Access
- Pairing code flow removed -relay auto-registers device on connect
- Web clients connect immediately (no approval blocking)
- ECDH encryption for tunnel WebSocket messages
Tunnel E2E Streaming
- Chat streaming via relay tunnel with SSE passthrough
- Image and document upload through tunnel
- Reconnect recovery with snapshot hydration
Fixes
- Electron UA: real platform/arch (was hardcoded Intel Mac)
- Session detection: Foxl/ UA parsing for device info
- Model naming: "Opus 4.6[1m]" style (Claude Code convention)
- sharp added to server-bundle for screenshot tool
Multi-Agent Thread UI
- Codex-style subagent orchestration with collapsible thread sidebar
- Real-time subagent streaming via WebSocket events (200ms batched flush)
- Event-driven child-to-parent result injection on subagent completion
- SpawnIndicator inline in parent chat with live elapsed timer
- Thread history endpoint (GET /api/agents/:agentId/history)
Streaming Recovery
- Snapshot endpoint for instant page-refresh recovery (text, tool calls, threads)
- Sequence-based SSE subscribe with gap detection
- Recovery state machine (idle, fetching_snapshot, subscribing, live, disconnected)
- WS streaming_state enrichment with currentText, toolCalls, threads
- Fallback to SSE replay when snapshot unavailable
Model Selector
- app.foxl.ai now follows desktop model/provider selection via tunnel
- Desktop BYOK models visible in relay-only mode when tunnel connected
- Model selection syncs back to desktop via tunnel API
- Fix: model selector silently overriding local model with foxl relay
SDK
- Strands Agents SDK upgraded to v0.7.0 (Plugin system, prompt caching)
Fixes
- Credit exhausted popup removed from AccountPage
- Chrome extension Pilot renamed to Foxl branding
- Default provider fallback changed from 'foxl' to 'bedrock'
- WS multi-subscriber Set pattern (prevents callback overwrite)
Tunnel
- Tunnel resilience: heartbeat 3x failure reconnect with backoff reset
- Online-gated routing: __foxlTunnelOnline flag, sidebar isOnline
- Tunnel auto-refresh on online/offline transition
- Load desktop conversations via tunnel API when connected
Chat
- Mobile-first ChatPage layout (relay-only always full-width)
- Model ID resolution: compound prefix + version suffix handling
- WS 4003 token mismatch auto-reload
Fixes
- Chrome extension health check 500ms AbortSignal timeout
- GatewayPage device field mapping normalized
- Provider selection persists via localStorage key
- All model tiers accessible on all plans (restriction removed)
Web App
- app.foxl.ai: relay-only chat with localStorage conversations
- OAuth hash login, Google/Apple sign-in on web and desktop
- AccountPage: credits display, subscription, lazy sessions
- Onboarding flow: welcome, extension, login, chat
Relay
- Welcome 200 credits on signup, monthly 10 credit refill (cron)
- Atomic credit deduction (D1 batch transactions)
- D1-backed rate limiting, OAuth CSRF protection
- Strict model ID validation, 5 Claude models enabled
- relay-worker/ consolidated to relay/
Desktop
- Universal macOS build (arm64 + x64)
- Random port + connection token (VSCode-style security)
- Server crash protection, CORS hardening
- sessions_status tool: waitSeconds parameter
Docs & Infra
- Starlight documentation site (16 pages, full-text search)
- llms.txt / llms-full.txt from real documentation
- CI workflows: deploy-app, deploy-docs, deploy-relay, deploy-site
- Version unified to 0.1.2 across all packages
Agent
- AgentsPage: make expanded session card scrollable
Chat
- Channel: group mention filter, Signal greeting, conversation history API
UI
- Topup UI, webhook idempotency, tray menu, deep link, build fix
- i18n: add useTranslation hook to all 29 sub-components
- i18n: apply t() to 109 strings across 6 pages
i18n
- i18n expansion (496 keys, 10 locales), dev data path fix
- 251 keys across 10 locales, sync script, comprehensive coverage
- Expand to 10 languages, system language detection, complete translations
Skills
- Revert nested skills scan, use symlink instead
- Support nested skills dir + add .omc to gitignore
Fixes
- Fix SettingsPage crash: add useTranslation hook to main component
- Fix i18n: add useTranslation import and hook to all pages
- Fix DialogTitle accessibility warning, add PILOT_SKIP_SERVER
- Fix message queue leaking across conversations
- CI cache-dependency-path for setup-node
Other
- Add Foxl proprietary license
- Security: path traversal protection, JWT production guard
- Show git commit hash in app version (Settings > About)
Agent System
- OpenClaw-parity heartbeat runner with active hours, stuck detection, requests-in-flight skip
- Context overflow auto-continuation (creates new conversation with summary)
- Subagent spawn with result/error saved to conversation messages
- Subagents blocked from spawning other subagents (infinite recursion prevention)
- WebSocket reconnection restores agent state automatically
Chat
- Tool call display with per-tool icons (15 icon types: Monitor, Globe, Terminal, Database, Git, etc.)
- Human-readable tool titles for all 20+ tools
- Confirmation component (shadcn AI pattern) for tool approval
- Extended thinking with collapsible reasoning display
- Image upload, paste, and document attachment support
Skills
- 68 built-in skills (ported from OpenClaw)
- Skills always loaded regardless of binary availability (install at runtime)
- Lazy skill loading (list only, read on demand) for token savings
- Skill eligibility check with missing dependency display
UI
- Agents page redesign: date grouping, time range filter, status filter
- Agent detail dialog: stepper activity timeline, tools used summary, last response
- Settings: Heartbeat config card, provider SVG icons, active hours selector
- Workspace/Skills: Cmd+F search with content search, search button
- Usage Explorer: 30-day default, estimated cost per model
- Dock badge: notifications + unread chat count
Providers
- 7 relay proxy providers: Bedrock, Anthropic, OpenAI, Google, Groq, xAI, DeepSeek
- 24 local providers via OpenAI-compatible API
- Provider SVG icons (light/dark mode)
- Credit system with 10% margin (1 credit = $0.04)
Channels
- Telegram bot integration (non-blocking start)
- Signal CLI integration (foxl-ai/signal-cli)
- Channel send tool for proactive outbound messaging
- Initial Electron desktop app with embedded server
- Pixel Office view with agent characters and pet system
- Code splitting: 14 lazy-loaded pages (1,407KB to 177KB main bundle)
- Token usage tracking with SQLite persistence
- Session memory with LLM-generated summaries
- Context compaction via Bedrock compact API
- Tool approval system with always-allow option
- Browser automation with accessibility tree snapshots (93% token reduction)
- Workspace memory system (SOUL.md, USER.md, MEMORY.md, daily logs)
- Scheduling system (cron, heartbeat, webhooks)
- Multi-provider support (Bedrock, Anthropic, OpenAI, Google, Ollama)