Skip to content

v0.9.0: mothership v1, live search, slack list and canvas tools, ui consolidation - #8273

Merged
waleedlatif1 merged 58 commits into
mainfrom
staging
Sep 25, 2026
Merged

waleedlatif1 merged 58 commits into
mainfrom
staging

Conversation

@waleedlatif1

@waleedlatif1 waleedlatif1 commented Sep 24, 2026 •

Copy link
Copy Markdown
Collaborator

Sg312 and others added 30 commits September 23, 2026 16:41
* mothership agent cli: grep --in accepts the world/resource path a match line prints

* workflow lint, block catalog, tables, files, sandbox tools: fixes from exploration run 5

Lint: trigger-category blocks are entry blocks (schedule was an orphan); references inside Function code are checked with the runtime tokenizer; the agent-cli lint and grep read the draft state instead of the sanitized export. Catalog: operation inputs publish sub-block ids only (no canonical-param aliases); trigger-category blocks expose their trigger-mode fields. Tables: dispatch processedCount counts unlimited dispatches; json-language code fields accept objects. Files: restore keeps the folder when it still exists. Sandbox tools: outputTable failures report the files already written and the per-language result shape; the file writer keeps the computed result.

* sim-cli: --output json prints the API data verbatim; the single-key unwrap stays a table-only convenience

* route and connection validation, trigger defaults on add, table folder restore, dispatch listing, group column attach, import block summary; logs query and deps engines; run-tool errors and payload compaction; stale tests aligned

Editing: router routes validated as {id?, title, value} with unknown keys named; malformed connections reported instead of dropped; sub-block value() defaults evaluated on add so a webhook gets its token. Tables: folder restore no longer 500s (lock inside the row transaction), completed dispatches are listed, groups attach to existing output columns. Workflows: import answers with its blocks. Mothership engines: logs query resolves bare paths under output, marks missing paths, drops non-executed runs under --where; deps lists graph predecessors and child return shapes; run-from-block validation errors reach the agent; run payloads compact input.code. CLI generated types regenerated.

* sim-cli: the operations apply confirmation describes the batch as written, not a delete

* sandbox export keeps the code's result; --trigger implies --manual; deps mock skeleton; run tools lift the terminal output and take select; lint all-clear names what it checked; docs chunker keeps code spans

* sim-cli: runs get --select-output takes block names; groups delete says it removes the output columns and their data; a publish that lands on public auth prints a note

* null-safe block.error, strict start-trigger coercion, lint checks reference paths against output schemas; logs stats segments; requiredWhen and model ids in the agent catalog; live tag usage; one row-filter grammar; minted service-account credential ids; webhook delivery URLs on deployment status; mv semantics for folder moves

Executor: <block.error> resolves empty on a block that succeeded so a shared error collector is writable; a number input given a non-numeric string fails the run at start naming the field; a regression test pins that failure traces carry child spans. Lint: a reference whose first path segment is not on the block's effective outputs (or its responseFormat schema) is an unknown-field finding. API: logs stats honours segmentCount and omits empty buckets unless includeEmpty; block detail publishes requiredWhen instead of flattening conditional requirements and always lists model options with hosted marks; knowledge tag usage counts through the document slot; every table rows filter accepts a bare condition; service-account credentials mint their id; deployment status lists each webhook's delivery URL; a folder move into an existing folder moves it inside. OpenAPI and CLI generated types regenerated.

* same-workspace import keeps or warns about workspace bindings; generic required-field lint; folder moves to the root; empty-graph and no-entry lint notes; span durationMs; MCP tools reported on undeploy and listed inactive; paged connector types and workspaces; grep --in refuses unknown selectors; run_function names exported files; run tools surface the failing block's error

Export takes includeWorkspaceBindings for same-workspace round trips and import answers with warnings naming every block whose required binding was stripped. Lint reports a missing required field for every block type (the knowledge base id was skipped), notes an empty graph and a graph with no entry block, and the trace spans carry durationMs. Undeploy answers with the MCP tools it archived and the tools list shows them inactive. connector-types list is paged (25, summary projection, detail=full) and workspaces list defaults to 25. The agent CLI's grep refuses a prefix or unknown --in selector with the accepted forms; a run_function that exported files and wrote a table says both; a run tool whose executor result carries no message uses the failing block's own error.

* table groups default to the deployed version and refuse a dispatch without one; column rename reports unmigrated Table-block filters; lint checks table fields against the live schema; runCount counts every settled run; runs cancel is honest about no-ops; dry-run apply answers with previewBlockIds; conditionResult is the chosen test's boolean with selectedTitle; workflows run --select-output keys blockOutputs by the selector and rejects unknown heads; knowledge search exposes rankScore and rank; the multi-trigger error names workflows state get; the Knowledge block declares cost, tokens, model; media writes refuse to fork a moved folder; grep --in knowledge points at knowledge search

* agent cli grep: the searchable text leads with the resource's name and description

* Catalog hides sunset blocks unless includeSunset; enrichment get returns the group's run state and outputs; knowledge upload prints the document fields; docs chunks titled by page not nav link; logs carry hasHandledErrors and opt-in handledErrorRuns; outputTable receipt keeps stdout

* Sandbox exports decode by the path rule the reader used: a .jpg declared without a format is written as image/jpeg bytes, not as its base64 text under the json format (thumbnails opened as raw text)

* Chat uploads resolve by uploads/<name> for reads, sandbox mounts, and image references (never listings or writes); an unresolved reference image fails the call instead of rendering without it; copilot session-sandbox calls are priced like Function-block sandboxes and report the raw cost beside the billed one; CLI docs regenerated

* grep: resolve --in against listings, fetch only the named resources

A bare --in selector (e.g. --in agent, --in file_v5) materialized every searched
world to find one block: 65 block details plus every workflow state per call. On
dev that took 18-34s per grep and tripped the per-user rate limit. Each world now
has a cheap index (its listing) and a per-resource fetch; a --in search reads the
indexes and fetches only the matches. Whole-world searches are unchanged.

