Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
130 commits
Select commit Hold shift + click to select a range
ac108e4
checkpoint
Sg312 Aug 12, 2026
797076c
Checkpoint
Sg312 Aug 12, 2026
a63c8fa
dot fixes
Sg312 Aug 12, 2026
b5bae34
Make async tool resume delivery recoverable
Sg312 Aug 12, 2026
eaee669
Support split table tools and option recovery
Sg312 Aug 13, 2026
3738347
Harden VFS mutation handling
Sg312 Aug 13, 2026
a721895
feat(platform): platform subagent support — docs corpus VFS, search_d…
j15z Aug 13, 2026
73ff4b7
Align Copilot tools and resource handling
Sg312 Aug 13, 2026
733e522
Expand workflow log query support
Sg312 Aug 13, 2026
2c8acbf
checkpoint
Sg312 Aug 13, 2026
297525e
Merge branch 'desktop-improvements-0' into mship-fixes
Sg312 Aug 13, 2026
46aae11
Port desktop-improvements-0 desktop and browser-agent work
Sg312 Aug 13, 2026
85ffaa7
fix(desktop): keep browser-agent input alive through live-SPA re-renders
Sg312 Aug 13, 2026
f54f7e0
Harden workflow sanitization and Slack setup
Sg312 Aug 13, 2026
6f36331
feat(desktop): coordinate clicks, caret insertion, and drag for the b…
Sg312 Aug 13, 2026
0cab4d0
Revert subagent group eager auto-collapse
Sg312 Aug 13, 2026
0f3f2fa
fix(chat): keep sends FIFO across the streaming-to-idle drain gap
Sg312 Aug 13, 2026
98baa20
Add the steering backend surface for mid-turn sends
Sg312 Aug 13, 2026
2f6e4ca
Sync generated contracts for async subagent orchestration
Sg312 Aug 14, 2026
7f9f11f
Add display titles for the async subagent orchestration tools
Sg312 Aug 14, 2026
4ad9f17
Show orchestrator-chosen subagent names on agent groups
Sg312 Aug 14, 2026
ba78829
Improve Copilot error handling and logging
Sg312 Aug 14, 2026
752ddd2
Backfill the subagent display name from the second start event
Sg312 Aug 14, 2026
0e78b14
Support Slack bot connection flow
Sg312 Aug 14, 2026
a4cdfa0
Harden Copilot error and VFS handling
Sg312 Aug 14, 2026
e0a1484
Harden VFS resource operations
Sg312 Aug 14, 2026
63bc108
Show 'Waiting for the first of N agents' for mode-any waits
Sg312 Aug 14, 2026
c516836
Collapsed-by-default agent cards with live intent status lines
Sg312 Aug 14, 2026
97cd8b7
Add the internal in-band tool execution route for live mothership turns
Sg312 Aug 14, 2026
dfccbac
Persist resource side effects for in-band tool execution
Sg312 Aug 14, 2026
90d07b0
Extract intents from group text on every path, sync and async
Sg312 Aug 14, 2026
9aaa428
Fall back to the live tool title for the agent card status line
Sg312 Aug 14, 2026
95153c0
Catch subagent <intent> tags in the server relay
Sg312 Aug 14, 2026
99397de
Drop the tool-title fallback: the status line is the agent's intent
Sg312 Aug 14, 2026
af516f3
Replace intents with live tool-title status lines on agent cards
Sg312 Aug 14, 2026
1e51860
Keep the main Sim lane live-expanded; collapse only real subagent cards
Sg312 Aug 14, 2026
b98ef9b
Persist subagent lane lifecycle blocks from the span handler
Sg312 Aug 14, 2026
19e5efd
Name agents in orchestration titles; '+ n more' overflow format
Sg312 Aug 14, 2026
e7a0d1c
Harden in-band tool execution and resources
Sg312 Aug 14, 2026
986829e
Route in-band execution through the comprehensive tool dispatcher
Sg312 Aug 14, 2026
9c364ad
Harden chat stream transition handling
Sg312 Aug 15, 2026
503b96f
Harden VFS provenance and resource writes
Sg312 Aug 15, 2026
56128be
Standardize tool environment references
Sg312 Aug 15, 2026
d1b9f1b
Harden browser panel and chat cleanup
Sg312 Aug 15, 2026
002a3a3
Merge remote-tracking branch 'origin/staging' into mship-fixes
Sg312 Aug 15, 2026
3d7ba5f
Descriptive, user-language tool titles across the board
Sg312 Aug 15, 2026
d3a1904
Deploying {workflow} as chat, not as chat app
Sg312 Aug 15, 2026
6f6e972
Loader gerunds; mv names both ends; mkdir names the folder
Sg312 Aug 15, 2026
382c2eb
Overflow counts read '+ n', dropping 'more'
Sg312 Aug 15, 2026
a566c49
Unify workspace find and search
Sg312 Aug 15, 2026
caabfd3
Merge remote-tracking branch 'origin/staging' into mship-fixes
Sg312 Aug 15, 2026
833d2f1
Scale desktop title bar with page zoom
Sg312 Aug 15, 2026
56958d6
Merge remote-tracking branch 'origin/feat/platform-agent' into mship-…
Sg312 Aug 15, 2026
34a5edb
Serialize account and organization truth into the copilot VFS
Sg312 Aug 15, 2026
370896d
Fix insert_text refusing an editable field focused inside a frame
Sg312 Aug 16, 2026
da39cf0
Keep retired browser takeover renderable in history
Sg312 Aug 16, 2026
7b3a804
Follow the agent into a tab it opened to work in
Sg312 Aug 16, 2026
d8b604b
Make the browser tools agree with each other
Sg312 Aug 16, 2026
1c4f404
Let hover actually see what it mounted
Sg312 Aug 16, 2026
e271252
Stop the browser agent acting on the wrong element, and say why it re…
Sg312 Aug 16, 2026
2b7b6de
Let edit_workflow configure block retries
Sg312 Aug 16, 2026
997fdd9
Updates
Sg312 Aug 17, 2026
7b522ce
Merge remote-tracking branch 'origin/staging' into mship-fixes
icecrasher321 Aug 17, 2026
d0fc1e0
Merge remote-tracking branch 'origin/staging' into mship-fixes
icecrasher321 Aug 17, 2026
3616de2
Always focus the resource the agent is working on, and its browser tab
Sg312 Aug 18, 2026
8f00296
Never paint a browser snapshot at stale geometry (the modal-open flash)
Sg312 Aug 18, 2026
edf76d7
Name the workflow in deployment and workflow-scoped tool titles
Sg312 Aug 18, 2026
dbf14d5
Name the block that ran; never fall back to a raw block id
Sg312 Aug 18, 2026
3bee586
Add the missing Removing -> Removed rewrite
Sg312 Aug 18, 2026
dc1f3c2
Name the target resource in the remaining tool titles
Sg312 Aug 18, 2026
22dbd2b
Bubble nested agents' tool calls into the parent's status line
Sg312 Aug 18, 2026
4b57fd8
Align nested tool call status rows
Sg312 Aug 18, 2026
db748ee
Merge remote-tracking branch 'origin/staging' into mship-fixes
Sg312 Aug 18, 2026
0cbd1b8
Revert branch-local KB connector error-message edits
Sg312 Aug 18, 2026
a2583f1
Fix the failing audits: NUL escape and route-count ratchet
Sg312 Aug 18, 2026
3e0db8d
Add Force Reload (Cmd+Shift+R) to desktop View menu
Sg312 Aug 18, 2026
34208f6
Route Force Reload through focused-resource boundary; regen docs mani…
Sg312 Aug 18, 2026
3f32259
Align the title-bar surface audit with the zoom rework
Sg312 Aug 18, 2026
d96c340
Budget the two structurally slow tests explicitly
Sg312 Aug 18, 2026
2d49305
Carry the cross-service trace id in sim log lines
Sg312 Aug 18, 2026
ffb045f
Improve nested tool status presentation
Sg312 Aug 18, 2026
e745fb4
Refresh secret schemas and shared test mocks
Sg312 Aug 18, 2026
8fd71c1
Open the deployed graph of org-published blocks, read-only, org-wide
Sg312 Aug 18, 2026
93d4349
Withhold the deployed graph from external collaborators
Sg312 Aug 18, 2026
02f5cd3
Fill out the organization namespace: workspaces, permission groups, c…
Sg312 Aug 18, 2026
43bea91
Stop reporting a click that navigated as a failed click
Sg312 Aug 18, 2026
96f6277
Re-hide the browser under a modal after main loses the occlusion lease
Sg312 Aug 18, 2026
d5cd4f7
Make a stale ref name which of its five causes fired
Sg312 Aug 18, 2026
e7d455b
Pulse throttling off when the browser view is revealed, so it actuall…
Sg312 Aug 18, 2026
0f4e0c5
Let the agent browser join meetings and finish passkey sign-ins
Sg312 Aug 18, 2026
2ef14b8
Compile and preview Sim-styled pages
Sg312 Aug 18, 2026
0db432f
Wait for the batched prepare intent instead of instantly failing appl…
Sg312 Aug 19, 2026
2e21dbf
Store page source, render docs-styled documents on view
Sg312 Aug 19, 2026
4d82d93
Merge origin/staging into mship-fixes
Sg312 Aug 19, 2026
d8ed7f1
Stagger the page rails so the resource panel keeps the docs sidebar
Sg312 Aug 19, 2026
0061e47
Fix in-page anchors escaping the preview; add the docs' toggle, code …
Sg312 Aug 19, 2026
bcd158a
Size the section sidebar to its content so it appears at panel widths
Sg312 Aug 19, 2026
1872e01
Let the clerk TOC join at 860px by sizing it to its content
Sg312 Aug 19, 2026
c3a56c6
Open external links from pages in a new tab
Sg312 Aug 19, 2026
3f91212
Lock Sim pages to the rendered view via an internal record type
Sg312 Aug 19, 2026
1beca2c
Honor the model's declared page type; default copilot .html to a page
Sg312 Aug 19, 2026
cbcc31c
Default undeclared .html back to plain text/html
Sg312 Aug 19, 2026
5a9e189
Match the docs' PageFooter for page navigation
Sg312 Aug 19, 2026
b14ef7c
Scroll the rails invisibly, like the docs
Sg312 Aug 19, 2026
471df8f
Send sim:file links to the Files page, like a markdown link
Sg312 Aug 19, 2026
ed46882
Inline workspace images after the page compiles, not before
Sg312 Aug 19, 2026
02b32cf
Highlight the section you are AT in the left rail, not the last one v…
Sg312 Aug 19, 2026
15fe31f
Stop the TOC jittering sideways as the highlight moves
Sg312 Aug 19, 2026
39bac75
Absolutize links and images in served page documents
Sg312 Aug 19, 2026
224d38d
Drop the eyebrow; add the docs' top page controls
Sg312 Aug 19, 2026
d71370b
Read kv keys and table first columns as labels, the docs way
Sg312 Aug 19, 2026
241be48
Platform font and emcn chrome for pages
Sg312 Aug 19, 2026
990f140
Color-only active state in the TOC — width can never move again
Sg312 Aug 19, 2026
7431b5f
Drop the Copy page control; keep the top chevrons
Sg312 Aug 19, 2026
2bae897
Set-level sidebar: docs-style groups with the current page expanded
Sg312 Aug 19, 2026
c7ebfc9
Center the content column at the docs' measure
Sg312 Aug 19, 2026
b29f182
Docs Steps, code-tab groups, and API method chips
Sg312 Aug 19, 2026
7b672ae
Downloaded pages carry their images
Sg312 Aug 19, 2026
e4e6bb1
Dead-center the content column between equal gutters
Sg312 Aug 19, 2026
1647770
Defer title-bar history state out of currententrychange dispatch
Sg312 Aug 19, 2026
83bcc6f
Show the section sidebar only when there are sections to list
Sg312 Aug 19, 2026
9f1b068
Execute the page shell in a DOM harness
Sg312 Aug 19, 2026
d00abf4
Medium panes keep the TOC, not the sidebar
Sg312 Aug 19, 2026
80bb24c
Sidebar is for doc sets only; stagger the rails like the docs
Sg312 Aug 19, 2026
ee50195
Center the lone-page content and TOC as a pair
Sg312 Aug 19, 2026
fd2655a
Equalize grid-template specificity across the rail tiers
Sg312 Aug 19, 2026
69d4592
extract_doc_assets: pull a reference deck's assets into the workspace
Sg312 Aug 19, 2026
2586c2f
extract_doc_assets learns .pdf via the doc sandbox
Sg312 Aug 19, 2026
271ea57
Pages have one navigation rail; compile errors go to the agent
Sg312 Aug 19, 2026
16fc4d1
Sync tool catalog: extract_doc_assets accepts pdf
Sg312 Aug 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 3 additions & 0 deletions .github/workflows/test-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ jobs:
- name: Repo audits
run: bun run check:audits

