Skip to content

fixing/merge-conflict#1

Open
Pavitra-programmers wants to merge 3851 commits into
Pavitra-programmers:merge-conflictfrom
different-ai:dev
Open

fixing/merge-conflict#1
Pavitra-programmers wants to merge 3851 commits into
Pavitra-programmers:merge-conflictfrom
different-ai:dev

Conversation

@Pavitra-programmers

Copy link
Copy Markdown
Owner

Summary

Why

Issue

  • Closes #

Scope

Out of scope

Testing

Ran

  • ...

Result

  • pass/fail:
  • if fail, exact files/errors:

CI status

  • pass:
  • code-related failures:
  • external/env/auth blockers:

Manual verification

Evidence

  • video/screenshot link, or N/A (docs-only)

Risk

Rollback

OmarMcAdam and others added 30 commits July 15, 2026 12:22
* fix(den): make enterprise MCP OAuth opt-in

* feat(den-web): add MCP OAuth recovery controls

* fix(den): tighten MCP OAuth rollout controls

* fix(mcp): support Salesforce OAuth discovery

* fix(den-web): make MCP OAuth migration recoverable

* fix(den): simplify enterprise MCP OAuth rollout

* refactor(den-web): simplify MCP discovery UI

* refactor(den-web): streamline MCP connection setup
…facture an outage (#2823)

On corporate Windows machines with TLS interception, the health check's
direct tools/list probe (Node undici, no OS trust store) threw 'fetch
failed' and was misclassified as cloud_tools_missing — flipping usable
to false, blocking delivery from being marked applied, and worst,
feeding the extensions-preview steering plugin a per-prompt instruction
telling the model Cloud agent access is not ready. The model then
refused MCP tools that the engine (Bun, OS trust) had registered,
connected, and could call the whole time: a false-negative probe
manufactured a real outage.

- transport-thrown probes now report probe_unreachable (diagnostic
  only): when the engine says the MCP is connected they no longer join
  failures, so usable/phase/delivery reflect the engine's reality
- the probe now prefers Electron net.fetch (Chromium, OS trust store)
  when embedded, falling back to global fetch elsewhere
- steering fails open: engine connected + probe-side failure returns
  the neutral instruction, never 'Direct the user to Repair and test'
- direct probe failures stay visible in the health JSON for support
…yments (#2830)

* feat(app,den-web): hide OpenWork Models surfaces on self-hosted deployments

Desktop: areOpenWorkModelsPromosDisabled() now also returns true when the
effective Den control plane is not app.openworklabs.com, silencing the model
picker promo group, picker modal card, status-bar hint, startup dialog, the
onboarding 'Use OpenWork Models' option, and the Settings > AI rows.

den-web: single-org (self-hosted) dashboards drop the 'OpenWork Models' nav
child and redirect /dashboard/inference to LLM Providers.

Includes fraimz flows + voiceovers for both journeys.

* fix(evals): repair self-hosted fraimz flow after Daytona run

- navigate back to the session when a reload lands on settings
- screenshot validator cannot see input placeholders; require 'All models'
- voiceover intro reflects the disposable sandbox environment

* fix(evals): adapt self-hosted fraimz flow to dev's welcome-route provider step

Upstream removed the session-route held-first-send provider step; the
provider choice now only appears during welcome workspace setup. Frames 3/7
drive it through the real journey (reset onboarding latch -> create a
workspace from the welcome page), with Base UI React-props clicks and
post-reload settling.
…able org mode (#2824)

Two failures found while running the eval suites against a Daytona den
server sandbox:

1. pkill patterns anchored on repo paths (ee/apps/den-api/src/main.ts)
   never match the real cmdline ('tsx watch src/main.ts' is cwd-relative),
   so re-running the start script silently kept the old den-api on the
   port — the health check then passed against the stale process and env
   changes never took effect. Match the cwd-relative cmdline instead
   (main.ts / server.ts are unique per app here).

2. den-api's DEN_ORG_MODE now defaults to single_org, which blocks the
   email signups scripts/seed-demo-org.ts performs — a fresh sandbox
   could not seed the Acme demo org. Default the server to multi_org
   (overridable) to match the seeded demo this sandbox exists for.
…rection, deterministic (#2829)

* docs(voiceover): runtime config ownership script + scaffolded flow

* docs(voiceover): simplify runtime-config-ownership to four frames

* docs(voiceover): reframe as one-way managed config with predictability guarantee

* feat(server,app): one-way managed runtime config with legacy sweep and debug card

The managed runtime config file becomes the only thing OpenWork writes:
- choke-point helper routes disabled-provider changes to a new
  /workspace/:id/runtime-config/disabled-providers route (runtime DB ->
  managed file) for local workspaces; remote keeps engine config.update;
  a guard test bans any other config.update call site
- managed file build is byte-deterministic (sorted-key stringify)
- one-time startup sweep removes only unambiguous OpenWork-written keys
  (mcp.openwork-cloud, agent.openwork, default_agent=openwork, openwork
  plugin entries) from ~/.config/opencode/* with jsonc-preserving edits,
  a timestamped backup, and an idempotent state marker
- Debug settings card shows the managed file path, last-rebuilt time,
  server-side-redacted content, and sweep results
* feat(den-web): simplify cloud landing page

* refactor(den-web): simplify landing shader
* fix(app): hide model promotions on custom Den

* fix(app): avoid duplicate model promo state
* feat(den): sync SCIM groups to teams

* test(evals): make SCIM group proof repeatable
…tch banned (#2835)

Every bare Node fetch in the server (undici) bypasses the OS certificate
store, so on enterprise machines with TLS interception any external
call fails with a generic 'fetch failed' while Electron and the engine
succeed (field incident class). One shared helper now routes egress:
externalFetch prefers Electron net.fetch (Chromium stack, OS trust)
when embedded and falls back to global fetch standalone; loopbackFetch
documents engine/127.0.0.1 traffic where CA trust is irrelevant and
streaming performance matters. All server call sites migrated; a guard
test fails the build on new bare fetch call sites. Engine-side plugin
bundles (src/opencode-plugins) are deliberately out of scope — they run
inside Bun, which trusts the OS store.
…es OpenWork Connect (last in sidebar) (#2836)

* feat(settings): rename Extensions to Extensions (Legacy), Connect to OpenWork Connect

- Extensions tab becomes "Extensions (Legacy)" across all locales; description
  shifts to the local-MCP story ("Local MCP servers and OpenCode plugins…").
  Plugins/marketplace inside it keep working unchanged.
- Connect tab becomes "OpenWork Connect" and always renders as the last
  settings sidebar item (memory tab now inserts before it).
- General hub Extensions card uses the shared i18n keys.
- fraimz flow + approved voiceover: extensions-legacy-rename.

* test(fraimz): click into OpenWork Connect in frame 2 to avoid duplicate-frame guard
… state (#2832)

* fix(plugins): steer Cloud tool availability from the engine's own MCP state

The extensions-preview steering previously phoned home to the OpenWork
server and asserted the server's health verdict to the model. Field
incident: that verdict can disagree with the engine (corporate TLS broke
the server's probe while the engine's MCP was connected), and the model
obeyed the wrong claim — refusing tools it actually had.

Invariant now enforced: tool-availability steering is computed from the
same process that owns the tools. The plugin asks the engine's mcp
status in-process (connected → ready, disabled → disabled, needs_auth →
sign-in, failed → degraded), falls back to server connect-state only
when the engine has no entry at all, and fails open to the neutral
instruction on any engine error.

* fix(plugins): fail open on unknown engine cloud status

* fix(plugins): remove degraded steering — steering is ready/sign-in/disabled/neutral only
…on-demand (#2834)

* fix(server): engine-attested Cloud MCP health; network probe becomes on-demand

Background health re-verified the engine's MCP over the server's own
network stack on every check — a duplicate verifier that can disagree
with the engine (field incident: corporate TLS). The engine is now the
authority: by default health attests tools from the engine's mcp status
(connected implies initial tools/list succeeded on opencode >=1.17) and
never touches the network. The direct tools/list probe runs only when
explicitly requested (GET health?probe=1) and on reconcile (an explicit
repair action). /experimental/connect/state — consumed per prompt by
the steering plugin — is pinned to probe:false.

* test(server): make Cloud MCP health cleanup Windows-safe

* test(server): make Cloud MCP reconcile Windows-safe
benjaminshafii and others added 30 commits July 24, 2026 08:29
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…f bold

Co-authored-by: Cursor <cursoragent@cursor.com>
…t seed

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Allowlist the Desktop Policies tag in the agent catalog policy so
search_capabilities/execute_capability can list, create, update, and
delete desktop policies. Route-level auth is unchanged and enforced on
replay: reads need org admin, mutations need super-admin plus the
Enterprise entitlement and mcp:write scope.

Adds the desktop-policies-cloud-mcp voiceover + fraimz flow proving the
rail end to end: capability search, MCP read/update, dashboard + member
desktop pickup, and an ordinary member's write refused.
On engines where JSON is a LONGTEXT alias (MariaDB), mysql2/Drizzle
returns the desktop_policy.policy column as a JSON-encoded string on
read. The canonical normalize functions failed the object parse and
silently collapsed every read to {} — list responses, the effective
policy calculation, and /v1/me/desktop-config all lost restrictions
even though writes stored the correct document.

Coerce JSON-string input once at the normalize entry points so every
consumer behaves identically for strings and objects, and widen
calculateEffectiveDesktopPolicy to accept raw column values it already
normalizes internally. Covered by desktop-policy-json-column-strings
bun tests.
…s none

Fresh sandboxes land on #/session with the create-workspace empty state
(not /welcome); cloud MCP auto-config only syncs once a workspace
exists.
…on policy

The dev server can bind [::1] only (Daytona sandboxes); navigation
between loopback origens should behave the same as 127.0.0.1/localhost.
Also harden the desktop-policies-cloud-mcp flow: reconnect CDP around
cross-origen navigations and accept a healthy cloud-MCP maintenance
outcome when the first-sync marker was already consumed.
…icies flow

The main window's navigation poli-cy intentionally blocks external
origens (they reroute to the built-in browser), so the dashboard frames
now use the designed affordance: open the Den dashboard with the
browser.open_url control action, drive it as a second CDP target, and
close the tabs before returning to the app frames. Session-page action
availability is awaited (and create_task retried) since control actions
register per route.
- Fix admin Delete user: validate usr_ TypeIDs via isDenTypeId instead of a wrong user_ prefix check that 400'd every real id
- Add owner-only DELETE /v1/org with fresh-session reauth, best-effort Stripe subscription cancellation, and a full org-scoped purge across all org tables
- Add Danger zone at the bottom of dashboard Settings > General with type-the-org-name confirmation dialog
- Repair pre-broken dev gates: route-access-policy parser (apostrophe comment) and connected-account revocation contract drift; defuse organization-capabilities mock-pollution landmine
…edentials (#3076)

Production forensics showed every runtime credential invalidation was
written by the terminal-401 path: any unresolved 401 (gateway redeploys,
VPN flaps, provider session flushes) wiped the member's stored tokens and
forced a reconnect - including from background search probes the user
never saw (confirmed cases: Notion, Stripe, Salesforce, Granola).

New policy:
- invalidation only during user-initiated tool execution, never during
  tool-discovery probes
- 401 is terminal only with an explicit WWW-Authenticate invalid_token
  bearer challenge; 403 bearer/scope policy unchanged
- every invalidation emits a credential-invalidation diagnostic and Den
  logs external_mcp_credential_invalidated unconditionally
…ory-aware back/forward (#3071)

* feat(chat): render capability calls as sentences, not JSON cards

Paper chat-transcript rendering rules, step 1:
- MCP/dynamic tool calls render as plain muted sentence lines with no
  tool icon: dot-matrix while running, small green dot + past-tense
  verb + duration when done
- Connection/tool names map to human sentences ("Searched your
  connections for "gmail drafts list"", "Asked Granola ...");
  body.query renders as quoted plain text
- Raw input/output, tool name, and call id move under a collapsed
  "Technical details" panel
- Durations measured client-side from live streaming; restored history
  shows no duration instead of a fabricated one
- Failed calls and sub-agent (task) runs keep the existing card with
  reconnect/Retry until their dedicated treatments land
- Dot-matrix loader promoted to shared components/ui (currentColor,
  reduced-motion static frame); sidebar re-exports it

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(chat): aggregate consecutive command/edit/read/search tool calls

Consecutive tool-only steps (across assistant messages) collapse into
one line — live totals plus a self-replacing "Now:" line while running,
past tense when done. Chevron expands the chronological list with
status dots, monospace actions, per-call durations, failure reasons,
and a "Show N more" cap. Prose, reasoning, or any other tool breaks
the run, per the Paper transcript artboard.

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(chat): failure-as-instruction lines and two-line sub-agent runs

Failed capability calls now use the sentence line: red dot, one line
saying what to do next, inline Reconnect/Retry when the error maps to
a known connection (logic extracted into useChatToolReconnect, shared
with the generic Tool card). Sub-agent task runs render the Paper
two-line treatment: task title + agent name, then live status or
"Completed" with duration; prompt/result under the collapsed panel.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(chat): separate merged reasoning sections with a paragraph break

Consecutive reasoning parts were concatenated with no separator, so
each section's bold "**Title**" got glued onto the previous
paragraph's last sentence mid-line.

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(chat): linkify bare https:// URLs in user message bubbles

User bubbles render plain text (not markdown), so pasted URLs never
became clickable. Bare http(s) URLs now render as anchors with the
same link styling as assistant markdown; search highlighting still
applies to the surrounding text.

Co-authored-by: Cursor <cursoragent@cursor.com>

* style(chat): drop traffic-light status colors from tool call lines

All tool call dots are now neutral gray; failure state reads through
the words ("failed", "Failed — reason") in muted text instead of
green/red dots. The only living marks in the transcript stay the
dot-matrix on running rows.

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(chat): collapse thinking by default, clickable file rows in aggregates

Reasoning renders as a collapsed "Thinking… / Thought" toggle instead
of always-expanded prose. Aggregate file rows show "Edited/Read <name>"
with just the file name (absolute path in the tooltip); clicking opens
the file in the artifact preview via the same open-target flow as the
artifact chips.

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(chat): humanize native and plugin execute_capability calls

CamelCase native capabilities ("getCapabilitiesGoogleWorkspaceCalendar
Events") become verb sentences ("Fetched Google Workspace Calendar
Events"). Opaque "plugin:…" refs pull the human name from the output
("Used skill "Plan My Day""). Structured provider errors render as a
sentence ("The provider rejected the call: invalid request — Invalid
ISO datetime.") instead of echoing raw JSON.

Co-authored-by: Cursor <cursoragent@cursor.com>

* style(sidebar): drop workspace color dot from pinned and archived rows

Co-authored-by: Cursor <cursoragent@cursor.com>

* style(chat): remove static gray status dots from tool call lines

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(sidebar): move conversation history back/forward controls into sidebar

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(chat): collapsed failed capability line expanding into Paper failure card

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(chat): render site favicons next to links in user and assistant text

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(chat): Paper file chips in aggregate rows and per-turn FILES artifact strip

Co-authored-by: Cursor <cursoragent@cursor.com>

* style(sidebar): move history arrows to top right of sidebar titlebar row

Co-authored-by: Cursor <cursoragent@cursor.com>

* style(sidebar): align history arrows with titlebar toggle row

Co-authored-by: Cursor <cursoragent@cursor.com>

* style(sidebar): add vertical spacing between session rows

Co-authored-by: Cursor <cursoragent@cursor.com>

* style(sidebar): apply row gap inside reorder groups and group content

Co-authored-by: Cursor <cursoragent@cursor.com>

* style(sidebar): selected session uses subtle color emphasis instead of bold

Co-authored-by: Cursor <cursoragent@cursor.com>

* test(evals): chat-transcript-sentences fraimz with dev-only transcript seed

Co-authored-by: Cursor <cursoragent@cursor.com>

* style(chat): remove underline from links; assert no-underline in fraimz

Co-authored-by: Cursor <cursoragent@cursor.com>

* test(evals): make chat-transcript flow idempotent via renderer reload

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(workbench): Arc-style tab context menu, joined split pill, resizable panes

Co-authored-by: Cursor <cursoragent@cursor.com>

* test(evals): workbench-split-view fraimz

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(workbench): vertical tab system in sidebar with history-aware split view

The sidebar is now the vertical tab list (Arc model): the horizontal tab
strip is gone, session rows carry the tab semantics, 'Open in split view'
lives in the row context/dropdown menus, and the active split pair renders
as a joined pill at the top of the sidebar.

Conversation history entries now record the split session too, so
back/forward restores the exact split layout of each step.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(split-view): per-conversation model picker with last-used memory

Each session surface now resolves its own model: picker open state is
local to the pane, selections are remembered per session in
localStorage (openwork.sessionModels.v1), and sends resolve the
session's remembered model/variant before falling back to the global
default. The full model picker targets the session it was opened from;
opening it without a session still edits the global default.

Co-authored-by: Cursor <cursoragent@cursor.com>

* ui: hide workspace name from the session header

Co-authored-by: Cursor <cursoragent@cursor.com>

* ui(welcome): match Paper first-load design

Pixel-dither mosaic background (Dithering shader, dark:invert for dark
mode) on a plain ground instead of the colored grain gradient, real
OpenWork mark in the card, larger welcome typography, and 48px
primary/outline buttons per the first-load spec.

Co-authored-by: Cursor <cursoragent@cursor.com>

* ui(signin): unify forced sign-in with the Paper welcome card

The fullscreen sign-in gate now renders the same first-load card as
WelcomePage (dither background, logo row, welcome typography, 48px
primary button). Forced sign-in only removes the Use Without Cloud
option; the fallback notice, on-premises server affordance, paste-code
disclosure, and dev-mode control-plane editor stay inside the card.
Drops the old two-column showcase layout.

Co-authored-by: Cursor <cursoragent@cursor.com>

* ui: Paper card for onboarding stages, sidebar workspaces header + groups, OpenWork Models dialog redesign

- page.tsx primitives: dither background + bounded card so every org-setup
  stage (org selection, resources, branding restart, prepared workspace,
  loading/error) matches the sign-in card design
- attribution/provider onboarding steps wrapped in the same bounded card
- welcome page now marks the route ready so the faded boot splash no longer
  blocks clicks on /welcome
- sidebar: WORKSPACES section header with + (create workspace), removed the
  footer Add-workspace button, removed the 'Create a Group' link from the
  show-more row, added a hover folder+ action on workspace rows to create
  groups
- OpenWork Models startup dialog redesigned in the Paper card language:
  model list rows, checkmark highlights, stacked primary/secondary actions

Co-authored-by: Cursor <cursoragent@cursor.com>

* ui(sidebar): align section labels and titles to one shared text lane

PINNED / WORKSPACES / group labels now start at the same 44px lane as
session titles and workspace names; icons, dots, and chevrons hang in
the left gutter.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Redesign session empty state as chat-first hero with policy-driven prompts

- New SessionEmptyHero: 'What do you need done?' composer with suggestion
  cards, following the Paper first-chat design. Suggestions come from
  desktop policies (organization onboarding prompts) when configured,
  with built-in defaults otherwise.
- Chat-first onboarding: with no workspace yet, the same hero shows and
  running a task creates a default 'OpenWork Chat' workspace under the
  home folder instead of asking where to put it (modal fallback off
  desktop).
- Fix prompt handoff: onCreateTaskWithPrompt saved drafts to a store the
  composer never reads; now also seeds the composer state store so the
  prompt actually appears in the new session's composer.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Remove workspace color concept; left-align sidebar hierarchy

- Delete WorkspaceIcon (hashed color dot) and all its usages: sidebar
  workspace headers and the settings workspace pickers.
- Workspace titles now start flush left (16px), giving the sidebar a real
  indent hierarchy: sections/workspaces at 16px, group headers indented,
  session titles deeper.
- PINNED and WORKSPACES section labels share the same 16px lane.
- The dot-matrix loader still shows inline while a workspace is loading.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Remove hover FolderPlus (new group) button from workspace rows

New group stays available in the workspace options menu and session
context menus. Hover padding shrinks back to two-button width.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
…3078)

Enterprise networks that inspect TLS (GlobalProtect and similar) present
certificates signed by a corporate CA that lives in the OS trust store.
Browsers trust it; the Bun-compiled installer only saw bundled Mozilla
roots, so resolving an install link failed with a misleading 'check your
internet or VPN' error even though the workspace was reachable.

- add src/system-ca.ts: best-effort OS trust-store export (PowerShell
  cert stores on Windows, System.keychain via security on macOS) merged
  into every installer fetch via Bun's fetch tls.ca (extends bundled
  roots); cache pre-warmed at server start so the first resolve-link
  keeps its full abort budget
- classify TLS trust failures separately from network reachability and
  say so honestly in /api/resolve-link, naming the certificate host
- ship the OpenWork icon: --windows-icon for Windows compiles (was the
  Bun logo) and icon.icns + CFBundleIconFile in every macOS bundle path
  (was the blank generic icon)
- reassert the webview window title after page load; the cocoa backend
  creates the NSWindow inside run() so pre-run titles were dropped
- fraimz: installer-tls-trust flow + voiceover proving the paste screen,
  the honest TLS message, CA-trusted resolution, and the unchanged
  happy path
…ider-safe mime (#3079)

Providers' AI SDK adapters only accept image/*, application/pdf, and
text/plain file parts; anything else throws
"'file part media type: X' functionality not supported" and the persisted
part replays the error on every later prompt.

- accept any file in the composer (remove the attach-time mime allowlist)
- re-mime text-like attachments (xml, json, csv, yaml, html, code, svg) to
  text/plain so opencode inlines their content via the Read tool, the same
  proven mechanism as @file mentions
- binaries upload to the workspace inbox as before but emit no model-facing
  file part; the synthetic path note gives the model tool access instead
- images/PDF/Office parts unchanged (Office is rewritten server-side by the
  OpenWorkOfficeAttachments plugin)
- drop the dead attachment-support.ts allowlist and update dropzone copy
…tifacts, no size caps (#3081)

- binary attachments now emit a text/plain file part pointing at the
  workspace copy; opencode mediates these through the Read tool (graceful
  'Cannot read binary file') and never forwards them to providers, so zips
  keep a transcript badge with zero provider risk
- user attachment file parts are now derived as open targets/artifacts via
  their file:// URLs, so entries in the Files/Artifacts panel are clickable
  even when filenames contain spaces (regex path scanning could not match
  those and left dead entries)
- media badge prefers the filename extension over the transport mime so a
  zip shows ZIP instead of PLAIN
- remove the opinionated 8MB composer and 25MB session caps; size errors now
  come from the upload endpoint or provider; inbox upload default raised to
  250MB with OPENWORK_INBOX_MAX_BYTES override no longer clamped
- drop the unused composer.file_exceeds_limit locale key
…nfra failures as revocation (#3080)

Two verified prod failure classes behind 'Server returned 401 after
successful authentication' loops and unfixable Degraded states:

1. Refresh grants outlived the session that authorized them. The token
   endpoint kept minting 45-min tokens carrying a dead sid, which the
   resource rejected with mcp_session_revoked forever. Census at fix
   time: 24 live zombie grants across 16 users (10 deleted sessions,
   14 expired). The token endpoint now checks session liveness for
   refresh_token grants: dead session => 400 invalid_grant + grant
   family cleanup, so clients fall into clean re-authorization.

2. hasActiveMcpSession ended in catch { return false }, reporting any
   DB/infra error as REVOKED (observed in prod: ~2h of rejections for
   a provably alive session, self-healing afterwards, with clients
   pointlessly rotating grants on every retry). Session liveness is now
   three-state (alive / missing / check_failed): check_failed maps to a
   retryable 503 mcp_session_check_unavailable (Retry-After, no
   WWW-Authenticate challenge) on the resource and fails open at the
   refresh gate, with a stable mcp_session_liveness_check_failed log
   marker. Rolling-touch failures alone no longer affect verdicts.
… chip (#3082)

* feat(shell): Arc-style card shell with header panel toggle and background rail

- Main content and side panel render as elevated rounded cards floating
  over the sidebar-colored background (seamless with left sidebar, no
  divider borders).
- Session header gains a PanelRight toggle next to the notification bell
  to open/close the right side panel; active state highlighted.
- Right icon rail (browser/voice/artifacts/extensions) now sits directly
  on the background instead of a bordered strip.
- Resizable handle between cards is transparent so the background gutter
  shows through.

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(shell): denser chrome, account chip in sidebar footer, no resize grips

- Header: 36px tall with 13px medium title (was 40px/15px semibold).
- Right rail: 36px wide with 15px icons (was 44px/17px).
- Composer panel radius tightened to 18px.
- Resizable handles no longer render the floating grip pill.
- Sidebar footer now shows a profile chip: signed-in Den user with
  initials avatar, name and email (opens settings), or a 'Sign in'
  chip that launches OpenWork Cloud auth when signed out.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(shell): remove opaque paint from sidebar resize rail

The rail painted a sidebar-colored overlay to mask the old sidebar
border. With the seamless Arc shell background this rendered as a
thick dark strip between the sidebar and the content card. The rail
is now an invisible drag area with only its subtle hover line.

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(shell): system UI font stack and 13px max body text

- Body and --font-sans/--font-heading now lead with -apple-system /
  system-ui instead of IBM Plex Sans / Geist.
- Base body size 14px -> 13px; Tailwind text-sm token remapped to 13px.
- Composer editor 15px -> 13px; empty-state hero textarea 14px -> 13px.
- Sidebar section labels (PINNED, WORKSPACES, groups, archived, split
  view) normalized to 12px uppercase.

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(sidebar): tighter chevron-to-label gap with matching session indent

Group headers use gap-1.5 (was gap-3.5) between the expander chevron
and the group name; session rows shift from ps-3 to ps-1 (nested ps-7
to ps-5) so their titles stay aligned with the group label lane.

* fix(shell): drop sidebar right border; account chip opens a menu

- The shadcn sidebar container's variant-scoped border-e survived the
  earlier plain border-e-0 override and rendered as a 1px black line
  between the sidebar and the content card. Override now uses the same
  group-data-[side=left] variant.
- The sidebar account chip now opens a dropdown: email header, Settings
  (opens settings), and Log out (server sign-out best effort, clears the
  stored Den session, refreshes auth state). Signed-out users get
  Sign in instead of Log out.

Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(sidebar): fade out overflowing labels instead of ellipsis

New .ow-fade-truncate utility masks the last 18px of the label with a
linear-gradient so long session, workspace, group, and split-pill names
fade out Arc-style; short labels are unaffected.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(browser): round native WebContentsView corners to match panel card

The browser WebContentsView is a native layer that CSS overflow cannot
clip, so its square corners poked out past the rounded side-panel card.
Electron 35 setBorderRadius(14) matches the card radius.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(shell): match side-panel gutter to outer gutter width

The 4px gap between the center card and the side panel card made the
rounded-corner junction read as a notch; use the same 8px gutter as the
shell edges.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Revert "fix(browser): round native WebContentsView corners to match panel card"

This reverts commit 0c11542.

* fix(shell): round the shell panel group so overflow clip matches the cards

react-resizable-panels forces overflow:hidden on the group, which
square-clipped the rounded panel cards at the shell corners. Give the
outer group the same 14px radius so the clip follows the card shape.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
…e icon (#3083)

The dashboard already swapped the favicon to the managed square app icon
client-side, but the tab flashed the default OpenWork mark until the org
context loaded. The dashboard layout now resolves the active org's managed
icon during SSR (via /v1/me/orgs with the request cookies) and ships it in
the initial <link rel="icon">, and WorkspaceFavicon no longer resets the
favicon while the org context is still loading.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants