Skip to content

Releases: MathiasWP/fiber

Fiber v0.14.6

Choose a tag to compare

@github-actions github-actions released this 24 Aug 14:33
2a7edd8

Patch Changes

  • #81 a7def54 Thanks @MathiasWP! - Read const when building a body from a schema.

    OpenAPI 3.1 uses JSON Schema 2020-12, where a literal is written as const and a literal union as anyOf: [{const: "once"}, {const: "always"}]. That is what 3.1 generators emit where 3.0 would have written an enum. Fiber read example, default and enum, but not const — so it walked into the first branch, found nothing to go on, and printed the string placeholder for a field whose only legal values were named right there. Sending that body back got it rejected by the very document it came from.

    One real spec this was found against writes 543 consts and not a single enum, so the existing enum handling never fired once across 658 paths. A const is now taken as the value it names, in request skeletons and in form fields alike.

Fiber v0.14.5

Choose a tag to compare

@github-actions github-actions released this 24 Aug 14:03
1d2ac38

Patch Changes

  • #79 5ee2e66 Thanks @MathiasWP! - Stop "Pick credential…" timing out when no sign-in window is open yet.

    Reading localStorage means evaluating script in the page, which fails until the page has loaded. That failure was propagated, discarding the cookies along with it — even though cookies are read from the Rust side, need no script, and are there immediately. So opening the picker straight from a closed window reported "timed out reading the sign-in window" while the session cookie sat in hand; opening the window first, then picking, worked.

    Cookies are now kept when the page can't be read, and the timeout is only reported when there is genuinely nothing to show. The retry loop still waits for a complete read before settling, so a credential kept in localStorage isn't missed by returning the cookies-only snapshot the instant the window opens.

  • #79 5ee2e66 Thanks @MathiasWP! - Stop two loader requests cancelling each other, and say when a rejection came from somewhere else.

    Every loader request for a section used the same id, and HttpState keys in-flight requests by that id — inserting a second under a key already there drops the first's cancel sender, which is the cancel signal. So a "Fetch a sample" while a background refresh was out came back "request cancelled", and which of the two died depended on timing. Loader requests now get a unique handle each; nothing cancels them by id, so there was never a reason for it to be predictable.

    A rejected manifest now also reports where the response actually came from, when that left the origin the request was aimed at. A Cookie or Authorization credential is dropped on a cross-host redirect, so "403" and "403, having ended up on a different host" are different problems wearing the same status — and only one of them is your API's fault.

    The sidebar's loader error is selectable and has a Copy button, because the first thing anyone does with an error they can't act on is send it to someone who can.

Fiber v0.14.4

Choose a tag to compare

@github-actions github-actions released this 24 Aug 12:52
ef29d1a

Patch Changes

  • #77 1c149c5 Thanks @MathiasWP! - Never capture a cleared cookie, and make "Sign in again" actually sign you in.

    Signing out clears a session cookie by setting it to the empty string, and some sign-in flows do it on the way through — often on the identity provider's host while the live cookie lands on another. The capture rule matched by name alone and took whichever came first, so it could store the blank one. That went out as Cookie: sid= and came back as the API's own version of "token is empty": a rejection that reads like a server problem and is really an empty header. A cookie now only counts if it has a value, an empty capture reports nothing rather than storing it, and the credential picker no longer offers blanks.

    "Sign in again" opened Section settings on the General tab and stopped there, leaving you to find Auth and press Open sign-in yourself. It now opens the Auth tab and starts the sign-in.

Fiber v0.14.3

Choose a tag to compare

@github-actions github-actions released this 24 Aug 12:28
336bd73

Patch Changes

  • #75 cb46eb7 Thanks @MathiasWP! - Stop a background loader refresh from firing at a section you are signing into, and make the failure it left behind actionable.

    Opening the sign-in window moves focus off the main window, and focus returning is one of the two triggers for a stale-loader refresh — so the run went out with the credential you were in the middle of replacing, failed, and posted an unattributed "the manifest request returned 403" in the sidebar at the exact moment you opened the window. Signing in never cleared it, because nothing re-ran the loader afterwards.

    A section is now skipped while its sign-in window is open, the loader re-runs once a credential is captured, and the error names its section and offers a sign-in button when the API turned the credential down. Rejected manifest requests also carry a snippet of the response body, so a 403 can say which 403 it was — and a 401 or 403 in the response pane offers the same button rather than leaving you to find the drawer.

Fiber v0.14.2

Choose a tag to compare

@github-actions github-actions released this 24 Aug 10:57
c874c4b

