Skip to content

v0.9.39: people page, desktop agent browser sign-in and updates, mothership memory erasure, oauth refresh hardening, v2 file paths, disposable email blocking - #9544

Merged
waleedlatif1 merged 42 commits into
mainfrom
staging
Nov 1, 2026

Conversation

@waleedlatif1

@waleedlatif1 waleedlatif1 commented Nov 1, 2026 •

Copy link
Copy Markdown
Collaborator

waleedlatif1 and others added 30 commits October 31, 2026 00:33
…anization is deleted (#9503)

* feat(mothership): erase private memory when a member leaves or an organization is deleted

Account deletion already queues the worker's memory cleanup. Removing a
member, removing an external collaborator from an organization's workspaces,
moving a member to another organization and deleting an organization now
queue it too, in the same transaction, with the worker's new
organization_member and organization targets.

* test(mothership): prove offboarding queues memory erasure with a real database

The unit tests only checked mocked outbox calls. The integration test runs
member removal, external removal and organization cleanup against Postgres:
each committed change queues its erasure, a rolled-back one queues nothing.

* test(mothership): cover a successful external collaborator removal
…elete (#9504)

* fix(files): accept files/ VFS paths in v2 file describe, rename and delete

* fix(files): match VFS paths as listings print them, without virtual suffixes or ambiguity
* fix(desktop): keep sign-in popups working in the agent browser

- Adopt window.open('') / about:blank popups as tabs that keep window.opener (MSAL-style sign-in and payment flows got null)
- Read an adopted popup's session from its contents, not its URL
- Refuse a form POST into a new tab rather than resending it as a GET; forward the referrer on reissued links
- Closing a popup returns to its opener unless the user switched tabs since (Chrome's rule)
- mailto: links in the app window open the mail client, with attach/extra headers refused

* fix(desktop): keep deferred popups in their opener's session

- A background-tab popup with no Chromium-supplied contents now opens in the opener's session rather than the agent partition
- Driver tests expect the referrer options loadURL now receives
…, and suggest links from the address bar (#9508)

* improvement(sim-links): pass queries through, trim pasted punctuation, and suggest links from the address bar

* fix(extension): keep typed values when a suggestion is chosen, bound the suggestion cache
…in line with Chrome (#9512)

* improvement(desktop): bring agent browser menus, keys and fullscreen in line with Chrome

- Page-menu Back/Forward/Reload go through the user-navigation path, so the leave-site prompt and load-error handling apply
- Page menu gains spelling suggestions, Undo/Redo/Cut/Paste and Match Style/Select All, and image items (open, save, copy, copy address); Open Link in New Tab sends the referrer
- Spellcheck on in the agent browser on macOS
- Ctrl+wheel zoom steps the same zoom ladder as the menu
- Chrome keys: Alt+Left/Right, Cmd+Opt+Left/Right, Cmd+Shift+[ ], Ctrl+PgUp/PgDn, Esc stops loading, mouse back/forward buttons
- Page fullscreen fills the browser panel without resizing the Sim window

* fix(desktop): ignore browser shortcuts and mouse buttons before any chat opens a browser
…every provider (#9516)

* fix(auth): refuse account creation from disposable email domains for every provider

* fix(auth): keep permanent mail-relay aliases out of the disposable check
* improvement(cli): files batch-delete takes file ids as arguments

* chore(docs): record the batch-delete usage line in the compatibility baseline
… real in-flight work (#9505)

* improvement(desktop): install updates on one click, asking only about real in-flight work

- Restart to update installs immediately; the generic Later/Restart dialog is gone
- Prompt only when a terminal command, agent action, computer use, or unsaved edit would be interrupted, naming it, with restart as the default
- The minimum-version gate never offers to wait
- Reopen every app window after an update relaunch
- Fix the menu's downloading copy, which promised a prompt that never came

* fix(desktop): count unresponsive windows and browser actions before an update restart

- A window that doesn't answer the unsaved-edits check counts as possibly unsaved instead of clean
- A running browser-agent action counts as work a restart would interrupt
- The queued-send claim is cleared on pagehide only, so the check (or a cancelled unload) can't strand a queued message

* fix(desktop): snapshot running work after the window probes and count queued browser actions

- Read terminal, computer-use, browser and agent activity after the unsaved-edits probes finish, so work started meanwhile still prompts
- A browser action waiting in the queue counts as running
- A window whose probe errors counts as possibly unsaved, like one that times out

* fix(desktop): ask the OS about terminals without shell integration before an update restart

Shells that announce nothing (fish, sh) now count as busy when their tty's
foreground process group is not the shell's own. Live windows are recorded
for relaunch without the cap, which only bounds persisted routes on read.

* chore(desktop): drop the unreachable foreground-read catch
…he session back (#9515)

* feat(desktop): continue a passkey sign-in in your browser and bring the session back

- From an agent browser tab, open the page in a chosen Chrome-family profile, finish the sign-in there, then bring that site's cookies back
- Per-site import scoped to the page's registrable domain (tldts, private suffixes respected), filtered in SQL and checked per row before decryption
- One pending handoff per chat in main; a remounted panel restores its Bring session back notice
- Subtle hint on known sign-in hosts; hidden on older shells, off macOS, or with no Chromium browser installed

* fix(desktop): keep sign-in handoffs current across cancel, migration, and sign-out

Retire in-flight launches on cancel, newer continue, and account teardown;
move a provisional chat's handoff with its browser scope; skip reopening the
tab when a bring-back's handoff was superseded; pin the platform in the
continue-sign-in tests so they pass on Linux CI.

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

* fix(desktop): refresh pending sign-in after every continue and gate on shell support

Re-read the chat's pending sign-in after any continue result so a failed
launch that retired the previous handoff cannot leave a stale notice, and
require the shell's continue-sign-in bridge before showing the feature, since
the profiles cache is shared with the import dialog on older shells.

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…, and people-data import (#9517)

* feat(people): organization People page with profiles, reporting lines, and people-data import

* fix(people): clearable manager and department pickers, exact spreadsheet dates and row numbers, loop checks through suspended members

* fix(people): consistent profile reads, capability-aware navigation, unambiguous email matching, stricter dates, guarded workbook parsing

* fix(people): read a page and its managers from one snapshot

* fix(people): send import rows as positional cells so wide files stay within request limits
…sswords, passkey accounts, client certificates, and app links (#9521)

* improvement(desktop): sign-in prompts for the agent browser — site passwords, passkey accounts, client certificates, and app links

* fix(desktop): require an explicit accept for every sign-in prompt answer and arm prompts only while visible

* fix(desktop): refuse window.open app links, gate every launch on a prompt-capable renderer, and keep page-raised prompts from taking focus

* fix(desktop): clearing browsing data forgets the agent browser's certificate and app-launch choices
…#9523)

* fix(execution): name the signal that killed a sandbox process in its error

* fix(execution): describe a signal's exit code without claiming a kill
…arched source (#9514)

* improvement(search): overlap live search stages and report every unsearched source

* fix(search): defer previews when verification shares their budget, and bound session opening by the account deadline
…stop detached runs on Stop (#9507)

* feat(mothership): answer a workflow tool's run still running past the worker's wait

A run_workflow* call held the turn until its run settled, up to the execution
limit, while a synchronous workflows run can already detach after
--wait-timeout (#9464). Sim now declares workflow-tool-wait-timeout and honors
the waitTimeoutMs a workflow tool frame names (synced from the mothership
contract):

- Server-run call: the handler gives the run its execution id up front and,
  once the wait passes, answers {status: running, executionId, workflowId}.
  The run goes on in-process; the tool execution keeps holding it, so its
  lease and a Stop through the call's abort signal still reach it.
- Browser-run call: once the wait passes and a browser holds the call's
  execution claim, the call is settled background, the detach a browser sends
  on pagehide. The browser's run goes on, still bound to the call, so a Stop
  cancels it.
- A background workflow completion now carries status: running beside its
  ids, the shape the worker waits on.

A frame without waitTimeoutMs, or one with a malformed value, holds the call
as before.

* fix(mothership): stop the workflow runs a stopped chat left running past a call

A synchronous workflows run the worker waits on in slices detaches after its
first --wait-timeout (#9464, mothership#872), and from then on no call's abort
signal reaches it. Stop delivery cancelled only browser workflow runs bound to
open calls, so a Stop mid-slice ended the chat while the draft run went on to
completion. Driven through the real controller and the Stop route (live case
in the next commit), the run was still running a minute after the Stop.

Stop delivery now also cancels the runs this chat run's calls started and left
running: a workflows run the CLI answered still running (exit 4 and its run
record), and a workflow tool answered still running. A run the chat only
waited on (workflows runs wait) is not one, since something else started it.
The cancel is the same in-process abort and durable cancel flag a browser run
gets; a detached run registers its in-process aborter.

Autopsy: the slice tests on both sides covered waits that settle, lapse or
lose an answer, and none stopped the chat mid-slice; the Stop tests seeded only
open browser-run calls. stop-delivery.test.ts and the live declared-stop case
now cover it.

* test(mothership): drive a workflow tool past its wait and a stop mid-slice through the real controller

Two live cases beside the sliced draft run (opt-in, SIM_HELPERS_SMOKE and
MSHIP_WORKER_ROOT):
- tool: run_workflow on a Sim declaring workflow-tool-wait-timeout answers its
  500 s run still running after 240 s, the worker waits on it as run-wait
  slices and reads it back, and the model sees the settled run's output.
- declared-stop: the Stop button's request while the worker waits on a
  detached draft run ends the turn and cancels the run.

The harness now marks the turn's tool execution and billing as the chat route
does, registers and wires the turn's controller as lifecycle/start.ts does,
gives the tool case a real AES key to seal its provenance, and keeps logged
errors' messages in the evidence.

* test(mothership): type the stopped run fixture and keep logged errors without a JSON round trip

* fix(mothership): answer a workflow tool still running only once its run is dispatched

Review of the wait:
- A run still in authorization or admission when the wait passes is not
  answered running under an id nothing has used yet; the call waits until
  the run is handed to the executor (onDispatch) or settles.
- The browser-run detacher sleeps interruptibly and stops on either outcome of
  its waiter, so no derived promise rejects unhandled.
- The live case takes its AES key from generateRandomHex.
- The mock-only Stop delivery test is dropped: the live declared-stop case
  drives the real Stop route, storage and cancellation, and fails without the
  fix (the run stays running); detachedWorkflowExecutionId keeps its unit test.

* test(mothership): prove the browser detach and the Stop read against real Postgres and Redis

The browser-run detach and the detached-run read now run through the real
claim, settlement, published confirmation, waiter and stored tool rows
(workflow-client-settlement.integration.ts), replacing unit tests that
asserted only on mocks.

* refactor(mothership): wait on a workflow tool's run with the shared interruptible sleep

* fix(mothership): find a detached workflows run behind global CLI flags

* fix(mothership): answer a workflow tool still running only once its run is readable

A run past the call's wait was answered running as soon as it was handed to
the executor, before the executor wrote its run log, so an immediate
workflows runs wait could find no run. The call now answers running only once
the run's log exists, re-reading it each second until then or until the run
settles; the dispatch hook is gone.

* fix(mothership): keep waiting on a workflow tool's run when its log cannot be read

* fix(mothership): answer a browser run still running only once its log exists, and never discard a run that settled meanwhile

* fix(mothership): retry a failed call read in the browser-run detacher

* fix(mothership): keep watching a browser-run call that is still pending

* fix(mothership): detach only a browser run still going, and retry a failed detach
…sponse (#9536)

Co-authored-by: Sim Pi Agent <pi@sim.ai>
* docs(library): update best-multi-agent-frameworks-2026

* Pi Babysit: address PR #9534 feedback

---------

Co-authored-by: Sim Pi Agent <pi@sim.ai>
…or SCIM provisioning (#9529)

* fix(auth): block only curated disposable domains, and never gate SSO or SCIM provisioning

* chore(auth): rename disposable list script to generate:, read SSO callback paths from the plugin

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…red Outputs, and Streaming (#9539)

Co-authored-by: Sim Pi Agent <pi@sim.ai>
…9527)

* fix(files): authorize the workspace before resolving a files/ path

* fix(files): admit a caller only when a files/ path fails to resolve, and refuse file-scoped delegates there

Path resolution now throws a typed UnresolvedWorkspaceFileVfsPathError for a missing or
ambiguous path; defineAuthorizedWorkspaceFileUseCase authorizes the asserted workspace with
the operation's own options before letting it out. A resolved path keeps the single
authorization the id path runs, and a delegation scoped to one file gets the same refusal
for every other path.
…ds and downloads as running work, and harden sign-in prompts (#9533)

* fix(desktop): ask before an update restart from the menu, count uploads and downloads as running work, and harden sign-in prompts

* fix(uploads): guard in-flight uploads from the workspace shell, not the page that started them

Uploads keep sending after in-app navigation unmounts their page, so the
beforeunload guard now reads a shared in-flight upload count from one guard
mounted in the workspace layout. The credential detail guard reuses
useBeforeUnloadWhile, and Continue in Browser reads the page origin only in
the desktop shell.
… held workflow run never blocks the next turn's workbench (#9532)

* fix(mothership): Stop only cancels detached runs still running, and a held workflow run never blocks the next turn's workbench

* improvement(mothership): read a detached run's call as flat columns, and name the paused case

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

* fix(mothership): answer a workflow tool run that settles as its log is read with its result

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
… place (#9511)

* chore(search): retire legacy search knowledge base projection rows in place

* fix(search): keep the purge on its locked session and refresh the dev projection function

- Re-check the session advisory lock inside every purge batch: the client reconnects silently after a dropped connection, and the new backend does not hold the old one's lock
- Build the purge client without the sslmode/sslrootcert URL parameters, enforcing them as ssl verify-full; postgres.js forwards sslrootcert as a startup parameter the server rejects
- Pin the purge connection's search_path to public, pg_temp
- Reinstall sync_embedding_search() on a dev push that already recorded 0016, since push runs no versioned migration

* test(search): expect no vector candidates for a dormant search index

A Search knowledge base's chunk writes now delete its candidate rows, so an explicit vector search of one finds nothing; hybrid search still decides access on the document

* chore(search): renumber the projection retirement migration to 0449 after staging's 0448

* fix(search): lock each purge batch's rows before deleting them by tuple id

A concurrent update could move every chosen row to a new tuple id before the delete, so the batch deleted nothing and the purge reported the knowledge base finished with rows left. The batch now locks its rows in one statement and deletes them in the next, whose snapshot sees the current versions

* test(search): bound the wait for the purge to block on the updated rows

* fix(search): refuse the purge until migration 0449 is live

- --execute checks that public.sync_embedding_search has the retiring body and its embedding_search_sync trigger is enabled; before that, chunk writes keep projecting the rows a purge deletes. The dry run reports the same check
- One whitespace-insensitive matcher for the live function source, shared by the preflight and the integration parity tests; drop the unit test that compared the migration file text
- --help adds the rebuild precautions: wait out an anti-wraparound autovacuum, bound maintenance_work_mem, clean up a failed concurrent reindex

* fix(search): require the purge preflight's trigger to fire and call the retiring function

- embedding_search_sync must be enabled for ordinary writes (origin or always, not replica-only) and call public.sync_embedding_search
- Drop the redundant client port option; postgres.js reads the URL port
…ad earlier (#9528)

* fix(oauth): keep a five-minute floor on served tokens and refresh ahead earlier

* improvement(oauth): share refresh-ahead through the refresh single-flight and log it at debug

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…rom a pre-release audit (#9530)

* improvement(release): harden favicons, sim links, and the extension from a pre-release audit

* fix(release): forward sim/ queries verbatim through the proxy, budget favicon lookups per caller, refresh oversized cached icons

* refactor(release): simplify the favicon lookup budget, share the link-name cap, read sim/ queries as Next parses them

* fix(sim-links): forget a row's menu when the row leaves the results
* improvement(docs): collect reader feedback inline

* fix(docs): validate feedback request authority and exercise retries

* fix(docs): normalize feedback paths and scope error assertions
…9540)

* fix(auth): check a workspace's personal-key switch after membership, so a non-member never learns what it named exists

* test(auth): import the key-switch error from the application barrel
…ce-account key reads, and label unsearched accounts (#9537)

* fix(search): keep a valid token when a refresh lease is orphaned, share overlapping service-account reads, and label unsearched accounts

* fix(oauth): serve a stored token only when a refresh wait ran out on a held lease

- A failed blocking refresh now falls back to the stored token only on a distinct
  lease-held outcome: this caller followed another lease holder for its whole wait, its
  last read still found the chain it started from, and no leader flagged it dead. A dead
  flag, a terminal refresh error, a vanished account or a leader exception stay failures.
- The in-process refresh settles after the follower's full wait plus headroom instead of
  the default 30s, which fired before the follower's last read could count; a leader hung
  in this process still fails its callers, now at that bound.

* fix(oauth): let a cancelled service-account mint stop waiting on a shared key read

* docs(oauth): say why the stored-token fallback floor sits below the refresh window

* fix(oauth): take over a lapsed refresh lease instead of serving the stored token

- A follower whose wait ends with nothing now tries the lock once more: a leader whose process
  died leaves its lease to lapse, and the follower leads the refresh instead of failing. Losing
  that try still returns nothing.
- Drops the stored-token fallback and its lease-held outcome, which served tokens below the
  five-minute floor a served token keeps.
- The leader rereads the dead flag under the lock, so a follower taking over after a leader
  that failed terminally does not call the provider again.
- The in-process refresh settles after the follower wait plus a full leader run and headroom.
… canonical resolver (#9531)

* fix(files): resolve v2 file paths only on the v2 surface, through the canonical resolver

* fix(files): every refusal a path lookup reads from the workspace waits for workspace authorization
… them under 100 MB (#9542)

* fix(files): stream served files with byte ranges instead of buffering them under 100 MB

* fix(files): stream finished document uploads, diagnose playback errors, prove ranges on real bytes

* fix(files): probe served bytes before handing off, keep generated documents in-page, version local objects by inode
@waleedlatif1
waleedlatif1 requested a review from a team as a code owner November 1, 2026 04:55
@vercel

vercel Bot commented Nov 1, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
docs Skipped Skipped Nov 1, 2026 6:33am UTC

Request Review

@github-actions github-actions Bot added the requires-mothership-merge Has a companion PR on the mothership/copilot side — merge in lockstep label Nov 1, 2026
@github-actions

github-actions Bot commented Nov 1, 2026

Copy link
Copy Markdown

⚠️ Cross-repo companion check

One or more companion PRs aren't merged into main yet (aggregated across the feature PRs in this release). Merging this without them will leave copilot and sim out of sync — merge them in lockstep.

  • ⚠️ simstudioai/mothership#878 — merged into staging (this PR targets main) — feat(worker): erase private memory when its owner is offboarded
  • ⚠️ simstudioai/mothership#881 — merged into staging (this PR targets main) — feat(worker): wait on a workflow tool's run in slices on a Sim that answers it s

@greptile-apps

greptile-apps Bot commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 4/5

[High impact] The PR reaches organization data, account creation, file delivery, and desktop browser workflows.

Fix the Excel date import before merging; the missed download warning is a smaller follow-up.

Findings

  1. P1 Excel dates skip valid rows ▶
  2. P2 Updates miss Files downloads ▶

Summary

This release adds organization People profiles and imports, desktop browser sign-in flows, safer update restarts, OAuth refresh changes, and streamed file delivery.

  • Organization members can view profiles and reporting lines on the People page.
  • Workspace files support canonical paths and byte-range downloads.
  • The agent browser can ask users to finish sign-in and app-link prompts.
  • The agent browser follows more Chrome menu, shortcut, and fullscreen behavior.
  • Desktop updates ask before restarting when work may be interrupted.
  • OAuth callers can use valid tokens while refresh work starts early.
  • Self-service sign-up blocks curated disposable email domains.
  • Mothership clears departed members' private memory and handles long runs differently.
  • Live search overlaps stages and reports sources it could not search.
  • Sim Links pass queries through and can be suggested from the address bar.
  • The CLI lists credential providers and accepts file IDs for batch deletion.
  • Readers can leave feedback from docs pages and find new agent guides.
  • Search projection rows are retired in place instead of receiving new writes.
  • Release and service workflows add bounded favicon lookups and optional tailnet database access.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  Excel[Excel HR export] --> Read[Read workbook cells]
  Read --> Date[Convert start dates]
  Date --> Preview[Preview people changes]
  Preview --> Confirm[Admin confirms import]
  Confirm --> Access[Check organization admin access]
  Access --> Lock[Lock organization profiles]
  Lock --> Plan[Recheck rows and reporting lines]
  Plan --> Save[Save profiles and record audit]
Loading

Reviews (1) · Last reviewed commit: "fix(ci): drop the duplicate --accept-rou..." · Reviewed by Greptile

Comment thread apps/sim/lib/oauth/credential-service.ts Dismissed
Comment thread apps/desktop/src/main/index.ts Resolved

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 311 files

Note: This PR contains a large number of files. cubic selects up to 200 of the highest-priority eligible files for this review, so some files may not have been reviewed.
This PR changes authentication, authorization, or input validation. Ultrareviews find 2.4x more serious bugs than standard reviews. Comment @cubic-dev-ai ultrareview to run one.

Turn on auto-fix | Re-trigger cubic

Comment thread apps/sim/app/api/files/utils.ts Resolved
Comment thread apps/desktop/src/main/terminal/index.ts Resolved
Comment thread apps/sim/lib/organizations/surface.ts Resolved
Comment thread packages/db/scripts/push.ts Resolved
Comment thread apps/extension/src/omnibox.ts Resolved
Comment thread apps/desktop/src/main/index.ts Resolved
Comment thread apps/sim/lib/favicon/application.ts Resolved
Comment thread apps/sim/lib/concurrency/leader-lock.ts Resolved
Comment thread apps/desktop/src/main/index.ts Resolved
…ked terminals before an update restart, send the page referrer on Save Image, and tighten sign-in and people edge cases (#9547)
…eated columns, keep typed escapes, no suggestions for punctuation (#9545)

* fix(release): read Excel start dates, refuse impossible times and repeated columns, keep typed escapes, no suggestions for punctuation

* fix(people): honor the 1904 date system and cover the sheet reader with workbook tests

* fix(people): pass an out-of-range date serial through instead of failing the import
…and large downloads (#9548)

* fix(files): share one served-bytes predicate between the serve route and large downloads

* fix(files): judge an attachment's document name by its file record, state the stream helper's caller precondition
@waleedlatif1
waleedlatif1 merged commit 6ebc04d into main Nov 1, 2026
204 of 206 checks passed

This branch was previously deployed

1 inactive deployment
Preview — ac604b73 Deployed Nov 1, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

requires-mothership-merge Has a companion PR on the mothership/copilot side — merge in lockstep

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants