Commit graph

214 commits

Author SHA1 Message Date
gagan
0e3d058c29
feat: Gmail-style email block with inbox container layout (#531)
* feat: restyle email block with Gmail-style layout and avatar

* style: apply Google Sans/Roboto font to email block

* feat: add Gmail inbox-style multi-email block with accordion rows

* style: fix sender name casing, weight, and email display in expanded view

* feat: emails inbox block with container layout, two-line rows, Gmail title style
2026-05-06 21:41:26 +05:30
gagan
3630032d21
feat/today-minimal-polish (#532)
* feat: remove emoji headings and polish track block chip styling

- Strip emojis from Today.md section headings (new + existing files via migration)
- Track chip: full-width card style matching email blocks, colored icons per track type
- Larger, taller chip with muted gray background for light/dark mode

* feat: increase track chip icon and text size

* feat: make track block icons configurable via yaml

* fix: migrate missing icon fields in existing Today.md on startup
2026-05-06 19:41:28 +05:30
gagan
0bb58e55ac
feat: minimal Today.md UI polish - no emoji headings, better track chip (#528)
* feat: remove emoji headings and polish track block chip styling

- Strip emojis from Today.md section headings (new + existing files via migration)
- Track chip: full-width card style matching email blocks, colored icons per track type
- Larger, taller chip with muted gray background for light/dark mode

* feat: increase track chip icon and text size

* feat: make track block icons configurable via yaml
2026-05-06 14:34:53 +05:30
Arjun
5e47bd4309 fix shell path issue on mac 2026-05-06 13:02:01 +05:30
arkml
72ed4bd6d9
pull browser-harness skills (#519)
use browser-harness skill without eval or http-fetch
2026-05-06 12:25:10 +05:30
arkml
e54b5cd27f
Background agents (#530)
a common place to track and add background agents
2026-05-06 11:59:37 +05:30
Arjun
7b119fbfcd refine note-writing instructions for self-reference and relationship phrasing 2026-05-05 19:56:57 +05:30
Arjun
c6083de054 show errors in activity tab for knowledge graph 2026-05-05 19:21:32 +05:30
Arjun
c382e3ee8a use gemini as default kg model 2026-05-05 16:08:57 +05:30
Ramnique Singh
d4850dace7 feat: native google sign-in for signed-in users
Signed-in users can now connect Gmail and Calendar directly through
Rowboat instead of going through Composio. Cleaner connection, no
third-party in the data path.

How it works:
- Click "Connect Google" anywhere it appears (sidebar, onboarding,
  settings) and the system browser opens to a Rowboat-hosted page.
  Authorize Google there and the app picks up the connection
  automatically — no client id or secret to paste.
- Token refresh happens through Rowboat's backend, so Google
  credentials never need to live on the user's machine.
- Disconnect cleanly revokes access on Google's side too.

Migration for existing Composio users:
- A one-time modal explains that we've moved off Composio and asks the
  user to reconnect Google directly.
- Their old Composio Gmail / Calendar connections are disconnected
  automatically when the modal first appears.
- All previously-synced emails and calendar events are preserved on
  disk — the new connection picks up where Composio left off rather
  than re-downloading the last week from scratch.
- "I'll do this later" dismisses the modal permanently; the user can
  still reconnect anytime via the connectors UI. (Sync stops in the
  meantime; nothing is deleted.)

Other coverage:
- BYOK mode (users who paste their own Google client id + secret) is
  unchanged — same modal, same local OAuth flow, same behavior.
- Composio integrations for non-Google services (Slack, Linear, etc.)
  are unaffected. Only the Gmail and Calendar paths moved.
- The "Connect Google" button label and connection state now apply
  uniformly to Gmail + Calendar (one OAuth grant covers both).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 14:29:13 +05:30
arkml
1c2b2ac1fc
feat: native desktop notifications + rowboat:// deep links
Adds INotificationService with an Electron implementation, plus a deep-link
dispatcher (rowboat://) for routing notification clicks back into the app.

Notifications:
- New `notify-user` skill + builtin tool. Title, message, optional primary
    link, optional secondary actions. Supports https:// (opens in browser) and
    rowboat:// (opens in app) targets.
- ElectronNotificationService holds strong refs to active Notification
    instances so click handlers survive GC (otherwise macOS click silently
    no-ops).
- Calendar meeting notifier fires 1-min warnings with "take notes" /
    "join + take notes" actions backed by deep links.

Deep links (rowboat://):
- forge.config.cjs declares the protocol; main.ts wires single-instance
    lock, setAsDefaultProtocolClient, open-url (mac), second-instance (win/
    linux), and first-launch argv extraction.
- New deeplink.ts dispatcher with dispatchUrl(url): main-handled actions
    (rowboat://action?type=...) vs renderer navigation (rowboat://open?...)
    via app:openUrl IPC. Includes pending-URL buffering for first-launch
    delivery before the renderer is ready.
- Renderer parseDeepLink supports file / chat / graph / task /
    suggested-topics targets.
- New app:consumePendingDeepLink IPC for renderer one-time drain on mount.

Refactor: extractConferenceLink moved out of calendar-block.tsx into
shared lib/calendar-event.ts (used by both the block and the take-notes
deep-link handler)
2026-05-04 15:47:30 +05:30
Ramnique Singh
de176ec458 identify signed-in users on every app startup
Previously identify() only fired during the OAuth completion flow, so
existing installs (signed in before analytics shipped) and every cold
start of v0.3.4+ would emit main-process events under the anonymous
installation_id until the user happened to re-sign-in.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 20:21:37 +05:30
Ramnique Singh
43c1ba719f add posthog analytics for llm usage and auth events
Captures per-LLM-call token usage tagged by feature (copilot chat,
track block, meeting note, knowledge sync), plus sign-in / sign-out
and identity. Renderer and main share one PostHog identity so events
from either process resolve to the same user.

See apps/x/ANALYTICS.md for the event catalog, person properties,
use-case taxonomy, and how to add new events.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 19:53:40 +05:30
Ramnique Singh
d42fb26bcc allow per-track model + provider overrides
Track block YAML gains optional `model` and `provider` fields. When set,
the track runner passes them through to `createRun` so this specific
track runs on the chosen model/provider; when unset the global default
flows through (`getTrackBlockModel()` + the resolved provider).

The track skill picks up the new fields automatically via the embedded
`z.toJSONSchema(TrackBlockSchema)` and adds an explicit "Do Not Set"
section: copilot leaves them omitted unless the user named a specific
model or provider for the track. Common bad reasons ("might be faster",
"in case it matters", complex instruction) are called out so the
defaults stay the path of least resistance.

Track modal Details tab shows the values when set, in the same
conditional `<dt>/<dd>` style as the lastRun fields.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 16:58:18 +05:30
Ramnique Singh
caf00fae0c configurable kg / meeting / track-block model overrides
Bring back per-category model selection that 5c4aa772 dropped, plus add a
new track-block category. Each is a BYOK-only override on `LlmModelConfig`
(`knowledgeGraphModel`, `meetingNotesModel`, `trackBlockModel`); signed-in
users always get the curated gateway default and never hit the on-disk
config.

Three helpers in core/models/defaults.ts — `getKgModel`,
`getTrackBlockModel`, `getMeetingNotesModel` — each check `isSignedIn`
first (fast path) and fall through to `cfg.<field> ?? cfg.model` for BYOK.

The model is now picked at the invocation site rather than via runtime
agent-name branching: each top-level `createRun` for a polling KG agent
or a track-block update passes `model: await getXxxModel()`. The `model:`
declarations on the affected agent YAMLs are dropped — they were dead
code under the per-call override. Standalone (non-run) callers
`track/routing` and `summarize_meeting` use the helpers inline.

Settings dialog and the two onboarding flows surface the two new fields
("Meeting Notes Model", "Track Block Model") next to the existing
"Knowledge Graph Model"; `repo.setConfig` persists all three per-provider.

Note: the signed-in `RowboatModelSettings` panel still has its
now-defunct kg selector; that's a UI cleanup for a later pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 16:44:02 +05:30
Ramnique Singh
bdf270b7a1 convert Today.md track blocks to event-driven and batch Gmail sync events
Removes polling schedules from the up-next and calendar track blocks on
Today.md so they refresh only on calendar.synced events, and rewrites
the emails track instruction to consume a multi-thread digest payload.
Batches Gmail sync so one email.synced event covers a whole sync run
(capped at 10 threads per digest) instead of one event per thread,
which collapses Pass 1 routing calls for multi-thread syncs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 11:15:56 +05:30
Arjun
f4dbb58a77 add rowboat meeting notes to graph 2026-04-23 00:35:08 +05:30
Ramnique Singh
5c4aa77255 freeze model + provider per run at creation time
The model dropdown was broken in two ways: it wrote to ~/.rowboat/config/models.json
(the BYOK creds file, stamped with a fake `flavor: 'openrouter'` to satisfy zod
when signed in), and the runtime ignored that write entirely for signed-in users
because `streamAgent` hard-coded `gpt-5.4`. Model selection was also globally
scoped, so every chat shared one brain.

This change moves model + provider out of the global config and onto the run
itself, resolved once at runs:create and frozen for the run's lifetime.

## Resolution

`runsCore.createRun` resolves per-field, falling through:

  run.model    = opts.model    ?? agent.model    ?? defaults.model
  run.provider = opts.provider ?? agent.provider ?? defaults.provider

A new `core/models/defaults.ts` is the only place in the codebase that branches
on signed-in state. `getDefaultModelAndProvider()` returns name strings;
`resolveProviderConfig(name)` does the name → full LlmProvider lookup at
runtime. `createProvider` learns about `flavor: 'rowboat'` so the gateway is
just another flavor.

`provider` is stored as a name (e.g. `"rowboat"`, `"openai"`), not a full
LlmProvider object. API keys never get written into the JSONL log; rotating a
key in models.json applies to existing runs without re-creation. Cost: deleting
a provider from settings breaks runs that referenced it (clear error surfaced
via `resolveProviderConfig`).

## Runtime

`streamAgent` no longer resolves anything — it reads `state.runModel` /
`state.runProvider`, looks up the provider config, instantiates. Subflows
inherit the parent run's pair, so KG / inline-task subagents run on whatever
the main run resolved to at creation. The `knowledgeGraphAgents` array,
`isKgAgent`, and the per-agent default constants are gone.

KG / inline-task / pre-built agents declare their preferred model in YAML
frontmatter (claude-haiku-4.5 / claude-sonnet-4.6) — used at resolution time
when those agents are themselves the top-level agent of a run (background
triggers, scheduled tasks, etc.).

## Standalone callers

Non-run LLM call sites (summarize_meeting, track/routing, builtin-tools
parseFile) and `agent-schedule/runner` were branching on signed-in
independently. They all route through `getDefaultModelAndProvider` +
`resolveProviderConfig` + `createProvider` now; `agent-schedule/runner`
switched from raw `runsRepo.create` to `runsCore.createRun` so resolution
applies to scheduled-agent runs too.

## UI

`chat-input-with-mentions` stops calling `models:saveConfig`. The dropdown
notifies the parent via `onSelectedModelChange` ({provider, model} as names);
App.tsx stashes selection per-tab and passes it to the next `runs:create`.
When a run already exists, the input fetches it and renders a static label —
model can't change mid-run.

## Legacy runs

A lenient zod schema in `repo.ts` (`StartEvent.extend(...optional)` plus
`RunEvent.or(LegacyStartEvent)`) parses pre-existing runs. `repo.fetch` fills
missing model/provider from current defaults and returns the strict canonical
`Run` type. No file-rewriting migration; no impact on the canonical schema in
`@x/shared`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 12:26:01 +05:30
Ramnique Singh
15567cd1dd let tool failures be observed by the model instead of killing the run
streamAgent executed tools with no try/catch around the call. A throw
from execTool or from a subflow agent streamed up through streamAgent,
out of trigger's inner catch (which rethrows non-abort errors), and
into the new top-level catch that the previous commit added. That
surfaces the failure — but it ends the run. One misbehaving tool took
down the whole conversation.

Wrap the tool-execution block in a try/catch. On abort, rethrow so the
existing AbortError path still fires. On any other error, convert the
exception into a tool-result payload ({ success: false, error, toolName })
and keep going. The model then sees a tool-result message saying the
tool failed with a specific message and can apologize, retry with
different arguments, pick a different tool, or explain to the user —
the normal recovery moves it already knows how to make.

No change to happy-path tool execution, no change to abort handling,
no change to subflow agent semantics (subflows that themselves error
are treated identically to regular tool errors at the call site).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 14:38:19 +05:30
Ramnique Singh
c81d3cb27b surface silent runtime failures as error events
AgentRuntime.trigger() wrapped its body in try/finally with no outer
catch. An inner catch around the streamAgent for-await only handled
AbortError and rethrew everything else. Call sites fire-and-forget
trigger (runs.ts:26,60,72), so any thrown error became an unhandled
promise rejection. The finally still ran and published
run-processing-end, but nothing told the renderer why — the chat
showed the spinner, then an empty assistant bubble.

Provider misconfig, invalid API keys, unknown model ids, streamText
setup throws, runsRepo.fetch or loadAgent failing, and provider
auth/rate-limit rejections on the first chunk all hit this path on a
first message. All invisible.

Add a top-level catch that formats the error to a string and emits a
{type: "error"} RunEvent via the existing runsRepo/bus path. The
renderer already renders those as a chat bubble plus toast
(App.tsx:2069) — no UI work needed.

No changes to the abort path: user-initiated stops still flow through
the existing inner catch and the signal.aborted branch that emits
run-stopped.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 14:36:00 +05:30
Ramnique Singh
ae296c7723 serialize knowledge file writes behind a per-path mutex
Concurrent track runs on the same note were corrupting the file. In a
fresh workspace, four tracks fired on cron at 05:09:17Z (all failed on
AI_LoadAPIKeyError, but each still wrote lastRunAt/lastRunId before the
agent ran) and three more fired at 05:09:32Z. The resulting Today.md
ended with stray fragments "\n>\nes-->\n-->" — tail pieces of
<!--/track-target:priorities--> that a mis-aimed splice had truncated —
and the priorities YAML lost its lastRunId entirely.

Two compounding issues in knowledge/track/fileops.ts:

1. updateTrackBlock read the file twice: once via fetch() to resolve
   fenceStart/fenceEnd, and again via fs.readFile to get the bytes to
   splice. If another writer landed between the reads, the line indices
   from read #1 pointed into unrelated content in read #2, so the
   splice replaced the wrong range and left tag fragments behind.

2. None of the mutators (updateContent, updateTrackBlock,
   replaceTrackBlockYaml, deleteTrackBlock) held any lock, so
   concurrent read-modify-writes clobbered each other's updates. The
   missing lastRunId was exactly that: set by one run, overwritten by
   another run's stale snapshot.

The fix: introduce withFileLock(absPath, fn) in knowledge/file-lock.ts,
a per-path Promise-chain mutex modeled on the commitLock pattern in
knowledge/version_history.ts. Callers append onto that file's chain
and await — wait-queue semantics, FIFO, no timeout. The map self-cleans
when a file's chain goes idle so it stays bounded across a long-running
process.

Wrap all four fileops mutators in it, and also wrap workspace.writeFile
(which can touch the same files from the agent's tool surface and
previously raced with fileops). Both callers key on the resolved
absolute path so they share the same lock for the same file.

Reads (fetchAll, fetch, fetchYaml) stay lock-free — fs.writeFile on
files this size is atomic enough that readers see either pre- or
post-state, never corruption, and stale reads are not a correctness
issue for the callers that use them (scheduler, event dispatcher).

The debounced version-history commit in workspace.writeFile stays
outside the lock; it's deferred work that shouldn't hold up the write.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 11:11:33 +05:30
Ramnique Singh
fbbaeea1df refactor ensure-daily-note 2026-04-21 11:06:09 +05:30
Ramnique Singh
a86f555cbb refresh rowboat access token on every gateway request
Wire a custom fetch into the OpenRouter gateway provider so each outbound
request resolves a fresh access token, instead of baking one token into
the provider at turn start. Add a 60s expiry margin and serialize
concurrent refreshes behind a single in-flight promise.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 10:13:40 +05:30
Ramnique Singh
a80ef4d320 Revert "add suggested topics using track blocks"
This reverts commit 93054066fa.
2026-04-20 22:21:58 +05:30
Ramnique Singh
dc3e25c98b add today.md using track blocks 2026-04-20 17:20:30 +05:30
Ramnique Singh
93054066fa add suggested topics using track blocks 2026-04-20 17:20:21 +05:30
Ramnique Singh
1306b7f442 improve prompting around output blocks 2026-04-20 16:22:53 +05:30
Ramnique Singh
9f776ce526 improve track run prompts 2026-04-20 14:30:50 +05:30
Ramnique Singh
0d71ad33f5 improve track skill re: yaml strings 2026-04-20 10:27:13 +05:30
arkml
acc655172d
Iframe (#502)
Added iframe block
2026-04-18 12:10:40 +05:30
Arjun
eaab438666 feat(suggested-topics): populate and integrate suggested topics 2026-04-17 23:09:54 +05:30
tusharmagar
50df9ed178 feat(composio): hide composio from copilot whilst the API key is not set in isSignedIn is false
- Added a function to invalidate the Copilot instructions cache when setting the API key.
- Updated the Composio tools prompt to return an empty string if Composio is not configured, simplifying the user experience.
- Refactored the Copilot instructions to conditionally include Composio-related guidance based on configuration status, improving clarity on third-party service interactions.
- Introduced a new function to build a skill catalog string, allowing for optional exclusion of specific skills, enhancing the skill management capabilities.
2026-04-16 17:12:43 +05:30
Arjun
933df9c4a8 assistant knows middle pane 2026-04-16 17:09:11 +05:30
Arjun
e71107320c improve instructions for assistant creating notes 2026-04-16 17:09:11 +05:30
arkml
7dbfcb72f4
Browser2 (#495)
Add tabbed embedded browser and assistant browser control
2026-04-15 13:21:09 +05:30
Ramnique Singh
e2c13f0f6f
Add tracks — auto-updating note blocks with scheduled and event-driven triggers
Track blocks are YAML-fenced sections embedded in markdown notes whose output
is rewritten by a background agent. Three trigger types: manual (Run button or
Copilot), scheduled (cron / window / once with a 2 min grace window), and
event-driven (Gmail/Calendar sync events routed via an LLM classifier with a
second-pass agent decision). Output lives between <!--track-target:ID-->
comment markers that render as editable content in the Tiptap editor so users
can read and extend AI-generated content inline.

Core:
- Schedule and event pipelines run as independent polling loops (15s / 5s),
  both calling the same triggerTrackUpdate orchestrator. Events are FIFO via
  monotonic IDs; a per-track Set guards against duplicate runs.
- Track-run agent builds three message variants (manual/timed/event) — the
  event variant includes a Pass 2 directive to skip updates on false positives
  flagged by the liberal Pass 1 router.
- IPC surface: track:run/get/update/replaceYaml/delete plus tracks:events
  forward of the pub-sub bus to the renderer.
- Gmail emits per-thread events; Calendar bundles a digest per sync.

Copilot:
- New `tracks` skill (auto-generated canonical schema from Zod via
  z.toJSONSchema) teaches block creation, editing, and proactive suggestion.
- `run-track-block` tool with optional `context` parameter for backfills
  (e.g. seeding a new email-tracking block from existing synced emails).

Renderer:
- Tiptap chip (display-only) opens a rich modal with tabs, toggle, schedule
  details, raw YAML editor, and confirm-to-delete. All mutations go through
  IPC so the backend stays the single writer.
- Target regions use two atom marker nodes (open/close) around real editable
  content — custom blocks render natively, users can add their own notes.
- "Edit with Copilot" seeds a chat session with the note attached.

Docs: apps/x/TRACKS.md covers product flows, technical pipeline, and a
catalog of every LLM prompt involved with file+line pointers.
2026-04-14 13:51:45 +05:30
Ramnique Singh
ab0147d475 refactor agent yaml frontmatter parsing 2026-04-14 10:14:00 +05:30
Ramnique Singh
b462643e6d refactor waitForRunCompletion, extractAgentResponse 2026-04-14 10:14:00 +05:30
Arjun
490b14ad58 switch to claude as default 2026-04-13 21:28:01 +05:30
Ramnique Singh
b3066a0b7a add cmd+k palette with chat mode that captures editor cursor context
Cmd+K (Ctrl+K on Win/Linux) now opens a unified palette with two
modes: Chat (default) and Search (existing behavior). Tab cycles
between them. In Chat mode, if the user triggered the shortcut from
the markdown editor, the palette auto-attaches a removable chip
showing the note path and precise cursor line. Enter sends the
prompt to the right-sidebar copilot — opening the sidebar if closed
and starting a fresh chat tab — with the chip carried as a
FileMention whose lineNumber is forwarded to the agent as
"... at <path> (line N)" so the agent can use workspace-readFile
with offset to fetch the right slice on demand.

Line numbers are computed against the same getMarkdownWithBlankLines
serializer used to write notes to disk, so the reference is
byte-identical to what the agent reads back.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 17:00:37 +05:30
Ramnique Singh
f4dc5e7db4 prefix line numbers and add offset/limit to workspace-readFile
Returns utf8 reads as `<path>`/`<type>`/`<content>` blocks with each
line prefixed by its 1-indexed line number, plus offset/limit paging
and an end-of-file/truncation footer. Helps the agent reference
specific lines when forming precise edits to knowledge markdown.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 14:30:36 +05:30
arkml
884b5d0414
fix composio related sync scripts (#484) 2026-04-11 09:08:26 +05:30
Arjun
80d134568c fix default model 2026-04-11 08:16:53 +05:30
arkml
220e15f642
fix workdir everywhere (#475)
* make workdir configurable everywhere for easy testing
2026-04-10 10:40:46 +05:30
Ramnique Singh
1ac4e648da fix model-fetch error: remove experimental field handling 2026-04-10 01:07:52 +05:30
Ramnique Singh
50bce6c1d6 feat(oauth): switch Google OAuth from PKCE to authorization code flow with client secret
Previously, the Google OAuth integration used a PKCE-only flow (no client
secret). This switches to a standard authorization code flow where the user
provides both a Client ID and Client Secret from a "Web application" type
OAuth client in Google Cloud Console. PKCE is retained alongside the secret
for defense in depth.

Key changes:

- oauth-client.ts: discoverConfiguration() and createStaticConfiguration()
  now accept an optional clientSecret param. When provided, uses
  ClientSecretPost instead of None() for client authentication.

- oauth-handler.ts: connectProvider() takes a credentials object
  ({clientId, clientSecret}) instead of a bare clientId. Removed eager
  persistence of clientId before flow completion — credentials are now
  only saved after successful token exchange. Renamed resolveClientId to
  resolveClientCredentials to return both values from a single repo read.

- google-client-factory.ts: same resolveClientId → resolveCredentials
  rename. Passes clientSecret to OAuth2Client constructor and
  discoverConfiguration for token refresh.

- repo.ts: added clientSecret to ProviderConnectionSchema. Not exposed
  to renderer via ClientFacingConfigSchema (stays main-process only).

- IPC: added clientSecret to oauth:connect request schema. Handler builds
  a credentials object and passes it through.

- UI: GoogleClientIdModal now collects both Client ID and Client Secret
  (password field). Always shown on connect — no in-memory credential
  caching. Renamed google-client-id-store to google-credentials-store
  with a unified {clientId, clientSecret} object.

- google-setup.md: updated to instruct users to create a "Web application"
  type OAuth client (instead of UWP), add the localhost redirect URI, and
  copy both Client ID and Client Secret. Added credentials modal screenshot.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 00:43:34 +05:30
Arjun
924e136505 change lookback to 7 days 2026-04-09 23:55:29 +05:30
Aaron Culich
e1c6758a3f fix(oauth): full callback URL, Google clientId, refresh, and review follow-ups
- Pass full OAuth callback URL through auth-server for openid-client validation
- Composio + Google flows: duplicate-callback guard; preserve timeout cleanup
- Persist and expose Google clientId via oauth:getState; hydrate UI from useConnectors
- getAccessToken returns refreshed credentials; clearer errors and missing-state handling
- IPC schema: per-provider userId + clientId
- Docs: google-setup redirect URI and troubleshooting

Made-with: Cursor
2026-04-07 11:24:25 -07:00
tusharmagar
75ffbc781c Add billing error handling and UI updates
- Introduced billing error patterns to match specific error messages and display appropriate user prompts in the ChatSidebar.
- Enhanced SidebarContentPanel and AccountSettings components to reflect subscription status, including trial expiration details.
- Updated button actions to direct users to the app URL for subscription management and upgrades.
- Added a new Payment section in AccountSettings for managing invoices and payment methods, with conditional rendering based on subscription status.
2026-04-07 21:51:17 +05:30
arkml
aea40e632b
Remove slack granola (#465)
* remove native slack and granola

* remove agent-slack instructions

* fix build error
2026-04-07 12:38:19 +05:30