Commit graph

1774 commits

Author SHA1 Message Date
Gagan
9173097715 style(apps): subtler light-mode page background 2026-07-05 00:22:15 +05:30
Gagan
2d991dbfc7 feat(apps): more card background patterns 2026-07-05 00:20:21 +05:30
Gagan
810fd2da1a feat(apps): detail panel, skill trigger, analytics, real apps:get
- app detail panel (toolbar Info toggle): manifest info, capabilities,
  provenance/publish state, bundled agents with enable toggles + run-now,
  rollback affordance, README
- copilot instructions: apps-skill trigger line (build/make/create an app →
  load the apps skill first)
- analytics: app_created / app_deleted (main), app_opened (renderer)
- apps:get returns real readme + rollbackAvailable (.previous/ check)
2026-07-05 00:17:55 +05:30
Gagan
3e34cbe1af feat(apps): M2 host integration — tools, fetch proxy, LLM, copilot, bundled agents
- checkCapability choke point (D7): tools/llm/copilot access requires the
  capability in the app's manifest; 403 capability_not_declared otherwise
- POST /_rowboat/tools/search|execute: Composio pass-through with the same
  request shape as the builtin, typed error mapping
- POST /_rowboat/fetch: SSRF-guarded proxy (loopback/RFC1918/link-local/ULA/
  *.localhost rejection re-checked per redirect hop, 5MB cap + truncated flag,
  30s timeout, Host/Cookie stripped)
- POST /_rowboat/llm/generate: default-model plumbing, override validated
  against the allowed set, token/concurrency caps, usage attributed
  app_llm_generate/<folder>
- POST /_rowboat/copilot/run: headless run (bg-task tool profile, no shell),
  app-attributed audit turn with origin context, 10-min timeout, 1-per-app cap
- registered M2 routes are POST-only (GETs are D17-exempt and must not reach them)
- bundled agents (§8): strict AppAgentDefinitionSchema, deterministic
  app--<folder>--<name> slugs materialized disabled with sourceApp, manifest
  removals deactivate, app delete removes owned tasks; sourceApp in summaries
- new use cases app_llm_generate / app_copilot_run in runs + analytics enums
2026-07-04 18:16:43 +05:30
Gagan
c81739f9f7 fix(apps): bind IPv6 loopback too — blank apps in-app
macOS's resolver maps *.apps.localhost to ::1 only, so Electron's iframe
connects to [::1]:3210 while the server listened on 127.0.0.1 only —
connection refused, blank app, while external browsers succeeded via their
own IPv4 fallback. Listen on both loopback addresses (::1 best-effort for
IPv6-disabled machines).
2026-07-04 17:30:55 +05:30
Gagan
7f15f67273 feat(apps): Rowboat Apps M1 — per-app origins, Host API core, apps skill
Implements M1 of the Apps V1 spec, replacing the mini-apps prototype:

- rowboat-app.json manifest + AppSummary/install/publish/registry schemas;
  sourceApp on background tasks
- apps server on 127.0.0.1:3210 (absorbs local-sites): Host-header routing to
  <slug>.apps.localhost origins, 421 rebinding guard, static from dist/ with
  entry/SPA fallback + realpath confinement, control host /health, chokidar
  watcher + per-app SSE with dist/data areas, embed-opt-in autosize bootstrap
  and cancelable rowboat:data-change event
- Host API: D17 anti-CSRF (X-Rowboat-App + strict Origin on non-GET),
  GET /_rowboat/app (manifest + theme), /_rowboat/events, data API under
  data/ with atomic writes and dataContracts enforcement
- indexer: list (ok/invalid surfaced) / create scaffold / delete
- IPC: apps:list/get/create/delete/setTheme; renderer reports theme live
- renderer: Apps home (My apps grid + catalog placeholder, server banner,
  invalid/kind badges) and full-height app view on the app origin
- apps copilot skill (replaces build-mini-app); app-set-data builtin replaces
  mini-app-install/set-data; deleted the app://miniapp protocol, postMessage
  bridge, mini-apps handler/channels, and local-sites
