Skip to content

Building in public

What we’ve shipped

Qiksy is a small studio building AI-native micro-tools — in the open. Every new tool, real bit of progress and the occasional fix lands here first. No hype, just what changed.

  1. QA CopilotShipped

    The extension changed its name, because the old one put it on a shelf with nothing on it

    It is called Qiksy Bridge now, and the store title says what it does: a browser MCP extension for Claude, Cursor and Codex. The old name led with manual QA, and the page led with it too — so people read it as a form filler and left. The bridge, which is the whole point, was the hundred and first word; MCP was the six hundred and sixty-eighth. We measured before renaming rather than after: the store search for "qa copilot" carries sixty-two installs across six cards, thirteen of them ours, while the search for "mcp" carries around a hundred and twenty-six thousand. Our own phrases for what we do — "use my logged in browser", "existing chrome session" — return no search suggestions at all. Nobody types them. The front page now opens with the thing itself: an MCP server for the tab you already have open, with your session and your logins, and the honest difference from Playwright MCP, which starts an empty browser and signs in from scratch. Nothing about the product changed, and the extension keeps working with no agent at all. The new listing is with Google for review.

  2. LegatoShipped

    The Legato reference now speaks the twenty-five languages the browser does

    The feature reference was English only while the landing beside it shipped in twenty-five languages, and the gap was not a matter of politeness: a screen reader picks its voice from the page’s declared language, so English text under a Polish or Japanese code is read through the wrong phonetics. Somebody could read why the browser exists in their own language and hit a wall the moment they wanted to know how it works. The page also doubled — twelve sections to twenty-two — because a good deal of the browser had never been written down: reading a page with the arrow keys existed only as one line in a table of shortcuts, and copying a piece of a page, the mouse wheel that walks instead of scrolling, the shelf of games, the shop card, the braille setting and the seventeen page fixes for low vision were not there at all. Two faults turned up in the translating and both were the same shape. The browser says «reader» out loud in Russian and the translation wrote the technical loanword instead — correct, and a different word for the same thing than the one the product uses. And the page quotes seventy-five menu items while promising you will find them under exactly that name: agreement ran from 38 % in Japanese to 70 % in Hungarian, so a sighted reader would have checked against the screen in a second and a blind one would have hunted for an item that is not there. Both are now taken from the browser’s own dictionary rather than translated afresh, agreement is 96–100 %, and a gate holds it there.

  3. LegatoNew

    Copying a piece of a page, without being able to see where the piece ends

    Selecting text is a mouse gesture, and every workaround a blind person has for it is awkward: a text cursor whose keys clash with reading, the screen reader’s own markers, or select-all — which takes the menu and the cookie notice too. None of the three tells you what you took; you find that out after pasting it somewhere else. Legato 0.3.84 answers the copy shortcut itself, and only when nothing on the page is selected, so the ordinary behaviour is untouched. Draw a frame with the mouse around a piece and it works out the block from what fell inside — no need to hit the edges of a paragraph you cannot see. Or press S where the piece starts, walk to where it ends, and copy. Then it reads back what it took: a short piece in full, a long one by its first words and its last, which answers both “is this the right piece” and “did I take too much”. While a start is marked, each step makes a quiet click — the mark is alive and the step counted. The same release fixes something the work uncovered: on a page that grew above where you were standing, the down arrow moved you up.

  4. RouteFixed

    The globe on the Route page did not exist for a screen reader

    The planet is the first thing on that page, you can click cities on it and watch a route stretch between them — and to a screen reader it was nothing at all: a canvas marked as decoration, on the grounds that the city names underneath were being read out anyway. Those names were, but the thing itself was not, so someone listening heard “Kyiv to Barcelona” arrive from nowhere. It is now described the way a person would describe it: a planet turning slowly, blue water, milk-coloured land, and no continents or borders drawn on it — one Earth, the same for everyone. The description also names what is missing rather than leaving it to be discovered. And the cities are reachable now: the same ones the globe shows are real buttons, one stop on the keyboard route with the arrow keys moving between them, invisible until focus lands on one. They call exactly the code a mouse click calls, so both ways of picking a route can never drift apart.

  5. LegatoShipped

    Every Legato release that ever reached anyone is now written down

    The notes page went from eleven versions to twenty — all the way back to 0.3.52, published on 19 August 2026, which is the first build that reached a person at all. Nothing is missing before it, and the page says so instead of trailing off. Versions that were built and handed to nobody are named and excluded, because they are not part of what anyone has. The biggest entry is 0.3.64 — two hundred and forty-nine changes, and the release where the browser stopped only reading pages out and started having things to do in it: a shelf of games with backgammon built to be played by ear (both dice in one keypress, a refused move that explains itself, network play that Windows and a Mac completed against each other), a family tree walked with the keys, routes that replay a path through a site, and a large-text switch. Forty-six topics and a hundred and fifty-one lines in total, each one traceable to a build somebody actually received.

  6. LegatoFixed

    The lower half of the landing page now uses the width it was given

    Those sections ran in a column narrower than the header above them, with the right third of the page empty. They are on the full container width now — the same line the header sits on. The width went to the BLOCKS rather than to the prose: what Windows and what macOS say on first launch now stand side by side instead of one under the other, the three checksums are three cards in a row, and the list of what the browser cannot do runs three across. Paragraphs keep their reading measure of about 65 characters, deliberately — filling 1080 pixels with prose would mean lines of a hundred and fifty characters, and this is a page for people with low vision. So the page fills its width without a single line getting longer.

  7. LegatoFixed

    The lower half of the landing page looked like a column had fallen off

    It had two faults and they compounded. The narrow column — six consecutive sections, everything from "How to install" down — was pinned to the left edge of the wide container, on the reasoning that a centred column would make the text jump sideways while scrolling. True, but the price was worse: the whole bottom of the page sat against the left edge with the right third empty. It is centred now, and the jump happens twice, at the two joins, instead of being permanent. The second fault was inside that column: it was 680px wide while the text in it is capped at 68 characters — measured live, 476px — so cards and quote rules ran two hundred pixels past their own content. The container now sits on the width that actually lives in it; the line length did not change by a single character. And one section had a short note beside a tall column of text, leaving six hundred pixels of nothing under it; the note is centred in its column now and reads as the aside it is.

  8. LegatoShipped

    The release notes page now covers twelve releases, not two

    It started at 0.3.82 with a note saying the earlier ones had never been written down and that reconstructing them from commit messages would produce something plausible rather than something true. There was an honest way to do it after all: go by the release tags rather than the branch — by what people actually received. So 0.3.72 is absent, because the version was bumped and never shipped to anyone, and the quit-key fix sits in 0.3.83 even though the branch would file it under 0.3.82, because it landed after 0.3.82 was already out. The nine reconstructed entries are deliberately shorter than the two newest: a fault is named, not narrated. Among them — pages freezing for seven seconds, a Portuguese page read with Russian sounds, a screen reader handed the bare word "collapsed" with nothing to say what was collapsed, and Arabic arriving as the twenty-fifth language and the first read right to left.

  9. LegatoNew

    A release notes page, because a blind tester had no way of knowing what to re-test

    Mehdi Malakane updates the browser and then has to guess what changed. He asked for the model NVDA uses: a What’s New item in the Help menu that opens a versioned page, with the version number as a heading so a screen reader’s heading list becomes the table of contents. It is now at qiksy.app/legato/whats-new/ and the menu item opens it at YOUR version rather than the top. It starts at 0.3.82, which is the first release whose notes were actually written down — reconstructing the earlier ones from commit messages would produce something plausible rather than something true, and the page says so out loud. 0.3.83 is on it and is out: the ring menu no longer swallows the quit shortcut, it no longer hides the whole browser on the light theme, and the backdrop behind it is dark enough to see.

  10. LegatoNew

    A release notes page, because a blind tester had no way of knowing what to re-test

    Mehdi Malakane updates the browser and then has to guess what changed. He asked for the model NVDA uses: a What’s New item in the Help menu that opens a versioned page, with the version number as a heading so a screen reader’s heading list becomes the table of contents. It is now at qiksy.app/legato/whats-new/ and the menu item opens it at YOUR version rather than the top. It starts at 0.3.82, which is the first release whose notes were actually written down — reconstructing the earlier ones from commit messages would produce something plausible rather than something true, and the page says so out loud. 0.3.83 is on it and is out: the ring menu no longer swallows the quit shortcut, it no longer hides the whole browser on the light theme, and the backdrop behind it is dark enough to see.

  11. StudioShipped

    Engine 1.12.0 — the first build an update can actually reach

    Published to the registry. It is the first version that tells the tools which version it is, which is what makes the new update notice possible at all: until now nothing on the page could tell a current engine from one installed months ago. It is also the first build whose autostart cannot be left pointing at a directory that gets cleaned — installing with npx used to pin the entry inside the npm cache, and when that cache was cleared the engine quietly stopped starting. Anyone already running an older engine will not be told about this one, because being told requires the version reporting that arrives with it; from here on the notice works. Update it with one line in a terminal: npx qiksy@latest.

  12. StudioFixed

    On dark backgrounds the accent colour was being used as text, and it was too dark to read

    A palette has two blues in it, not one: a fill colour, judged against a lower bar because nobody reads a button’s background, and a text colour that has to clear the full contrast threshold. Across the Route and Offer pages the fill colour had been used for text in a dozen places — step numbers, badges, links in the product strip, the duration label in a timeline — and on a dark background it landed between 2.8 and 4.4 against a requirement of 4.5. Every one of them now uses the colour meant for text, which lightens in dark instead of darkening. The worst of the set was the product name beside the logo: white on a light blue pill, 1.76 to 1, the first thing anyone reads on the page. Its fill had been switched to a light one without switching the ink to match. And the check itself got better at explaining: it already knew the two colours and the exact ratio for every failure and printed neither, so fixing one started with half an hour of hunting through tokens. It says the numbers now.

  13. RouteFixed

    The walkthrough’s steps were invisible until their animation had played

    Each step of the demo on the Route page faded in, and it did that by starting at zero opacity and animating up. That is fine while the animation plays — and the trouble is that "while" is an assumption. A tab that has been throttled, a machine saving battery, a mistake in a neighbouring rule: any of those and the step never becomes visible at all. The accessibility check caught the page in exactly that state and counted 392 elements with no contrast across fourteen pages — text on top of invisible text. The movement stayed; the fade went. It looks the same and it can no longer leave content that nobody can read.

  14. StudioFixed

    Updates to the local engine were reaching nobody who had already installed it

    The engine runs on your own machine, and once it was installed it stayed exactly as it was — for good. Three separate reasons, each enough on its own: the autostart entry pins the absolute path of the copy that installed it and runs that file forever; there was no version check anywhere, not in the engine and not in what it tells the page; and the install command only fetches a newer build when somebody types it, which the person who set up autostart never does again. So a published fix sat in the registry and never travelled. The engine now reports its own version, the page knows which one it expects, and when they differ it says so once — a line you can dismiss, and a permanent one in each tool’s settings for when you come back to it. It still never updates itself: it is holding running searches and your Claude sign-in, and software that quietly replaces itself underneath a search in progress will one day cost somebody an hour with no explanation. Two things that made this worse are gone too. Rebuilding the engine refreshed its tools but never the supervisor that starts them, so a fix to that half could not reach an installed engine at all. And for anyone who installed with npx, the autostart pointed inside the npm cache — a directory that gets cleaned — after which the engine silently stopped coming up and the tool simply said the local server was not running.

  15. OfferFixed

    The live search feed flickered a new border into view every second

    While the agents hunt, the feed adds a line every second or two — and each new line arrived carrying two fresh borders with it: a divider above itself and a box around its icon. On a still mockup that reads as a tidy grid. In a feed that is actually moving it reads as flicker, in the corner of the eye, exactly where someone is waiting for a result rather than admiring the layout. Both are gone; the one piece of movement that means something — the pulse on the line being worked on right now — stays. The feed also ends where it should now, with no doubled line at the seam where it meets the results below, and the button that adds a country is the same height as the country chips it stands beside, instead of eight pixels taller than the row it belongs to.

  16. StudioFixed

    Opened outside the studio, Route and Offer looked like somebody else’s products

    The colour you pick applies to everything — background, borders, every active element — and it was reaching only the pages the studio shell draws. Open the same tool on its own address and a different palette took over: not a worse arrangement of the same colours, a different set entirely, written years apart and hardest to read in dark mode. Both tools now carry the colour, the light/dark choice and the classic/modern style outside exactly as they do inside, and they carry it from the first painted frame rather than repainting it in front of you. Two things that only existed in the shell came out with it: how much of the Claude subscription is left — the session and weekly rings, with the real figures Claude itself reports — and whether the agent is answering at all, which Offer had never shown anywhere. And because four appearance switches in a row had grown wider than the tool’s own menu and had started colliding with it, they now live together under one settings button, leaving the header to say what a working tool should: is it running, and how much is left.

  17. LegatoShipped

    Legato 0.3.83 — the ring menu you could not get out of

    Open the ring menu with the right button, then try to close the browser: nothing happened, and the menu would not close either. The ring lives in a frameless window of its own that takes the keyboard, and application-menu shortcuts were not reaching past it — Escape worked, because the menu handles that itself, but Command-Q did not. Measured with a clean control: same window, same state, the ring open and Command-Q does nothing; press Escape and the same key quits. Fixed for all five of our own windows — the ring, the menu card, the tour, the account card, the extensions card — because all five had the same hole, and it quits the ordinary way, so the session, history and downloads are written to disk exactly as on a normal quit. Closing the window now takes the ring with it, and whatever asked for the menu gets its refusal: a site that had requested to share your screen used to wait forever. Two things about how the ring looks, both reported from a real screen: on the light theme it was painting a solid sheet over the entire browser — no toolbar, no tabs, no page, just a blank field with the circles in it, measured at full opacity across the whole window; and the disc behind the circles was tinted with the theme’s own background, which on a dark page is dark over dark, so it was not visible at all. It is darkened with black now, which works on any page, and the page still shows through. And the Help menu has a «What’s New» item that opens the release notes at YOUR version — the update channel has existed since 0.3.20 and had never once said what it delivered.

  18. RouteFixed

    While the engine was being checked, the status pill said nothing at all

    The pill in the Route header had two states — connected and not connected — and the first seconds of every page load belong to neither: the answer has not come back yet, so nothing is known. The label was simply left empty in that gap, which meant a grey dot with no word beside it, and the honest-looking alternative would have been worse — “agent disconnected” announces a fault that may not exist. The gap is longest right after a reload, because that is when the engine is still starting the Claude CLI. There is now a third state that says what is actually happening: connecting, with the dot breathing quietly, a button that does not offer to repair something that has not broken yet, and nothing promised to a screen reader that the button cannot do. The pulse stops for anyone who asked for less motion.

  19. StudioNew

    The header stopped talking about money and started answering the question people ask

    On a subscription the dollars in the header meant "this is what the work would have cost" — an answer to a question nobody asked. What people actually want to know is how much of the plan is left. So the money is gone and two rings took its place: the current five-hour session and the week, with the reset time for each. These are Claude’s own percentages, not our estimate. There is no usage endpoint a subscriber can call, but the binary answers its own /usage locally and that read costs nothing, so nothing is invented and no request is spent asking. They refresh on their own every two minutes, and a screen reader is told when the state changes rather than every time a digit does.

  20. RouteFixed

    Signing out of Claude threw you onto an installer for an engine that was already running

    Route asked the machine one question — can you run the agent — and treated every answer that was not «yes» the same way: by showing the install screen. But an engine that is installed, running and merely signed out answers that question with a polite «no», so a person who signed out was handed a «Download for macOS» button and the line «we will connect as soon as it starts», on top of an engine that had already started. That is a dead end in the literal sense: the screen waits for an engine to appear, the engine has appeared, and the only place in the whole app where you can sign in to Claude sat behind a branch you could no longer reach. The other half of the same trap was in Settings, where the account card could do exactly one thing — sign out — and offered it to people who were already signed out: press it, confirm, hear «signed out», see nothing change. Somebody whose limit had run out wanted the opposite thing, and there was no way to do it from there at all. The button now says what will actually happen: not connected — «Sign in with Claude», which starts the Anthropic sign-in on this machine and waits for the engine to come back green; connected — the old «Switch account», still behind a confirmation, because signing out takes Claude away from everything else on the computer. The wording comes from the shared dictionary rather than new strings of its own: the same button is already named there in seven languages for the gate, and two editions of one sentence drift apart.

  21. RouteFixed

    Settings could sign you out of Claude but never back in

    The account card in Route’s settings had one button and it always meant the same thing: sign out. That is the right offer when an account is connected, because the Claude CLI has no switch and changing account really is a sign-out followed by a sign-in. It was the wrong offer to everyone else — someone whose spending limit had run out, or who had already signed out, was invited to sign out again, asked to confirm it, told it had worked, and shown no change at all, because there had been nothing to sign out of. Signing in from settings was not possible in the first place. The button now says what will happen: it offers to connect an account when none is connected and starts Anthropic’s own sign-in, and it keeps offering to switch when one is.

  22. RouteFixed

    Signing out of Claude threw you onto an install screen for software you already had

    Route asked the machine one question — can it run the agent — and treated every answer that was not yes the same way: it showed the page that explains how to install the engine. But an engine that is installed, running and simply signed out answers that question with a polite no, so anyone who signed out of Claude, or never signed in after installing, was handed a download button and the line "we connect the moment it is running" — over an engine that was already running. It was a dead end in the strict sense: that screen waits for the engine to appear and it had already appeared, and the only screen in the whole app that carries the sign-in — the button, the link and the field for the code — sat behind a branch the code could never reach. Route now separates the two answers: no engine, and here is how to get one; an engine that is signed out, and here is the way in. Offer was repaired this way in July and Deal was never wrong; Route was the one left behind.

  23. StudioFixed

    The one button on two landing pages that opens the tool opened nothing

    On the Offer and Route pages the main call to action pointed at the hub with a hash — and a hash here is an id in the app registry. Both products had been renamed, so the id in the link no longer existed: the hub looked it up, got nothing back, and quietly stayed on its own home page. No error, no 404, nothing to notice — the button simply did not do the one thing it exists for, and it had been that way since the rename. The same defect was found on Route earlier the same day and this is the rest of it. The links now go straight to the product’s own prerendered address rather than through the hub, which also removes a flash that was there even when the id was right: the hub would paint its home page first and only then navigate away.

  24. LegatoNew

    You could update the browser and have no way of learning what changed

    The update channel has been in Legato since 0.3.20. What it never had was a way to say what it had just delivered — the menu item installs the new version and then goes quiet. For a sighted person that is curiosity; for a blind tester it is work with nothing to check it against. Mehdi Malakane, who tests through AppleVis, asked for the fix in one sentence and named the model himself: NVDA’s. So there is now a release notes page at /legato/whats-new/, and a «What’s New» item in the browser’s own Help menu that opens it. The structure is the whole design: the page heading names the page, every VERSION NUMBER is a heading one level down, and the topics inside a release are one level below that — so a screen reader’s heading list is the table of contents, and jumping between releases is one keystroke repeated. The menu item does not open the top of the page either: it builds an anchor from the version actually installed and lands you in your own release. We already had a changelog — this one, the page you are reading — and it is the wrong instrument for that reader: it runs by date across every product, Legato appears in it about ninety times, and no heading names a version, so answering «what is in 0.3.82» would mean listening to the whole feed. The new page starts at 0.3.82 and says so out loud rather than pretending to a history it does not have: earlier versions shipped with no notes written down, and reconstructing them from commit messages now would produce something plausible instead of something true — and this is the text people re-test against. The menu string went into all twenty-five dictionaries in the same commit, Russian and Ukrainian by hand: the menu is rebuilt from scratch on a language change, and one English line in someone else’s menu is a dead stop for a person walking it by voice. The page also carries the NEXT release already, marked in a sentence as not yet shipped — preparing before the update arrives is the whole reason it was asked for, but somebody landing there after updating has to be able to tell «I have this» from «this is not out yet» in one line, so it is said in words rather than shown with a badge or a colour.

  25. RouteFixed

    The page promised three minutes and blamed a finished trip for someone else’s failure

    Three places where the interface said something other than what was happening. The red plate above a trip took the LAST job of any kind and printed the wording written for a failed search — «the agent ran out of time, try again or narrow the trip» — while the search had long finished and eight options were sitting right below it. What had actually timed out was the how-to-book lookup for ONE of them, which has a clock of its own. There was nothing to narrow, and a finished trip was being painted as a crash; the plate now names the option it is talking about and leaves the results alone. Then the numbers: «about 3 minutes» under the search button was met by NONE of the fifteen runs in the log — median 8.2 minutes, spread 6.6 to 18.2 — and «usually under two minutes» on the booking lookup was met by 2 runs out of 14, median 3.8. Both are now the measured figures. That is not admitting to being slow, it is refusing to promise what we cannot keep: at the third minute of a three-minute promise a person starts believing the tool has frozen. And the last one is about language. The contents of a trip — the options, the summary, the boards — are written by the agent during the run, in the language of that run; switching the interface language moves the labels around them and deliberately leaves that text alone, because translating what an agent already said would show a retelling instead of the answer. The product never mentioned this, so a Ukrainian trip under a Spanish interface simply looked broken. It now says so twice: a quiet line on the card explaining that the contents are in the language of the search and that a fresh search brings them over, and one explanation at the moment of switching — shown only when the open trip really does contain the agent’s text, because warning about something that is not on screen teaches people to dismiss warnings unread.