- name: Verify docs manifest is in sync
run: bun run docs-manifest:check

- name: Migration safety (zero-downtime) audit
run: |
if [ "${{ github.event_name }}" = "pull_request" ]; then
Expand Down
10 changes: 10 additions & 0 deletions apps/desktop/build/entitlements.mac.plist
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,15 @@
even after the user grants access in System Settings. -->
<key>com.apple.security.device.audio-input</key>
<true/>
<!-- The agent browser joins real meetings (Google Meet, Zoom web): its
getUserMedia grant is gated on the OS grant, and without this key the
Hardened Runtime denies the camera no matter what the user allowed. -->
<key>com.apple.security.device.camera</key>
<true/>
<!-- WebAuthn hybrid transport (passkey on the user's phone via QR) rides
Bluetooth proximity; without this the QR option silently never
completes in signed builds. -->
<key>com.apple.security.device.bluetooth</key>
<true/>
</dict>
</plist>
4 changes: 3 additions & 1 deletion apps/desktop/electron-builder.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ mac:
# macOS refuses to show the microphone prompt at all — it kills the process —
# unless the bundle declares why it wants the device.
extendInfo:
NSMicrophoneUsageDescription: Sim uses your microphone for voice input in Chat.
NSMicrophoneUsageDescription: Sim uses your microphone for voice input in Chat and for meetings you join in the built-in browser.
NSCameraUsageDescription: Sim uses your camera for meetings you join in the built-in browser, such as Google Meet.
NSBluetoothAlwaysUsageDescription: Sim uses Bluetooth to complete passkey sign-ins with a nearby phone in the built-in browser.
entitlements: build/entitlements.mac.plist
entitlementsInherit: build/entitlements.mac.plist
notarize: true
Expand Down
89 changes: 88 additions & 1 deletion apps/desktop/src/main/browser-agent/cdp.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import { describe, expect, it, vi } from 'vitest'

vi.mock('electron', () => import('@/test/electron-mock'))

import { WebContentsView, type WebFrameMain } from 'electron'
import { nativeImage, type WebContents, WebContentsView, type WebFrameMain } from 'electron'
import {
captureScreenshot,
clickAt,
ensureInstrumented,
evaluateInIsolatedFrame,
Expand Down Expand Up @@ -482,3 +483,89 @@ describe('browser-agent CDP theme', () => {
})
})
})