* mothership: model-facing strings name only what exists on the CLI surface

The copilot back-derives fixes from the strings sim hands it, so a retired name
becomes a wrong instruction to the user (dev 2026-09-03: a save_upload mention
became "drag the photo into the files panel"). Every model-facing string audited
today now names the current surface:

- upload notice: a chat upload lives at uploads/<name> and is not a workspace
  file; workflows import takes --workflow (there is no --file); a .zip is mounted
  and unzipped in the sandbox rather than a files unzip path that does not resolve
- table import resolves uploads/<name> directly (includeChatUploads) instead of
  pointing at the retired save_upload tool
- function-execute / generate-image: outputs get, files ls, files restore and
  tables list replace read/grep/glob/restore_resource and Go VFS meta.json paths
- process-contents: browser/terminal pointers no longer name browser_* or a
  terminal tool this surface does not have; docs fallback names docs search
- lint/deps usage strings use the plural workflows group
- integration credential error names credentials list

* docs: every model-searchable page states the current surface

The copilot answers users from these pages (docs search), so a wrong sentence
becomes a wrong instruction. Audit fixes:

- chat: uploads live under uploads/, not the Files panel; on-demand workspace
  reach instead of a per-message snapshot; Chat runs Opus 4.8; connectors and
  deletes/restores as they actually behave; login pages via the shared browser
- cli: --select-output works on sync runs (only --async conflicts); runs get
  takes the same block selectors; secrets set needs --scope; workflows run runs
  the deployment or --manual; sim profiles honours --output; which groups have
  no singular alias; the embedded CLI has no profile, login, or config; @path
  reads the chat sandbox
- model defaults are claude-sonnet-5 (guardrails has none); API examples use
  https://www.sim.ai/api/v2 (apex 301s POSTs into GETs)
- quick reference / shortcuts: only affordances that exist (no Deploy tab, no
  workspace duplicate/export, Mod+B not Mod+E, variables under the ⋯ menu,
  <variable.name> syntax)
- editor read-only rules match round-trip-safety.ts; card links fixed
- sim-cli: runs-get selector error and the Settings label match the product;
  batch delete describes its ids as deleted, not updated; docs/api regenerated

* mothership: prepare_file_edit create + new_file pass input validation

The workspace-file handler has always supported operation=create with a
new_file target, but the generated tool schema (from the copilot catalog)
forbade both, so the watched write could never create a file: a "save this
report as a workspace file" turn died on `/operation must be equal to one of
the allowed values` (dev 2026-09-03). Regenerated from the catalog that now
declares create, new_file, and fileName; regression test on the validator.

* mothership: the embedded CLI answers v2 in-process; grep memoizes both platform catalogs

The embedded CLI and the agent-cli engines were typed v2 clients pointed at the
server's own URL: every tool call was a network round trip through the proxy,
API-key auth, the abuse rate limits, and the proxy body ceiling. A grep over one
block definition cost 8-34s and tripped the per-key limit (dev 2026-09-03).

- sim-cli: ResolvedProfile / EmbeddedCliIdentity take an optional transport; the
  client sends through it instead of fetch. The installed CLI never sets it.
- sim: an in-process transport resolves a v2 path against a generated route table
  (scripts/generate-v2-route-table.ts, check:v2-route-table in check:audits) and
  invokes the route handler directly. The request is marked internal through a
  WeakSet — not a header — so admission still authenticates it but skips the
  pre-auth IP bucket and the per-key rate limits, which exist for callers on the
  wire. Contracts, use cases, presenters, and error envelopes are the ones the
  network path runs. Anything outside the v2 table falls through to fetch.
- grep engine: blocks and tools (5,000 built-ins at 100 a page) are memoized per
  workspace; an exact block or tool id (--in file_v5) resolves from that corpus
  without listing any workspace world; name fragments still index every world
  and fetch only the matches.

* mothership: take the embedded CLI off the in-process transport until the dev hang is understood

Every cli_grep on dev timed out at 60s from the first deploy of 99aad28. The
transport, marker, route table, and grep memo stay; the embedded identity goes
back to the HTTP path while the hang is diagnosed from sim's logs.

* grep: share in-flight builds, bound nested requests process-wide, cache file text by version

The first dev turn on the in-process transport fired eight world-wide greps at
once. Each rebuilt every world concurrently on the one process serving the chat
— 24 block-catalog listings, 150 tool-catalog pages, 130 file reads in sixty
seconds — until all eight timed out. Over the wire the same fan-out had been
spread across tasks and throttled by the network.

- concurrent greps now await the build already in flight for a (world, workspace)
- nested requests are bounded to eight for the whole process, not per world
- platform corpora (blocks, tools) are kept an hour, not ten minutes
- a file's text is cached by id + updatedAt + size, so repeat greps re-read only
  files that changed

* grep: an exact block id answers before the tool catalog is built

* grep: honour -A and -B context flags

The engine read only -C; -A and -B were ignored silently, so `-A 40` returned
the bare match line and the model concluded context flags were unreliable
(dev 2026-09-03). A bad value is refused like -C's.

* sandbox pricing: normalize COST_MULTIPLIER at the boundary

Under skipValidation the value arrives as the raw string it was deployed with;
the sandbox lease's finite check rejected it, so on dev every run_code failed
as "Boot sandbox" (Sandbox pricing multiplier must be a finite nonnegative
number). getCostMultiplier now goes through envNumber, as the env module's own
rule says numeric overrides must.

* sandbox pricing: cost-multiplier imports env relatively — next.config.ts loads env-flags outside alias resolution

* mothership: pack a workspace inventory with every chat request

The agent spent nine tool rounds and ~20K tokens learning what exists in the
workspace before an orientation task could start. The chat request now carries
a compact inventory (contracts ChatRequest.inventory): workflows, tables,
knowledge bases, files, skills, custom tools, MCP servers, credentials, and
secret names — names and ids, one page per world, capped worlds named in
`truncated`. It is read through the same use cases the v2 listings run, under
the caller's session principal, so authorization is unchanged; a world that
fails to list is left empty and logged rather than failing the turn. The worker
renders it once per turn as a request-local message.

* grep: the tool catalog is one use-case call when the engine has the caller's principal

The tools world paged 5,000 built-in tools through the route stack at 100 a
page — fifty round trips, each re-resolving the gate and walking the registry —
which was the whole cold cost of a world-wide grep. The embedded bridge now
resolves the delegation key to its principal exactly as the v2 surface does and
hands it to the engines; with it, the tools world reads the catalog through
listCatalogTools in one call — same authorization, same projection. Without a
principal the client path stays.

* mothership: background tasks — subscriptions, wake turn, task pill (21 §6)

Sim side of copilot background tasks. copilot_task_subscriptions
(migration 0315) records a worker task's watch on a workflow execution;
the logging session's completion attempt posts every subscribed run's
outcome to the worker. POST /api/mothership/tasks/subscribe and
POST /api/mothership/wake (internal key): the wake runs the inbox's
headless lifecycle under the task id as message id, announces itself on
the chat status channel so an open chat reconnects, persists the user
message with origin 'task', and resolves the pill in the arming turn.

Client: a 'task' content block end to end (run handler, turn-model node,
both serializer directions, persisted normalizer — which also flattened
plan blocks to text on reload —, display block, segment, TaskPill) and a
muted TaskNotificationRow for task-origin messages. The stream
validator's run kinds now derive from the generated contract; the
generated mothership-stream-v1 gains task_armed / task_delivered.

* mothership tasks: resolve the pill by task id (jsonb text spacing broke the exact-key match)

* task pill: icons from @sim/emcn (lucide-react is not an app dependency; the Docker build failed)

* mothership: checkpoint Sim interaction and workbench boundary repairs

Capture the accumulated Mothership control, recovery, sandbox session, embedded CLI, and standalone diagnostic repairs. Companion worker checkpoint: c8245400. Validation and limitations are recorded in the Mothership revamp ledger through iteration 38; the latest expanded Sim diagnostic selection passed 1231 tests. The new table-mount audit is excluded and will follow separately.

* mothership: authorize table snapshot mounts and honor folder references

Move Mothership table snapshot resolution, provenance checks, and bounded storage reads into a registered application operation. Reuse the table VFS resolver for folder paths, recheck current actor access before materialization, and project safe mount errors. Preserve CSV transport, budgets, default paths, and workflow/public API behavior. Validation: 517 related tests, app/auth type checks, API and agent-CLI boundary checks.

* mothership: stream workbench downloads with atomic publication

* mothership: stream uploads and imports from workbench snapshots

* mothership: bind upload requests to the snapshot lifetime

* fix(mothership): preserve and bound embedded CLI output

* fix(mothership): preserve file provenance through host CLI reads

* test(mothership): guard current CLI catalog entry points

* fix(mothership): make search current, isolated, and explicit about coverage

* fix(mothership): bind file mounts to one canonical version

* feat(mothership): persist private upload source classification

* fix(mothership): preserve classification across workbench file copies

Record encrypted source evidence against host-streamed bytes and physical workbench identity. Bind completed upload streams through the authorized application operation, sealing pending provenance with the completion lease so recovery preserves the first result.

* fix(mothership): retain source evidence for saved CLI output

Classify settled stdout through the existing workspace-file helper and persist evidence against the streamed workbench bytes. Preserve completed command outcomes on publication failure and verify copied output across fresh invocations and pending sibling tools.

* test(mothership): exercise CSV composition through the Sim runtime

* test(mothership): connect CLI workflow runs to report publication

* fix(mothership): preserve raw CLI data with scoped presentation

* fix(mothership): expose canonical workflow identity for watches

* fix(mothership): preserve watches across transcript replay

* fix(mothership): convert code execution timeouts once

* fix(mothership): preserve child failures across transcript recovery

* test(mothership): distinguish replay from executable handoff

* test(mothership): verify persisted run diagnostics through CLI

* test(mothership): verify workflow execution log readback

* test(mothership): verify controller execution and resume recovery

* fix(mothership): acknowledge text received before stream retries

* fix(mothership): reconcile response text across reconnects

* test(mothership): verify automatic relay interruption recovery

* fix(mothership): unify replayable child lifecycle handling

* test(mothership): verify child recovery after worker exit

* fix(mothership): distinguish tool history from executable handoffs

* fix(mothership): acknowledge received activity between stream legs

* test(mothership): recover missing initial relay frames

* test(mothership): cover overlapping relay attachments

* fix(mothership): observe results owned by overlapping controllers

* fix(mothership): preserve long CLI command budgets

* test(mothership): verify table pipeline against real execution

* fix(mothership): recover one-shot response delivery

* fix(mothership): align one-shot MCP discovery guidance

* fix(mothership): make inbox attachments readable

* fix(mothership): scope upload names to the requesting chat

* fix(mothership): preserve worker history when forking chats

* fix(mothership): cancel only response-owned workflow executions

* fix(mothership): serialize workflow pickup with run Stop

* fix(mothership): track browser workflow execution through Stop

* fix(mothership): require settlement for Stop before chat attachment

* fix(mothership): preserve canonical history when stopping a response

* fix(mothership): handle abort failures while Stop history persists

* fix(mothership): retain queued Stop dependencies through retries

* fix(mothership): recover outgoing handoffs through the durable queue

* fix(mothership): bind queued retries to the active Stop operation

* test(mothership): exercise physical workflow edits and oracle execution

* test(mothership): verify extracted workflow invocation through saved logs

* test(mothership): verify build-only consent through physical run history

* fix(mothership): retain terminal failures in saved chats

* fix(mothership): retain active runs through worker connection loss

* fix(mothership): persist Stop before worker delivery

* fix(mothership): recover interactive streams after Sim process loss

* fix(mothership): durably admit chat turns before worker dispatch

* fix(mothership): recover lost tool handlers with fenced execution leases

* fix(mothership): finalize steered answers by turn identity

* fix(mothership): separate committed tool outcomes from stream publication

* fix(mothership): serialize saved resource panel changes

* fix(mothership): persist resource effects once before publication

* fix(mothership): preserve complete saved resource addresses

* fix(mothership): preserve saved table views in chat context

* fix(mothership): follow the current embedded table view

* fix(mothership): preserve exact table selection identities

* fix(mothership): attach usable file folder references

* fix(mothership): render saved file folder resources

* Revert "fix(mothership): render saved file folder resources"

This reverts commit d785434.

* fix(mothership): align attachment context with available tools

* fix(mothership): authorize MCP calls as the chat subject

* fix(mothership): keep workbench policy out of the public CLI

* fix(mothership): preserve composed code export outcomes

* fix(mothership): retain completed files after export failure

* test(mothership): verify hosted workbenches and task compositions

* ci: restore staging jobs and keep Mothership acceptance local

* feat(mothership): receive private Sim controls over outbound transport

* fix(mothership): bound stream reconnection attempts

* fix(mothership): export chat sandbox files through workspace storage

* fix(cli): isolate embedded output from host process logging

* fix(mothership): preserve file intents and workflow result contracts

* perf(mothership): trace CLI and tool persistence boundaries

* fix(mothership): preserve resource effects and execution recovery

* fix(mothership): reconcile staging contracts and consolidate migrations

* fix(mothership): share and verify billing callback contracts

* fix(mothership): preserve catalog curation and embedded CLI access

* fix(mothership): mount code secrets explicitly

* fix(mothership): own sandbox profile at the code tool boundary

* fix(workflows): validate field values before full-state writes

* fix(chat): collapse main tool groups into action summaries

* fix(mothership): restore workspace API key dispatch

* fix(chat): label workflow dry runs as validation

* feat(chat): expose model, reasoning effort and Astra Fast controls

* fix(chat): align composer model and effort controls

* Group Mothership tools by activity and show scoped resource names

* Report requested Mothership model without legacy telemetry defaults

* Restore Mothership Slack bot connection from stored secrets

* Preserve execution events for deployed Copilot workflow runs

* Expose active workflow API details to Mothership

* Restore desktop parity and preserve interrupted chat progress

* Keep Mothership resource panels and activity groups in sync

* Show active tools before completed activity summaries

* Fix shared agent tool execution and discovery boundaries

* Port Assistant to shared Mothership runtime and repair resource recovery

* Refresh CLI docs and desktop validation after staging rebase

* Restore staging image inventory commands

* Fail migrations correctly and resolve empty direct database URLs

* Match chat attachment guidance to supported file capabilities

* fix(ci): retain the latest published desktop prereleases

* fix(mothership): read file contents through one adaptive command

* fix(chat): simplify pending tool activity label

* feat(chat): inspect scratch files and preserve inline images

Resolve workspace, upload, and sandbox references through authorized file readers. Preserve explicit Markdown images privately with each chat turn without creating workspace files, and keep visual bytes out of bounded UI tool-status events.

Keep sandbox CLI credentials scoped to the active callback so file provenance checks cover data entering the workbench.

* fix(chat): keep tool failures in expanded history

* fix(db): avoid repeated dev index builds and search backfills

* fix(chat): preview inline images with shared lightbox

* feat(mothership): operate across organization workspaces

* feat(mothership): manage settings and workflow file inputs

* fix(mothership): preserve stopped chat admission and queued corrections

* fix(mothership): show sequential activity intent and concrete tools

* fix(mothership): expose canonical model hints in internal discovery

* fix(mothership): unify scoped CLI and organization resource panels

* feat(assistant): connect and use personal organization integrations

* feat(chat): unify Home modes and search resource tabs

* feat(chat): tailor Home controls and starters to the selected mode

* fix(mothership): preserve file upload and preview resource context

* fix(mothership): stabilize Home search panels and add optional Fast Search

* fix(mothership): preserve staging authorization and resumed billing

* fix(db): make development schema pushes noninteractive (#7906)

* fix(db): resolve dev schema push column ambiguity

* refactor(db): generalize push rename handling

* docs(db): describe schema push reconciliation steps

* feat(search): unify Home search levels and composer

* fix(db): retire file size bridge before forced schema push

* fix(ci): restore test isolation and memory file scope checks

* fix(ci): keep metadata imports pure and narrow component graphs

* fix(mothership): refresh client settings after scoped mutations

* fix(db): repair partial member sync status on existing databases

* fix(home): reuse the shared loading fallback

* fix(mothership): remove eager catalogs and bulky admission saves

* fix(mothership): keep reads out of resource panels

* test(search): assert lazy integration catalog in headless chat

* fix(search): label balanced search level Auto

* fix(mothership): provide authorized context for chat titles

* fix(search): restore standalone search and refine chat mode controls

* fix(search): align mode selector with the standard search icon

* fix(mothership): resolve integration discovery service identities

* fix(desktop): reuse Sim login for authenticated browser previews

* fix(chat): preserve configured origin in deployment URLs

* fix(search): recover GitHub installation setup and verify ownership

* fix(search): retain sync failures and resume reconnected accounts

* fix(chat): restore thinking indicator after tools finish

* fix(mothership): expose and validate tool attachment identities

* feat(mothership): inspect configured workflow tool bindings

* feat(mothership): support dynamic Sim Chat tool modes

* fix(mothership): continue Sim Chat block conversations

* feat(mothership): create organization workspaces through CLI

* perf(desktop): observe browser state in action calls

* fix(mothership): repair background wakes and simplify watch activity

* fix(mothership): clarify tool permissions and folder context

* fix: reconcile staging rebase contracts and migrations

* fix(db): reconcile staging search migrations in dev

* fix(chat): preserve live turns and recover interrupted streams

* fix(workflows): scope custom block schemas during authoring

* fix: reconcile staging search and file contracts after rebase

* style(db): format rebased migration snapshots

* fix(slack): deliver Sim Chat text and tool progress reliably

* test(slack): verify Agent and Sim Chat thinking parity

* fix(slack): bound each long-answer append request

* fix(slack): continue long streams across message limits

* fix(slack): recover explicitly rejected size overflows

* fix(mothership): simplify saved results display label

* fix(slack): clean up long-response continuations

* feat(mothership): simplify Build picker to Astra effort levels

* fix(mothership): hide mode selection after the first message

* feat(search): add feature-flagged live provider retrieval

* fix(search): scope repository retrieval and add Coda MCP OAuth

* fix(search): restore account hooks client directive

* Fix GitHub connected-account tools in Search Assistant

* Add organization-scoped live search and admin-managed GitLab

* Add date-aware live enterprise search and bounded listings

* Polish live Search results, citations, and effort controls

* fix(mothership): preserve hosted service billing through cutover

Record hosted integration, sandbox and media spend through a trusted durable
service outbox independent of tool output, cancellation and worker delivery.
Preserve service billing under model BYOK and restore title admission.

Use workspace BYOK settings and fresh credentials, retain execute transport,
and restore the locked actor-authority check for billing-sensitive membership
removal. Add migrations and local HTTP/PostgreSQL billing acceptance coverage.

Validation: 1,453 billing tests passed with 30 environment-gated skips, app
and dev infrastructure types passed, and local SQL charge proofs passed.

* fix(search): restore live citations and streamed source panel

* fix(search): replace live results tab with cited sources

* feat(search): simplify federated sources and add scoped secrets

* fix(search): make service account setup directly accessible

* feat(mothership): add dev-gated Plan mode across chat surfaces

* fix(search): preserve account connection links in Slack

* fix(search): remove indexing language from live search

* fix(search): keep admin setup out of member integrations

* fix(search): route Search MCP through live retrieval

* fix(plan): normalize the runtime feature flag to a boolean

* ci(dev): deploy Trigger tasks independently of app images

* feat(mothership): set organization Generic Secrets in chat

* fix(search): verify federated connectors and align setup docs

* fix(search): remove stale Slack indexing copy

* docs(search): document Generic Secrets and clarify source setup

* fix(mothership): allow authorized organization code secrets in Build and Plan

* fix(search): restore live integration connection chips

* fix(search): include Gmail in live connection inventory

* fix(search): expand composer around image attachments

* fix(mothership): restore saved Plan chat history

* fix(mothership): address review findings and CI regressions

* test(deploy): align promotion expectation with Trigger CLI

* improvement(desktop): make saved password autofill field-aware

* fix(mothership): preserve trace filters and shared app workers

* fix(desktop): dismiss credential picker when browser hides

* feat(mothership): simplify model controls and add native desktop files

* fix(desktop): preserve password picker focus and lifetime

* chore(mothership): align model and deployment test expectations

* fix(mothership): resolve model and Plan controls from AppConfig

* fix(desktop): contain native imports and preserve UTF-8 pages

* fix(credentials): preserve unrelated setup controls

* feat(browser): file transfer, popups, PDFs, click gestures, and dialog answers for the browser agent

- Upload workspace, chat-upload, or granted local files into a page's
  file input (DOM.setFileInputFiles on the input a ref, label, or drop
  zone resolves to), staged privately and bound to the claimed tool
  call; save completed downloads into workspace files. New
  /api/desktop/tool/file route with application use cases.
- Same-session popups adopt Chromium's WebContents so window.opener
  works (sign-in and connect flows); a page that closes itself leaves
  cleanly and agent work returns to its opener.
- PDFs render: enable Electron's internal PDF plugin and let its
  packaged viewer resources past the network guard.
- Clicks take button, clickCount, and modifiers; agent right-clicks
  never open the native menu. Actions answer confirm/alert dialogs via
  dialog: {accept}. press_key gains F1-F12, Insert, and repeat; scroll
  and hover accept post-action observation.

* chore(chat): provide runtime flags in composer tests

* fix(browser): isolate actions and bound file transfers

* fix(browser): retain upload input identity through dispatch

* fix(mothership): validate complete billing protocol headers

* fix(browser): preserve upload dispatch before acknowledgement

* fix(browser): distinguish unconfirmed upload outcomes

---------

Co-authored-by: Vikhyath Mondreti <vikhyathvikku@gmail.com>
Co-authored-by: Vikhyath Mondreti <vikhyath@simstudio.ai>
Co-authored-by: Waleed Latif <walif6@gmail.com>
* fix(knowledge): skip global readiness checks for ordinary KBs

* test(knowledge): align KB search assertions with document pages
* fix(execution): resolve stored file references only for workspace members

Workflow file inputs can reference stored files by id, key, or internal URL,
and every resolved file is added to the run's explicit file grants. Any
caller could use this, so an anonymous public-API, public MCP, chat, or
webhook caller could pull another workflow's run files or workspace files
into a run and receive a presigned URL for them.

Execution now derives a stored-file reference scope from the run's
principal: authorized member principals (session, personal/workspace API
key, OAuth token, delegated) resolve workspace-wide; system principals may
only reference files already stored under the current execution, which keeps
chat and webhook uploads working. The default is the restricted scope, so a
new caller fails closed. Input-format defaults are workflow-authored and
still resolve workspace-wide.

Outside workspace scope, an upload whose URL is an internal file URL is
resolved as the stored reference it names rather than downloaded with the
run user's access, and a key from another execution is refused before it is
looked up, so the refusal does not reveal whether the file exists.

* fix(mothership): withhold unregistered table secrets from sim_cli results

Table rows read through sim_cli reached the model without their persisted
secret provenance, so stored secrets in cells were never redacted. Row use
cases now report the provenance of the rows they return to an observing
transport (mirroring the workspace-file delivery observer), and the agent CLI
table transport imports it into the tool call's registry, answers 503 without
a registry, and marks the registry incomplete when a row-bearing table route
returns without reporting provenance. Provenance reported by detached work
after the call settles is ignored.

Export download links are refused outright: a signed link to the whole table
as plaintext CSV cannot carry provenance once fetched.

Run-state and enrichment error text (runState.error, blockErrors, enrichment
provider errors) is captured from executor output without its secret
provenance, so a read that returns any of it is withheld as well; reads whose
run state carries no error text are unaffected.

* fix(search): run live Calendar service search on the crawl scope

PR #8208 widened Google Calendar's domain-wide delegation scopes to include
calendar.readonly for every service-account token. Google refuses the whole
token exchange when any requested scope is not authorized for the client, so
indexed admin-mode Calendar syncs configured for calendar.events.readonly
failed every run and were eventually disabled.

Live service search only needed the wider scope to read an all-day event's
calendar time zone. events.list returns the calendar's timeZone under
calendar.events.readonly, so live search now reads it there and delegates with
the same single scope as the indexed crawl, matching Drive and Gmail. The admin
calendar picker keeps its own calendar.readonly request, as documented.

* fix(search): keep results painted when Show more widens the page

* fix(chat): use the defined brand token for the resource activity dot

* fix(knowledge): document connector auth in the v2 contract and reject $NAME secrets

* fix(mothership): resolve Copilot env-reference passwords for chat deploy and file share

Copilot now deploys chats and shares files through the v2 API, which stored a
whole-value {{NAME}} password literally (or 400'd a short one on length). The
application use cases now resolve the reference from the effective environment
when, and only when, the caller is an admitted Copilot workspace invocation and
the password will actually be stored (password mode; for a file share, only
while enabling it), refuse an unset variable by name, and hold the resolved
value to the password rules. Every other principal keeps literal semantics.

The v2 password fields admit a whole-value reference below the password
minimum as one refined string (not a union, which would make the CLI flag
JSON-only), still capped at the password maximum; the use cases enforce the
15-character rule on the value actually stored. Connector API-key references
share the same principal environment lookup, and the exact reference regex now
lives in one module.

Unlike the removed Copilot tool path, the resolved password is not recorded in
a resolved-secret trace registry: the v2 use case has none, and the password
is write-only and never echoed back.
… refused clicks (#8214)

* fix(browser): keep snapshot ids valid after an observed action is refused

An observed click refused before dispatch (for example, covered by an overlay)
never starts its observation, yet it invalidated every id in the snapshot, so
the agent could not click the overlay's own close button without re-observing.
A failed observed action with no dispatched outcome now only cancels an
in-flight capture, which clears the refs itself when it starts.

* feat(browser): run planned page actions in order with browser_batch

The desktop runs 2-8 single-page interactions from one authorized call, in
order, stopping at the first failed action or after an action navigates,
switches tabs, or invalidates the snapshot's element ids. A batch stopped by a
failure reports an error status; one stopped by a page change does not. Once
an action has run, a cancelled or timed-out batch reports an unknown outcome
so the agent does not repeat it.

* fix(browser): mark batched actions pending and stop batches on same-document URL changes

A batch now reports its outcome as pending before every action, since an
action can dispatch input before it returns; a cancelled or timed-out batch
therefore never reads as not started. It also stops after an action changes
the tab URL within the document, not only on cross-document navigation.
…8216)

* fix(insights): show member profile photos with the canonical avatar

* fix(insights): read names and avatars for the whole tie at the breakdown cutoff

* fix(insights): cut breakdowns by key so the entity read stays bounded
* Add Slack Lists and Canvas blocks with custom-bot Lists access

* Keep Lists and Canvas actions in the existing Slack block

* Drop unrelated import formatting from staging merge

* fix(slack): keep optional scopes opt-in and validate resource inputs

* fix(slack): preserve app permissions when reconnecting custom bots

* docs(slack): move resource guidance after action reference

* fix(slack): default custom bot setup to full permissions

* test(slack): update embedded setup expectations for full scopes
…8220)

* improvement(chat): reduce streaming render work and completion delay

* chore(chat): align streaming constants with type conventions
…8221)

* fix(settings): use one member avatar with profile photos everywhere

* improvement(emcn): collapse MemberAvatar into Avatar with name and src props

* fix(emcn): announce avatar status in the person's label and keep the name on email-only rows

* fix(emcn): keep a composed avatar's status announced and export fallback variants
…026 (#8224)

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

* improvement(search): polish organization search and source results

* fix(search): align activity headers and preserve complete drafts

* fix(search): tighten draft recovery and shared sidebar behavior
…tion summaries (#8225)

Mothership v1.0.0 reintroduced the "Searching -> Searched -> Searching"
flicker that staging had fixed: between two calls of an open main-agent
activity, the header dropped to the past tense, lost its shimmer, and the
turn-level Thinking row appeared until the next call started. It also removed
the header icon and summarized headers as "<latest title> + N".

Stable in-progress header
- An open main-agent activity group (the streaming turn's tail, with nothing
  after its last call) stays in the present tense through the gaps between
  its calls, so the header no longer flips tense. Succeeded calls arrive
  with past-tense titles, so the open header maps them back through the exact
  inverse of the completed-verb rewrite; one helper (getToolInProgressTitle)
  serves main lanes, subagent lanes, and the landing hero.

One live indicator per lane
- A new pure module (lane-activity) owns the rule and states it in TSDoc.
  Each active lane has one live call: the newest running call anywhere in
  the lane (across all its runs, including runs split by a search or an
  interaction card, and its nested lanes). With none running and the lane
  open, the latest call of its trailing run owns the gap, and only if it
  succeeded. A finished search shows static results, so the gap after it
  belongs to Thinking.
- Only the run holding that call shimmers: its group header, or its one
  search row. Tool rows never shimmer by themselves. A parent lane defers
  to a visible nested lane holding the live call only while that lane is
  still working; an ended nested lane hands its last call back to the
  parent's header.
- Tense follows liveness: a header reads in progress only while it is live
  or its call still runs, so a group whose latest call failed or stopped
  reads as finished instead of keeping a stale present tense.
- The turn computes this once; every lane view receives its share, and the
  Thinking row reads the same result. The main lane spans all main-agent
  segments. Thinking shows only when no lane is live and no lane waits on
  the user. A lane waiting on an approval, terminal handoff, or browser
  takeover shows no indicator, while other lanes doing real work keep theirs.
  When the stream finishes, nothing shimmers.
- Rendering and liveness share one run split, and failed subagent lanes no
  longer count as working. Only the tail group is open, so a later pending
  interaction no longer re-opens earlier finished groups.

Header icons
- Group headers and single inline rows render the icon of the call they
  describe again, including integration brand icons, and keep it through
  completion. Main and subagent headers share one title rule: "Working…"
  while a sim_cli or run_code call generates its arguments, a live wait
  countdown, and streaming file-edit titles.

Summaries without "+N"
- Running headers show only the active call. Main and subagent lanes share
  one completed-label rule: the model's completedTitle only when every call
  succeeded, and otherwise a fallback naming up to three distinct successful
  actions ("Navigated, read pages, clicked elements"), picked by first
  occurrence in transcript order. Failed calls are
  left out, and the " · N stopped/skipped" outcome suffix stays.
- A rebuilt action catalog covers the current tool surface: every visible
  catalog tool and operation, plus sim_cli commands. Each command's verb comes
  from its own display title, and the object comes from its resource path, so
  commands on one resource share a word ("Listed, read tables"). `mkdir`
  commands read as creating folders and `tables upsert` as writing table rows.
  Tools outside the catalog use their own completed title.

Separate finished activity groups
- groupByActivity still splits main-agent calls by activity id, but no longer
  merges finished groups into one header, so the completedGroupCount plumbing
  is removed, along with the unused getAgentIcon fallback parameter.

Flat expanded layout
- Indentation now only marks nested work. Expanded tool rows in main and
  subagent groups line up with their header: the icon in the shared 14px
  icon column, the text one gap-2 to its right. Nested subagent lanes,
  narration, lane errors, and the permission card's rows sit on that same
  text column through one shared primitive instead of pl-6 or pl-[22px].
- One spacing scale: gap-1.5 between rows inside a group (tool rows, search
  queries), gap-3 between blocks in the main lane (tool groups, search runs,
  lanes, interaction cards, prose).

Inline links in answers
- A link's favicon is centered on the text's own middle with align-middle,
  like inline citation chips, instead of a baseline pixel nudge.
- The link tooltip names the page instead of showing its URL. It uses the
  turn's retrieved source for that exact URL, then the link preview's title,
  then the site name, with the site name muted beneath. One helper dedupes a
  turn's sources by URL everywhere they are listed or looked up.
- Prose links show a thin muted underline on hover instead of a filled
  background, and keep the keyboard focus outline.

Verb rewrites
- The past-tense and present-tense verb tables are Maps, because titles
  include model-written text, and a description starting with "constructor"
  must never resolve to an inherited object property.

Live file-edit titles
- A prepare_file_edit title streamed with escaped characters (e.g. a quote)
  was cut at the escape; it now reads through the shared streaming-argument
  parser, which matches escapes and decodes them.
…st (#8227)

The live service-source test asserted updateSearchIntegration immediately
after the create onSuccess act, but onCreated awaits the nuqs URL-state
reset (which flushes asynchronously) before it starts the mutation, so the
assertion raced the flush and failed most runs. Wait for it the same way the
sibling setup test already does (vi.waitFor with a 1ms interval).
…me (#8232)

* fix(file-parsers): read side-by-side calendar grids one block at a time

* fix(file-parsers): tighten calendar block detection from review

* fix(file-parsers): accept a weekday header drawn as one text item

* fix(file-parsers): require a shared header to name every grid column

* fix(file-parsers): match multi-word header cells and group rows by local height
…mpared (#8234)

Co-authored-by: Sim Pi Agent <pi@sim.ai>
* fix(search): use shared inline tool activity

* fix(search): clarify activity result states and labels
…ical Teams (#8250)

Co-authored-by: Sim Pi Agent <pi@sim.ai>
* improvement(logs): refresh the table on demand

* fix(logs): detect snapshot changes before paging
* improvement(chat): unify message styling and source previews

* fix(chat): bound preview work and preserve readable tables

* fix(chat): preserve link contrast and bound preview retries

* fix(chat): restore Inter and refine table overflow
* fix(slack-search): stream task progress in plan mode

* test(search): await async source integration selection
* Cancel waiting tools and retain completed replay after title updates

* Retain Stop marker creation coverage for every unfinished tool state
Co-authored-by: Bill Leoutsakos <billleoutsakos@Bills-MacBook-Pro.local>
* refactor(auth): share loading skeleton treatments

* test(auth): cover shared loading shapes and composition

---------

Co-authored-by: Bill Leoutsakos <billleoutsakos@Bills-MacBook-Pro.local>
* improvement(ui): share product page heading recipe

* test: include shared heading export in logs error mock

---------

Co-authored-by: Bill Leoutsakos <billleoutsakos@Bills-MacBook-Pro.local>
* Scope preview workflow cursors to each instance

* test(preview): verify scoped cursor CSS across mounted previews

---------

Co-authored-by: Bill Leoutsakos <billleoutsakos@Bills-MacBook-Pro.local>
Co-authored-by: Bill Leoutsakos <billleoutsakos@Bills-MacBook-Pro.local>
* improvement(ui): source collaborator colours from CSS palette

* fix(ui): map resolved collaborator colours to palette slots

* docs(ui): document collaborator palette lookup
…ne step (#8282)

* improvement(search): guide independent live searches and reads into one step

* test(search): assert the batching guidance
…s stable on refresh (#8284)

* fix(workspaces): persist visit recency server-side so sidebar order is stable on refresh

* fix(workspaces): serialize visits and stamp them with the database clock

* chore(workspaces): drop leftover churn and mark the legacy last-active column for contract

* chore(db): drop contract marker on settings.last_active_workspace_id

* chore(workspaces): write the permission-group exemption as TSDoc
)

* fix(browser): press chord modifiers as real keys

A chord such as Control+Shift+Y was sent as one key-down with a modifier
bitmask, so pages that track held keys never saw Control or Shift go down.
Modifiers are now pressed in order before the main key and released in
reverse, as a physical keyboard delivers them, and a bare modifier key can be
pressed on its own.

* feat(browser): let clicks press and hold

Clicks released the button immediately, so press-and-hold controls could not
be operated. A click now accepts holdMs (0 to 10000, single clicks only) and
keeps the button down that long before release.

* fix(browser): read disablePortal modals hidden with their app root

MUI hides every <body> child except a modal's mount node; a disablePortal
modal mounts inside the app root it just hid, so every node had an aria-hidden
ancestor and the snapshot came back empty while the dialog was on screen.
Visibility checks now skip aria-hidden only on ancestors above the single
topmost modal hidden that way; portaled modals and other hidden regions are
unchanged.

* fix(browser): stage agent downloads synchronously so Electron never opens a Save dialog

The save path was set only after an asynchronous non-conflicting-name lookup.
When Electron's own path step won that race it opened a native Save dialog, so
an agent download stalled forever at full size (and a user would see a
surprise dialog). Downloads now write to a hidden staging file set during
will-download and are renamed to the allocated name when they complete.

* feat(browser): mark snapshot elements that appeared since the previous snapshot

After an action the agent saw a fresh snapshot but no hint of what changed, so
a popup, suggestion list, or validation message looked like any other line.
The page now remembers which elements an earlier snapshot of the document
listed, and later snapshots mark the rest new (the first snapshot marks
nothing).

* refactor(browser): tighten the computer-use desktop changes

- Modifier aliases (Ctrl, Cmd, Command, Option) share one descriptor with their
  canonical key, so a bare alias sets its own flag; a bare modifier's key-up
  reports it released.
- The framed-control fallback no longer treats a held click as a plain click,
  and a batch refuses press-and-hold so eight holds cannot outlast its watchdog.
- installPageHelpers caches the modal lookup per invocation, and one
  serializePageCall builds the page expression for the driver and the tests.
- Download completion drops a branch whose state was never published.

* fix(browser): close the edge cases review found in the desktop agent changes

- A held right-click renews its agent context-menu marker before release, so
  Windows' release-time menu stays suppressed after a hold over one second.
- A failed chord releases only the keys whose press was attempted.
- A disk probe that resolves after a download completed can no longer cancel it.
- A disablePortal modal nested inside another open modal is picked as topmost.
- holdMs is an integer bounded to 0-10000 in the tool contract.

* fix(browser): harden holds, modal exemption, and download moves

- An aborted press-and-hold rejects and releases the button at once instead of
  staying held into the next action.
- The disablePortal exemption applies only when a <body> child hides the modal
  (MUI's mechanism), so a dialog the app hid itself stays hidden, and it is
  looked up per document so same-origin iframes get it too.
- A completed download's move retries transient EBUSY/EPERM/EACCES errors, as
  Chromium's own final rename does, instead of discarding the file.
- Keyboard docs describe the separate modifier presses; the partial-release
  test covers a failure at the first modifier.

* fix(browser): claim agent download names on disk while bytes stage

The allocated destination gets an empty placeholder created with O_EXCL, as
Firefox does, so another program picking a name sees it taken and the final
rename only ever replaces Sim's own placeholder. A name that something else
grabbed first stops the download instead of being overwritten. Teardown and
failures remove the placeholder once, so a late-settling download cannot delete
a name a newer download has claimed.

* fix(browser): close cancellation and teardown races in holds and downloads

- An already-aborted click presses nothing, and a held click marks its outcome
  pending before dispatch, so cancelling mid-hold reports an unknown outcome
  with doNotRetry instead of an error that invites a retry.
- The disablePortal exemption resets when a visibility walk crosses from an
  iframe into its host page, where the host's own aria-hidden applies.
- Teardown keeps a download's name reserved until its placeholder claim
  settles, so a newer download cannot be handed a name the claim then takes.
- Downloads are paused before the staging path is set, as on staging, so a
  pause failure leaves no staging file behind.
…laim (#8288)

- browser_find collects its outline with markNew off, so a search never
  matches the `new` token and never consumes markers the next snapshot owes.
- An element counts as shown only once its line is emitted.
- The placeholder claim runs inside the allocation timeout, so a hung
  filesystem stops the download instead of leaving it paused with its name
  reserved; a late placeholder is removed when the claim settles.
- A successful move drops the placeholder pointer, and an already-aborted
  click sends no input at all, not even the pointer move.
…ist by date without a bound (#8286)

* improvement(search): name Slack authors, read only when needed, and list by date without a bound

* fix(search): accept date listings on the search route and name match authors by user ID
@waleedlatif1 waleedlatif1 changed the title v0.8.60: mothership v1, live search, slack list and canvas tools, ui consolidation v0.9.0: mothership v1, live search, slack list and canvas tools, ui consolidation Sep 25, 2026
@waleedlatif1
waleedlatif1 merged commit ac8274f into main Sep 25, 2026
75 of 76 checks passed

This branch was previously deployed

1 inactive deployment
Preview — f6035de7 Deployed Sep 25, 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.

5 participants