Koder kruze

Koder Kruze — products/horizontal/kruze/app/desktop

  • *rea:*Workspace
  • *ath:*products/horizontal/kruze/app
  • *ersion:*1.0.7
  • *tatus:*Active beta
  • *ind:*Flutter desktop browser app

Role in the stack

Koder Kruze is the Workspace browser: a Flutter desktop app that combines a tabbed webview surface with Koder ID account access and a Koder AI assistant panel. It is the user-facing place where internal koder:// pages, web content, account management, downloads, bookmarks, and AI help meet inside one desktop shell.

The current implementation targets Linux through webview_cef, with Android project files present and broader platform work tracked in the module backlog. Kruze is also a Koder app consumer of the shared Flutter SDK surface: KoderApp wraps the root app, engines/sdk/store provides update checks, and the app is moving remaining local cross-cutting behavior toward koder_kit.

Core capabilities

  • *abbed browsing*— multiple tabs, close/reopen, duplicate, reorder, pin,

    and keyboard shortcuts

  • *ddress bar*— URL normalization, search fallback, and preserved internal

    schemes such as koder://settings

  • *nternal pages*— settings, downloads, extensions, and history (koder://history) rendered in-app
  • *rivacy controls*— incognito history suppression, tracker-blocked

    navigation screen, and besteffort cookie/sitedata/cache cleanup on incognito exit

  • *ownloads*— direct-download detection, persisted history, destination

    preferences, progress state, and humanized HTTP failure handling

  • *ookmarks*— persisted bookmarks, folders, and a toggleable bookmark bar
  • *I panel*— Koder AI chat panel with file attachments and persisted panel

    placement, model, temperature, and pagecontext settings; optin *penAI-native contract*(preview, flag ai.openai_native_contract) that routes chat directly to ai-gateway via OpenAI-compat /v1/chat/completions and supports the MCP tool-use loop against userconfigured MCP servers (KMCP001 / KMCP-001.2)

  • *xtensions*— WebExtensionstyle contentscript matching and injection
  • *ccount sidebar*— Koder ID login state and account-management entry point
  • *rror registry*— KRUZE-* user-facing error IDs with copyable technical

    details for AI, download, and auth failures

  • *age zoom*— per-tab zoom (Ctrl++/−/0, range 25%–300%) via CSS; address bar zoom badge
  • *heme toggle*— Dark / Light / System from Settings → Appearance, persisted via SharedPreferences
  • *rowsing history*— koder://history with search and clear, date-grouped sections, opened via Ctrl+H
  • *I retry backoff*— chat requests retried up to 3× (0 s → 1 s → 3 s) before surfacing error
  • *elf-update check*— Koder Hub update prompt on startup
  • *idebar nav shortcuts*— Downloads, Extensions, History buttons in sidebar with active-page highlight and download badge
  • *avicon display*— tab bar and bookmark bar show each site's favicon via JS extraction + host cache (max 100 entries)
  • *ab session restore*— open tabs persisted to SharedPreferences and restored on next launch
  • *ookmark bar context menu*— right-click on bookmarks (EditDeleteOpen in new tab) and folders (Open allRenameDelete)
  • *xtension script cache*— in-memory cache (path → source) with eviction on toggle/uninstall
  • *xtension install UI*— "Install" button in Extensions screen opens folder picker
  • *I chat persistence*— last 200 chat messages survive restarts (incognito-aware, purged on account boundary)
  • *elemetry events*— KoderTrack emits tabnavigateaiauthdownload events to the koder_kit telemetry pipeline; host suppressed in incognito
  • *ddress-bar autocomplete*— overlay with up to 8 ranked matches (bookmarks first, then history) with full keyboard navigation
  • *xtension consent dialog*— folder install prompts with humanized permission list and "Broad access" badge before any files are copied
  • *ab audio mute*— context menu + clickable inline icon; JSbased mute (no native API in webview_cef 0.2.2) reapplied after navigations
  • *rint / Save as PDF*— Ctrl+P and tab-context entry trigger the OS print dialog (Save as PDF available there)
  • *ullpage PDF export*— addressbar button (also Ctrl+Alt+P) renders the entire scrollable content of the active tab to a PDF in ~/Documentos/ via the vendored webviewcef plugin's new printToPdf method (CefBrowserHost::PrintToPDF); `prefercsspagesizetrue, print_backgroundtrue`, A4 fallback, taggedPDF + document outline enabled (KRUZE160)
  • *ebug Mode*— addressbar bugreport toggle starts a session under ~/Documentos/Kruze Debug/<timestamp>/{images,videos,logs,replay}/ that records video of the tab content area; captures viewport screenshots on every onLoadEnd and on every click (cursor + element rectangle + selector label drawn onto click screenshots); tails every browser console message into logs/console.jsonl with sourcemapresolved stack frames for minified bundles; tails every CDP Network.* event into logs/network.jsonl and Network.webSocket* into logs/websocket.jsonl; snapshots cookies + localStorage + sessionStorage at startstop into `logsstorage{start,stop}.json`; runs MTR networkpath traces against the active host + 8.8.8.81.1.1.1google.com baselines into logs/network-path.jsonl; records tab title timeline + focusblur + activetabswitch into `logstabtimeline.jsonl`; generates perpixel visual diffs between repeat navigations to the same URL; emits a chromedp Go replay script that reproduces the captured action sequence; assembles a selfcontained index.html report with video player + interactive timeline + screenshot gallery; every screenshot ships with a white URL header strip at the top (KRUZE161163164); on stop, asks whether to open the folder in the file manager
  • *istory store*— sqflitebacked (10k cap, indexed, keysetpaginated), one-shot migration from the legacy SharedPreferences blob
  • *ddressbar autocomplete*consults the full sqflite history (not just the inmemory mirror), with a staleresult guard for inflight queries
  • *sync error reporting*— runZonedGuarded routes unhandled async errors through KoderTrack alongside the synchronous errors caught by KoderErrorBoundary
  • *ettings → Restore defaults*— flatten preferences (homepage / engine / theme / privacy) without touching data
  • *serdefined search engines*— OpenSearchstyle templates (%s placeholder) in addition to the built-in Koder / Google / Bing / DuckDuckGo
  • *ab hover preview*— 500 ms hover on a tab reveals a card with favicon + full title + URL (no real screenshot — webview_cef 0.2.2 has no snapshot API)
  • *losemanytabs confirmation*— "Close other tabs" / "Close tabs to the right" prompt with Close N tabs? when the action would close ≥ 3 tabs
  • *ettings exportimport*— versioned JSON document (homepage, engines, theme, blocked domains, AI panel layout); partial JSON applies only present sections; bookmarkshistory/auth deliberately excluded
  • *ookmark search*— koder://bookmarks page with a single search box and a flat list across all folders; bookmark bar gains a "Manage all bookmarks" entry-point
  • *hromium DevTools*— F12 and a tab-context entry call webview_cef.openDevTools()
  • *ddress-bar clear button*— small ✕ on the right when the field has focus and content
  • *erhost zoom memory*— host → zoom map (FIFO 200 entries, persisted) autoapplied on navigation; reset forgets the host
  • *indbar casesensitivity*— Aa toggle threaded through both window.find() and the match counter so the displayed count agrees with the highlight
  • *asteandgo*— Ctrl+Shift+V reads the clipboard and navigates after the address-bar normalization pipeline
  • *ookmark exportimport*— versioned JSON document on `koder:bookmarks`; additive merge, dedup by URLfolder id
  • *DF inline preview*— Settings → Downloads toggle (default on); .pdf URLs render in-tab via webview_cef's Chromium PDF viewer
  • *+" tab respects home page*— parity with Ctrl+T
  • *ll-tabs dropdown*— chevron between "+" and window controls lists every tab (favicon + title) for quick jumps once the strip overflows
  • *istory page pagination*— scroll past the 200entry inmemory cache loads more from sqflite in pages of 100
  • *11 fullscreen*— toggles windowManager.setFullScreen; Esc exits when no find bar is open
  • *inkhover status pill*— bottomleft pill shows the resolved URL of any link under the cursor (delegated JS listener over a kruzeLinkHover channel)
  • *iteinfo popover*— clicking the addressbar padlock opens a connection summary with a "Open DevTools" action
  • *age-load timing telemetry*— page.load event with elapsed ms and host (host suppressed in incognito)
  • *emote tracker blocklist*— https://cdn.koder.dev/kruze/blocklist.json (24h TTL); merged on top of the built-in default; falls back to cached/default when the CDN is unavailable
  • *I streaming responses*— /api/chat/stream SSE; placeholder message fills in tokenbytoken; falls back to legacy POST on 404
  • *xtension signature verification*— manifest koder_signature field; consent dialog and tile show verified / invalid / unsigned; no install path is blocked (CA still pending)
  • *ookmark sync via Koder ID*— https://api.koder.dev/kruze/bookmarks with localwins merge and a sync indicator in the bookmark bar (idle / syncing / error / offline); falls back to localonly when the endpoint is unavailable
  • *uick switcher (Ctrl+K)*— fuzzy palette over open tabs + bookmarks, fully keyboard-driven
  • *eading list*— readlater queue at `koder:/eadinglist` with sidebar entry (unread badge) and an address-bar toggle book icon
  • *orce dark on light pages*— Settings → Appearance toggle injects an inversion CSS filter; respects user's light theme choice
  • *ymmetric tab close + reload-all*— "Close tabs to the left", "Close tabs to the right", "Reload all tabs" in the tab context menu
  • *ookmark sorting*— Newest / Oldest / Alphabetical dropdown on koder://bookmarks

Primary couplings

Dependency Relationship
engines/sdk/koder_kit App shell through KoderApp; supplies shared Koder app behaviors such as theme, telemetry, error boundary, deep-link subscription, and IPC bootstrap
engines/sdk/store Startup update check through KoderHubUpdater.check(slug: appSlug, currentVersion: appVersion)
foundation/id OIDC authorizetokenuserinfo endpoints used by Kruze account login
ai/gateway AI chat provider posts browser-assistant messages to https://ai.koder.dev/api/chat

Interfaces

  • koder://settings — in-app settings page
  • koder://downloads — in-app downloads page
  • koder://extensions — in-app extension manager
  • koder://history — in-app browsing history
  • koder-kruze / Flutter package koder_kruze
  • Android package name: dev.koder.koder_kruze

Status

*1.0.5 (20260502)*— released. tenth /k-evolve pass added five product features (KRUZE95–KRUZE99): a quick switcher palette over Ctrl+K, a read-later queue at koder://reading-list with sidebar badge, a force-dark CSS filter toggle, symmetric closetabstotheleft + reloadalltabs, and sort-by NewestOldestAlphabetical on the bookmarks page. Local backlog is empty; the only remaining items are the corresponding backend tickets tracked in foundationid, aivoice, ai/gateway, infra/cdn.

*0260516 robustness + architecture wave (/k-go kruze)*

  • *RUZE143*— desktop CEF staleSingleton* symlinks (left by any

    non-clean exit at ~/.config/cef_user_data/) no longer block the next launch. A Linuxonly preflight removes the trio when the SingletonLock target points at a dead PID, and SIGTERM/SIGINT handlers wipe them on the way out. Per-app root_cache_path isolation tracked separately in KRUZE-145.

  • *RUZE-139*— shared providers (BookmarkProvider,

    ReadingListProvider) now persist through a KruzeStore interface with SharedPreferencesStore (production) and InMemoryStore (tests) backends. Theme tokens were already unified via koderTheme() in koder_kit. Extending the abstraction to the remaining shared providers is KRUZE-146.

  • *RUZE-140*— mobile InAppWebView honors two new global Privacy

    toggles ("Block notifications" / "Block geolocation requests", default OFF). When ON, the engine's onPermissionRequest returns DENY without showing the OS dialog; when OFF, returns PROMPT so the OS dialog asks normally. Desktop CEF parity is KRUZE-147.

  • *RUZE144 i18n full coverage (closed 202605-16)*— every

    user-facing string in the desktop variant goes through KoderL10n.t(key, fallback: ...) with enUS + ptBR coverage registered at boot. ~290 keys across 6 waves: sidebar + settings primary (Phase 1), AI panel + bookmark bar + reading list + findaddress bars (Phase 2), 5 internal `koder:/ pages including history/bookmarks/sessions/recently-closed/extensions plus downloads + settings core (Phase 3), search-engine modal + reporter + account flow + quick switcher + settings sub-dialog tail (Phase 4). KoderL10n.t doesn't yet support ICU params; placeholder strings use {name}/{n}/{file} patterns + inline .replaceAll()`. Mobile variant still uses fallback strings (full mobile i18n is variantlevel followup).

Test totals after the wave: 246 desktop + 35 mobile + 38 shared = 319, all green.

*0260516 privacy + parity wave (/k-go kruze)*

  • *RUZE-146*— KruzeStore now backs PrivacyProvider +

    BrowserSettingsProvider. The abstraction picked up setDouble / getDouble for defaultZoomLevel. AuthProvider left unchanged — documented inline as having no local persistence (delegated to koder_kit's KoderAuth).

  • *RUZE-147*— desktop notification + geolocation gates now respect

    the KRUZE-140 globals. New BrowserProvider.blockNotificationsGlobal / blockGeolocationGlobal mirror fields, plus pure-decision helpers shouldDenyNotificationsFor(host) / shouldDenyGeolocationFor(host) for testable twostage policy (global wins over perhost allow).

  • *RUZE148*mobile parity audit closed. *148.5*(recentlyclosed)

    shipped inline: app/mobile/lib/recently_closed.dart ring buffer + longpress on bottomnav + opens reopen bottom-sheet. *148.1*AI chat, *148.2*downloads (Android system DM + iOS in-app split), *148.3*extensions (content-script subset), *148.4*sessions spawned to pending/.

  • *RUZE-145*— vendor webview_cef for CefSettings.root_cache_path

    remains deferred. Detailed pre-vendoring checklist added to the ticket; needs cross-platform native rebuild (LinuxmacOSWindows CEF).

Test totals after the wave: 269 desktop + 42 mobile + 45 shared = 356, all green.

*0260516 mobile parity wave 2 (/k-go kruze)*

  • *RUZE-148.4*— SessionsProvider lifted to koder_kruze_shared

    (KruzeStore-backed). Desktop keeps the old import path via a oneliner reexport shim. Mobile gains a SessionsScreen (drawer entry) for listrestoredelete plus a longpresstab-card flow that prompts for a name and saves the current tab set.

  • *RUZE-148.1*— AiChatProvider lifted to koder_kruze_shared

    (KruzeStorebacked). Desktop reexport shim preserves all 8 existing AI chat tests. Mobile gains a minimal AiChatScreen (drawer entry) with user/assistant bubbles + TextField + send + clearwithconfirm. Attachments, model picker, temperature slider, and tablet bottom- sheet variant deferred — v1 just unblocks parity.

Test totals after the wave: 269 desktop + 48 mobile + 48 shared = 365, all green.

*0260516 web companion wave (/k-go kruze)*

  • *RUZE-135*— new app/web/ Flutter Web variant. PWA companion that

    surfaces bookmarks, reading list, and a subset of settings (theme, homepage readonly, default search engine readonly) without embedding a webview. 4 tabs (Home / Bookmarks / Reading list / Settings), responsive nav (NavigationRail ≥720px, bottom NavigationBar otherwise), Koder ID sign-in via KoderApp. Storage routes through KruzeStoreSharedPreferencesStore → browser localStorage. flutter build web --release ~34s, 4 widget tests. Vhost on kruze.koder.dev/companion is infra/net/jet#154. Cross- device sync depends on the asyetunbuilt cross-cutting sync SDK — companion is localtotab until then.

  • *uthProvider*— _auth switched from late final to nullable so

    widget tests can construct it without paying the network init. Production unchanged (init runs at boot).

Test totals after the wave: 269 desktop + 48 mobile + 48 shared + 4 web = 369, all green.

*0260517 mobile downloads (/k-go kruze)*

  • *RUZE-148.2*v1 — onDownloadStartRequest wired with

    useOnDownloadStart: true in the InAppWebView settings. The new pure helper handleDownloadRequest launches the URL via url_launcher in LaunchMode.externalApplication. Android hands off to Chrome (system DownloadManager native); iOS hands off to Safari (iOS download UI). No native code in v1. Tighter in-app experience (Android direct DM enqueue + iOS download bottom-sheet) tracked under #148.2.1. 4 mobile tests for the helper.

Test totals after the wave: 269 desktop + 52 mobile + 48 shared + 4 web = 373, all green.

*0260517 TV scaffold (/k-go kruze)*

  • *RUZE-137*v1 — app/tv/ TSReactVite scaffold mirroring Tune's

    stack. 5 screens (HomeBookmarksReading listHistorySettings) readonly because crossdevice sync hasn't shipped. D-pad nav via @noriginmedia/norigin-spatial-navigation. Forced dark theme. npm run build ~205 KB JS / ~67 KB gzip. 4 vitest tests. Tizen/WebOS packaging + real webview engine deferred to #137.1.

*0260517 Universal Links serverside (`/kgo kruze`)*

  • *RUZE141*serverside shipped in services/foundation/id. Two

    new .well-known/ handlers (apple-app-site-association for iOS Universal Links, assetlinks.json for Android App Links) live at id.koder.dev. Both env-var configurable, return 404 when unset (no app to claim deeplink ownership of yet). Multiapp support, content-type pinned to application/json, cache TTL 1h. 7 tests in the id repo. Client iOS (Associated Domains capability) + Android release key fingerprint tracked under #141.1, Mac-runner blocked. CHANGELOG entry in the id module.

Source: ../home/koder/dev/koder/meta/docs/stack/modules/koder-kruze.md