2026-07-04 17:12:54 +05:30
Gagan
2c038fe518 feat(mini-apps): live data refresh + install reliability
- watch ~/.rowboat/apps: data.json changes push into open apps (shim
  re-fetches, onData fires); installs/updates re-list the gallery live and
  reload an open app once the write settles
- atomic installs (temp->rename) so an app opened mid-install never reads a
  partial file
- serve app assets by direct disk read instead of net.fetch(file://) —
  Chromium's network service could stall and blank every open app at once
2026-07-04 15:59:13 +05:30
Gagan
b548173593 feat(mini-apps): capable models for app bg-tasks
- list-models tool: returns allowed model IDs (gateway for signed-in, config
  for BYOK) + a safe defaultModel, so the copilot picks a valid capable model
  instead of guessing rejected IDs
- patch-background-task: clearModel option to reset a bad model/provider
  override (falls back to default); patchTask can now delete fields
- build-mini-app skill: use list-models + set a capable model on data tasks
2026-07-02 02:31:00 +05:30
Gagan
61f2bcff5a feat(mini-apps): New-app prefill + light/dark theme for apps
- New app card opens the chat sidebar and pre-fills (not sends) a
  'Build me a mini-app that ' prompt via the presetMessage path
- Push host theme to apps over the bridge: shim applies html.dark/.light +
  color-scheme and exposes getTheme/onTheme; host observes theme changes live
- build-mini-app skill: generated apps must style both light and dark
2026-07-02 02:17:33 +05:30
Gagan
c424976926 fix(mini-apps): reliability fixes + self-contained data loading
From two rounds of copilot build feedback:

- runtime: null-check hallucinated tool names (was crashing the whole run)
- add window.rowboat.fetch + builtin fetch-url: CORS-safe HTTP for UI and
  bg-task agents (no shell needed for plain HTTP)
- mini-app-set-data/install: reject stringified JSON; require object
- manifest dataContract (requiredKeys/nonEmptyArrayKeys) enforced on writes so
  a stray/legacy task can't corrupt an app's data or wipe series
- self-contained data: data.json is a served sibling (dist/), apps fetch it via
  relative URL; removed host-side data injection
- build-mini-app skill: CORS/fetch-url/no-shell/capable-model/dataContract gotchas
2026-07-02 01:06:05 +05:30
Gagan
6d7fd7b013 feat(mini-apps): open built app in middle pane from chat
After the copilot builds + verifies + populates an app, it opens it in the
middle pane under Mini Apps / <title>, with an 'Opened <app>' card in chat.

- app-navigation: new open-app action (reads manifest title)
- renderer: pending-nav opens the Mini Apps view with the app pre-selected;
  MiniAppsView accepts initialAppId/initialVersion
- chat: open-app app-action card labels
- build-mini-app skill: finalize step opens the app once data is populated
2026-07-01 02:12:05 +05:30
Gagan
4a4dcb1fa0 feat(mini-apps): copilot builder — build-mini-app skill + install/data tools
Lets the copilot build a Mini App into ~/.rowboat/apps from chat.

- build-mini-app skill: intent gate (confirm when ambiguous), verify Composio
  wiring by actually calling tools before building, writer branch (Code Mode
  via code-with-agents vs Copilot), agent-backed data pipeline, install
- mini-app-install tool: write an app folder (manifest + dist/index.html)
- mini-app-set-data tool: atomic deterministic data.json write (agent returns
  content; path/write handled in code)
- serve canonical bridge shim at app://miniapp/__bridge__.js
2026-07-01 01:25:45 +05:30
Gagan
924a93fa4a feat(mini-apps): serve apps from ~/.rowboat/apps via app://miniapp
Apps are now user data on disk, not bundled in the repo.

- MiniAppManifest schema + mini-apps:list/get-data/seed IPC channels
- main: mini-apps-handler (list/get-data + seed install primitive) and an
  app://miniapp/<id>/ protocol host serving ~/.rowboat/apps/<id>/dist
- renderer lists installed apps from disk and loads each via app://miniapp
  (real origin: remote images/fetch work); data sourced from data.json
- removed the bundled sample apps from source (they live in ~/.rowboat/apps)
2026-07-01 00:27:00 +05:30
Gagan
6cbf40b165 feat(mini-apps): refine card accent palette
- Assign card accents by grid position (adjacent cards differ)
- Add premium red + pink; drop blue/indigo/ocean purples
2026-06-30 01:28:00 +05:30
Gagan
30a46178d1 feat(mini-apps): real scoped Composio bridge + GitHub Dashboard
Phase 2 makes the Mini App bridge real instead of stubbed.

- New composio:execute-tool and composio:search-tools IPC channels
  (shared schema + main handlers reusing the agent's execute path)
- Bridge refactored to a scoped RPC: callAction/searchTools/isConnected/
  connect, enforced against each app's declared scope at the host
- Auth prompt: acting on a disconnected toolkit triggers Composio OAuth
- GitHub Dashboard sample: track repos, view their 20 most-recent open PRs
  with descriptions, plus the authenticated user's profile + contribution
  graph — all live via the bridge
- Twitter sample reverted to a local UI demo (X has no managed OAuth2)
2026-06-30 01:17:38 +05:30
Gagan
7acbf67cd4 feat(mini-apps): add Mini Apps section with sandboxed app runtime
Phase 1 of Mini Apps: a new sidebar section that renders user apps as
premium tiles and opens each in a sandboxed iframe.

- New first-class 'apps' view wired through App.tsx (mirrors bg-tasks)
- 'Mini Apps' sidebar entry
- MiniAppFrame: sandboxed iframe host + window.rowboat bridge
  (getData/onData, getState/setState, scoped callAction; actions stubbed)
- Self-contained vanilla apps (no CDN) so they render offline in the frame
- Sample apps: Twitter (X-style feed + topic filters), Newsletter Digest,
  Competitor Watch
- Premium card gallery: accent themes, decorative patterns, ambient glow,
  light/dark support
2026-06-30 00:30:29 +05:30
Arjun
753e3448f0 Show previous chats related to the workspace in the workspace section. 2026-06-29 12:27:43 +05:30
Arjun
0887ee7fc0 ability to add note to workspace 2026-06-27 13:28:56 +05:30
hrsvrn
4a26bc9d80 feat(email): faster inbox load, Ctrl+Tab tab cycling, square preset buttons
- Inbox load: add an mtime-keyed in-memory cache to listInboxPage so it no
  longer re-reads and JSON.parses every cached thread (bodies included) on
  every call — only files whose mtime changed are re-parsed. Speeds up the
  Important→Everything-else handoff, live reloads during sync, and re-opening
  the inbox tab.
- Add Ctrl+Tab / Ctrl+Shift+Tab to cycle to the next/previous tab (wraps
  around), alongside the existing Cmd+Shift+] / [ shortcuts.
- Improve bar: make the tone preset buttons square (rounded-md), left-aligned,
  with a bit of vertical gap so wrapped rows aren't cramped.
2026-06-26 15:51:04 +05:30
hrsvrn
824610f84f feat(email): restyle inbox, composer & reply to the Rowboat design system
- Inbox (gmail-shell): map the bespoke --gm-* palette onto the app design
  tokens (background/foreground/border/accent/primary), drop the unloaded
  "Inter" font override so it inherits the app font, and remove the redundant
  ".light .gmail-shell" block so theming follows :root/.dark.
- Composer: rebuilt on the shadcn Button/Input/Dialog primitives with app
  tokens; bring the AI describe-and-write bar and tone presets into reply mode.
- Auto-generated reply block (editor.css): retokenize the Gmail-blue pill
  buttons and compose surface onto app tokens; inherit the editor font.
- Add a Gmail-style "n" shortcut to open the composer from the inbox.
2026-06-26 15:51:04 +05:30
Harshvardhan Vatsa
40d684684c
feat(electron): add Cmd/Ctrl +/-/0 zoom shortcuts for the renderer (#646)
The app sets no application menu, so it relied on Electron's default menu
for the zoom accelerators — and on Linux that menu bar is suppressed by the
frameless `hiddenInset` title bar, leaving the shortcuts unhandled. Wire
them directly via `before-input-event`: Cmd/Ctrl + (+/=) zooms in,
(-/_) zooms out, and 0 resets, clamped to zoom levels -3..3.
`event.preventDefault()` stops the keystroke from leaking into the editor.
2026-06-26 14:40:34 +05:30
Harshvardhan Vatsa
41a6a8f519
Merge pull request #639 from hrsvrn/fix/compose-dark-mode
fix: respect dark mode in email compose/reply UI
2026-06-25 15:02:28 +05:30
arkml
a6572689b2
Update Readme (#644) 2026-06-24 23:47:13 +05:30
gagan
6dbaa618e7
feat(onboarding): add Code Mode setup step (#643)
* feat(onboarding): add Code Mode setup step

Adds a new onboarding step (3, between Connect and Done; Completion moves
to 4) shown in both Rowboat and BYOK paths. It informs the user up front
that Code Mode needs Claude Code and/or Codex installed and signed in
locally (claude login / codex login), then offers a master 'Enable code
mode' toggle that reveals per-agent toggles.

Downloads do NOT block onboarding: on Continue, selected-but-not-yet-
installed engines are provisioned fire-and-forget in the main process,
and their live % surfaces in Settings -> Code Mode. Approval policy is
left at the default ('ask'); users adjust it later in Settings. The step
is skippable like Connect Accounts.

To make an onboarding-started download show its progress in Settings, the
module-level provisioning store (startProvisioning/useProvisioning) is
lifted out of settings-dialog.tsx into lib/code-mode-provisioning.ts and
shared by both.

* feat(onboarding): simplify Code Mode agent rows and refine copy

- Show just the agent name (Claude Code / Codex) with a toggle and a
  green check when ready; drop the per-row download/sign-in clutter
- Value-led description: use your existing Claude Code or Codex
  subscription inside Rowboat, signed in locally via the terminal
2026-06-24 17:30:34 +05:30
gagan
8b76c54295
fix(byok): decouple chat model picker from config.models (#642)
* fix(onboarding): BYOK saved entire model catalog as assistant models

testAndSaveActiveProvider persisted the provider's full fetched catalog
into config.models. That field is the user's curated assistant-model
list (rendered as one row per entry in Settings > Models), so every
available model showed up as a separate assistant-model dropdown. Seed
it with just the selected model; users add more from Settings.

* feat(byok): decouple chat model picker from config.models

BYOK config.models was doing double duty: it both seeded the in-chat
model picker AND was rendered as a per-entry dropdown stack in Settings.
That coupling forced a tradeoff between a clean Settings UI and full
model choice in chat, and baked a stale catalog snapshot into config.

Decouple them so BYOK matches the signed-in experience:
- Chat picker (signed-out) now lists the full live provider catalog from
  models:list, filtered to providers the user has a key/baseURL for, with
  the saved default model leading. No longer limited to config.models, so
  newly released models appear without re-saving.
- Settings assistant model collapses to a single default-model dropdown
  (removed the .map() stack + add/remove). config.models is now just the
  one default; save/load/delete logic is unchanged.
2026-06-24 16:33:40 +05:30
gagan
caa80f7c07
fix(onboarding): inline completion checkmark & widen indicator gap (#641)
- Remove the circular background and pulsing ring behind the completion
  checkmark; place the tick inline to the right of the "You're All Set!"
  heading
- Increase spacing between the step indicator and step content
2026-06-24 15:42:31 +05:30
gagan
aa347c9047
fix(onboarding): center step connector line & refresh welcome layout (#640)
* fix(onboarding): center step connector line with circles

The connector line was vertically centered against the circle+label
column, landing below the circle's center. Absolutely position the
label below the circle so the row height equals just the circle and
items-center aligns the line to the circle's center.

* feat(onboarding): refresh welcome layout & indicator spacing

- Place logo inline to the right of the Welcome heading
- Move the tagline badge below the heading with more breathing room
- Add space between the step indicator and step content
2026-06-24 15:35:22 +05:30
Arjun
7e1acedfcf remove recents from new chat 2026-06-24 12:01:10 +05:30
hrsvrn
0d069e8148 fix: respect dark mode in email compose/reply UI
The compose modal/card hardcoded light-mode CSS variables unconditionally
(introduced in 851c3be6 "gmail contacts should use light mode"), overriding
the theme variables inherited from .gmail-shell. As a result the reply/compose
box rendered as a white card with dark text even in dark mode.

Split the single hardcoded block into theme-aware blocks following the existing
.gmail-shell convention: dark values as the unprefixed default, light values
under `.light`. Light mode is unchanged; dark mode now gets a proper dark card.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 01:51:48 +05:30
PRAKHAR PANDEY
1bfda94f48
fix: suppress notification spam on app re-open (#623)
* fix: suppress notification spam on app re-open

- Add background_task notification category (default ON) so users can
  toggle off background-task pings via Settings → Notifications
- Route notify-user builtin through notifyIfEnabled gate so the
  category toggle takes effect
- Add 60s startup grace period: background-task notifications fired
  within 60s of launch are suppressed, killing the reopen flood where
  all queued agents complete at once
- Suppress new_email notifications for emails older than 5 min so
  Gmail's startup backlog replay doesn't surface day-old mail

Fixes both issues reported by Ramnique.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix: skip automatic chat_completion ping for background task agents

Background task runs were triggering "Response ready / Your agent
finished responding" on every completion. Skip the automatic
chat_completion notification when finalState.runUseCase ===
'background_task_agent' — background tasks notify explicitly via
notify-user when they have something worth surfacing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix: correct notification deeplinks and skip internal agent pings

- runtime.ts: also skip chat_completion ping for knowledge_sync
  useCase (agent_notes_agent was opening notes view on click)
- sync_gmail.ts: new_email notification now links to specific
  email thread (rowboat://open?type=email&threadId=...)
- App.tsx: add email case to parseDeepLink, parse threadId param,
  wire threadId through applyViewState, update viewStatesEqual

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix: distinguish background-agent notifications from auto knowledge-sync

Per team clarification, two background types are handled differently:
- knowledge_sync (auto knowledge-graph generation): never notifies;
  skips the generic chat_completion ping entirely.
- background_task_agent (user-configured agents): notifies via its
  own notify-user path, gated behind the toggleable "Background
  agents" category, deep-linking to the background-tasks page.

- runtime.ts: skip the generic chat_completion completion ping for
  both knowledge_sync and background_task_agent (the latter notifies
  via notify-user, so the generic ping would duplicate it).
- builtin-tools.ts: notify-user branches on getCurrentUseCase() —
  background agents route through notifyIfEnabled('background_task')
  with a bg-tasks deeplink default; chat agents notify directly.
- App.tsx: add the bg-tasks deeplink target (ViewState, parseDeepLink,
  applyViewState, currentViewState).
- settings-dialog.tsx: rename the category label to "Background agents".
- runner.ts: wrap the background-task run in withUseCase so tools see
  the correct use-case context.

* fix: route coding-session notifications through notifyIfEnabled

Code-mode status-tracker was calling notificationService.notify() directly,
bypassing the user's notification-category toggles. Routed both calls
through notifyIfEnabled() with correct categories:
- needs-you state → agent_permission
- idle after 30s  → chat_completion

Removed now-redundant container/INotificationService plumbing.

* fix: fall back to persisted run useCase when ALS context is missing in notify-user

AsyncLocalStorage does not propagate across the background-task agent's
async generator — getCurrentUseCase() returns undefined inside notify-user,
causing the background_task_agent branch to be skipped and the Background
agents toggle to be ignored.

Fix: load persisted useCase from run record via fetchRun(ctx.runId) when
ALS is falsy. Lazy dynamic import() avoids the known module-init cycle.
Background-agent notifications now correctly respect the toggle and only
fire when the app is in the background, with deep link to the bg-tasks page.

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 01:36:06 +05:30
Harshvardhan Vatsa
c0b38d46d3
Fix/GitHub workflow (#638)
* fixed workflow

* fix(forge): hoist staged ACP node_modules to stay under Windows MAX_PATH

The Squirrel/nuget Windows maker failed with 'path too long': stageAcpAdapters
rebuilt the ACP dependency closure by always nesting each dep under its parent,
producing 5-level chains (codex-acp -> open -> wsl-utils -> is-wsl ->
is-inside-container -> is-docker) whose paths hit ~260 chars on the CI runner and
blew past Windows' MAX_PATH (nuget.exe ignores long-path settings).

Hoist every package to the top-level node_modules npm-style, nesting only on a
genuine version conflict. Deepest staged path drops 177 -> 114 chars (worst-case
CI absolute ~197, well under 260). Add verifyAcpStaging() which asserts every
dependency edge resolves, in the staged tree, to the same version as the source
pnpm tree, failing the build loudly instead of shipping a broken installer.
2026-06-23 23:25:19 +05:30
PRAKHAR PANDEY
812ed9222c
Merge pull request #633 from prakhar1605/fix/filter-chat-models
Filter non-chat models from BYOK model picker
2026-06-23 18:18:00 +05:30
gagan
6ba6f494c1
fix(google-docs): move Add Google Doc into Knowledge Quick actions (#635)
Place the action in the files-view "Quick actions" row (next to New note)
instead of the header, where it sat after the dev↔drive merge. Widen
QuickAction's icon type to accept the custom GoogleDriveIcon component.
2026-06-23 03:20:17 +05:30
arkml
be81ffb27b
Drive (#583)
* add drive sync up and down

* add drive button

* google doc icon

* icon changes

* show error state with retry in google doc picker

* feat(google-docs): import and sync down as Markdown, record remote revision

* feat(google-docs): structure-preserving sync up with remote-conflict guard

* feat(google-docs): overwrite-confirm on sync conflict and last-synced indicator

* feat(google-docs): store linked docs as .docx, edit in docx editor, sync via Drive

* feat(google-docs): offer BYOK connect in picker so signed-in users can grant Drive/Docs scopes

* fix(google-docs): request full drive scope so .docx sync-up can write back

* fix(google-docs): search all drives in doc picker, log result count

* feat(google-docs): import native Docs AND uploaded .docx files from Drive

* chore(google-docs): drop dev-only test file

* feat(google-docs): use Google Picker + drive.file scope instead of full-drive listing

* fix(google-oauth): request offline access so BYOK tokens refresh

BYOK never requested access_type=offline/prompt=consent so no refresh token was issued and tokens died after ~1h; also stop handing back expired tokens and extend the connect timeout to 10m.

* feat(google-docs): pick docs via system-browser Google Picker

Runs the Picker in the user's real browser (it 403s inside Electron), sets appId so the drive.file grant attaches to the picked file, and downloads + opens the selected doc.

* feat(google-docs): managed OAuth-redirect Picker (no API key, no BYOK) (#620)

* feat(google-docs): managed OAuth-redirect Picker (no API key, no BYOK)

Adds the managed (rowboat-mode) Google Docs picker via Google's trigger_onepick
flow. The Rowboat backend runs a standalone drive.file OAuth with the company
client, renders the Picker inside the browser consent screen, and deep-links the
selection back; the desktop downloads the picked doc with the fresh drive.file
token the backend returns. No Picker API key, appId, or BYOK credentials on the
desktop.

- core: importGoogleDocWithToken downloads a picked doc with an explicit token;
  fetch/metadata helpers take an optional Drive client and share writeDocxAndLink.
  claimPickedFilesViaBackend claims the parked file ids + token from the api.
- main: google-picker-managed.ts opens the backend start URL and resolves on the
  rowboat://oauth/google/picker/done deep link; deeplink.ts routes that completion.
- ipc: google-docs:pickViaManaged.
- renderer: the picker dialog gates on Rowboat sign-in (the picker grants
  drive.file per-file, so no pre-existing connection or scope is required).

Backend contract: rowboatlabs/rowboatx-backend#7
(GET /oauth/google/picker/{start,callback}, POST /v1/google-oauth/claim-picked).

* chore(google-docs): remove the dead API-key/system-browser Picker

The managed picker replaced the only consumer (the picker dialog), so the
experimental API-key Picker is now unused. Removes:
- main: google-docs:openPicker handler (system-browser loopback Picker)
- shared: google-docs:openPicker + google-docs:getAccessToken IPC schemas
- core: getGoogleAccessToken (token plumbing for the client-side Picker)
- renderer: lib/google-picker.ts (Picker JS SDK loader)

Kept GoogleClientIdModal / google-credentials-store — still used by the
general BYOK Google connect in onboarding, connectors, and settings.

---------

Co-authored-by: Gagancreates <gaganp000999@gmail.com>
2026-06-23 03:13:58 +05:30
gagan
a12bf4837b
feat(voice): audio-reactive waveform while recording (no live transcript) (#634)
* feat(voice): show audio-reactive waveform instead of live transcript

When recording, the chat input now displays only a live waveform that
accumulates from the left and grows to full width, with bar heights
driven by real mic amplitude. The transcribed words are still captured
and submitted, just not shown while recording. New bars animate in and
flow smoothly at ~16 updates/sec.

* feat(voice): auto-gain waveform bar heights to track voice dynamics

Normalize each frame's amplitude against a running peak (instant attack,
slow release) at capture time and map it with a near-linear curve, so bar
heights accurately reflect how loud/soft the voice is regardless of mic
gain — replacing the old fixed-gain sqrt curve that saturated near max.
2026-06-23 02:40:56 +05:30
Arjun
de7d6b7a10 assistant notes below each note 2026-06-22 22:35:54 +05:30
Prakhar Pandey
1368d84bac fix(onboarding): filter non-chat models from provider list using models.dev 2026-06-22 12:49:48 +05:30
PRAKHAR PANDEY
6040c54807
Merge pull request #631 from prakhar1605/feat/byok-multiple-keys
Feat/Add multiple provider keys in BYOK onboarding (task 5)
2026-06-22 12:09:05 +05:30
Prakhar Pandey
30373765e7 Merge remote-tracking branch 'upstream/dev' into feat/byok-multiple-keys 2026-06-22 12:03:40 +05:30
PRAKHAR PANDEY
51ca8778b5
Merge pull request #629 from prakhar1605/feat/byok-onboarding-simplify
Simplify BYOK onboarding to provider + key (tasks 4 & 6)
2026-06-22 11:59:55 +05:30
gagan
45188e7c1c
feat(code-mode): per-session model + effort, and keep output on nav (#632)
Two improvements to the Code section:

- Fix: leaving the Code section and returning no longer drops the open
  session's output. The selected session id is persisted to localStorage
  (mirroring the terminal-height pattern) and restored on remount, so the
  right-hand chat pane re-binds instead of falling back to the empty state.

- Feature: choose the coding agent's model and reasoning effort per session.
  Choices are discovered live from the engine (the same list `/model` shows)
  via a new `codeMode:listModelOptions` IPC, cached per agent — never
  hardcoded, so they track whatever the provider currently offers. Claude
  exposes model + effort as separate axes (with explicit Opus/Sonnet/Haiku
  alias rows surfaced for clarity); Codex folds effort into the model id and
  reports no separate effort. Selections persist on the CodeSession and are
  re-applied to the ACP session each turn (best-effort), editable from both
  the new-session dialog and the session header.
2026-06-21 21:08:49 +05:30
Arjun
c8d801a123 add toolkits to the new chat for ease of discovery 2026-06-20 03:02:41 +05:30
Arjun
a0429fc037 email reply all and first name signoff 2026-06-20 02:32:08 +05:30
Arjun
f848d235d8 fix file diffs 2026-06-20 00:02:29 +05:30
Ramnique Singh
f65f7e8fc8 feat(billing): consume plan variant catalog
Fetch the public billing catalog during account config load and use durable plan IDs from /v1/me for display, analytics, and upgrade/manage labels.

Renderer billing surfaces now resolve plan display data from the catalog and show Unknown when the backend returns an unmapped plan ID.
2026-06-19 16:52:22 +05:30
Arjun
aa8dfb74ad minor ui fixes and default model to claude 2026-06-19 16:24:29 +05:30
Arjun
dfd4075e0e filter out random contacts 2026-06-19 14:59:45 +05:30
Arjun
851c3be69f gmail contacts should use light mode 2026-06-19 14:45:21 +05:30
Prakhar Pandey
2fb0e7402a feat(onboarding): allow adding multiple provider keys in BYOK 2026-06-19 12:47:35 +05:30
Arjun
811ae22bb1 knowledge to brain 2026-06-19 11:59:56 +05:30