/**
* The browser panel shows a LIVE view, so a capture must not perturb the page.
* Chromium serves `clip` by applying device-emulation params to the widget and
* syncing visual properties, which the user sees as the page rescaling and
* snapping back. Resolution is bounded on the returned image instead.
*/
describe('browser-agent screenshot capture', () => {
function captureFixture(imageSize: { width: number; height: number } | null) {
const contents = new WebContentsView().webContents
vi.mocked(contents.debugger.sendCommand).mockImplementation((method: string) => {
if (method === 'Page.getLayoutMetrics') {
return Promise.resolve({ cssLayoutViewport: { clientWidth: 2048, clientHeight: 1024 } })
}
if (method === 'Page.captureScreenshot') return Promise.resolve({ data: 'c2lt' })
return Promise.resolve(undefined)
})
const resized = {
toJPEG: vi.fn(() => Buffer.from('resized')),
}
// Shared module-level mock: without this, a later fixture reads the
// earlier test's decoded image.
vi.mocked(nativeImage.createFromBuffer).mockReset()
vi.mocked(nativeImage.createFromBuffer).mockReturnValue({
isEmpty: vi.fn(() => imageSize === null),
getSize: vi.fn(() => imageSize ?? { width: 0, height: 0 }),
resize: vi.fn(() => resized),
toJPEG: vi.fn(() => Buffer.alloc(0)),
} as unknown as ReturnType<typeof nativeImage.createFromBuffer>)
return { contents, resized }
}

function screenshotParams(contents: WebContents): Record<string, unknown> {
const call = vi
.mocked(contents.debugger.sendCommand)
.mock.calls.find(([method]) => method === 'Page.captureScreenshot')
if (!call) throw new Error('no capture was requested')
return call[1] as Record<string, unknown>
}

it('never sends a clip, which would emulate the live page for the capture', async () => {
const { contents } = captureFixture({ width: 4096, height: 2048 })

await captureScreenshot(contents)

expect(screenshotParams(contents)).not.toHaveProperty('clip')
})

/**
* A 2048px CSS viewport bounded to 1024px is scale 0.5, and the capture
* arrives at device resolution (4096px on a 2x display). The resize is what
* lands the image on the CSS-relative size the coordinate contract
* (cssX = imageX / scale) assumes.
*/
it('downscales the returned image to the CSS-relative size', async () => {
const { contents, resized } = captureFixture({ width: 4096, height: 2048 })

const shot = await captureScreenshot(contents)

const image = vi.mocked(nativeImage.createFromBuffer).mock.results[0].value
expect(image.resize).toHaveBeenCalledWith({ width: 1024, height: 512, quality: 'good' })
expect(resized.toJPEG).toHaveBeenCalled()
expect(shot).toEqual({
dataUrl: `data:image/jpeg;base64,${Buffer.from('resized').toString('base64')}`,
scale: 0.5,
})
})

it('skips the re-encode when the capture already matches the target size', async () => {
const { contents } = captureFixture({ width: 1024, height: 512 })

const shot = await captureScreenshot(contents)

const image = vi.mocked(nativeImage.createFromBuffer).mock.results[0].value
expect(image.resize).not.toHaveBeenCalled()
expect(shot).toEqual({ dataUrl: 'data:image/jpeg;base64,c2lt', scale: 0.5 })
})

it('returns the raw capture when the image cannot be decoded', async () => {
const { contents } = captureFixture(null)

const shot = await captureScreenshot(contents)

expect(shot).toEqual({ dataUrl: 'data:image/jpeg;base64,c2lt', scale: 0.5 })
})
})
Loading