Patch Changes

  • #72 276d629 Thanks @MathiasWP! - Fix the credential picker crashing with each_key_duplicate. Rows were keyed on the capture rule — source, key and path — which isn't unique: a session holding the same cookie name on two domains (sid on .example.com and on api.example.com) produced two rows with the same key, and Svelte threw instead of rendering the list. Each row now carries its own id.

  • #72 276d629 Thanks @MathiasWP! - Make the crash banner and the update toast usable while a dialog is open. An open modal dialog sets pointer-events: none on <body>, which both of them inherited: a click on Copy, Hide or Update passed straight through and landed on the dialog, which read it as an outside click and closed itself. With dialogs stacked, the banner stayed out of reach until every one of them had been dismissed. Both now take pointer events of their own and keep the click from reaching the dialog underneath.

Fiber v0.14.1

Choose a tag to compare

@github-actions github-actions released this 24 Aug 10:26
d0ac49f

Patch Changes

  • #70 a793695 Thanks @MathiasWP! - Structure the MCP tab and leave out the clients that aren't there. The tab now lists only the clients it can find on this machine, with the rest one line away — detection is a guess at a directory, not a fact, and a client that already holds an entry is always shown. That check was wrong for Claude Code, whose ~/.claude.json sits directly in the home directory and so counted as present everywhere; it asks about ~/.claude now. The tab is in three labelled parts, the copy buttons are bordered controls beside a caption rather than bare text that only appeared on hover, and the snippets wrap instead of scrolling sideways.

Fiber v0.14.0

Choose a tag to compare

@github-actions github-actions released this 24 Aug 09:05
b893b60

Minor Changes

  • #68 098da51 Thanks @MathiasWP! - Add an MCP tab beside Collections and History that installs Fiber into an AI client for you. It lists Claude Code, Claude Desktop, Cursor, VS Code, Windsurf, Codex CLI and Gemini CLI with the config file each one uses, and Add writes the entry pointing at wherever this copy of the app actually lives. An entry left behind by a copy that has moved shows as Update. The edit only ever adds or removes Fiber's own key: other servers and settings survive, Codex's hand-written TOML keeps its comments and key order, and a config file that doesn't parse is left untouched with the snippet offered to paste instead. Below the list, the ToolHive route is offered as a copyable command with a link to its guide, for collections served from a repo rather than this machine.

Patch Changes

  • #67 3c60cbd Thanks @MathiasWP! - Loader folders now start collapsed. A spec with hundreds of endpoints opens to
    its list of tags rather than a wall of paths, and each folder header carries the
    full count of what it holds. Endpoints are paged in per open folder, so opening
    one mounts its rows and a closed one costs nothing.

Fiber v0.13.0

Choose a tag to compare

@github-actions github-actions released this 22 Aug 20:54
50fa88f

Minor Changes

  • #59 68ab80c Thanks @MathiasWP! - Richer OpenAPI (tags as folders, path and query parameters, operation descriptions, response-schema checks), per-collection HTTP identity (cookie jar, timeout, redirects, proxy, invalid certs), and non-JSON bodies (form, multipart, file). Query parameters are available on every method.

Patch Changes

  • #66 d24f8d8 Thanks @MathiasWP! - Harden MCP credential boundaries, concurrent request handling, response storage, endpoint discovery, and protocol validation.

  • #60 33fdf99 Thanks @MathiasWP! - Creating a collection now shows its first request immediately. The new section was mutated as a plain object after $state had already proxied it, so the sidebar never saw the push.

  • #60 33fdf99 Thanks @MathiasWP! - Importing an OpenAPI spec now reports how many endpoints were actually added. The count used to re-read a live list after those endpoints had already been pushed, so it always said zero.

  • #63 bfbfcd0 Thanks @MathiasWP! - A few performance fixes: computing what a loader refresh added or removed was quadratic in the number of endpoints, sending a request whose body comes from a file blocked the async runtime instead of reading it off-thread, and the sidebar's "Move to" submenu recomputed its target list twice per request row.

  • #64 749d148 Thanks @MathiasWP! - Obvious performance wins on both sides of the glass. The URL preview no longer round-trips to Rust on every keystroke. ⌘K and collapsed collections stop rebuilding every loaded endpoint in the background. Schema validation and placeholder highlighting skip bodies too large to be worth it. Loader samples are no longer pretty-printed whole just to show the first 20 KB. Streamed chunks are joined rather than concatenated, and a large response is not shipped over IPC a second time after it has already streamed. Collections stay in memory after the first read so a send does not re-parse every saved body; the MCP server does the same across tool calls. History deletes and section deletes no longer run on the UI event-loop thread. A send with static auth no longer clones the request body just in case a 401 retry needed it.

  • #56 94f8b39 Thanks @MathiasWP! - Svelte 5 best practices: $state.raw for wholesale-replaced data (loader caches, OpenAPI samples, browser snapshots), {@attach} in place of actions and the CodeMirror mount effect, and window listeners on <svelte:window> rather than inside $effect.

