Changelog
All notable changes to this project are documented in this file.
The format is based on Keep a Changelog.
The workspace is at 0.1.0 with no tags and no releases yet, so everything
to date lives under Unreleased. See docs/roadmap.md
for what's still ahead.
[Unreleased]
-
Measure offscreen wrapped cursor neighborhoods on demand in temporary bounded batches instead of retaining hidden paint rows. Keep persistent editor paint in its viewport window and preserve exact movement for distant cursors in both workspace modes.
-
Bound long-line native offset and cursor line/column queries with sparse Unicode coordinate checkpoints shared by documents and folded views in both workspace modes. Preserve CRLF and surrogate boundaries through edits, undo/redo and composition; add matching native/WASM construction and query measurements.
-
Apply queued wrapped cursor movement before typing, composition, paste and cut while the full editor layout is still preparing in both workspace modes. Measure exact styled cursor neighborhoods through the shared motion engine, retaining Unicode, folds, sticky columns and stale ownership guards.
-
Give the expanded frontend browser CI suite a five-minute runner budget, retaining individual UI readiness deadlines and all behavioral checks.
-
Reuse exact unchanged wrapped-row heights after localized and disjoint edits, row insertions/deletions and undo in both workspace modes. Guard reuse by document ownership, layout, styled tokens and line endings; invalidate cached heights on font changes.
-
Measure cold wrapped editor layouts in temporary row/byte batches, keeping native input visible and yielding to browser tasks and frames in both modes. Reject superseded jobs, preserve queued arrows while progress advances, and keep projection identity stable when cursor motion does not change folds. Incremental height reuse and fine long-row rendering remain in progress.
-
Add Open Graph and Twitter large-image previews to every website page, plus an open-source credits page generated from Cargo and site-build dependency metadata.
-
Add a WebFinger discovery alias for
@openwebide@openwebide.comthat resolves to the existing Mastodon account. -
Show a screenshot of the running PWA on the project landing page, with a full-resolution image for sharing.
-
Add a disposable production-editor benchmark for native browser input, scrolling, frame stalls, WASM allocation and Chrome process-tree memory in both workspace modes. Record byte, row-count and long-line boundary baselines; bounded cold paint and incremental input remain in progress.
-
Update project links and Pages configuration guidance for the repository transfer to
openwebide/openwebide. -
Synchronize native editor viewport dimensions before paint and wrapped cursor measurements, keeping immediate and queued movement aligned when resize or scrollbar geometry settles between frames in both workspace modes.
-
Add a dedicated project landing page and GitHub Pages build workflow for openwebide.com. Generate documentation directly from repository Markdown with automatic navigation, validated links, shared app colors and buttons, GitHub Issues links for feedback and support, and Bluesky, Mastodon, and YouTube profile links with Mastodon website verification support.
-
Window wrapped editor paint using exact browser row heights in both workspace modes. Preserve global Unicode/CRLF caret mapping, offscreen multi-cursor motion and resize remeasurement; reject stale layout tables. Initial full paint and bounded cold measurement remain in progress.
-
Open files beyond full-editor byte, line-count or long-line limits in bounded, read-only Unicode text pages in both workspace modes. Keep complete source separate from page text, preserve before/after review access, reject oversized interactive transactions before indexing, and recover clean oversized tabs by reopening their host file.
-
Maintain incremental document line/UTF-16 coordinates through edits, grouped undo/redo and IME; reuse immutable folded/normalized view allocations across scrolling and caret consumers. Use indexed rows for commands and native selections, record native/WASM query and projection measurements, and keep composer growth compatible with the shared welcome container. Full wrapped viewport and end-to-end resource measurements remain in progress.
-
Bound unwrapped editor paint, line-number gutters and fold controls to an overscanned row window. Cache syntax paint and indentation guides across scrolling, preserve global Unicode/CRLF caret offsets, and reveal offscreen Find/navigation targets in both workspace modes. Wrapped viewport rendering remains in progress.
-
Prepare lexical JSON, TOML, YAML, SQL and Markdown paint through the same immutable syntax cache and Rust/WASM worker as grammar-backed languages. Preserve multiline comments, Unicode and CRLF; discard partial results on cancellation and reject stale source replies in both modes.
-
Match wasm-bindgen's headless Linux Chrome flags in production-worker and recovery checks when running in CI, and include WebDriver failure details in test output.
-
Prepare editor folds, structural contexts and syntax tokens in a dedicated Rust/WASM worker. Share the preparation engine and bounded LRU cache with the synchronous fallback, coalesce pending edits, reject stale or malformed replies, and wait for worker readiness before sending requests. Cache the matching hashed worker/WASM assets for PWA use; CI exercises the built worker in Chrome. Full viewport rendering and device verification remain in progress.
-
Share one immutable syntax preparation per source and tab width across editor folds, structural commands and highlighting. Reuse source/context/token snapshots, preserve old snapshots across edits, and reject results after account, file-read, source or indentation changes in both modes.
-
Split oversized Edit paint into escaped, Unicode-safe text runs so browser range measurement avoids scanning one enormous text node. Preserve grapheme clusters, syntax classes, source coordinates and wrap behavior in both modes.
-
Add reproducible native/browser-WASM editor storage workloads with optional Crop/Ropey comparisons, CRLF-aware offset checks and recorded results. CI checks workload correctness without timing thresholds; production storage remains unchanged while viewport/worker work continues.
-
Move cursors within long wrapped lines by indexing Unicode graphemes separately and measuring only each cursor’s current and neighboring visual rows. Locate rows with bounded DOM range searches, reuse measurements across cursors, and preserve pixel goals, folds and soft-wrap affinity in both modes.
-
Protect PHP heredoc/nowdoc and shell heredoc text in shared editing and syntax paint. Expose PHP interpolated expressions and their braces, shell substitutions and arithmetic expansions as code; retain nested literal protection through enclosing string wrappers, Unicode/CRLF and incremental updates in both modes.
-
Queue wrapped cursor movement while syntax paint is pending, preserving arrow order and Shift selections. Flush through the shared paint primitive before typing, editing, IME and clipboard actions; cancel stale file/account/projection requests and bound retries in both modes.
-
Move multiple cursors by measured visual rows when word wrap is enabled, retaining horizontal position across short rows and soft-wrap affinity in the shared selection overlay. Skip hidden folds, preserve Unicode/CRLF and selection direction, and reject stale measurements atomically in both modes.
- Fix parser-disabled diff highlighting lint failures in backend and bridge builds by using the lexical fallback directly.
- Share full-document grammar and lexical paint across Inline/Split diffs, Git and recovery reviews, and chat diff previews. Combine syntax colors with word-change highlights, preserve Unicode and line-ending notes, and keep original line coordinates through alignment gaps in both modes.
-
Add grammar-aware Edit highlighting through the cached shared editor facade and extensible provider selectors. Paint functions/types, HTML tags and CSS properties, preserve multiline literals/comments, and color interpolation and embedded script/style code independently. Preserve source text and CRLF overlay alignment in both modes.
-
Use parser contexts for structural selection expansion and bracket navigation. Expand through named syntax nodes, expressions, blocks and functions while preserving selection direction and shrink history. Match interpolation code and embedded-language brackets, reject stale source data, and share the editor facade and bounded fallbacks in both modes.
-
Use parser contexts for line comments, combining per-cursor line markers and CSS/HTML block-comment fallbacks in one undoable transaction. Clip inline script edits to their bodies, reject stale or escaping selections, deduplicate same-line targets, and share selection mapping with other editor commands in both modes.
-
Use parser contexts for block comments, selecting the language independently for each cursor. Keep inline HTML script/style caret edits within their bodies, reject escaping selections and stale contexts, and retain selection direction and atomic undo in both workspace modes.
-
Use validated parser contexts for selected-line reindent, preserving multiline literal content and separating HTML script/style bodies even after unclosed blocks. Reject stale contexts, retain undo and use the same editor facade in both workspace modes.
-
Add a disposable live editor-recovery check against the built WASI API, SQLite and Chrome. Verify both-mode browser edits and autosave, selected-tab/draft restoration after server restart, reload and new windows, and durable close-all revisions that reject stale windows. Local browser recovery is checked without native folder access; native permission/device verification remains pending.
-
Add recovered-file conflict reviews using the shared inline diff and modal components. Reload disk discards the draft; Save draft uses normal EditorConfig/save rules with one-use approval for the reviewed disk and draft versions. Preserve drafts on cancellation or stale editor/disk/root/account state, and explicitly recreate missing or empty files. Native folder-permission/device verification remains in progress.
-
Wire automatic editor tab/draft restoration and debounced, serialized database recovery saves through one facade. Retain edits arriving during writes, show retry feedback, guard late loads and account/root changes, and require explicit choices for database revision conflicts. Check recovered baselines before enabling host Save and again before writes. Native folder-permission/device verification remains in progress.
-
Add shared recovery client transport and coherent active/hidden buffer snapshots. Classify revision conflicts by HTTP status, validate recovery replies and save acknowledgements, keep transient IME text out of snapshots, and refuse dirty snapshots without a saved baseline. Guard shared REST session-expiry handling against old-session responses. Native folder-permission/device verification remains in progress.
-
Add validated editor recovery snapshots and versioned user-scoped database/API storage. Preserve committed UTF-8/CRLF text, saved baselines, selections and collapsed folds; restore drafts as an undoable change. Guard project ownership/root identity and stale window revisions, retain close-all revisions, and keep draft bodies out of general settings reads. Native folder-permission/device verification remains in progress.
-
Add editor file tabs with shared selected-tab styling, unsaved indicators, keyboard navigation and inline close icons. Keep independent buffers when selecting tabs; confirm unsaved closes, reject stale confirmations, and select an adjacent file after closing the active tab. Both workspace modes share the same facade. Native folder-permission/device verification remains in progress.
-
Retain independent unsaved editor buffers when navigating between files, alongside each document's undo history, selections, folds and scroll position. Protect pending reads from newer input, project/account switches and repeated opens; guard hidden drafts against file mutations and clear affected buffers after confirmed delete/revert. Both filesystem modes use the same workspace facade. Native folder-permission/device verification remains in progress.
-
Use shared parser contexts for paired typing/deletion and Enter, selecting the language per cursor in HTML script/style bodies and exposing template interpolation code while protecting literals. Retain bounded lexical fallback for incomplete input, including nested/escaped JavaScript templates. Reject stale contexts before changing text or history; richer highlighting and worker/performance work stay on the roadmap.
-
Parse JavaScript and CSS bodies inside HTML independently, preserving global fold coordinates through Unicode/CRLF edits and declared-type changes. Share cancellation, recovery and bounded injection policy in both workspace modes; embedded-language highlighting remains in progress. Use stable Chrome in CI and optimize grammar dependencies in development builds.
-
Add shared incremental grammar/folding providers for TypeScript/TSX, JavaScript/JSX, Python, Java, C#, C++, PHP, Shell, C, Go, HTML and CSS alongside Rust. Retain Python suite headers and distinguish JSX/TSX and Java/C#/PHP file types. Use extensible grammar descriptors and one browser C compatibility adapter; native and both-mode browser contracts exercise Unicode/CRLF updates, cancellation, size limits and recovery. Provider-backed editing, embedded-language contexts, richer highlighting and worker rendering remain in progress.
-
Include fresh browser timezone, local date/time and UTC offset, locale, and 12/24-hour formatting defaults in run context for local, remote, and projectless chats. Share formatting across startup context and run transports, and omit unavailable values.
-
Preserve multiline clipboard fragments across multiple editor selections using compact validated metadata. Restore each cursor’s fragment, including Unicode, CRLF and empty selections; match indentation per fragment when requested. Fall back to plain-text paste when metadata is missing, changed or invalid, with atomic limits and one undo step. Both workspace modes share the Rust engine and clipboard facade; native-device clipboard verification remains in progress.
-
Add multi-cursor controls to Edit: occurrence, vertical cursor and expand/shrink commands in the shared editing menu and shortcuts; Alt-click toggles cursors and Alt+Shift click/drag selects columns. Paint secondary selections/carets with the syntax layer's text metrics and announce cursor counts. Move all cursors by grapheme, word, logical line or document boundary, retaining columns across short lines and skipping folded source. Both modes use the same Rust engine and facade; pending-paint motion queuing, large-file viewport preparation and real-device verification remain in progress.
-
Integrate multi-selection clipboard operations with the shared editor engine. Copy/cut use source ranges across folds, cut waits for a successful clipboard write, and paste distributes matching lines or repeats the full text with one undo step. Failed clipboard access keeps the source unchanged in both modes. Real-device clipboard verification remains in progress.
-
Replay native editor input across selections through the shared Rust document engine. IME previews retain the browser's primary input, then commit all selections in one undo step; cancellation, invalid frames and stale project/file/account events preserve the original document and history in both modes. Real-device input verification remains in progress.
Changed
-
Preserve Edit viewport offsets while folding and unfolding. Refocus the native input without scrolling its distant caret into view, and keep syntax paint aligned in both modes.
-
Add shared editor selection primitives: overlap normalization, next/all occurrences, grapheme/tab-aware columns, vertical cursors and expand/shrink selection. Preserve primary order/direction, canonicalize cursors after folds and edits, and replace selected ranges with bounded aggregate allocation and grouped undo. Route selection commands through the scope-checked editor facade and retain secondary selections during editing commands in both modes. Real-device verification remains in progress.
-
Enable database-backed Word wrap and Show whitespace controls for Edit. Preserve native source offsets and text, measure wrapped fold rows after panel resizing, keep logical gutter numbers and navigate using rendered caret geometry. Normalize CRLF only in browser paint to match the textarea, retain horizontal scrolling by default and update decorations without regenerating syntax for a wrap-only change in both modes.
-
Extend Find with case, Unicode whole-word and Rust regex options, source selection scope and match counts. Add next/all replacement with regex captures and atomic undo; retain Unicode/CRLF, reveal folded matches and reject invalid/stale queries or excessive match/output sizes. Keep pending review, read-only files and diff views protected, and share search/replacement policy in both modes.
-
Add Edit navigation through the shared Rust editor facade: Ctrl/Cmd+G goes to a line/column and Ctrl/Cmd+Shift+\ jumps between matching code brackets. Reveal folded destinations, scroll long lines into view, show source cursor/selection status, and paint active lines, matching brackets and indentation guides. Preserve Unicode/CRLF source coordinates and reject delayed navigation after file/project changes in both modes.
-
Retain unaffected collapsed blocks during native typing, editor commands, paste/cut, composition and undo/redo. Reveal only the source lines selected for a native edit; revalidate rebased fold anchors before restoring projected text and source selections. Keep unchanged native composition values and carets intact, including Unicode and CRLF, and share the behavior in both modes.
-
Extend the shared folding provider with language-aware bracket/literal ranges, indentation fallback, consecutive comment groups and balanced explicit regions. Prefer Rust parser ranges; protect Python multiline strings, JavaScript regex/template literals and YAML block scalars from false folds. Use configured tab stops, preserve shared closing/header rows, bound synchronous work and clear cancelled/stale ranges in both modes. Embedded-language contexts and worker rendering remain in progress.
-
Integrate Rust folding into Edit with gutter controls, cursor/recursive/all commands and keyboard shortcuts. Preserve source line numbers and syntax context, reveal Find matches, copy complete source selections and expand safely for editing/IME/clipboard operations; replay input-only browser events against full source without deleting hidden blocks. Use the shared editor facade in both modes. Provider-backed command contexts and advanced folding remain roadmap work.
-
Build shared document fold state and source/visible-text projection for the upcoming folding controls: preserve logical lines, Unicode/CRLF offsets and directional selections; reveal hidden navigation targets, reject replacements across hidden gaps, and rebase unaffected headers through edits and grouped undo/redo. Route commands through the same editor facade in both modes; editor-view controls are described above.
-
Add the shared incremental Rust syntax/folding provider, with Unicode/CRLF-safe tree updates, parser cancellation/size limits and per-file/project/account caches. Supply portable Clang/LLVM builds for browser WASM, CI and Docker; keep backend WASI builds independent of the optional parser. Provider-backed editing contexts and worker rendering remain in progress.
-
The editor restores each file’s caret, selection direction and horizontal/vertical scroll position across file, project and edit/diff view switches; detached editor events cannot overwrite another view’s position.
-
Add shared editor line movement, duplication/deletion, indented line insertion, snippet duplication and language-aware line/block comments. Expose commands through the existing action menu and familiar shortcuts. Preserve normal paste whitespace; Ctrl/Cmd+Shift+V explicitly matches snippet indentation. Add undoable selected-line reindent that ignores literal contents and preserves Python block depth, with unsupported actions visibly disabled. Share all commands across local and remote projects and retain Unicode, mixed line separators and directional selections.
-
Add shared Rust block-aware Enter, closing-delimiter outdent and paired typing commands: auto-close language-supported brackets/quotes, wrap directional selections, skip existing closers and delete empty pairs. Keep strings, nested Rust comments/raw strings/lifetimes, Python triple strings and JavaScript regex literals opaque. Handle cancelable mobile input and desktop shortcuts through the same editor facade, retain Unicode/CRLF and atomic undo, and fall back to ordinary editing when synchronous structure limits are reached. Count indentation in visual columns when tab and indentation widths differ, and preserve selection columns inside rewritten indentation.
-
Keep directory listings usable when an entry disappears during enumeration, including Chromium writable swap files and temporary bridge discovery probes. Skip missing metadata entries in browser, native bridge and WASI listings.
-
Add shared Rust editor indentation settings: independent indentation and tab widths, per-file controls and explicit conversion, with user defaults saved in database settings. Both local and remote workspaces discover nested
.editorconfigrules with root/section precedence andunset, then fall back to detected file style and defaults. Apply configured line endings, final-newline and trailing-whitespace policies as one undoable save command; retain caret positions and distinguish the saved snapshot from newer typing. Keep paint and diff tab widths aligned, and prevent unrelated typing groups from merging after editor remounts. -
Begin the Rust/WASM editor foundation: shared atomic text transactions, directional selections, bounded grouped undo/redo, per-file/project history, Tab/Shift+Tab indentation and indentation-preserving Enter. Route native typing and IME input through the shared editor facade, preserve CRLF and unrelated mixed line endings, reject stale file events, and provide Ctrl+M to let Tab move focus. Advanced editor roadmap work remains in progress.
-
Limit rich Markdown gutter bars to changed list items and table rows, instead of marking their entire unchanged container. Keep unchanged changelog items unmarked in both Git and pending-edit previews.
-
Diff Markdown prose within its existing lists, tables and inline formatting. Highlight changed words in place, so editing one word in a changelog item no longer duplicates the entire list in rich Preview; share the behavior across Git and pending-edit previews in both modes.
-
Show green added, yellow modified and red removed gutter bars in rendered Markdown Preview for Git HEAD comparisons and pending agent edits, showing removed/replaced prose struck through in red alongside green additions in both modes.
-
Refine file menus: enable New folder only on folders; distinguish Explain from Summarize; send chat shortcuts immediately while preserving unsent drafts/images; keep Review available for known changes. Share Git/chat menus with Changes rows and suppress the browser context menu throughout the app.
- Visibly dim disabled editor Preview options without hover highlighting. Support literal text previews for .txt/.text/.log and extensionless documentation (LICENSE/LICENCE, COPYING, NOTICE, AUTHORS, README and CHANGELOG) in both modes; keep Preview disabled for code and JSON.
-
Enable editor Preview for Markdown, images, PDFs and plain-text documents, render PDFs through the browser viewer in both modes, and keep unsupported binaries in their placeholder view.
-
Open existing session, server, prompt, chat-message and panel action menus with right-click, long press or Shift+F10. Preserve the inline menu buttons, shared styling, focus restoration and outside-click dismissal.
-
Align backend history regression coverage with reload recovery: retain interrupted tool-call/result pairs with explicit unrecorded outcomes.
-
Expand the editor roadmap with researched editing, indentation, folding, navigation and search/replace requirements, a Rust/Leptos WebAssembly implementation with thin browser glue, and explicit integration with the existing code-intelligence work.
-
Offer Resume after reloading a local run with unfinished tool calls. Preserve call/result pairing in shared history, mark unrecorded outcomes explicitly, and continue with fresh turn IDs without replaying unfinished tools. Verify slow-model reloads, approvals and conflicting edit decisions across browser windows in both modes; user-confirmed OS-picked local folder access also survives reload without re-picking.
-
Keep chat history message menus anchored to their prompt without obscuring history; outside clicks dismiss them normally.
-
Keep Edit scrollbars above the syntax paint and outside the line-number gutter, with the gutter clipped to the visible text area when scrollbars or panel sizes change.
-
Center chat prompt rows and their inline menus. Compact the status line and Send/Queue/Steer/Stop controls, add Ctrl/⌘+Enter to steer, and move Attach images into the Chat panel menu while preserving paste/drop.
-
Show full-file Inline diffs, remove Content, and number logical lines in Edit, Inline and Split with compact, pinned gutters. Scroll long lines horizontally and keep Split panes synchronized. Add literal Find in file with next/previous navigation and Ctrl/⌘F.
-
Show the existing PWA code mark beside the Open WebIDE wordmark.
-
Explain each approval mode directly in its dropdown item instead of a shared footer hint.
-
Keep Layout and Theme segmented controls compact in Settings, matching Sessions and Files.
-
Keep the app within the viewport and give status-bar controls enough height to avoid page-level scrolling.
-
Keep Minimize visible on every panel heading; menus contain only the remaining actions.
-
Group Settings, Models and Log out under the username dropdown.
-
Keep Terminal in the status bar as a full-width bottom dock with a resizable, remembered height; disable it without a project.
-
Share one resize grip per vertical panel boundary, keeping drag direction correct after reordering and highlighting only the dragged grip.
-
Standardize dock title-bar spacing and right-edge resize handles. Left-align labeled terminal actions and prioritize server names over provider types in narrow Sessions panels.
-
Keep overflow menus inline with session and contextual rows. Place file creation actions beside Explorer/Changes and show them only in Explorer; use the shared Plus icon for all add/new buttons.
-
Complete live Tailscale HTTPS verification: trusted certificates, PWA installability, REST/SSE/WSS in both workspace modes, and persistent node identity, Serve routes and app accounts after container recreation.
-
Keep Git branch menus open during background status updates and avoid rediscovering branches when only working-tree status changes.
-
Keep Run context and other transcript panels at their natural height in overflowing, narrow chat panes. History disclosure arrows point down when collapsed and up when expanded.
-
Replace secondary action rows with shared inline overflow menus in chat (Edit/Fork/Rewind), sessions, servers/prompts, dock headings, files, Git diffs, and terminal controls.
-
Standardize all dropdowns on the Recent menu’s shared surface, rows, keyboard navigation and dismissal. Use editor-style segmented switches and shared search rows throughout panels and settings; remove repeated reasoning/tool history rules.
-
Display the top-bar wordmark as “Open WebIDE”.
-
Add a minimize button beside each dock panel’s move controls; collapsing preserves mounted content and saved layout state.
-
Switch Git branches from a shared selector in Changes and the footer, with New branch opening the existing name dialog. Load and switch repository branches through the same Git facade in local and remote projects.
-
Keep one heading per tool panel, group session search and New chat together, and align Changes rows, selection, spacing and actions with Explorer.
-
Share left-aligned disclosure headers across reasoning, run context and tool groups. Anchor resize handles to the full panel boundary so Terminal and other docked panels remain draggable regardless of their content wrappers.
-
Build dialogs from shared sections, fields, notices and action bars with consistent spacing and visual hierarchy.
- Consolidate Explorer, Git Changes and persistent search into one resizable Files panel. Searching shows results; clearing restores the selected file view. Share resize handles, limits, keyboard resizing and user-scoped width saves across Sessions, Files, Chat and Terminal; move panel ordering controls into their headers.
- Use Lucide SVG icons through a shared component, larger action targets, fast accessible tooltips and labeled desktop top-bar actions. Give selected project tabs the same accent/background treatment as expanded panel tabs.
- Put prompt edit/fork/rewind actions inline, left-align thinking headings and group tool calls into initially collapsed disclosures with per-tool counts. Keep live output and pending approvals available, with inline Copy icons.
-
Grow and shrink the chat composer with its content while reserving transcript space, align action buttons with the short input and allow image drops throughout the chat pane using the same attachment flow in every workspace.
-
Keep an installed app's page and cached scripts on the same build during deployments; activate the new build after existing app windows close.
-
Keep conversation forking busy until the new branch's draft and attachments are restored, preventing completion from racing the composer reset in every workspace mode.
-
Add automatic phone layout with full-screen chat and mounted tool sheets, a saved Automatic/Desktop/Phone override, touch targets, a Terminal tool window, integrated Files/Changes/search views, and per-user panel ordering. Preserve drafts, terminal output and desktop panel preferences in local, remote and projectless chats.
-
Make Open WebIDE installable with a manifest, icons, a versioned shell-only service worker and an offline server-unreachable screen. Add Settings installation guidance and browser prompting; exclude all API/bridge traffic from the cache and default HTTPS pages to same-origin
wss://<host>/bridgewhile retaining explicit bridge settings. -
Make browser CI checks wait for session restoration, composer focus and persisted approval-mode changes instead of relying on microtask counts or fixed delays. Guard deferred layout saves after owner disposal or account changes. Wait for the HTTPS test's model fixture before streaming, and retain failure diagnostics.
-
Clarify Auto approval policy so routine public-page research can be approved without the user naming an exact URL. Keep destructive actions, secret exposure, unrelated actions and uncertain decisions subject to manual approval; share the classifier prompt across browser, bridge and Spin runs.
-
Add a
tasktool for parallel child agents with independent contexts in local, remote and projectless chats. Show nested collapsible runs with live status, elapsed time, tokens, tool counts, reasoning, output and inherited approvals; preserve child history through reload, Markdown export, fork and rewind. Use the fast model with primary fallback before any tool request, propagate cancellation, and bound recursion, model concurrency and tool/output budgets. Serialize file mutations through durable checkpoint/result recording so child edits participate in the parent’s review and rewind in execution order. -
Add session search across names and messages, durable pin/archive/restore controls, and full Markdown export in local, remote and projectless chats. Generate titles from the initial exchange using the fast model with primary fallback; serialize background attempts, preserve manual names and ignore stale account results. Keep pinned sessions first, archived history accessible, and metadata intact through rewind; forks start unpinned and unarchived with manual branch names.
-
Add a searchable command palette (
Ctrl/⌘+Shift+P) and keyboard-shortcut overlay (Ctrl/⌘+/), with a Commands button in the top bar. Support arrow keys, Enter, Escape and restored focus; reuse shared session, project, settings, model, panel and slash-command actions. Disable project-only commands in projectless chat, preserve drafts and close stale dialogs on account, project or session changes. -
Polish tool steps in local, remote and projectless chats with live elapsed time, persisted final durations, expandable ANSI-colored output and plain-text Copy (including an HTTP LAN fallback). Add per-prompt tool/file counts, including shell changes, and recorded model/tool time; mark incomplete timing as a lower bound. Exclude approval waits, freeze cancelled tools, preserve timing through reload, fork and rewind, and keep timing-save failures from stopping runs.
-
Show live reasoning time to tenths of a second and estimated tokens for inline
<think>blocks and provider reasoning in every chat mode. Freeze a compact “Thought for 3.2s · ~1.4k tokens” summary on completion, cancellation or provider failure, keep traces collapsed until expanded, and support keyboard toggling. Historical traces without observed timing show their token estimate without inventing a duration. -
Add private HTTPS deployment configuration for an external official Tailscale container, persistent same-origin
/bridgeServe routes, loopback listeners, native and rootless Podman instructions, and a Caddy internal-CA alternative. Verify TLS REST, SSE and WSS in Docker and rootless Podman; keep the backend-only bridge secret bootstrap inaccessible through a proxy. -
Default new sessions to Auto approval mode and label the former Default choice Manual. Preserve saved modes and keep older sessions without a saved choice manual.
-
Simplify model setup to one Detect settings action per chat model and a single modal Cancel / Save. Preview and testing leave configuration untouched until Save atomically commits server options, credentials, profiles and initial defaults. Keep only Edit on server rows and New server in the Servers heading.
- Add server presets and shared detection for Ollama, llama.cpp, LM Studio, vLLM, LiteLLM, OpenRouter, SGLang and KoboldCpp. Discover standard host endpoints on first setup, cache model facts by transport revision, preserve manual overrides, surface sampling, runtime context, size, quantization, loaded state, server version, CPU spill and tokenizer details when reported, and exclude embedding-only models from chat.
- Add optional model testing for structured and streamed tools, first-token latency and tokens/sec. Probe failures fall back to plain chat with a notice; tool streaming capability is scoped to each server and model. Shared project detection suggests test commands and linters in local and remote workspaces.
- Harden bridge lifecycle and HTTP handling: reap idle detached PTYs, send SIGHUP before forced termination, await delayed process cleanup at shutdown, time out stalled body reads and response writes, close HTTP/1.0 connections, support half-close responses, enforce WebSocket message limits, avoid response-body copies and bound displayed bridge errors. Compile Windows adapters in CI.
- Bound unterminated terminal lines, respect composer IME composition, restore background editor content after backup rejection while preserving new input, mark the active
/modeland support/model default. Normalize provider URLs with query strings or fragments without losing nested proxy prefixes. -
Extend auth, search, database rollback, model detection, transport, process lifecycle and browser parity regression coverage. Fake-backend deletions cascade, component click helpers accept combined classes, and frontend tests build natively without
--lib. Revert the WASM size optimization that did not improve compressed size or startup. -
Establish shared feature facades for local and remote files, Git, execution hosts and session runs. UI send/stop/approval/resume actions use the run facade; planning, context, history recovery, streaming, persistence, permission policy and tool workflows live above thin browser, Spin and bridge adapters.
- Share provider model precedence, wire messages, plain and tool-stream lifecycles; split core domains and diff rendering, share line/word alignment and storage row mapping, and remove storage’s agent dependency. Use typed VFS creation/permission errors and Git responses while retaining browser thread checks and legacy wire formats.
- Verify common provider and filesystem contracts across adapters, including failure and fallback behavior. Browser chat-only runs share server reply persistence and telemetry; populated-directory deletion and binary Git previews behave consistently in both modes.
Added
-
Add transactional editor recovery hydration and shared disk reconciliation primitives. Preserve saved baselines, ordered tabs and hidden drafts; reject stale editor activity and distinguish changed, missing and already-written disk text. Native folder-permission/device verification remains in progress.
-
Add file and folder context menus in both workspace modes: create, rename, move, copy path, confirmed delete/revert, status-aware Git tracking/staging/unstaging/ignore, and Explain/Summarize/Review chat shortcuts. Share filesystem policy and Git planning across adapters; guard unsaved buffers, pending reviews, concurrent operations and stale account/project/folder results. Preserve originals on failed moves and untracked files on revert.
-
Add
todo_writefor an agent-maintained checklist pinned above the composer in local, remote and projectless chats. Show pending, in-progress and completed items with progress counts and collapsible themed scrolling. Persist prompt-anchored revisions in the database, restore the correct plan after reload, rewind and Fork, and include the latest checklist in subsequent model context. Reject stale prompt updates, preserve the plan when tool persistence or loading fails, and offer Retry for failed loads. Share tool policy and execution above thin browser, Spin and bridge persistence adapters. -
Add opt-in browser notifications for finished runs and approval requests in local, remote and projectless chats. Notify for chats that are out of focus, collapsed or inactive; clicking opens the owning project and session. Save the preference per user in the database, request browser permission only from Settings, explain unsupported/blocked browsers, and keep approvals available in the app. Suppress duplicate/replayed events and automatic approvals; guard pending permission responses and notification clicks across account changes, and close notifications on logout. Keep the app open to receive notifications; Web Push remains planned separately.
-
Queue prompts while a run is active, edit/remove pending prompts, pause or continue the queue, and steer by saving priority guidance before stopping the current run. Persist captured attachments and queue revisions in the database; consume each prompt atomically when its user message is saved, keep failed sends queued, and restore pending queues paused after reload or session changes. Add Edit and Fork on earlier prompts: copy the conversation prefix into a new branch while preserving the original session, images, editor context, model selection and approval mode. Share these workflows across local, remote and projectless chats; branching leaves project files unchanged.
-
Attach immutable file contents, folder listings and Git diffs using
@file:path,@folder:pathand@diff[:path], with keyboard autocomplete and quoted paths for spaces. Resolve mentions through shared workspace/Git facades in local and remote projects. Add image picker, paste and drag/drop with previews and removal, including projectless chat; persist images and reference snapshots with prompts for reload and rewind. Send real image inputs to Ollama and llama.cpp in plain and tool requests, normalize GIF/WebP and large rasters to PNG, expose detected/custom vision capability in model settings, and keep image pixels out of text compaction. Limit attachments to four images (2 MiB each, 4 MiB total) and reference context to 16 references/128 KiB. Guard preparation against cancellation and account/project/session changes. -
Add
/contextwith a themed breakdown bar for the latest model request: system instructions, files, tool output, history and tool schemas, plus generated reply and free context. Share accounting with the compaction engine, scale estimated categories to the provider’s input count, and persist the breakdown with reply telemetry for reloads. Support local, remote and projectless runs through both streaming transports; retain/tokensfor cumulative accounting. -
Add a changes panel beneath each new agent run’s prompt in local and remote projects. Review text changes per file or hunk, and created/deleted or binary files as a whole. Persist decisions in the database, mark pending lines in the editor, preserve accepted hunks during later edits, and keep rewind consistent after rejection. Capture shell changes even when a command fails; stale revisions and later manual edits cannot be overwritten.
-
Add Rewind to here on chat prompts in local, remote and projectless sessions. Restore project file contents and conversation together, including shell/Git working-tree changes, created/deleted files and binary contents. Keep Git history, external effects and gitignored paths intact during shell rewind. Checkpoint snapshots and recovery history live in the database; conflict checks protect later edits, interrupted restores can resume, and unfinished or missing checkpoints refuse unsafe rewinds. Checkpoints capture up to 32 MiB and 10,000 project files, with a 10 MiB single-file limit; excluded paths remain unchanged.
-
Keep a permanent speech-bubble chat tab at the right of the project tabs. Chat without a project using web search, page fetching and read-only
host_info, with file, Git and shell access disabled. Save sessions and the selected chat in user-scoped database settings, restore them across devices, and preserve open project workspaces when switching back. Both bridge WebSocket and backend SSE runs use the same tool restrictions, permissions and compaction. Collapse and disable Files and Editor in projectless chat, restoring their saved visibility on return to a project. Remove the redundant open-project panel from chat. -
Add Rider-style vertical panel tabs: Sessions, Files, Editor and Chat together in one left tab bar. Collapse and expand panels without unmounting editors, drafts or running terminals; save visibility in user-scoped database settings and restore it across devices. Resize only visible panels, preserve collapsed widths, and reveal the relevant pane when opening a file, session, model setup or terminal in either workspace mode.
- Add
host_infofor local, remote and projectless chat. Read CPU, available/total RAM and disk capacity from the bridge host; report available temperatures, Linux fan RPM, NVIDIA GPU/VRAM/temperature/fan percentage, Linux AMD VRAM and macOS GPU inventory. Identify the bridge as the source and mark unavailable readings and container scope explicitly. -
Theme scrollbars throughout the app with the active dark/light palette, including panels, editor, terminal, dialogs and native controls.
-
Set up model servers through a rerunnable wizard: choose Ollama or OpenAI-compatible, enter URL and optional write-only auth token, then discover models and review/customize settings. Retry discovery without duplicate servers, preserve saved tokens and manual model overrides, and choose an initial default model when applying reviewed settings. Launch setup from Servers, model configuration or the workspace toolbar in either mode.
-
Automatically compact local and remote chat/agent context before model requests and tool continuations, using the configured threshold (85% by default, 0 disables). Reserve response and summary space, use provider tokenization with an estimate fallback, summarize through the fast model or primary fallback, and persist reusable summaries while retaining original history. Failed or cancelled summaries never replace history.
-
Render Markdown tables with aligned columns, themed headers and borders, and horizontal scrolling for wide tables in agent replies and file previews. Support strikethrough while retaining sans-serif prose and monospace code in both modes.
-
Distinguish user prompts with a compact, rounded, theme-aware background inset from the TUI panel edges and aligned on the right with tool and thought panels; remove repeated assistant headings while preserving a shared text alignment for prompts and replies.
-
Keep the file tree ordered at every level: directories first, then files, using case-insensitive natural name sorting consistently across local and remote loads and refreshes.
-
New chat immediately creates and selects a session, persisting its project startup context in both modes before the first prompt.
-
Choose Default, Auto-accept edits, Auto, or YOLO from the TUI or with Shift+Tab. Persist session choices in user-scoped database settings and enforce them through one shared policy gate, with thin browser, bridge, and SSE adapters. Auto uses the configured fast model or the primary model and falls back to manual approval on uncertain, malformed, failed, or timed-out classification.
-
Configure primary and optional fast models, per-model context/sampling/output/thinking/tool overrides, and an 85% auto-compaction threshold in database-backed settings shared by local and remote mode. Background work falls back to the primary model when no fast model is selected..
-
Add model servers by URL, discover common local endpoints, detect model context/capabilities, and configure write-only API keys, proxy headers, timeouts, and Ollama keep-alive.
-
Choose a session’s connection and model from a tiered TUI menu, with models discovered on expansion and new sessions starting from the configured default.
-
Generate fresh startup context in local, backend, and bridge runs: environment and available tools, root and nested project instructions, and relative imports. Save the exact context as a collapsible session entry, with visible size and import limits.
- Automatically refresh the file tree in local and remote projects, preserving expanded folders and editor contents while pausing background tabs.
-
Restore the last-used session per project when opening a project or a fresh browser window, using user-scoped database settings.
-
Reload pending agent edits per project from the database and persist Accept/Reject decisions, retaining failed reviews and backups for retry.
-
Store pending agent edits and review decisions per project in the database, with replay protection and revision checks; review UI integration follows separately.
-
Keep terminal shells and output when hiding the dock, and start new shells in the active project folder with a visible workspace-root fallback notice, including when a remote folder no longer exists.
-
Guard local browser file operations and agent completions with originating-thread checks, including cancellation when a completion stream is dropped.
-
Reduce repeated recent-project filtering and statusline formatting work while preserving project order, telemetry text, and saved themes.
-
Make dialogs keyboard accessible with focus containment, stacked Escape handling, focus restoration, and keyboard folder navigation.
-
Apply the saved database theme before first paint without browser preference storage, and unify action buttons and theme-aware warning/diff colors.
-
Reuse the browser database connection and remove saved local folder handles when projects are deleted, including stale handles owned by the signed-in account found at startup; preserve other accounts’ folders and handles saved during startup, including when the system clock changes.
-
Handle CRLF and CR fallback chat streams and multi-line SSE data fields correctly.
-
Clarify Open local / Open remote with device-based tooltips, a remote folder-picker subtitle, and matching documentation.
-
Reduce the release WebAssembly download size with size-focused optimization.
-
Debounce file-search typing by 250 ms while keeping clearing and ignored-folder toggles immediate.
-
Load workspace settings and lists in parallel, and avoid redundant model requests when switching or renaming sessions on the same connection.
-
Render terminal output incrementally with 10,000 lines of scrollback, split ANSI colour support, recovery from unfinished controls when processes exit or restart, progress-line updates, and scrolling that follows only near the bottom.
-
Coalesce editor syntax highlighting to one animation frame while keeping typing and saving immediate.
-
Keep conversation rows mounted while replies stream, reducing chat update work and preserving expanded reasoning and diff previews.
-
Show streamed model reasoning and mark replies cut off by the output token limit; omit prior reasoning from model context.
- Preview file diffs before approving agent edits, expand long previews, and flag unreadable overwrites.
- Run
/test [filter]in the terminal with shell-quoted filters and the project directory. - Bundle the execution bridge in Docker and Podman deployments for terminals, Git operations, and streamed chat on port 3001.
- Resume interrupted local-mode runs from their saved conversation, preserving user messages and tool-step numbering.
- Add bridge-hosted chat/agent runs and streamed completions, with reconnect replay, cancellation, approvals, and TLS enabled by default.
- Add provider streaming for tool-call turns, with automatic non-streaming fallback for older llama.cpp servers.
- Add a frontend component test harness with a fake backend and headless Chrome tests in CI.
- System theme option: the default follows the OS light/dark preference and reacts live to changes; explicit theme choices are stored in per-user database settings.
- Search "include ignored folders" toggle: the file tree's search box now has a toggle button that also searches the ignored folders (
.git,target,node_modules,dist,.spin); the hit and byte caps still apply, and toggling re-runs the current query. The flag is per query — not persisted, off on reload. - Bridge confinement: canonicalize the workspace root and enforce lexical cwd bounds, while permitting directory symlinks.
- Agent edits back up original bytes before overwriting unreadable (binary or large) files; refusing an unreadable file edit now safely restores it from a backup rather than deleting it.
- Scaffold: Rust workspace (
core,llm,storage), a Spin (wasm32-wasip2) backend, a Leptos WASM frontend shell, and CI running fmt, clippy, native tests, and both WASM builds. - Provider HTTP: real Ollama and llama.cpp calls (
/api/models,/api/chat) over Spin outbound HTTP, with a fakeHttpClientfor native tests and actionable errors for unreachable engines. - Chat sessions: a sidebar of sessions (new/switch/rename/delete), SQLite message persistence, SSE token streaming, and a per-session system prompt and connection.
- Container deployment: a single-image multi-stage
Dockerfile,docker-compose.yml, and Podman quadlet units, with SQLite on a named volume. - Workspace modes: Remote mode (Spin-mounted host folder,
/api/files) and Local mode (File System Access API, directory handle persisted in IndexedDB), plus Rider-style multi-project tabs. - Agentic coding loop: tool-calling agent (
read_file,write_file,list_dir,search) confined to the workspace, with turn/tool budgets, a permission handshake for gated tool calls, and server-side run cancellation. - IDE surface: an in-browser syntax-highlighting code editor, a diff-first file viewer (inline diff, side-by-side diff, updated content, markdown/image preview), full-text file search, a per-session model picker, a Settings dialog (theme, default connection, default system prompt), and a system prompt manager.
- Local user accounts: registration and login, argon2id password hashing, HttpOnly cookie sessions, and user-scoped projects/sessions.
- Custom dialogs & remote file browser: themed confirmation and prompt
dialogs, and a host file browser for picking a remote project folder,
replacing browser-native
alert/confirm/prompt. - Virtual File System (VFS): a shared
Vfstrait withHostFsVfs(remote) andBrowserFsaVfs(local) implementations, a universalVfsToolExecutorshared by both modes, a browser-driven local-mode agent loop against/api/chat-tools, workspace-widegrep_search,search_web,fetch_web_page, and zero-turn temporal context injection. - Process execution & WebSocket terminal bridge: the native
openwebide-bridgedaemon (PTY sessions,run_commandagent tool) and an integrated terminal pane, with Git operations forwarded to the bridge against the real host repository. - TUI-driven chat surface: a terminal-native linear stream layout,
collapsible
<think>reasoning blocks, readline-style prompt history, an in-stream keyboard permission handshake, a slash-command engine (/model,/tokens,/clear,/test,/diff,/help,/commit,/checkout,/branch,/sync), and active-editor-context injection via a context pill andCtrl+L/Cmd+L. - Git integration: passive
.git/HEAD/.git/refsstatus telemetry with a bridge-backed active engine for status, diff, branch, commit, checkout, and sync against the real host repository; a status bar branch/ahead-behind widget, file tree status badges, andgit_status/git_diff/git_commit/git_branchagent tools. - Editor enhancements: cursor/selection tracking (
EditorContext) shared between the editor and chat prompt, diff viewing against Git HEAD, a markdown/image preview mode, and syntax highlighting expanded from 5 to 16 languages. - TUI telemetry meters: the statusline's
t/sandCtx:gauge are now backed by real provider usage. Ollama (prompt_eval_count,eval_count,eval_duration) and llama.cpp (usage,timings) report token counts and timing per call; missing fields fall back to an estimator and are marked~in the statusline and/tokens. Usage is forwarded as atelemetrySSE event, recorded intoSessionTelemetry, persisted on the assistant message, and replayed on session reload. - Per-connection context limit: an optional
context_limiton each connection, resolved from the configured value, then provider discovery (GET /api/models/context— Ollama'sPOST /api/show, llama.cpp'sGET /props), then a fallback. Ollama connections send it asoptions.num_ctxon every request so the gauge and the runtime context window agree; for llama.cpp the value drives the gauge display only, since its context size is fixed whenllama-serverstarts. - Bridge
helloauthentication with short-lived backend-minted tokens (/api/bridge/token), abridge_urluser setting, and optionalOPENWEBIDE_BRIDGE_TOKENpairing credentials. - Local mode integrity: validate UTF-8 with a read-only fallback for unreadable files, surface missing directory permissions, and abort local runs without waiting for server round-trips.
Changed
-
Keep personal default/fast model choices in Settings; move shared model configuration to a separate dialog opened from Servers. Model profiles, context detection and compaction thresholds are shared per server/model, with existing preferences migrated.
-
Share content/file search policy and budgets across browser, WASI and native filesystems, and share run planning and persisted agent events across browser, SSE and bridge runs.
- Route Git, terminal and agent startup through a common project execution-host facade. Model discovery uses shared probes on the backend or the local companion host.
-
Normalize file paths and enforce a shared 10 MiB read limit across editor and agent adapters; browser filesystem failures retain typed error categories.
-
Keep assistant thinking blocks collapsed while the model is thinking (click the header to expand the live trace), move the spinner after the "Thinking..." label with a live elapsed-time counter, and show the final elapsed time in the collapsed "Thought" summary; the spinner now cycles proper braille frames. Elapsed time scales with the run (e.g.
42s,2m05s,1h03m20s), and aborting a turn clears the "Thinking..." state so the partial trace collapses into the summary. - Raise the agent run budget from 12 turns / 24 tool calls to 256 turns / 512 tool calls; the budget is a runaway-loop guard (runs stay cancellable), so nontrivial tasks no longer exhaust it mid-task.
- Enforce selected pedantic Clippy lints across the workspace, remove unused code, and trim bridge Tokio features.
- Split bridge terminals, tool execution, and agent runs into modules; share an executor trait for host tools and add structured logs with
RUST_LOGfiltering. - Refactor backend routing and typed errors; hide internal 500 details, surface project lookup failures, and accept raw binary file writes.
- Stop interrupts running commands, web requests, and searches while allowing file writes and Git mutations to finish.
- Sync prompt history and theme through user settings, import legacy history once, and fit panel widths to the viewport.
- Split frontend state into per-feature stores provided through Leptos context.
- Run local-mode command and git tools in the picked folder, discovered and verified through a temporary bridge probe.
- Persist interim tool calls for follow-up history and remember servers that reject streamed tool calls.
- Unify SSE and WebSocket chat events in one shared protocol; deploy frontend and backend together.
- Use the bridge for frontend chat and local completion streaming, with SSE fallback, run resume, and project availability notices.
- Share one authenticated bridge connection across terminal, run, and completion traffic; reconnect terminals automatically and open a fresh shell after a bridge restart.
- Stream server-side agent replies token by token, retain text before tool calls in conversation history, and add a run-plan API.
- Added session expiry handling (auto-logout) and statusline model switcher dropdown.
- Bridge process lifecycle: every command the bridge spawns now runs in its own process group, so timeout, request disconnect, Kill, and shutdown signal that group. Interactive shells may place background jobs in separate groups that survive shell cleanup.
Killsends the requested signal (TERM/HUP/KILL, defaultKILL) to the whole group; on a PTY,INTinstead writes^Cto the terminal like a real Ctrl+C./execoutput over ~1 MiB per stream now keeps the first 256 KiB and last 768 KiB with an omission marker instead of buffering unbounded output. Exited terminal/process sessions are now removed 30 minutes after they exit; running sessions are never reaped. The daemon now shuts down gracefully on Ctrl+C orSIGTERM, terminating every session's process group first. - Bridge HTTP resilience: The execution bridge's HTTP and WebSocket server is now built on
hyperinstead of a hand-written parser, fixing header/body misreads under fragmented or chunked writes and case-sensitiveUpgradeheader matching. Requests are capped (16 KiB head, 1 MiB/exec/Git body, 16 MiB WebSocket message), idle sockets close after 10 s without a request head, WebSocket connections are pinged every 30 s and closed after 90 s without a reply, and the accept loop now backs off and keeps serving instead of exiting on the first accept error (e.g. EMFILE), bounded by 256 concurrent connections. - Backend git operations now run within the project context, and bridge failures cleanly propagate rather than showing false success.
- Backend resource bounds: API request bodies are now capped per route (64 KiB auth, 1 MiB JSON, 4 MiB settings, 16 MiB chat, 10 MiB file write) and rejected with 413 Payload Too Large when exceeded. File search is bounded to 500 hits / 64 MiB / 20,000 entries, and the
include_ignoredflag is honored server-side. - Database methods that update multiple interrelated tables (e.g. deleting a project, first-admin creation) now run within strict SQLite
BEGIN IMMEDIATE...COMMITtransactions on the backend. This guarantees complete rollback if an operation fails or if the WASM task cancels or panics midway, fixing race conditions and half-deleted states without relying on manual cascading deletion code or risking lock deadlocks. - The user registration API endpoint (
POST /api/register) now correctly isolates creation by atomically using the transaction, preventing race conditions where multiple parallel signups could occur on first setup. - Constraint-violation errors are now reliably returned as HTTP 409 Conflict.
- Direct Workspace Mounts: Spin development servers and Docker deployments now require the
--direct-mounts --allow-transient-writeflags. This ensures file modifications write to the native host directory instead of a temporary Spin sandbox. Project creation validates paths, and the.spin/configuration directory is explicitly forbidden from file API and agent access. - Web fetch & redirect safety: Hardened web fetching against SSRF by refusing requests to cloud metadata endpoints (
169.254.169.254,fd00:ec2::254, their IPv4-mapped representations, andmetadata.google.internal) on initial requests and redirect hops while keeping LAN and private access open. Hand-rolled RFC 3986 §5.2 redirect reference resolution to correctly handle absolute paths, network-path (//) references, relative paths, port preservation, and query-only redirects. Capped streaming HTTP response bodies directly at 512 KiB for web pages and 2 MiB for JSON to prevent memory exhaustion. - Bridge Git safety: Protected native Git execution against command-line argument injection. Branch and remote names are validated (
git check-ref-format --branch, remote membership) with option-like leading-and pathspecs like.rejected with 400 Bad Request. Branch switching now strictly usesgit switch(requiring Git ≥ 2.23), commit operations with specified paths only stage and commit those paths, Git output is untrimmed, push/pull commit counts are calculated accurately viarev-list, and phantomoriginbranches fromorigin/HEADsymrefs are ignored. - Approval UX: "Always approve" is now scoped per-session (cleared on logout) instead of globally, and explicitly never covers
run_command. Keyboard approval shortcuts moved from barey/n/atoAlt+Y / Alt+N / Alt+A(typed responses no longer trigger approvals). Stopping a run now cancels any pending tool prompt instead of leaving it clickable, fixing an issue where later runs' shortcuts acted on dead prompts. - Enabled running unit tests for
openwebide-backendnatively via anAppDbabstraction backed by in-memory SQLite (rusqlite) on native targets and Spin SQLite (SpinDb) on WASM targets. - Toolchain pinned to Rust 1.98.1;
argon20.6,rand0.10,base640.23,hmac0.13,sha20.11, andtokio-tungstenite0.30 (bridge only), with existing password hashes and bearer tokens verifying unchanged. /tokensnow shows the context-window gauge as the latest call's token count against the resolved context limit, instead of a running total summed across the whole session; the Input/Output rows stay cumulative.- The context-window fallback, used when a connection has no configured
limit and provider discovery finds none, is
4,096tokens (was a hard-coded32,768), and is marked estimated (~) in the UI. - Deliver terminal output through a cursor-based SeqRing with ordered replay, retained exit events, truncation notices, and duplicate session-ID rejection.
- Apply numbered, idempotent database migrations transactionally via
PRAGMA user_version; refuse databases newer than the build. - Decode typed tool arguments and report malformed calls as tool errors; cap file, directory, and search tool results and support
include_ignoredin agent searches. - Reconcile setup, architecture, bridge protocol, roadmap, changelog, and
/helpdocumentation with current behavior.
Fixed
-
Honor project and nested
.gitignorerules in shell/Git checkpoints in local and remote projects, including negated patterns. Keep explicit file-edit snapshots for ignored files. Skip oversized or unreadable files without stopping the turn, persist coverage gaps, warn in tool results and rewind confirmation, and leave excluded paths untouched even when file sizes or ignore rules change. -
Delete nested remote files with writable directory descriptors and support recursive folder deletion without following symlinks, matching browser/native adapters.
-
Recover recent local projects when browser folder access is missing: request permission or re-pick the original folder, starting at the saved handle when available and retaining the project and sessions.
-
Defer oversized CLAUDE.md/AGENTS.md instructions with scoped read-file directions instead of injecting truncated fragments; retain imports beyond the inline limit.
-
Route file-tree Git indicators, HEAD diffs, branch/sync controls, and Git slash commands through a shared project Git facade in both modes. Local projects use the verified local bridge instead of the remote-only project API; background refresh includes Git status and stale results are discarded.
-
Keep editor syntax highlighting aligned during rapid scrolling and bottom-to-top scrolling by translating the highlight layer from the textarea’s offsets, matching scroll gutters, and showing only one text layer at a time.
-
Side-by-side diff alignment: the detailed side-by-side diff is now built on the same line-level LCS as the inline diff, so an inserted or deleted line no longer shifts every line below it into a false pair (previously the whole changed middle rendered as insertions); unchanged lines stay aligned as context, and paired changed lines keep intra-line word highlighting and line-ending notes.
-
Disable the agent chat composer until a project is open, with shortcuts to open a local or remote project.
-
Accept llama.cpp base URLs with or without a trailing
/v1for model discovery, chat completions, and context limits. -
Stop bridge agent runs when a tool result cannot be saved, delivering the completed result before the error and preventing overlapping runs in the same session.
-
Keep split terminal controls intact when busy or recoverable-error notices appear during a running process.
-
Preview SVG files with uppercase extensions.
- Preserve binary Git HEAD contents and hide Revert with a clear binary-file notice in text diffs.
- Isolate SSE run cancellation and permission cleanup so a quick resend preserves Stop and concurrent runs retain their decisions.
- Editor: Added confirmation dialogs before discarding unsaved edits and conditionally offered the Revert button only when HEAD is known.
- Web fetch HTML→Markdown conversion: the converter is now built on the
html5evertokenizer (same versionammoniaalready uses, so no second copy in the dependency tree), so fetched pages keep text the old hand-written scanner dropped — an unescaped<no longer swallows the rest of the line, bare&in text (Q&A,AT&T) survives, HTML5 entities are decoded fully, self-closing skip tags (<svg/>) no longer swallow everything after them, and<head>content (e.g.<title>) no longer leaks into the output. Links with unsafehrefschemes (javascript:,data:, …) are now removed (link text is kept), relative/fragment links are kept, anddata-hrefis no longer mistaken forhref. - Line-ending and final-newline diffs: the inline and side-by-side diffs now align lines with a line-level LCS that compares each line including its ending, so a CRLF→LF conversion or an added/removed trailing newline shows up as a change (with a small "⏎ CRLF → LF" / "no newline at end of file" note) instead of being invisible, and an inserted line no longer marks every line below it as changed. A whole-file line-ending change collapses to a single summary line.
- Git status for paths with spaces, unicode, and unborn branches: the bridge now reads
git statuswith--porcelain=v1 -b -z(NUL-separated, unquoted paths) and the parser consumes rename/copy source records and recognizes theNo commits yet on/Initial commit on/HEAD (no branch)headers, so files with spaces or non-ASCII names report the correct status and new repositories show their branch instead of failing to parse. - Stale search results no longer overwrite the view: file-content searches are now guarded by a per-run generation, so a slow search for an older query can no longer land after a newer search for the same project and clobber its results, and clearing the search box can no longer be undone by a search that resolves after the clear.
- Stale chat history no longer overwrites the view: loading a session's message history is now guarded by a per-run generation, so a slow history request can no longer land after a newer request — including one for the same session — and clobber the conversation on screen. The first send in a brand-new chat also no longer duplicates the user message, since the redundant history fetch that fired the instant the session was created is now skipped.
- Stale file-browser listings no longer overwrite the view: the folder picker's directory listing is now guarded, so a slow browse response for an old directory can no longer land after a newer navigation and show the wrong listing.
- \"New file\" no longer truncates an existing file: creating a file at a path that already exists now returns an error (HTTP 409 in remote mode, an error banner in local mode) and leaves the file's content untouched. Agent
write_fileto a new local-mode path now works correctly. - Auth correctness: the token-signing secret is now created with an atomic insert-if-absent, so concurrent first requests can no longer write different secrets and invalidate issued tokens, and token expiry checks fail closed with a 500 instead of accepting every token when the system clock is unavailable.
- Docker project-path migration: Remote project paths created before the
/workspacemount (stored relative to the container root, e.g.workspace/foo) are rewritten automatically on first start, so projects from older Docker installs no longer appear missing after an upgrade. - Plain-chat SSE streams always emit a terminal done/error event, including persistence failures.
- Truncated replies are kept, not silently saved or dropped: a reply cut short by a crashed or disconnected provider is now kept with a visible "[reply truncated]" marker instead of being silently saved as complete or dropped, and llama-server
error:events now surface their message. - Database foreign keys (
PRAGMA foreign_keys = ON) are now correctly enabled when opening the Spin WASM SQLite database connection. - Calling
delete_projectnow relies natively on SQLite's cascading deletes, vastly simplifying the query footprint. - Frontend panics and terminal cleanup: Fixed a panic in editor context capture when truncating selections lands inside a multi-byte character by mapping UTF-16 selection offsets to byte offsets and truncating at a UTF-8 char boundary. The terminal dock's WebSocket connection task is now cancelled and its spawned sessions killed when the dock closes, and its output auto-scroll no longer panics on an already-disposed DOM node. The status bar no longer panics on a stale Git status signal. Added a browser panic hook that logs to the console instead of showing an opaque
unreachableerror. Typed shell commands with arguments are now run viash -lcinstead of failing. - Provider stream robustness: The Ollama/llama.cpp line-splitter now decodes UTF-8 across the whole buffered line instead of per network chunk, so a multi-byte character split across chunks no longer corrupts the reply. The buffer is capped at 16 MiB per line instead of growing without bound. A
tool_calls: []response is now treated as a text reply instead of an empty tool-call turn that looped until the turn budget ran out. - Highlighter and diff robustness: Fixed panics in the syntax highlighter on non-ASCII source lines and in HTML-to-Markdown truncation on multi-byte character boundaries. Lines over 10,000 bytes now render as a single unhighlighted token instead of freezing. Word-level diffs fall back to a whole-line delete/insert past a size budget instead of using unbounded
O(m·n)memory. - Approving one tool call could silently approve a later, different call
(Ollama reuses
call_0every turn), letting e.g.run_commandrun without a prompt. Tool calls now get session-unique ids and each approval is used once. This also stops later runs from overwriting earlier tool steps in history. - Agent-directed file writes on the streaming write path no longer produce 0-byte files.
- Remote file API path handling for nested and root-relative paths.
- Filesystem and outbound-denial error messages now point at the actionable
fix (the host egress allowlist in
spin.toml, or the remote mount configuration) instead of an opaque error. - Duplicate projects sharing the same mode/path are deduplicated on startup, reassigning their sessions to the surviving project.
- Return CORS headers on API errors and reject extra path segments on session update/delete routes.
- Match file extensions without case sensitivity and use Markdown fences longer than any backtick run in injected editor context.
Security
- Bridge Security: Added
Authorization: Bearer <SECRET>for Origin-less/execand/git/*routes. The bridge generates a 32-byte secret at startup and the backend auto-fetches it over loopback viaPOST /secret, with caching in SQLite. - Hardened login system: transitioned to HttpOnly cookie sessions, added brute-force lockout, and implemented global logout (invalidates sessions on all devices). Added CSRF protection via custom header.
- Default-deny tool approval policy: agent tools now default to requiring user approval unless explicitly allow-listed as auto-approved (
read_file,list_dir,search,grep_search,git_status,git_diff,search_web).fetch_web_pagenow requires user approval, andwrite_filerejects any path with a.gitcomponent (case-insensitive). Tool descriptions and summaries updated forwrite_file(showing line and byte counts) andgit_commit(clarifying all tracked changes vs specific paths). - Bridge exposure baseline: Enforced strict
HostandOriginvalidation, rejecting foreign cross-origin browser requests and DNS rebinding. Removed wildcardAccess-Control-Allow-Origin: *and restricted preflight responses. Enforcedapplication/jsonContent-Type on browser POSTs (POST /exec,/git/*) to prevent CSRF, and added--allowed-originand--allowed-hostCLI/env configuration. files/rawnon-image requests are now forced to download instead of rendering inline.- Directly opened SVG/HTML files via
files/raware now sandboxed. - Dropped support for
?token=query parameter authentication. Media preview URLs now use short-lived blob URLs instead of exposing the bearer token. - Markdown previews sanitize raw HTML with
ammoniaand no longer execute unsafe elements (e.g.,<script>,<style>,<iframe>,onload/onerror,javascript:links). Safe elements like<details>,<sub>, and inline<img>remain. SVG previews display as images and no longer execute scripts. Addedopenwebide-frontendas a lib crate for a native test harness.