Home

mweinbach / agent-coworker

publicmweinbach/agent-coworker
Overview Code History Branches Pull requestsIssuesInsights
main
HomeOverview Code PRsIssues

Add desktop Deep Research workflow and exports (#88)

6 months ago

575c4eb
Authored
Max Weinbach4/24/2026, 11:14:10 PM
* feat(research): add backend service and export pipeline

* feat(research): add desktop research workspace

* refactor(research): collapse duplicate page chrome and defer follow-up composer

Drop the in-view Research header (AppTopBar already shows it), remove the
vestigial Refresh button, and move "+ New" into a slim left-column toolbar.
Strip the redundant title + prompt subtitle from the detail pane header;
render status badge + started-ago + actions only, and surface the prompt once
as a "Prompt" block in the body. Hide the follow-up composer entirely while
the run is not completed rather than rendering it disabled.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(research): promote thinking feed and skeleton the report while streaming

Auto-expand the thought panel whenever status is running or pending and
rebuild the disclosure as a single full-row trigger with a chevron, so the
captured thoughts act as the live progress signal while markdown is still
en route. Replace the flat "Waiting for the report stream" card with an
animated skeleton so the report area communicates liveness instead of dead
space.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(research): live progress strip and guarded exports

While a run is streaming, replace the "started ago" label with an inline
strip showing elapsed time, source count, and note count so users get
real-time feedback. Surface thoughts → sources → report order during runs
and flip back to report-first once terminal. Gate the export pill behind
status === completed && markdown non-empty, show a per-format spinner when
an export is in flight, and swap the text-only pill buttons for icon + label.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* refactor(research): simplify run list cards

Drop the redundant prompt preview (always identical to the title), replace
the full status pill with a colored dot + relative timestamp (pulsing while
running), and trade the heavy bordered card for a lighter hoverable row.
Follow-ups now use a ↳ indicator plus a subtle left border instead of
nesting inside ever-smaller boxed cards.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(research): tabbed detail pane, hidden prompt, clickable citations

Restructure the detail pane around a tabbed surface (Report / Notes /
Sources / Prompt). The Report tab is the default and the only one the user
sees up front — the prompt is no longer a primary artifact in the body,
which is consistent with the research flow being about the output, not the
input. Notes and Sources move from stacked collapsibles to peer tabs with
count badges, and the Notes tab renders each progress note as a timestamped
entry so thinking is visibly distinct from the report.

Swap the plain Streamdown renderer for MessageResponse so the desktop's
existing citation chip popover handles sources, and rewrite Deep Research's
inline [cite: N, M] markers into 【N†title】 form so the shared citation
normalizer can turn them into clickable <cite> chips keyed to the sources
array. Also tighten typography for long reports (H1/H2 scale, paragraph
rhythm).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(research): derive title from the first report heading

Once text deltas contain a usable H1, lift it into the research record as
the title and broadcast research/updated. We only overwrite the auto-
generated prompt-truncation title so an explicit user-supplied title is
preserved, and we strip leading section prefixes like "1." / "Chapter 2:"
so the list card shows the real subject instead of the prompt opening line.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* style(research): flatten report onto the sheet

Drop the rounded card around the report renderer and the tinted background
on the detail scroll container so the report reads as a single continuous
sheet instead of a card floating on panel chrome. Skeleton and empty-state
inherit the same flush layout.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(research): rename runs from the list + show report snippets

Add a research/rename JSON-RPC method and wire a renameResearch store
action that optimistically updates the record and reverts on error.
Research cards now show a 2-line plaintext preview of the actual report
under the title, and the title becomes the primary affordance — not the
prompt. Right-click on a card opens a context menu with Open / Rename, and
double-click jumps straight into an inline rename input (Enter to commit,
Escape to cancel, blur commits) the same way the chat sidebar renames work.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(research): cover ResearchService.rename

Add a regression test that exercises trim + empty-guard + persistence +
broadcast for research/rename. Also proves the unknown-id path returns
null rather than throwing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* style(research): flatten code blocks in the report

Streamdown's code-block-body already applies a rounded border, background,
and p-4 on the outer container, so the old [&_pre]:border + bg + padding
overrides were stacking a second box inside. Scope inline-code styling to
<p>/<li> only, soften the Streamdown outer container to the muted palette
we use elsewhere in the report, and strip the inner <pre> of border,
background, margin, and padding so the code lives inside a single box.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* style(research): tighten code block padding

Streamdown stacks p-2 on the outer container with p-4 on the body and a
separate 32px header row, so a one-liner code block was painting 50-60px
of empty space above the code. Zero the outer gap and padding, shrink the
header to h-6 with px-3/pt-2, move padding onto the body (px-3 pt-1 pb-2),
and strip the actions pill of its opaque backdrop so the copy/download
buttons float over the code without adding their own frame.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* style(research): drop code block header and action rails

The Streamdown code block stacks a 32px language-label header, a second
sticky 32px wrapper that reserves room for the copy/download pill via
-mt-10, and then the body with its own p-4 — leaving ~60-80px of empty
band above a one-line snippet. Hide both non-content rails (header and
the bare div wrapping the actions) so the outer rounded frame wraps the
body directly with a tight px-4 py-3. Language is already implied by
syntax highlighting; copy/download can come back as an overlay if needed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* style(research): slim header with language label + floating actions

Bring back the language label as a compact h-7 strip with px-3, a subtle
muted tint, and a bottom hairline to separate it from the code. Overlay
the copy/download pill as an absolutely positioned h-6 chip in the
top-right corner (top-0.5 right-1.5) instead of reserving a 40px sticky
rail for it. The outer frame is now relative + overflow-hidden so the
absolute actions clip cleanly with the rounded border.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* style(research): merge detail header into a single row

Collapse the two stacked header rows (status/actions + tabs) into one
horizontal strip: tabs on the left (Report/Notes/Sources/Prompt grouped
into a single segmented control), status badge + started-ago/live-metrics
inline in the middle, and export pill + Cancel pushed right with ml-auto.
One border-b, one padding, one visual unit. flex-wrap keeps it usable on
narrow widths.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(citations): open the citation chip card on hover

Citation chips already render a popover with favicon, title, and source
navigation on click — extend the same popover to open when the cursor
enters the chip or the portaled card, and schedule a 180ms close when it
leaves both. Cancel the close timer on click and unmount so quick hovers
don't leave stale popovers mid-animation. Works for chat messages and
research reports since both use MessageResponse.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* style(research): dissociate research from workspaces in the shell

Research is a workspace-agnostic surface — it uses a transport workspace
internally but the user shouldn't think of it that way. Drop the
"Research | <workspace>" subtitle from the top bar (passes null, so the
pipe and workspace name are hidden), remove the now-unused
researchWorkspace/selectedWorkspace memos, and null out the sidebar's
active workspace + selected thread when view === "research" so no
workspace card or chat row is highlighted while the user is in Research.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* style(research): make detail pane header responsive to container width

Tighten the three-column header so it reflows cleanly at any pane width:
- Tabs stay on one row as a shrink-0 pill that can scroll horizontally
  if the pane ever gets narrower than the tab group.
- Metadata is the flexible middle column (min-w-0 flex-1 basis-0,
  internal flex-wrap), so individual spans (elapsed / sources / notes)
  wrap onto new rows instead of clipping, with whitespace-nowrap on each
  atomic label to prevent mid-label breaks.
- Export pill + Cancel stay shrink-0 and pushed right via ml-auto, so
  they drop to their own line when the middle column runs out of room
  instead of compressing.
- Added min-w-0 on the root so the header actually participates in
  flex shrinking inside the outer min-h-0 flex-col parent.

Layout now responds to sidebar toggles and window resizes without any
JS measurement — all CSS flex behavior.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(research): collapse export pill into a Download dropdown

The three-button Markdown / PDF / DOCX pill ate ~200px of header
real-estate. Replace it with a compact "Download ⌄" trigger that opens
a small dropdown anchored to the button (outside-click and Escape both
close it). Each menu row shows an icon, the format name, and the file
extension hint; the format being exported gets a spinner in-place.
Trigger shows a spinner too while any export is in flight, and stays
disabled until the report has actually produced markdown.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(research): floating follow-up FAB anchored to the detail pane

Replace the bottom-of-report follow-up composer with a floating action
button pinned to the detail pane's bottom-left. Collapsed, it's a 44px
circular chat button that floats above the content no matter how far the
user has scrolled. Clicking it expands into the existing composer (now
accepting an autoFocus + onSubmitted callback, with the stale "Follow-up"
header stripped since the context is obvious from the FAB). Escape closes
the expanded state, as does submitting; the FAB auto-collapses when the
selected research changes.

The composer itself took a className + placeholder knob so the FAB can
override its chrome to feel like a single shadowed card, and the report
tab content no longer carries a trailing composer.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* style(research): springy morph for the follow-up FAB

Swap the plain CSS cross-fade for a framer-motion AnimatePresence
transition between the collapsed chat button and the expanded composer
card. Both states share the same bottom-left origin so the expansion
feels like the button growing into the card instead of a hard swap.
Scale + opacity + slight y-lift use a spring (stiffness 420, damping
34, mass 0.9) for the size change, and the inner card body cross-fades
separately so the composer doesn't appear inside-out mid-expand. Hover
and tap on the collapsed button get a subtle 1.06 / 0.94 scale spring.
Reduced-motion users get an instant swap via usePrefersReducedMotion.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* style(research): flatten the FAB into a single card, move close next to paperclip

The FAB was stacking an outer bg-card wrapper around the composer's own
card, so expanded state showed a card-on-card with the close X marooned
in the gap between them. Drop the outer wrapper entirely — the composer
is the single floating card. Expose a toolbarExtra slot on
ResearchFollowUpComposer and render the close button inside the footer
tools row, next to the paperclip, so it sits where users already look
for composer actions instead of drifting in a margin.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* refactor(research): composer is the chat bubble, outside-click closes the FAB

Drop the composer's outer rounded-2xl border wrapper — PromptInputRoot
already renders a rounded-[28px] border-bg-panel bubble, so the old
wrapper was stacking a card on top of it. Return a React fragment and
forward className straight to PromptInputRoot so the FAB can shadow the
bubble without layering another frame.

Remove the toolbarExtra slot and the close X entirely. The FAB now
collapses on outside mousedown (detected via a ref on the expanded
shell), Escape, or a successful submit. No dangling close affordance,
no nested cards.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(research): sources becomes a left sidebar drawer, not a tab

Promote Sources from a tab to a collapsible 320px drawer that slides in
from the left edge of the detail pane, so the report stays visible while
the user browses citations. Notes and Prompt remain as tabs. Toggle lives
in the right-hand action cluster next to Download; shows the source count
and flips its icon when open.

Body is now a horizontal flex of [sources drawer | scroll container], and
the drawer animates its width 0 → 20rem with the same spring we use for
the follow-up FAB (stiffness 420, damping 34, mass 0.9). usePrefersReduced
Motion collapses the transition to an instant swap.

ResearchSourcesList gains a variant prop ("card" | "inline") so the drawer
can render just the list rows without doubling up on card chrome.

Move the follow-up FAB from bottom-left to bottom-right to clear the new
drawer; update both morph states to origin-bottom-right so the spring
still anchors to the correct corner.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* style(research): sources drawer slides in from the left as an overlay

The old implementation animated width 0 → 20rem, which meant the drawer
reflowed the content area (pushing the report right and subtly affecting
the header action cluster via re-measurement). Switch to an absolutely-
positioned drawer on the left edge of the pane: fixed 320px width,
translateX(-100% → 0%) with a slightly softer spring (stiffness 380,
damping 36), and a shadow on the right edge so it reads as floating over
the content. The report stays anchored at full width behind it; the
Sources/Download buttons in the header cannot shift because nothing in
their layout context changes when the drawer toggles.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* style(research): flip sources drawer to the right edge of the pane

Move the drawer from the left edge to the right edge: absolute inset-y-0
right-0, slides in from translateX(100% → 0%), border-l instead of
border-r. Swap the toggle icon to PanelRightIcon. Put the follow-up FAB
back at bottom-left so it no longer collides with the drawer; both the
collapsed button and expanded composer use origin-bottom-left.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* style(research): push-from-right sources drawer

Drop the absolute overlay approach. Drawer is now a shrink-0 flex sibling
after the report content in the flex-row body, so when it opens the
report's flex-1 flex-basis shrinks to make room. Width animates 0 → 20rem
with the same spring, overflow-hidden + fixed w-80 inner content means
the panel visually expands from its right edge. Only the detail pane's
internal flex row is affected — the tab header (sibling of the flex row)
and everything outside the detail pane stay untouched.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* style(research): source rows look like a sidebar, not a URL card column

Rebuild the inline variant as dense flat rows: favicon (with letter
fallback) + clean title + host label + hover-only external-link hint.
Drop the per-row border/card treatment, shrink font sizes to 12.5/11px,
use padding-y 1.5 like other sidebar rows in the app. Pipe every source
through describeCitationSource so Google's opaque grounding-api-redirect
URLs show the actual host (or existing title) instead of the raw
vertexaisearch.cloud.google.com gibberish.

Drawer chrome: swap the boxed header section for a flat h-9 label row,
soften the bg to bg-muted/15, drop outer padding from p-3 to p-2.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix: make research detail layout responsive

* test: stabilize desktop research state isolation

* fix: overlay narrow research sources panel

* chore: update desktop tsbuildinfo

* chrome mcp + research tweak

* more

* Update bun.lock

* fix: restore research topbar spacing

* feat: streamline research report detail

* fix: remove research prompt card

* fix: resolve research source redirects

* fix: align research sources with citation metadata

* fix: repair research source list records

* refactor: restyle research history rail

* fix: align research rail with desktop tokens

* refactor: flatten research history list

* refactor: mirror chat sidebar rows in research rail

Drop multi-line research cards with status row + snippet + metadata and
adopt the chat sidebar's thread-row idiom: single-line rounded rows with
just title and a small right-side age. Selected and hover states reuse
the same `border-border/45 bg-foreground/[0.05]` and sidebar-lift
treatments threads use. Follow-ups keep their nested left border with a
small inline Follow-up tag. Source and note counts now live only in the
detail pane, so the rail stays readable even with long titles.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* refactor: restore report snippet in research rail rows

Bring back a 1-2 line muted snippet of the first report paragraph below
the title so each row carries a hint of the run's content. Row layout
switches to items-start to accommodate the second line while keeping the
chat-sidebar styling (rounded row, sidebar-thread-item/sidebar-lift,
transparent border that lights up on select/hover).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(desktop): add research export save dialog

* test(research): isolate export save flow coverage

* chore(desktop): refresh tsbuildinfo

* refactor(research): remove unused defensive plumbing

* fix: harden research workflow feedback

* fix: complete research follow-up safeguards

* fix: stabilize research CI feedback

* fix: avoid research cancel resume race

* fix: resolve research follow-up feedback

* linter

* docs: refresh jsonrpc generated artifacts

* biome more

* new

* refactor: clean up stale desktop Biome findings

* fix: tighten desktop runtime typing and guards

* fix: stabilize desktop hook dependencies

* fix: use semantic desktop UI controls

* chore: reduce remaining biome warnings

* chore: unblock verification lanes after biome rollout

* chore: trim remaining biome warnings

* chore: finish biome cleanup and test stabilization

* fix(mobile): type thread detail list items

* fix: close remaining deep research review threads

* fix: clean up leaked research uploads

* fix: regenerate JSON-RPC schema artifacts

* chore(desktop): refresh tsbuildinfo

* fix: close research attachment validation races

* fix: preserve live research state on follow-up refresh

* fix: reclaim rejected research uploads safely

* fix: cancel pending research plans cleanly

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

Parent8a4f225

775 files changed
  • .factory/settings.json+1−1
  • .gemini/settings.json+2−5
  • .github/workflows/ci.yml+3−36
  • .mcp.json+1−6
  • AGENTS.md+2−1
  • apps/desktop/.tsbuildinfo-desktop+1−1
  • apps/desktop/README.md+4−4
  • apps/desktop/build/icon.icon/icon.json+22−27
apps/desktop/electron.vite.config.ts
+2
−3
  • apps/desktop/electron/ipc.ts+1−1
  • apps/desktop/electron/ipc/files.ts+159−87
  • apps/desktop/electron/ipc/invoke.ts+2−2
  • apps/desktop/electron/ipc/mobileRelay.ts+43−33
  • apps/desktop/electron/ipc/system.ts+62−38
  • apps/desktop/electron/ipc/types.ts+1−1
  • apps/desktop/electron/ipc/window.ts+32−21
  • apps/desktop/electron/ipc/workspace.ts+58−32
  • apps/desktop/electron/ipc/workspaceRoots.ts+3−1
  • apps/desktop/electron/main.ts+51−32
  • apps/desktop/electron/preload.ts+28−19
  • apps/desktop/electron/services/appearance.ts+23−19
  • apps/desktop/electron/services/desktopSmoke.ts+38−12
  • apps/desktop/electron/services/dialogs.ts+4−3
  • apps/desktop/electron/services/ipcSecurity.ts+29−4
  • apps/desktop/electron/services/menu.ts+1−4
  • apps/desktop/electron/services/menuTemplate.ts+92−11
  • apps/desktop/electron/services/mobileRelayBridge.ts+156−113
  • apps/desktop/electron/services/mobileRelayStore.ts+22−13
  • apps/desktop/electron/services/mobileRelayTypes.ts+1−5
  • apps/desktop/electron/services/persistence.ts+49−28
  • apps/desktop/electron/services/remodexState.ts+61−22
  • apps/desktop/electron/services/remoteDebug.ts+21−0
  • apps/desktop/electron/services/rendererUrl.ts+1−1
  • apps/desktop/electron/services/serverManager.ts+66−37
  • apps/desktop/electron/services/sidecar.ts+14−12
  • apps/desktop/electron/services/updater.ts+40−16
  • apps/desktop/electron/services/validation.ts+16−3
  • apps/desktop/electron/services/windowChrome/index.ts+1−2
  • apps/desktop/package.json+1−1
  • apps/desktop/scripts/notarize.cjs+1−1
  • apps/desktop/src/App.tsx+76−38
  • apps/desktop/src/app/a2uiDockReducer.ts+15−12
  • apps/desktop/src/app/attachmentInputs.ts+6−4
  • apps/desktop/src/app/localStateCache.ts+1−1
  • apps/desktop/src/app/modelStream.ts+1−3
  • apps/desktop/src/app/openaiCompatibleProviderOptions.ts+38−24
  • apps/desktop/src/app/persistedProviderState.ts+16−6
  • apps/desktop/src/app/pluginManagement.ts+14−11
  • apps/desktop/src/app/providerUiState.ts+6−4
  • apps/desktop/src/app/store.actions.ts+4−3
  • apps/desktop/src/app/store.actions/a2uiDock.ts+1−6
  • apps/desktop/src/app/store.actions/backup.ts+109−42
  • apps/desktop/src/app/store.actions/bootstrap.ts+430−328
  • apps/desktop/src/app/store.actions/explorer.ts+25−54
  • apps/desktop/src/app/store.actions/mcp.ts+98−81
  • apps/desktop/src/app/store.actions/memory.ts+7−7
  • apps/desktop/src/app/store.actions/onboarding.ts+5−2
  • apps/desktop/src/app/store.actions/provider.ts+159−105
  • apps/desktop/src/app/store.actions/research.ts+957−0
  • apps/desktop/src/app/store.actions/skills.ts+176−91
  • apps/desktop/src/app/store.actions/thread.ts+184−268
  • apps/desktop/src/app/store.actions/workspace.ts+38−51
  • apps/desktop/src/app/store.actions/workspaceDefaults.ts+286−205
  • apps/desktop/src/app/store.feedMapping.ts+258−160
  • apps/desktop/src/app/store.helpers.ts+199−84
  • apps/desktop/src/app/store.helpers/backupActionKey.ts+5−1
  • apps/desktop/src/app/store.helpers/controlSocket.ts+140−75
  • apps/desktop/src/app/store.helpers/jsonRpcSocket.ts+106−44
  • apps/desktop/src/app/store.helpers/persistence.ts+5−2
  • apps/desktop/src/app/store.helpers/runtimeState.ts+15−5
  • apps/desktop/src/app/store.helpers/threadEventReducer.ts+368−186
  • apps/desktop/src/app/store.helpers/transcriptBuffer.ts+5−1
  • apps/desktop/src/app/store.ts+19−5
  • apps/desktop/src/app/transcriptHydration.ts+3−1
  • apps/desktop/src/app/types.ts+50−17
  • apps/desktop/src/components/ConnectPage.tsx+22−8
  • apps/desktop/src/components/ai-elements/conversation.tsx+19−5
  • apps/desktop/src/components/ai-elements/message.tsx+218−125
  • apps/desktop/src/components/ai-elements/prompt-input.tsx+115−83
  • apps/desktop/src/components/ai-elements/reasoning.tsx+10−4
  • apps/desktop/src/components/ai-elements/sources-carousel.tsx+46−12
  • apps/desktop/src/components/ai-elements/tool.tsx+50−16
  • apps/desktop/src/components/ui/badge.tsx+3−2
  • apps/desktop/src/components/ui/button.tsx+37−27
  • apps/desktop/src/components/ui/card.tsx+7−10
  • apps/desktop/src/components/ui/checkbox.tsx+5−3
  • apps/desktop/src/components/ui/collapsible.tsx+26−19
  • apps/desktop/src/components/ui/dialog.tsx+78−44
  • apps/desktop/src/components/ui/input.tsx+1−1
  • apps/desktop/src/components/ui/scroll-shadow.tsx+1−1
  • apps/desktop/src/components/ui/select.tsx+7−37
  • apps/desktop/src/components/ui/switch.tsx+5−3
  • apps/desktop/src/components/ui/textarea.tsx+1−1
  • apps/desktop/src/components/ui/tooltip.tsx+5−2
  • apps/desktop/src/lib/designTokens.ts+1−2
  • apps/desktop/src/lib/desktopApi.ts+19−4
  • apps/desktop/src/lib/desktopCommands.ts+49−21
  • apps/desktop/src/lib/desktopSchemas.ts+242−138
  • apps/desktop/src/lib/docxPreview.ts+38−16
  • apps/desktop/src/lib/modelChoices.ts+27−15
  • apps/desktop/src/lib/providerDisplayNames.ts+12−4
  • apps/desktop/src/lib/providerOrdering.ts+11−4
  • apps/desktop/src/lib/reactGrabDevTools.ts+1−4
  • apps/desktop/src/lib/webAdapter.ts+104−64
  • apps/desktop/src/lib/webWorkspaceState.ts+5−2
  • apps/desktop/src/lib/wsProtocol.ts+47−36
  • apps/desktop/src/main.web.tsx+1−1
  • apps/desktop/src/styles.css+13−5
  • apps/desktop/src/styles/theme-bridge.css+10−4
  • apps/desktop/src/styles/tokens/base.css+3−15
  • apps/desktop/src/styles/tokens/platform.css+8−26
  • apps/desktop/src/ui/ChatView.tsx+341−205
  • apps/desktop/src/ui/CodeFilePreview.tsx+3−5
  • apps/desktop/src/ui/ContextSidebar.tsx+68−19
  • apps/desktop/src/ui/FilePreviewModal.tsx+55−22
  • apps/desktop/src/ui/PromptModal.tsx+44−31
  • apps/desktop/src/ui/ResearchView.tsx+85−0
  • apps/desktop/src/ui/Sidebar.tsx+159−73
  • apps/desktop/src/ui/SkillsView.tsx+19−7
  • apps/desktop/src/ui/chat/ActivityGroupCard.tsx+89−27
  • apps/desktop/src/ui/chat/a2ui/A2uiInlineCard.tsx+24−10
  • apps/desktop/src/ui/chat/a2ui/A2uiRenderer.tsx+161−78
  • apps/desktop/src/ui/chat/a2ui/A2uiSurfaceDock.tsx+44−26
  • apps/desktop/src/ui/chat/a2ui/A2uiSurfaceHistoryRow.tsx+6−6
  • apps/desktop/src/ui/chat/a2ui/surfaceTitle.ts+5−4
  • apps/desktop/src/ui/chat/activityGroups.ts+44−40
  • apps/desktop/src/ui/chat/toolCards/ToolCard.tsx+19−12
  • apps/desktop/src/ui/chat/toolCards/legacyToolLogs.ts+14−8
  • apps/desktop/src/ui/chat/toolCards/toolCardFormatting.ts+53−32
  • apps/desktop/src/ui/file-explorer/WorkspaceFileExplorer.tsx+128−65
  • apps/desktop/src/ui/layout/AppTopBar.tsx+111−50
  • apps/desktop/src/ui/layout/ContextSidebarResizer.tsx+6−4
  • apps/desktop/src/ui/layout/MessageBarResizer.tsx+6−4
  • apps/desktop/src/ui/layout/PrimaryContent.tsx+36−7
  • apps/desktop/src/ui/layout/SidebarCollapseControl.tsx+3−1
  • apps/desktop/src/ui/layout/SidebarResizer.tsx+6−4
  • apps/desktop/src/ui/layout/useWindowDragHandle.ts+111−82
  • apps/desktop/src/ui/onboarding/DesktopOnboarding.tsx+327−203
  • apps/desktop/src/ui/plugins/InstallPluginDialog.tsx+113−66
  • apps/desktop/src/ui/plugins/PluginCardGrid.tsx+7−5
  • apps/desktop/src/ui/plugins/PluginDetailDialog.tsx+32−10
  • apps/desktop/src/ui/plugins/PluginsCatalogPage.tsx+22−14
  • apps/desktop/src/ui/research/NewResearchComposer.tsx+124−0
  • apps/desktop/src/ui/research/ResearchCardGrid.tsx+364−0
  • apps/desktop/src/ui/research/ResearchDetailPane.tsx+562−0
  • apps/desktop/src/ui/research/ResearchExportMenu.tsx+148−0
  • apps/desktop/src/ui/research/ResearchFollowUpComposer.tsx+136−0
  • apps/desktop/src/ui/research/ResearchReportRenderer.tsx+115−0
  • apps/desktop/src/ui/research/ResearchSettingsPopover.tsx+36−0
  • apps/desktop/src/ui/research/ResearchSourcesList.tsx+141−0
  • apps/desktop/src/ui/research/useResearchAttachments.ts+85−0
  • apps/desktop/src/ui/settings/SettingsChromeContext.tsx+1−1
  • apps/desktop/src/ui/settings/SettingsShell.tsx+23−16
  • apps/desktop/src/ui/settings/pages/BackupPage.tsx+302−116
  • apps/desktop/src/ui/settings/pages/DeveloperPage.tsx+40−16
  • apps/desktop/src/ui/settings/pages/FeatureFlagsPage.tsx+21−10
  • apps/desktop/src/ui/settings/pages/McpServersPage.tsx+441−266
  • apps/desktop/src/ui/settings/pages/MemoryPage.tsx+81−33
  • apps/desktop/src/ui/settings/pages/ProvidersPage.tsx+640−436
  • apps/desktop/src/ui/settings/pages/RemoteAccessPage.tsx+49−32
  • apps/desktop/src/ui/settings/pages/UpdatesPage.tsx+75−22
  • apps/desktop/src/ui/settings/pages/UsagePage.tsx+76−31
  • apps/desktop/src/ui/settings/pages/WorkspacesPage.tsx+425−199
  • apps/desktop/src/ui/settings/pages/mcpServerDraft.ts+19−8
  • apps/desktop/src/ui/settings/pages/mcpServerEditorState.ts+1−3
  • apps/desktop/src/ui/sidebarHelpers.ts+15−5
  • apps/desktop/src/ui/skills/InstallSkillDialog.tsx+26−12
  • apps/desktop/src/ui/skills/InstallationCardGrid.tsx+8−4
  • apps/desktop/src/ui/skills/SkillDetailDialog.tsx+237−169
  • apps/desktop/src/ui/skills/SkillsCatalogPage.tsx+14−7
  • apps/desktop/src/ui/skills/index.ts+1−1
  • apps/desktop/src/ui/skills/utils.tsx+11−3
  • apps/desktop/test/a2ui-dock-reducer.test.ts+52−11
  • apps/desktop/test/a2ui-extended-catalog.test.tsx+39−35
  • apps/desktop/test/a2ui-inline-card.test.tsx+2−5
  • apps/desktop/test/a2ui-renderer-actions.test.tsx+22−9
  • apps/desktop/test/a2ui-surface-dock.test.ts+7−4
  • apps/desktop/test/a2ui-surface-title.test.ts+4−4
  • apps/desktop/test/app-jsonrpc-disposal.test.tsx+59−43
  • apps/desktop/test/app-topbar.test.tsx+98−7
  • apps/desktop/test/attachment-inputs.test.ts+19−19
  • apps/desktop/test/backup-page.test.ts+55−43
  • apps/desktop/test/bootstrap-cache.test.ts+66−53
  • apps/desktop/test/button-component.test.tsx+1−2
  • apps/desktop/test/chat-activity-group-card.test.tsx+78−42
  • apps/desktop/test/chat-activity-groups.test.ts+226−34
  • apps/desktop/test/chat-reasoning-ui.test.ts+286−211
  • apps/desktop/test/chat-view.stability.test.tsx+134−123
  • apps/desktop/test/context-sidebar.test.tsx+103−91
  • apps/desktop/test/control-socket.test.ts+137−68
  • apps/desktop/test/desktop-smoke.test.ts+27−13
  • apps/desktop/test/developer-page.test.tsx+71−50
  • apps/desktop/test/dialog-component.test.tsx+62−53
  • apps/desktop/test/feature-flags-page.test.tsx+1−2
  • apps/desktop/test/file-preview-modal.test.tsx+22−12
  • apps/desktop/test/helpers/mockDesktopCommands.ts+11−3
  • apps/desktop/test/ipc-file-ops.test.ts+7−7
  • apps/desktop/test/ipc-files.test.ts+283−0
  • apps/desktop/test/ipc-security.test.ts+37−13
  • apps/desktop/test/ipc-window.test.ts+5−5
  • apps/desktop/test/ipc-workspace.test.ts+27−21
  • apps/desktop/test/jsdomHarness.ts+9−6
  • apps/desktop/test/jsonrpc-single-connection.test.ts+187−118
  • apps/desktop/test/legacy-tool-logs.test.ts+40−12
  • apps/desktop/test/local-state-cache.test.ts+6−2
  • apps/desktop/test/main-process-startup.test.ts+3−1
  • apps/desktop/test/mcp-server-draft.test.ts+6−2
  • apps/desktop/test/memory-actions.test.ts+3−1
  • apps/desktop/test/memory-page.test.ts+41−44
  • apps/desktop/test/menu.test.ts+6−2
  • apps/desktop/test/message-links.test.ts+50−23
  • apps/desktop/test/mobile-relay-bridge.test.ts+281−189
  • apps/desktop/test/mobile-relay-ipc.test.ts+49−33
  • apps/desktop/test/model-stream-mapper.test.ts+181−79
  • apps/desktop/test/modelChoices.test.ts+82−23
  • apps/desktop/test/onboarding-ui.test.tsx+92−47
  • apps/desktop/test/onboarding.test.ts+65−47
  • apps/desktop/test/persistence-state-sanitization.test.ts+48−11
  • apps/desktop/test/plugin-detail-dialog.test.tsx+47−45
  • apps/desktop/test/plugins-catalog-page.test.ts+261−154
  • apps/desktop/test/prompt-modal-ask.test.ts+7−4
  • apps/desktop/test/protocol-v2-events.test.ts+198−105
  • apps/desktop/test/provider-actions.test.ts+0−1
  • apps/desktop/test/providers-page.test.ts+136−56
  • apps/desktop/test/react-grab-dev-tools.test.ts+28−13
  • apps/desktop/test/remodex-state.test.ts+141−74
  • apps/desktop/test/remote-access-page.test.ts+143−139
  • apps/desktop/test/remote-debug.test.ts+56−0
  • apps/desktop/test/research-actions.test.ts+675−0
  • apps/desktop/test/research-detail-pane.test.tsx+428−0
  • apps/desktop/test/research-export-menu.test.tsx+159−0
  • apps/desktop/test/research-view-layout.test.tsx+193−0
  • apps/desktop/test/runtimeState.test.ts+6−2
  • apps/desktop/test/server-manager.test.ts+26−7
  • apps/desktop/test/settings-nav.test.ts+156−69
  • apps/desktop/test/settings-shell.test.ts+4−2
  • apps/desktop/test/sidebar-resizer.test.tsx+1−2
  • apps/desktop/test/sidebar-ui.test.tsx+268−238
  • apps/desktop/test/sidecar.test.ts+20−12
  • apps/desktop/test/skill-detail-dialog.test.ts+73−58
  • apps/desktop/test/skills-actions.test.ts+159−67
  • apps/desktop/test/skills-catalog-page.test.ts+76−53
  • apps/desktop/test/sources-carousel.test.tsx+12−6
  • apps/desktop/test/store-explorer.test.ts+78−51
  • apps/desktop/test/store-feed-mapping.test.ts+76−19
  • apps/desktop/test/thread-reconnect.test.ts+92−67
  • apps/desktop/test/time-format.test.ts+0−1
  • apps/desktop/test/token-compliance.test.ts+8−2
  • apps/desktop/test/token-consumers.test.tsx+11−10
  • apps/desktop/test/tool-card-formatting.test.ts+28−10
  • apps/desktop/test/updater-service.test.ts+15−4
  • apps/desktop/test/updates-page.test.ts+49−40
  • apps/desktop/test/usage-page.test.ts+114−45
  • apps/desktop/test/web-adapter.test.ts+37−32
  • apps/desktop/test/window-enhancements.test.ts+3−3
  • apps/desktop/test/workspace-file-explorer-ui.test.tsx+87−76
  • apps/desktop/test/workspace-file-explorer.test.ts+10−10
  • apps/desktop/test/workspace-mcp-editor.test.ts+50−38
  • apps/desktop/test/workspace-settings-sync.test.ts+228−118
  • apps/desktop/test/workspace-startup.test.ts+61−50
  • apps/desktop/test/workspaces-page.test.ts+183−79
  • apps/desktop/vite.config.web.ts+6−5
  • apps/mobile/app.json+3−12
  • apps/mobile/babel.config.js+1−1
  • apps/mobile/modules/remodex-secure-transport/src/index.ts+371−278
  • apps/mobile/src/app/(app)/(tabs)/_layout.tsx+4−6
  • apps/mobile/src/app/(app)/(tabs)/settings/index.tsx+4−7
  • apps/mobile/src/app/(app)/(tabs)/skills/index.tsx+103−27
  • apps/mobile/src/app/(app)/(tabs)/threads/index.tsx+6−5
  • apps/mobile/src/app/(app)/(tabs)/workspace/index.tsx+16−24
  • apps/mobile/src/app/(app)/_layout.tsx+3−7
  • apps/mobile/src/app/(app)/settings/mcp.tsx+158−57
  • apps/mobile/src/app/(app)/settings/providers.tsx+78−15
  • apps/mobile/src/app/(app)/settings/usage.tsx+8−1
  • apps/mobile/src/app/(app)/thread/[id].tsx+45−22
  • apps/mobile/src/app/(app)/workspace/backups.tsx+83−27
  • apps/mobile/src/app/(app)/workspace/general.tsx+49−16
  • apps/mobile/src/app/(app)/workspace/memory.tsx+31−12
  • apps/mobile/src/app/(pairing)/index.tsx+273−365
  • apps/mobile/src/app/(pairing)/scan.tsx+27−9
  • apps/mobile/src/app/index.tsx+1−2
  • apps/mobile/src/components/FileExplorerDrawer.tsx+20−7
  • apps/mobile/src/components/thread/a2ui-surface-card.tsx+34−25
  • apps/mobile/src/components/thread/markdown-text.tsx+26−13
  • apps/mobile/src/components/thread/pending-request-card.tsx+1−4
  • apps/mobile/src/components/thread/reasoning-card.tsx+1−3
  • apps/mobile/src/components/thread/subagent-bar.tsx+4−1
  • apps/mobile/src/components/thread/thread-feed-item.tsx+2−2
  • apps/mobile/src/components/thread/tool-call-card.tsx+13−3
  • apps/mobile/src/components/ui/app-button.tsx+1−5
  • apps/mobile/src/components/ui/header-glass-button.tsx+2−3
  • apps/mobile/src/components/ui/hub-link-row.tsx+1−1
  • apps/mobile/src/components/ui/screen.tsx+1−5
  • apps/mobile/src/components/ui/sf-symbol.tsx+20−18
  • apps/mobile/src/components/workspace/workspace-switcher.tsx+29−13
  • apps/mobile/src/features/cowork/backupStore.ts+15−7
  • apps/mobile/src/features/cowork/controlRpc.ts+8−6
  • apps/mobile/src/features/cowork/jsonRpcClient.ts+91−65
  • apps/mobile/src/features/cowork/mcpStore.ts+12−3
  • apps/mobile/src/features/cowork/memoryStore.ts+6−2
  • apps/mobile/src/features/cowork/protocolTypes.ts+359−266
  • apps/mobile/src/features/cowork/providerStore.ts+16−11
  • apps/mobile/src/features/cowork/sessionBootstrap.ts+2−1
  • apps/mobile/src/features/cowork/skillsStore.ts+39−12
  • apps/mobile/src/features/cowork/snapshotReducer.ts+19−8
  • apps/mobile/src/features/cowork/threadStore.ts+44−36
  • apps/mobile/src/features/cowork/workspaceStore.ts+11−5
  • apps/mobile/src/features/pairing/pairingStore.ts+3−6
  • apps/mobile/src/features/pairing/qrValidation.ts+14−12
  • apps/mobile/src/features/relay/connectionState.ts+15−5
  • apps/mobile/src/features/relay/relayTypes.ts+1−4
  • apps/mobile/src/features/relay/secureTransportClient.ts+26−23
  • apps/mobile/src/polyfills/crypto.ts+4−3
  • apps/mobile/src/providers/MobileAppProvider.tsx+21−9
  • apps/mobile/tsconfig.json+2−9
  • biome.json+344−0
  • bun.lock+236−335
  • docs/generated/websocket-jsonrpc.d.ts+37−3
  • docs/generated/websocket-jsonrpc.schema.json+1−1
  • docs/harness/index.md+3−0
  • docs/session-storage-architecture.md+4−0
  • docs/websocket-protocol.md+99−0
  • examples/ws-legacy-smoke.ts+7−5
  • opencode.json+2−6
  • package.json+21−8
  • scripts/build_cowork_server_binary.ts+42−12
  • scripts/build_desktop_resources.ts+30−24
  • scripts/check_docs.ts+28−13
  • scripts/chrome_inspector.ts+15−13
  • scripts/generate_ws_jsonrpc_schema.ts+4−1
  • scripts/postinstall.ts+1−1
  • scripts/releaseBuildUtils.ts+39−18
  • scripts/run_raw_agent_loops.ts+353−193
  • scripts/run_tests_stable.ts+6−1
  • scripts/start_web_dev.ts+9−4
  • src/agent.ts+58−26
  • src/auth/oauth-server.ts+8−3
  • src/cli/parser.ts+23−5
  • src/cli/prompts.ts+7−1
  • src/cli/repl.ts+73−41
  • src/cli/repl/authPrompts.ts+16−11
  • src/cli/repl/commandRouter.ts+48−29
  • src/cli/repl/promptController.ts+2−2
  • src/cli/repl/serverEventHandler.ts+40−26
  • src/cli/repl/stateStore.ts+14−10
  • src/cli/repl/streamFormatting.ts+3−6
  • src/client/jsonRpcSocket.ts+61−27
  • src/config.ts+202−112
  • src/connect.ts+29−29
  • src/harness/buildTurnSystemPrompt.ts+26−10
  • src/harness/contextStore.ts+0−1
  • src/harness/rawLoopValidation.ts+85−32
  • src/harness/renderHarnessContextSection.ts+1−3
  • src/mcp/authStore.ts+15−18
  • src/mcp/authStore/editor.ts+12−3
  • src/mcp/authStore/parser.ts+24−17
  • src/mcp/authStore/resolver.ts+6−2
  • src/mcp/authStore/store.ts+12−4
  • src/mcp/authStore/types.ts+1−1
  • src/mcp/configRegistry.ts+14−15
  • src/mcp/configRegistry/editor.ts+14−4
  • src/mcp/configRegistry/layers.ts+68−17
  • src/mcp/configRegistry/types.ts+7−1
  • src/mcp/index.ts+71−43
  • src/mcp/oauthProvider.ts+61−34
  • src/memoryStore.ts+32−19
  • src/models/childAgentModelInfo.ts+66−20
  • src/models/childModelRouting.ts+42−15
  • src/models/metadata.ts+12−9
  • src/models/registry.ts+54−35
  • src/observability/otel.ts+11−10
  • src/observability/runtime.ts+15−10
  • src/plugins/catalog.ts+25−12
  • src/plugins/discovery.ts+14−8
  • src/plugins/index.ts+12−12
  • src/plugins/manifest.ts+120−70
  • src/plugins/marketplace.ts+50−29
  • src/plugins/mcp.ts+77−48
  • src/plugins/operations.ts+24−22
  • src/plugins/overrides.ts+17−9
  • src/plugins/skillBridge.ts+15−5
  • src/plugins/sourceResolver.ts+98−59
  • src/projectInstructions.ts+25−11
  • src/prompt.ts+120−65
  • src/providerStatus.ts+198−97
  • src/providers/anthropic.ts+9−3
  • src/providers/authRegistry.ts+69−22
  • src/providers/baseten.ts+9−3
  • src/providers/basetenShared.ts+4−8
  • src/providers/bedrock.ts+1−1
  • src/providers/bedrockShared.ts+119−76
  • src/providers/catalog.ts+7−4
  • src/providers/codex-auth.ts+86−55
  • src/providers/codex-cli.ts+9−2
  • src/providers/codex-oauth-flows.ts+56−30
  • src/providers/connectionCatalog.ts+46−26
  • src/providers/fireworks.ts+9−3
  • src/providers/fireworksShared.ts+3−4
  • src/providers/google.ts+9−3
  • src/providers/googleReplay.ts+32−16
  • src/providers/index.ts+20−11
  • src/providers/lmstudio.ts+9−2
  • src/providers/lmstudio/catalog.ts+54−38
  • src/providers/lmstudio/client.ts+10−15
  • src/providers/modelAdapter.ts+60−35
  • src/providers/nvidia.ts+9−3
  • src/providers/nvidiaShared.ts+3−4
  • src/providers/openai.ts+9−3
  • src/providers/opencode-go.ts+8−2
  • src/providers/opencode-zen.ts+8−2
  • src/providers/opencodeShared.ts+29−12
  • src/providers/together.ts+9−3
  • src/providers/togetherShared.ts+4−8
  • src/runtime/bedrockProviderModule.ts+68−30
  • src/runtime/googleInteractionsRuntime.ts+58−40
  • src/runtime/googleNativeInteractions.ts+163−77
  • src/runtime/index.ts+9−6
  • src/runtime/openaiEventStream.ts+3−1
  • src/runtime/openaiNativeResponses.ts+53−32
  • src/runtime/openaiResponsesModel.ts+11−7
  • src/runtime/openaiResponsesProjector.ts+49−16
  • src/runtime/openaiResponsesRuntime.ts+50−27
  • src/runtime/openaiResponsesShared.ts+35−19
  • src/runtime/piMessageBridge.ts+67−43
  • src/runtime/piRuntime.ts+122−74
  • src/runtime/piRuntimeOptions.ts+64−50
  • src/runtime/piStreamParts.ts+60−43
  • src/runtime/toolOutputOverflow.ts+14−9
  • src/runtime/types.ts+1−2
  • src/server/agents/AgentControl.ts+46−20
  • src/server/agents/DelegateRunner.ts+17−7
  • src/server/agents/StatusBus.ts+15−8
  • src/server/agents/commandPolicy.ts+99−34
  • src/server/agents/modelRouter.ts+80−33
  • src/server/agents/reportParser.ts+1−1
  • src/server/agents/roles.ts+32−3
  • src/server/agents/toolPolicy.ts+4−1
  • src/server/agents/types.ts+5−6
  • src/server/citationMetadata.ts+129−76
  • src/server/commands.ts+21−9
  • src/server/index.ts+5−4
  • src/server/jsonrpc/decodeJsonRpcMessage.ts+1−1
  • src/server/jsonrpc/dispatchJsonRpcMessage.ts+76−45
  • src/server/jsonrpc/eventProjector.ts+1−1
  • src/server/jsonrpc/journalProjector.ts+82−50
  • src/server/jsonrpc/projectorShared.ts+1−1
  • src/server/jsonrpc/protocol.ts+49−33
  • src/server/jsonrpc/routes/a2ui.ts+22−22
  • src/server/jsonrpc/routes/agents.ts+15−7
  • src/server/jsonrpc/routes/index.ts+4−2
  • src/server/jsonrpc/routes/mcp.ts+21−13
  • src/server/jsonrpc/routes/memory.ts+10−11
  • src/server/jsonrpc/routes/outcomes.ts+31−10
  • src/server/jsonrpc/routes/plugins.ts+19−18
  • src/server/jsonrpc/routes/provider.ts+70−61
  • src/server/jsonrpc/routes/research.ts+133−0
  • src/server/jsonrpc/routes/session.ts+102−60
  • src/server/jsonrpc/routes/shared.ts+13−14
  • src/server/jsonrpc/routes/skills.ts+41−23
  • src/server/jsonrpc/routes/thread.ts+73−52
  • src/server/jsonrpc/routes/turn.ts+29−25
  • src/server/jsonrpc/routes/types.ts+12−2
  • src/server/jsonrpc/routes/workspace.ts+19−12
  • src/server/jsonrpc/routes/workspaceBackups.ts+33−22
  • src/server/jsonrpc/schema.a2ui.ts+4−3
  • src/server/jsonrpc/schema.agents.ts+103−76
  • src/server/jsonrpc/schema.backups.ts+20−12
  • src/server/jsonrpc/schema.core.ts+40−25
  • src/server/jsonrpc/schema.mcp.ts+10−9
  • src/server/jsonrpc/schema.memory.ts+0−1
  • src/server/jsonrpc/schema.misc.ts+20−14
  • src/server/jsonrpc/schema.provider.ts+6−8
  • src/server/jsonrpc/schema.research.ts+214−0
  • src/server/jsonrpc/schema.session.ts+125−89
  • src/server/jsonrpc/schema.sessionRuntime.ts+177−134
  • src/server/jsonrpc/schema.skills.ts+24−18
  • src/server/jsonrpc/schema.threadTurn.ts+277−185
  • src/server/jsonrpc/schema.ts+8−0
  • src/server/jsonrpc/schema.workspace.ts+12−9
  • src/server/jsonrpc/sessionEventCapture.ts+1−1
  • src/server/jsonrpc/threadReadProjector.ts+38−15
  • src/server/jsonrpc/transportAdapter.ts+49−44
  • src/server/modelStream.ts+27−10
  • src/server/projection/conversationProjection.ts+72−46
  • src/server/projection/shared.ts+7−2
  • src/server/protocol.ts+401−350
  • src/server/research/ResearchService.ts+1453−0
  • src/server/research/export/exportDocx.ts+299−0
  • src/server/research/export/exportMarkdown.ts+69−0
  • src/server/research/export/exportPdf.tsx+343−0
  • src/server/research/export/index.ts+28−0
  • src/server/research/export/markdownAst.ts+60−0
  • src/server/research/researchFileStore.ts+224−0
  • src/server/research/researchRuntime.ts+197−0
  • src/server/research/settings.ts+12−0
  • src/server/research/types.ts+93−0
  • src/server/session/A2uiSurfaceManager.ts+25−15
  • src/server/session/AgentSession.ts+278−137
  • src/server/session/HistoryManager.ts+8−2
  • src/server/session/InteractionManager.ts+11−8
  • src/server/session/McpManager.ts+2−2
  • src/server/session/PersistenceManager.ts+9−9
  • src/server/session/ProviderAuthManager.ts+155−54
  • src/server/session/ProviderCatalogManager.ts+21−9
  • src/server/session/SessionAdminManager.ts+275−82
  • src/server/session/SessionBackupController.ts+82−22
  • src/server/session/SessionContext.ts+37−24
  • src/server/session/SessionMetadataManager.ts+109−75
  • src/server/session/SessionRuntimeSupport.ts+6−4
  • src/server/session/SessionSnapshotBuilder.ts+14−6
  • src/server/session/SessionSnapshotProjector.ts+51−16
  • src/server/session/SkillManager.ts+208−69
  • src/server/session/TurnExecutionManager.ts+195−85
  • src/server/session/mcp/McpAuthFlow.ts+26−10
  • src/server/session/mcp/McpRegistryFlow.ts+24−5
  • src/server/session/mcp/McpValidationFlow.ts+13−5
  • src/server/sessionBackup.ts+56−18
  • src/server/sessionBackup/command.ts+1−1
  • src/server/sessionBackup/delta.ts+20−6
  • src/server/sessionBackup/fileSystem.ts+6−2
  • src/server/sessionBackup/fingerprint.ts+5−2
  • src/server/sessionBackup/metadata.ts+5−2
  • src/server/sessionBackup/snapshot.ts+5−3
  • src/server/sessionBackup/tar.ts+6−2
  • src/server/sessionDb.ts+50−9
  • src/server/sessionDb/legacyImport.ts+1−1
  • src/server/sessionDb/mappers.ts+192−133
  • src/server/sessionDb/migrations.ts+21−0
  • src/server/sessionDb/normalizers.ts+17−7
  • src/server/sessionDb/repository.ts+468−77
  • src/server/sessionDb/writeCoordinator.ts+25−18
  • src/server/sessionStore.ts+333−248
  • src/server/sessionTitleService.ts+13−10
  • src/server/sharedSkillMutationSignal.ts+6−6
  • src/server/startServer.ts+290−174
  • src/server/startServer/types.ts+9−6
  • src/server/webDesktopRoutes.ts+88−47
  • src/server/webDesktopService.ts+101−66
  • src/server/workspaceBackups.ts+68−26
  • src/session/costTracker.ts+442−414
  • src/session/index.ts+16−16
  • src/session/pricing.ts+38−20
  • src/session/sessionUsageSchema.ts+65−53
  • src/shared/a2ui/component.ts+2−2
  • src/shared/a2ui/expressions.ts+2−1
  • src/shared/a2ui/functions.ts+26−20
  • src/shared/a2ui/index.ts+24−28
  • src/shared/a2ui/protocol.ts+5−4
  • src/shared/a2ui/surface.ts+19−11
  • src/shared/agents.ts+68−46
  • src/shared/askPrompt.ts+1−1
  • src/shared/attachments.ts+11−7
  • src/shared/displayCitationMarkers.ts+147−84
  • src/shared/featureFlags.ts+4−2
  • src/shared/googleInteractionsStreamParts.ts+88−30
  • src/shared/googleThinking.ts+12−11
  • src/shared/jsonrpcControlSchemas.ts+1281−986
  • src/shared/mobileRelaySecurity.ts+121−81
  • src/shared/modelStream.ts+49−32
  • src/shared/modelStreamReplay.ts+24−11
  • src/shared/openaiCompatibleOptions.ts+70−39
  • src/shared/openaiContinuation.ts+23−11
  • src/shared/projectedItems.ts+111−91
  • src/shared/providerAuthMethods.ts+1−4
  • src/shared/providerContinuation.ts+12−15
  • src/shared/sessionSnapshot.ts+184−151
  • src/shared/structuredInput.ts+18−16
  • src/skills/catalog.ts+82−28
  • src/skills/defaultGlobalSkills.ts+33−22
  • src/skills/github.ts+4−2
  • src/skills/index.ts+25−18
  • src/skills/manifest.ts+28−18
  • src/skills/operations.ts+103−39
  • src/skills/sourceResolver.ts+101−48
  • src/store/connections.ts+71−47
  • src/tools/a2ui.ts+20−15
  • src/tools/api-keys.ts+2−2
  • src/tools/ask.ts+30−26
  • src/tools/bash.ts+29−10
  • src/tools/context.ts+20−14
  • src/tools/edit.ts+7−6
  • src/tools/exa.ts+18−13
  • src/tools/glob.ts+44−23
  • src/tools/grep.ts+18−10
  • src/tools/index.ts+29−18
  • src/tools/memory.ts+18−11
  • src/tools/notebookEdit.ts+32−21
  • src/tools/parallel.ts+32−26
  • src/tools/persistentAgents.ts+31−9
  • src/tools/read.ts+4−5
  • src/tools/skill.ts+5−2
  • src/tools/spawnAgent.ts+24−22
  • src/tools/usage.ts+167−153
  • src/tools/webFetch.ts+75−49
  • src/tools/webSearch.ts+93−59
  • src/tools/write.ts+3−4
  • src/types.ts+9−10
  • src/utils/approval.ts+11−6
  • src/utils/atomicFile.ts+3−3
  • src/utils/authHome.ts+4−1
  • src/utils/paths.ts+2−2
  • src/utils/permissions.ts+10−16
  • src/utils/ripgrep.ts+80−37
  • src/utils/webSafety.ts+8−5
  • src/utils/workspacePath.ts+14−3
  • src/workspace/context.ts+6−5
  • src/workspace/map.ts+33−10
  • test/a2ui/actionValidation.test.ts+3−4
  • test/a2ui/conversationProjection.test.ts+1−1
  • test/a2ui/expressions.test.ts+4−4
  • test/a2ui/feedItem.test.ts+3−4
  • test/a2ui/functions.test.ts+23−11
  • test/a2ui/integration.test.ts+17−13
  • test/a2ui/jsonRpcActionRoute.test.ts+92−52
  • test/a2ui/mobileReducer.test.ts+1−1
  • test/a2ui/protocol.test.ts+5−2
  • test/a2ui/surface.test.ts+14−13
  • test/a2ui/surfaceManager.test.ts+82−43
  • test/agent.remote-mcp.grep.test.ts+66−71
  • test/agent.test.ts+118−67
  • test/agent.toolloop.test.ts+55−55
  • test/agentControl.test.ts+135−62
  • test/approval.test.ts+26−28
  • test/atomicFile.test.ts+17−23
  • test/bash.readonly-policy.test.ts+70−56
  • test/childModelRouting.test.ts+4−2
  • test/ci.workflow.test.ts+10−9
  • test/citationMetadata.test.ts+13−7
  • test/config.test.ts+67−50
  • test/connect.test.ts+32−21
  • test/cowork-server-release.workflow.test.ts+2−5
  • test/default-global-skills.test.ts+24−8
  • test/delegateRunner.test.ts+13−6
  • test/desktop-release.workflow.test.ts+31−12
  • test/desktop.controlSocket.configUpdated.test.ts+28−19
  • test/desktop.controlSocket.threadList.test.ts+40−26
  • test/desktop.providerDisplayNames.test.ts+12−15
  • test/displayCitationMarkers.test.ts+294−175
  • test/docs.check.test.ts+34−28
  • test/fixtures/mcp-local-integration-runner.ts+20−14
  • test/fixtures/session-db-worker.ts+30−12
  • test/harness-context-store.test.ts+28−17
  • test/harness.raw-loop-validation.test.ts+48−40
  • test/harness.ws.e2e.test.ts+223−187
  • test/helpers/mock-react-native.ts+24−7
  • test/helpers/wsHarness.ts+38−15
  • test/jsonrpc.codegen.test.ts+20−8
  • test/jsonrpc.control-schemas.test.ts+144−125
  • test/jsonrpc.projectors.test.ts+269−125
  • test/jsonrpc.protocol.test.ts+30−24
  • test/jsonrpc.router.test.ts+41−33
  • test/jsonrpc.routes.review-fixes.test.ts+50−22
  • test/jsonrpc.thread-read-projector.test.ts+1−3
  • test/jsonrpcSocket.runtime.test.ts+91−46
  • test/mcp.auth-flow.test.ts+32−15
  • test/mcp.auth-store.test.ts+28−11
  • test/mcp.config-registry.test.ts+192−100
  • test/mcp.local.integration.test.ts+1−4
  • test/mcp.oauth-provider.test.ts+62−40
  • test/mcp.remote.grep.test.ts+38−25
  • test/mcp.test.ts+64−19
  • test/mobile.connection-state.test.ts+45−33
  • test/mobile.control-store.test.ts+76−55
  • test/mobile.jsonrpc-client.test.ts+241−213
  • test/mobile.pairing-qrcode.test.ts+30−21
  • test/mobile.pairing-scan-handler.test.ts+7−5
  • test/mobile.relay-security.test.ts+18−10
  • test/mobile.remodex-native-contract.test.ts+12−12
  • test/mobile.thread-feed-item.test.tsx+4−2
  • test/mobile.thread-store.test.ts+12−9
  • test/mobile.transport-integration.test.ts+33−15
  • test/mobile.transport.relay-role.test.ts+6−4
  • test/mobile.transport.secure-finalize.test.ts+111−80
  • test/mobile.workspace-switch-bootstrap.test.ts+24−20
  • test/model-stream.provider-loop.test.ts+2−2
  • test/modelStreamReplay.test.ts+337−285
  • test/models.registry.test.ts+59−16
  • test/observability.otel-extended.test.ts+4−5
  • test/observability.otel.test.ts+11−8
  • test/observability.runtime.test.ts+1−2
  • test/package-manifest.test.ts+1−2
  • test/paths.test.ts+8−8
  • test/permissions.test.ts+27−11
  • test/persistentAgents.tool.test.ts+22−12
  • test/plugins.catalog.test.ts+417−222
  • test/plugins.sourceResolver.test.ts+57−21
  • test/projectInstructions.test.ts+14−3
  • test/prompt.test.ts+196−144
  • test/providerStatus.test.ts+116−75
  • test/providers/auth-registry.test.ts+52−40
  • test/providers/baseten.test.ts+1−1
  • test/providers/bedrock-shared.test.ts+76−67
  • test/providers/bedrock.test.ts+18−15
  • test/providers/codex-auth.test.ts+30−15
  • test/providers/codex-cli.test.ts+8−1
  • test/providers/codex-oauth-flows.test.ts+28−20
  • test/providers/connection-catalog.test.ts+4−2
  • test/providers/cross-provider.test.ts+5−5
  • test/providers/fireworks.test.ts+1−1
  • test/providers/google.test.ts+7−3
  • test/providers/helpers.ts+3−2
  • test/providers/index.test.ts+28−6
  • test/providers/live-api.integration.test.ts+9−4
  • test/providers/lmstudio.test.ts+44−32
  • test/providers/modelAdapter.test.ts+24−15
  • test/providers/nvidia.test.ts+1−1
  • test/providers/provider-options.test.ts+3−9
  • test/providers/saved-keys.test.ts+1−1
  • test/providers/together.test.ts+1−1
  • test/repl.disconnect-send.test.ts+51−47
  • test/repl.prompt-controller.test.ts+1−1
  • test/repl.restart-failure.test.ts+138−137
  • test/repl.resume-cwd.test.ts+44−41
  • test/repl.server-event-handler.test.ts+5−3
  • test/repl.test.ts+9−14
  • test/repl.thread-envelope.test.ts+54−48
  • test/research.schemas.test.ts+89−0
  • test/research.test.ts+1750−0
  • test/run_raw_agent_loops.test.ts+39−23
  • test/runtime.google-interactions.test.ts+295−220
  • test/runtime.openai-responses-runtime.test.ts+201−134
  • test/runtime.pi-message-bridge.test.ts+30−9
  • test/runtime.pi-options.test.ts+163−146
  • test/runtime.pi-runtime.test.ts+350−259
  • test/server.backpressure.test.ts+9−4
  • test/server.commands.test.ts+10−6
  • test/server.jsonrpc.control.test.ts+185−102
  • test/server.jsonrpc.flow.test.ts+590−367
  • test/server.jsonrpc.test.ts+117−79
  • test/server.memory.test.ts+1−1
  • test/server.model-stream.test.ts+110−159
  • test/server.test.ts+51−46
  • test/server.toolstream.test.ts+64−22
  • test/session-backup-delta.test.ts+3−1
  • test/session-backup.test.ts+68−18
  • test/session-db-mappers.test.ts+7−5
  • test/session-db-write-coordinator.test.ts+86−59
  • test/session-db.test.ts+36−12
  • test/session-store.test.ts+6−2
  • test/session-title-service.test.ts+6−2
  • test/session.managers.test.ts+130−116
  • test/session.stream-pipeline.test.ts+20−16
  • test/session.test.ts+812−416
  • test/session/pricing.test.ts+320−320
  • test/sessionSnapshotBuilder.test.ts+9−9
  • test/sessionSnapshotProjector.test.ts+20−9
  • test/shared/googleInteractionsStreamParts.test.ts+47−28
  • test/shared/googleThinking.test.ts+6−2
  • test/shared/openaiCompatibleOptions.test.ts+37−27
  • test/shared/processLock.ts+1−4
  • test/skills.catalog.test.ts+71−29
  • test/skills.extractTriggers.test.ts+10−7
  • test/skills.operations.test.ts+58−25
  • test/skills.sourceResolver.test.ts+44−22
  • test/skills.test.ts+29−13
  • test/slides-scripts.test.ts+25−11
  • test/spawnAgent.tool.test.ts+129−93
  • test/start_web_dev.test.ts+2−2
  • test/statusBus.test.ts+1−2
  • test/structured-input.test.ts+5−5
  • test/tools.api-keys.test.ts+2−7
  • test/tools.exa.test.ts+21−17
  • test/tools.test.ts+277−228
  • test/tools.usage.test.ts+131−128
  • test/tools/a2ui.test.ts+3−7
  • test/types.test.ts+0−2
  • test/utils.browser.test.ts+2−2
  • test/version.test.ts+1−1
  • test/webDesktopRoutes.test.ts+13−15
  • test/webSafety.test.ts+13−12
  • test/workspace-backups.test.ts+27−12
  • test/workspace-path.test.ts+14−4
  • test/workspace.map.test.ts+2−6
  • test/ws-protocol-negotiation.test.ts+30−22
  • test_model.ts+31−9