Fiber v0.12.0

Choose a tag to compare

@github-actions github-actions released this 21 Aug 15:32
e71d067

Minor Changes

  • #54 1af9a51 Thanks @MathiasWP! - Large collections keep scrolling instead of asking you to page them. Opening a header still mounts a first screen of endpoints so that click stays quick; reaching the end of the list loads the next screen on its own.

    And a loaded OpenAPI body now says when it does not match the operation's schema — under the editor, and in the lint gutter — without dragging every component schema across the bridge at startup. The schema for the open endpoint is fetched when you select it, and again if you refresh the loader while it is still open.

Fiber v0.11.0

Choose a tag to compare

@github-actions github-actions released this 21 Aug 14:12
0619155

Minor Changes

  • #53 5da1e11 Thanks @MathiasWP! - A generated body has a way back. Filling in a loader endpoint's request body is destructive to the placeholders that guided it — once "offset": number becomes "offset": 42, the tabbable gap is gone. A Reset button next to Format now restores the manifest's generated skeleton, placeholders and all. It sits disabled while the body already matches, and Cmd+Z undoes it.

    And clicking quickly through requests no longer builds a backlog that drains one slow response pane at a time. Loading a response body was a synchronous command, and synchronous commands share the event-loop thread — every click queued another read behind the last. The reads now run concurrently off that thread, and a body still in flight for an entry you have already left is dropped instead of parked in memory.

Patch Changes

  • #53 a088263 Thanks @MathiasWP! - Hover states that never were. The section cog, the two add-buttons in the sidebar header, header/param delete buttons, and a handful of others were written with UnoCSS variant-group syntax — hover:(bg-border text-text) — which the PostCSS pipeline never expands: it scans class names but does not rewrite source, so the browser received split-by-space junk and no rule matched. Every one is now written out in full, and the transformer that was quietly doing nothing is gone from the config, with a comment explaining the trap.

  • #53 5da1e11 Thanks @MathiasWP! - A hardening pass across security, reliability, and performance, from a full audit.

    Security: the MCP send_request tool no longer honors an absolute URL that leaves the section's origin — an agent could previously point path at any host and the section's credential went along with it. Custom auth headers (an X-Api-Key, say) are now dropped when a redirect leaves the original host, the way reqwest already drops Authorization. Inbound credential headers — Set-Cookie and friends — are redacted before they reach the history database. The app window has a Content-Security-Policy, the opener capability is scoped to https, and history spill filenames go through the same traversal guard section files always had.

    Reliability: a corrupt history.db is moved aside and rebuilt instead of panicking on every launch. A collection file that won't parse is now named in the sidebar — it used to vanish silently — and a corrupt file at send time is an error rather than a request quietly sent without auth. Quitting flushes the debounced saves that used to lose the last 400 ms of typing. Saves fsync before the atomic rename. The data-dir migration retries with a copy when the rename fails, and the keychain migration is keyed on a marker so it can't be orphaned. Deleting a history entry or section rolls back in the UI when the disk says no. Requests without an explicit timeout get 60 s instead of forever.

    Performance: responses past 1.5 MB skip pretty-printing, JSON parsing, and linting instead of freezing the window. Streaming appends to the editor instead of rewriting the whole document every frame. The loader preview is debounced and no longer ships the manifest across IPC per keystroke. Commands that read or parse files run off the event-loop thread. Typing no longer serializes the whole section per keystroke to ask whether anything changed, and the history tab looks names up in a map instead of scanning every section per row.

  • #51 748226e Thanks @MathiasWP! - Filling in a generated body behaves. A comma typed to mean "next field" no longer lands next to the one the body already had, leaving 1,,. A comma inside a string value stays in the string — typing "Ada, Lovelace" used to jump away at the comma and type the rest of the name over the next field. Tabbing to a field now puts the caret at the front of it rather than after it, so it looks like something you are about to replace. And a nullable field in an OpenAPI 3.1 document names its type again instead of coming out as null: 3.1 writes "type": ["string", "null"], which read as no type at all, so every such field arrived looking already filled in. A choice with a null branch — anyOf: [{"type": "null"}, {"type": "string"}], which is how most specs write it — now names the half that says something, whichever side it sits on. Anything else the importer cannot read is now an unknown gap you can tab to, rather than a null that claims the API wants null.