| Name | Modified | Size | Downloads / Week |
|---|---|---|---|
| Parent folder | |||
| README.md | 2026-08-05 | 77.2 kB | |
| v0.11.0 source code.tar.gz | 2026-08-05 | 147.2 MB | |
| v0.11.0 source code.zip | 2026-08-05 | 154.3 MB | |
| Totals: 3 Items | 301.7 MB | 1 | |
Core/SDK 0.11.0 (2026-08-05)
Minor Changes
-
Replace
Surface.isAvailablewithSurface.useIsAvailable, a hook returning a stable, memoized function. Surfaces and graph extensions with an invalid (non-camelCase) local id are now dropped with a warning instead of throwing and crashing plugin activation. (2048cb3) -
Surface.createaccepts an optionalpropsmapper, so a container can be registered directly instead of being wrapped in an adapter that unpacks the surface'sdataenvelope:
ts
Surface.create({
id: 'defaultPluginSettings',
filter: AppSurface.settings(AppSurface.Article),
component: DefaultSettings,
props: ({ data: { subject } }) => ({ subject }),
});
The mapper's input type derives from the same filter that defines the surface's data shape, so the
unpacking is type-checked rather than restated by hand, and is exported as Surface.ComponentProps
for components that consume the whole envelope. component accepts any ComponentType, so a
container re-exported through a lazy() barrel needs no cast. Additive: definitions without props
receive the full surface props exactly as before. (ed992c2)
- Plumb ephemeral trace events through the swarm (DX-1125).
Adds tag-based broadcast pub/sub over the existing swarm messaging layer (spec 1): a message may carry tags instead of a single recipient, and a subscriber registers a tag set and receives any broadcast whose tags intersect (logical OR). New wire fields (signal.Message.tags, signal.SubscribeMessagesRequest, messenger.Message.tags, SwarmRequest.SUBSCRIBE/subscribe_tags) and a dedicated onBroadcast channel keep broadcasts off the point-to-point path.
On top of that (spec 2), remote runtimes broadcast their ephemeral trace messages so clients can watch live progress: Trace.messageToTags/Filter/matchesFilter/encodeTraceMessage, a SwarmTraceSink producer, Process.Monitor.subscribeToTraceMessages(filter), a RemoteTraceMonitor swarm source merged into the aggregate monitor, and a plugin-client consumer that projects remote status.update events into the progress registry. (08a3eea)
-
Drive connector-auth ("Connect X") toolbar actions from a
ConnectorAuthAnnotationschema annotation, resolved by a single app-graph extension in plugin-connector — replacing the per-pluginconnectorAuthExtensionhelper (removed). Owning plugins inline their own sync/generate toolbar actions. AddsactionGroupstoGraphBuilder.createExtension/createTypeExtensionand aprimarymenu-action variant. (68e61ca) -
Graph actions can now declare
dispositionas an array and apresentationchrome override per surface, letting one action multi-target the object toolbar and nav-tree context menu with appropriate chrome in each. Mailbox and calendar "Sync" now surface from a single graph action instead of a duplicated toolbar button. (1a989ed) -
Redesign Composer URLs as pair chains (
/w/<workspace>/<key>/<id>/…) resolved by the graph builder via per-extensionurl: { key, kind, path }declarations (replacing theNavigationPathResolvercapability), and collapse the deck's layout modes into a single mode: presentation derives from plank count (fullbleed / tiling / sliding) and fullscreen is transient. Navigation is now gesture-based (nonavigationDefaultsetting): nav-tree plain click navigates solo (shift adds a plank), and in-plank/card navigation follows the deck — adding beside the origin when sliding and replacing when solo.LayoutOperation.Open'sdispositionvalues aresolo | add | auto. Breaking:LayoutOperation.SetLayoutModeis removed,?plank=URLs are replaced by the pair-chain grammar,AppCapabilities.NavigationTargetResolvernow declares its real requirement (Effect<NavigationTarget[], never, Database.Service>) so implementations no longer need a cast, and the unusedcompanionFrameSizingfield is dropped from the deck's persisted state (stripped by the existing migration). (5585ec8) -
Add stable
data-testids across the inbox and connector UI (mailbox sync/reply/message actions, message and conversation tiles, connect dropdown) and an optionaltestIdparam onAppNode.makeToolbarActionGroup/react-ui-menu's menu builder, enabling reliable browser-e2e targeting. (30ae5eb) -
Replace
CommentConfig.getAnchorLabelwith a typename-keyedAppCapabilities.AnchorResolvercapability; the assistant companion chat now includes the markdown editor's current selection as request context. Fix view-state persistence so a written value (e.g. a text selection) survives without a live subscriber instead of being garbage-collected back to its default. (9f7d5ad) -
Move the
WithPropertiestest helper from@dxos/plugin-markdown/testingto a new@dxos/app-toolkit/testingsubpath export. (499dde4) -
Add an optional
attachflag to thedatabase.objectCreateoperation that files the created object in the space root collection (visible in the navigation tree). CLI:dx profile createtemplates now enable edge features (fixes device invitations hanging at "Connecting…" for CLI-created profiles), anddx halo shareprints the joinable URL. (bda1a02) -
Project model unification, phase 1 (breaking, no data migration — nothing deployed). Two forms of work: markdown checklists (
Outline) are the cheap, fluid form; ECHOTaskobjects in aTaskSetare the durable, assignable form; promotion links the two.ExternalProjectbecomesTaskSet(org.dxos.type.taskSet@0.2.0); containment is the ECHO parent edge (TaskSet → Task → sub-Task), replacing theTask.projectref.Task0.2.0 renamesassigned: Ref<Person>toassignee: Actor(human by Person ref/email/name, agent by DID) and addsfailed/cancelledstatuses.Outlinemoves into@dxos/types(0.2.0) with checklist markdown helpers and the task-promotion helpers.Project0.3.0 addsgoals,outline, andtaskSet. ThePlantype is REMOVED: a conversation's working set is its outline (Chat.outline; project chats write the project's outline) plus promoted Tasks; the planning skill edits checklist markdown, and delegation promotes to a durable agent-assigned Task the supervisor reconciles over. (37c17cc) -
Stop exporting
TestStreamfrom the package's main entry. The helper extendsnode:stream'sDuplex, and re-exporting it from the browser-reachable barrel leakednode:streaminto every browser bundle — with source-first dev resolution (vite + rolldown build system) this threwModule "node:stream" has been externalized for browser compatibilityat module scope on dev-server boot, hanging the app on the loading screen.
Breaking: import TestStream from @dxos/async/testing (new Node-only subpath) instead of @dxos/async. (aea1e6e)
-
Remove the legacy SharedWorker client-services path. The
@dxos/client/workerand@dxos/react-client/workersubpath exports, thecreateWorkerclient option, andServicesMode.SHARED_WORKERsupport are gone; use the dedicated-worker mode (createDedicatedWorker) instead. TheSHARED_WORKERproto enum values are retained but deprecated for wire compatibility. (856c4f0) -
Remove the legacy protobuf byte-transport client providers
fromSocket(websocket) andfromAgent(unix socket), along withAgentClientServiceProvider,FromAgentOptions, andgetUnixSocket.createClientServicesno longer supports aruntime.client.remote_sourceendpoint — it now throws, since the remaining deployment modes (HOST,DEDICATED_WORKER) and the shell↔app transport run over effect-rpc. This also removesclientServiceBundlefrom@dxos/client-protocol, which had no remaining consumers; the effect-rpcrpcsurface and the Promise/Streamservicessurface are unchanged. Aremote_sourcetransport can be reintroduced over the effect-rpcRpcPortprotocol if needed. (f15c632) -
Remove the deprecated
descriptorsmember fromClientServicesProvider(and the correspondingServiceRegistrydescriptor slot). The protobuf service descriptors it exposed had no consumers; the effect-rpc surface (rpc) and the Promise/Streamservicessurface are unaffected.clientServiceBundleremains for the legacy byte-transport bridges that still use it. (6df314a) -
Delete the redundant
dxos.iframe.WorkerServiceprotobuf service (and itsStartRequestmessage) now that the tab→worker control channel is defined and served via effect-rpc (WorkerServicein@dxos/protocols/rpc, over the appMessagePort). Also removes the now-unusediframeServiceBundleandworkerServiceBundleexports from@dxos/client-protocol(they had no consumers). Thedxos.mesh.bridge.BridgeServiceanddxos.iframe.AppService/ShellServiceprotobuf definitions are retained — they are still used by the WebRTC transport bridge and the shell↔app iframe transport respectively. (962c8cd) -
Add a
directtrigger kind that is invoked on demand rather than scheduled by the dispatcher, along with its spec/event constructors and anisManuallyInvokablehelper. (a19443b) -
Mailbox sync progress can now be cancelled from the sync meter: for an edge-executed sync trigger the cancel control stops the current run and its continuation chain, while the trigger's schedule stays enabled and re-syncs on its next tick.
@dxos/computenow exports theCancellationservice the runtimes provide (Cancellation.Service) and operations observe (Cancellation.signal).
Breaking:
@dxos/app-toolkit:ProgressTraceSinkOptions.terminateProcessis renamed tocancelProcessand takes aCancelTarget(pid, space, runtime, trigger) instead of a pid, so a cancel can be routed to the runtime that owns the run.-
@dxos/compute-runtime:SwarmRemoteTraceMonitorOptions.subscribeyieldsSwarmTraceBroadcast({ payload, tags }) instead of a bare payload — the envelope tags carry the ref-typed trace meta dropped by the wire codec. (5e7839e) -
McpToolAnnotationopts an operation into MCP projection: a name, model-facing description, safety class (read/write/destructive), and aspect, applied at the definition site withOperation.mcpTool({ … })and read back withOperation.getMcpTool. The annotation rides throughOperation.serializeinto the persisted record, so a remote projector (edge mcp-space-service) discovers tools from the operation registry instead of a hand-maintained table. Projected operations must be remotely invocable — refs in, JSON snapshots out, serializable schemas, worker-safe handlers. (6067460) -
Add
Project(@dxos/compute), the successor toTopic, holding owned instructions, routine references, and an artifacts collection; theRoutineschema moves into@dxos/computealongside it.Instructionsgains a structuredcommandsfield, surfaced as sentinel-command autocomplete in the assistant chat prompt. The existing@dxos/typesGH/Linear-styleProject(name, description, image) is renamed toExternalProjectto free the typename for the new concept.dx-inputnow owns its full input chrome (padding, focus shift, a single-band ring/border treatment) so markdown-backed fields match plain inputs. (f7d7735) -
Subscription triggers now report a real mutation type on
SubscriptionEvent.type—'created' | 'updated' | 'deleted'(previously the placeholder'unknown'; the field is now a narrowed literal). Subscription semantics (create/update/delete) apply uniformly to both the space database and feed items — build a feed-scoped subscription withTrigger.specSubscription(Query.select(...).from(Scope.feed(...))). Change detection is content-signature based (feed-backed objects are unversioned), and deletes are detected uniformly via queryable tombstones (deleted: 'include'+Obj.isDeleted) for both sources — a feed removal now leaves a body-preserving tombstone in the index. (7b270f2) -
Collapse
@dxos/functionsand@dxos/functions-runtimeinto@dxos/compute-runtime(local runtime +Remote*interface tags) and a new private@dxos/edge-compute(EDGE deploy/scripts +Edge*implementations). Assistant-coupled agent runtime and test helpers move to a new private@dxos/agent-runtime(avoiding acompute-runtime↔assistantbuild cycle).
@dxos/compute-runtime now exports the former functions SDK/services/protocol/triggers/executor plus new namespace modules: RemoteOperationInvoker, RemoteProcessManager, RemoteTriggerManager (interface tags with layerNoop), and the aggregate ProcessMonitor.layer / TriggerMonitor.layer that merge local and remote views. FunctionInvocationService now routes through RemoteOperationInvoker (superseding RemoteFunctionExecutionService). Breaking: ProcessManager.layer no longer provides Process.ProcessMonitorService — provide ProcessMonitor.layer (plus a RemoteProcessManager layer) instead; imports of @dxos/functions / @dxos/functions-runtime move to @dxos/compute-runtime, @dxos/edge-compute, or @dxos/agent-runtime. (1a9bca1)
-
Remove the deprecated local/remote function-execution machinery:
FunctionInvocationService,LocalFunctionExecutionService,FunctionImplementationResolver,ServiceContainer, andFunctionExecutor. Operation invocation now runs exclusively throughOperation.Service(ProcessOperationInvoker); select edge dispatch per invocation with{ on: 'edge' }, keyed by the operation'sdeployedId. (bf013a1) -
Fix running a routine manually. The runnable's input now comes from the routine's first trigger, so a sync routine's
bindingreaches the operation instead of throwing, and a routine whose trigger isremoteforce-runs on the edge dispatcher rather than silently running on the client. Also exportcreateInvocationPayloadfor building a trigger's invocation payload. (bf055c8) -
Default edge replication to the Subduction sedimentree transport: the built-in client config now enables
edgeFeatures.subductionReplicatorinstead ofedgeFeatures.echoReplicator. SetsubductionReplicator: false(andechoReplicator: true) to restore the previous Automerge edge replicator. (41141d8) -
Agents become identity/presets (breaking, no data migration — 0.1.0 agents must be recreated):
Agent0.2.0 keeps only name, DID, enabled, and a typedInstructionsref; a chat and the agent it runs as are linked by theCompanionTorelation (resolved withAgentChat.loadAgent/AgentChat.loadChat), neither type referencing the other by field; durable artifacts belong to a Project collection; subscriptions and cron schedules compile to Routines whose relay qualifies events with a cheap model and forwards them onto the durable agent session. (f9ba47a) -
Add an
orderoption toAggregate.items({ limit, order }): an explicit, per-group member ordering independent of anyorderByelsewhere in the query. Previously a precedingorderBydid double duty — establishing group order and silently determining which members (and in what order) landed in a followingAggregate.items({ limit })— so moving thatorderByrelative toaggregatecould silently change which items appeared. The mailbox list now usesorderto keep each thread's preview newest-first, independent of the query's own group ordering. (4e64123) -
Ambient (Google-Docs-style) document review. The default document view now overlays every author's suggestions plus comments on main, with a per-user Editing/Viewing mode governed by a product-level
ReviewRenderPolicy; the explicit branch switcher / diff selector remains as the advanced path. Also fixes a crash when adding a comment while viewing a branch (comment anchors now resolve against the editor-bound document) and prohibits inline comments on suggestion branches.@dxos/ui-editorgainssuggestionsOverlayand areadonlyoption oncomments(). (c035062) -
Chats carry a typed
instructionsref rendered into the system prompt at request time (replacing typename-based inlining of bound Instructions objects, which now bind as ordinary context objects), and the new Project skill lets the assistant file created objects into a project's artifacts collection and list them. (b5ecf54) -
Make the published
@dxos/clirunnable, and keep React out of node and bun builds.
@dxos/cli@0.10.0 could not execute at all once installed from npm. Nothing marked external in
the compiled binary can resolve at runtime (Bun's embedded filesystem has no node_modules), so the
externals are gone and esbuild-wasm's WASM is inlined; the @dxos/node-std shims resolve to node
builtins, since Bun miscompiles export * from 'node:<mod>'; @automerge/automerge-subduction uses
its self-contained web entry rather than the node one that reads a sibling file; the platform
binary keeps its executable bit through publishing; and the pinned bun no longer leaks --smol into
process.argv. Persistent SQLite on bun also now creates its parent directory, which any dx
command needed on a machine with a stored profile but no data root.
The binary also contained React, react-dom and the whole react-ui graph. Capability.lazy,
OperationHandlerSet.lazy and React.lazy defer evaluation but not bundling, so plugin barrels that
merely listed a React surface pulled it into every non-browser consumer: the plugins with a node
variant now have node-conditioned #capabilities, and plugin-sheet a node-conditioned
#operations. Headless code no longer reaches for React packages — @effect-atom/atom instead of
@effect-atom/atom-react wherever only Atom/Registry/Result are used, and @dxos/client/*
instead of @dxos/react-client/*. @dxos/ui-editor/headless is a new UI-free entrypoint for the
editor helpers operation handlers need.
Breaking:
formatForDisplayandformatForEditingmove from@dxos/react-ui-formto@dxos/schema.renderBylineandBylineIdentitymove from@dxos/react-ui-transcriptionto@dxos/plugin-transcription.- The icon list moves from
@dxos/react-ui-pickers/iconsto@dxos/ui-types, and that subpath is removed;huesmoves from@dxos/ui-themeto@dxos/ui-typesbesideChromaticPalette. @dxos/plugin-graphno longer exports its React hooks from the package root — import them from@dxos/plugin-graph/hooks.-
@dxos/plugin-deckand@dxos/plugin-navtreeare browser-only:#pluginno longer resolves anodeorworkerdcondition. (3f6ac61) -
The
dxbinary no longer depends on the machine that built it:@dxos/kv-store'screateLevelmoves to@dxos/kv-store/levelso importing the package for its types no longer binds LevelDB's native addon, and Automerge's WASM is inlined rather than read from disk.LevelDB,SublevelDBandBatchLevelare unchanged on the main entry. Each@dxos/cli-<platform>-<arch>package also exposesdxdirectly, so one platform can be installed without pulling the rest. (091ebe4) -
Add ECHO-core per-object time travel and subtree branching:
setTimeTravel/clearTimeTravelpin a live object to a historical version (writes throw,latestOnlysubscribers stay live),createBranch/switchBranch/mergeBranch/deleteBranchfork an object subtree into writable CRDT branches with shared history and true merge-back, anddb.branch()returns caller-owned writable per-surface branch bindings. (46ec569) -
New
Lensnamespace: an object lens that views one live ECHO object through a second declared type. Sibling of the existingPanprotowire lens, which crosses the serialization boundary to a foreign record — an object lens never creates a second object, so reads project the base object and writes invert onto it.
A lens binds two written-out types (Lens.make(id, Source, Target, mapping)), so the target's TypeScript type is the view's type and an interface written once against the target works for every source that maps to it. A lensed object reports the target's typename, so surfaces and forms already written for that type resolve unchanged, while Obj.getURI still resolves to the underlying object.
The mapping is partial. A target property with a same-named, type-compatible source property maps itself; one with no counterpart stores itself in the object's annotation dictionary; a name match whose types are incompatible is reported by Lens.coverage as suspicious rather than auto-mapped or auto-overlaid, since either would record the same fact twice and let the copies drift. Lens.coded covers transforms a per-property mapping cannot express, such as parsing.
Lens.of returns a live handle the ordinary Obj.* API accepts, including Obj.update, which batches every assignment in its callback into a single change touching only the properties actually assigned — so two peers editing one object through different lenses merge instead of clobbering each other. Lens.checkLaws verifies the GetPut round trip, Lens.register preserves its argument's precise type, and a declarative mapping can be persisted as an ordinary ECHO object (Lens.Object) referencing its value conversions by registered codec name.
useLens ships on the new @dxos/echo-panproto/react entrypoint, mirroring @dxos/echo-react's useObject tuple and overload shape. It sits on its own subpath so the package's main entry stays React-free for worker contexts. A lens holds no state: the hook subscribes to the base object for the render schedule and projects on every render, so replicated changes, overlay writes, and character-level text edits all reproject.
The wire lens schema moved from src/lens.ts to src/wire-lens.ts, internal to the package; the Panproto export surface is unchanged. (f8637f1)
-
Add soft-fork support to feeds:
Feed.append(feed, items, { parent })continues a feed from an earlier item, andFeed.history(items)resolves the live branch at read time. Feeds that set no parent are unaffected. (af5fbf4) -
Resolve a replicated document's containing space from local collection membership in the share policy, so a document whose handle is evicted or still loading is no longer falsely reported as belonging to no space, removing the false share-policy denials and the replication stalls they caused on both the edge/subduction and mesh replication paths.
Additionally, the subduction WASM console log level is set to error once the repo is constructed. Subduction syncs every document with every connected peer, so with multiple spaces each space-scoped edge peer is asked for every foreign document and correctly denied — and subduction_core logged each denial as a not authorized to access sedimentree warning, flooding the console (dispatch-scoping gap tracked as DX-1121). Set localStorage.debug to a value matching subduction (or set globalThis.__SUBDUCTION_DEBUG) to restore verbose WASM logging when debugging.
Breaking: createIdFromSpaceKey is no longer re-exported from @dxos/echo-host; import it from @dxos/echo-protocol instead. (ae18615)
-
Move the space protocol, control/feed pipeline, and metadata store out of
@dxos/echo-hostinto@dxos/client-services.@dxos/echo-hostnow exposes onlyEchoHostand its Automerge/database implementation. Consumers ofSpaceManager,SpaceProtocol,Space,AuthProvider/AuthVerifier,Pipeline,MetadataStore,SqliteMetadataStore,createMappedFeedWriter, andvalueEncodingmust now import them from@dxos/client-services(test helpers from@dxos/client-services/testing). (14983db) -
New package
@dxos/echo-panproto: declarative, JSON-serializable lenses (Panproto.Lens) between ECHO objects and foreign wire records, executed by a runner (Panproto.encode/decode) rather than expressed as closures.
Annotation-driven publishing of ECHO objects to the AT Protocol. @dxos/schema gains AtprotoRecordAnnotation (type-level: target collection, record-key strategy, and a declarative serializable lens) and AtprotoVisibilityAnnotation (field-level, private by default — a field is published only when explicitly marked), so a generic companion can discover and publish any annotated type without knowing the type itself.
MasterDetail moves from plugin-routine into @dxos/react-ui-list as a reusable primitive: a selectable master list above a detail slot, nestable by placing another MasterDetail in detail. Per-row overflow menus are driven by useMenuBuilder from @dxos/react-ui-menu.
ComboboxField now shows the selected option's label rather than the stored value, which is often an opaque id the user never chose to see. (9da013f)
- One identity rule per type, shared by the extractor's create-vs-merge decision and by a new duplicate scan, plus a Duplicates tab on the database type article for reviewing and merging what has already accumulated.
Contact extraction is now an allow-list: a sender earns a Person only when we sent or replied to it, or its domain matches a known Organization, and never when the address or message is automated. Mail sync and Google Contacts sync resolve against one index per space rather than a snapshot each, so concurrent syncs no longer both create the same person. (0a4bbde)
-
Gmail and JMAP sync are now always bidirectional and durably resumable: the sync cursor tracks a
max/minwatermark pair (replacingvalue), each run syncs new mail forward and continues backfilling backward in the same pass, and a per-run message cap requests a durable re-run viaOperation.runAgain()instead of looping in-process. The sync operations now take only the binding — thedirection/after/beforeinputs are removed. Breaking: theCursorschema fieldvaluebecomes themax/minpair,Cursor.resolveWindowis replaced byCursor.resolveHorizon/Cursor.resolveWindows,Cursor.dedupStagedrops itsdirectionoption, andCursor.advance/Cursor.parseKey/Cursor.formatKeyoperate onmaxinstead ofvalue. (48d168e) -
Mail sync is now incremental and provider system state maps onto shared canonical tags.
Incremental delta-resume: the sync cursor carries an opaque provider delta token (Gmail historyId, JMAP Email/get state). After the initial window backfill, each run fetches only the delta since the token (Gmail history.list — paginated so multi-page deltas are not dropped; JMAP Email/changes), applying additions plus label/flag reconciliation to already-committed feed messages via objectless commit units. A stale token falls back to the window scan and recaptures; the token advances only after the run's merged stream fully drains, so a crash re-fetches the delta idempotently.
Unified system tags: Gmail system labels, JMAP mailbox roles, and the JMAP $flagged keyword now resolve to a shared, provider-agnostic tag registry (org.dxos.tag: starred / inbox / important / sent / and the Gmail categories) instead of provider-scoped tags — so a Gmail star, a JMAP flag, and a locally-toggled star are the same tag. Read-state, drafts, trash, spam, and archive are intentionally not tagged (archive is derived as "not in inbox"). The starred tag's foreign key moves from org.dxos.org to org.dxos.tag; existing locally-starred items under the old key are not migrated. (2543b63)
-
Add an in-app log viewer as a composite
Loggercomponent (@dxos/react-ui-debug, replacingLogPanel) with per-file log-level control and a text-match buffer filter, backed by a new dev-modelogFileRegistryin@dxos/logthat records every log file at module load via the@dxos/vite-plugin-logtransform. (f6a01e3) -
Unify the signaling
sendMessage/sendBroadcastmethods and encapsulate message-subscription routing.
Breaking:
SignalMethods.sendMessage(ctx, message)now handles both point-to-point and swarm-broadcast (DX-1125) delivery. A message carries exactly one ofrecipient(point-to-point) ortags(broadcast, targeting the swarm inauthor.swarmKey);Message.recipientis now optional. The separatesendBroadcastmethod is removed.subscribeMessages({ peer, tags?, onMessage })now takes the delivery callback, encapsulates routing (point-to-point by recipient, broadcasts by tag intersection), and returns an unsubscribe callback that owns the subscription lifecycle. The standaloneunsubscribeMessagesmethod and theonMessage/onBroadcastevents are removed.- The
@dxos/signalpackage (the KUBE signal-server test harness) has been removed; tests now useMemorySignalManager. -
The KUBE signaling client is removed:
WebsocketSignalManager,SignalClient,SignalRPCClient,SignalLocalState, and theSignalClientMethodsinterface no longer exist. Edge signaling (EdgeSignalManager) is the only real transport; the non-edge fallback in the services host / worker runtime / local client services is nowMemorySignalManager(isolated, no cross-process signaling). (b3a3fcf) -
Google OAuth access tokens are no longer replicated through ECHO. EDGE stores the granted token and returns a
MANAGED_ACCESS_TOKENplaceholder in its place, whichCredential.CredentialsServiceresolves transparently — consumers no longer see whether a credential came from the space or from EDGE.CredentialQuerygainsaccessTokenIdso a specificAccessTokencan be looked up rather than any credential for a service, which also fixes a by-service lookup that picked arbitrarily among a space's several connections to the same provider.OnTokenCreatedandTestConnectionnow takeCredential.CredentialsServicein their requirement channel rather than readingaccessToken.token. Existing connections keep working until their token expires; re-authenticating migrates them. (c727a43) -
Inbox draft composer rebuilt as a compose-style form, plus the shared UI it needs.
@dxos/react-uiInput.TextInputgains MUI-stylestart/endadornments rendered inside the input container;@dxos/ui-themeadds a shared.dx-inputbox treatment (surface + hairline border + focus-within shift) now used by Input,MarkdownField,RefEditor, and the inbox editor.@dxos/react-ui-formRefEditoremail mode renders committed mailboxes as atomic tag widgets (trailing delete affordance, no@marker) — a raw address stays plain text until committed with comma/Space/Enter, typing before a tag starts a fresh token, and the single line is centered so text and tags align.@dxos/ui-editor'sdefaultThemeSlotsis nowfullWidth(no longer forcesh-full).@dxos/plugin-inboxEditMessagegains To/Cc/Bcc recipient pickers with Person autocomplete, arrow-key field navigation, and a layout fix so Send no longer overlaps the editor. (d958118) -
Rework the light-mode surface ladder and control states.
Surface levels, separators, wells, scrollbar thumbs and rail tones are now
derived from the enclosing --surface-bg and attenuated for light mode through
a single --dx-attenuate-* table, replacing several fixed neutrals that had
drifted from the ladder. Filled controls derive their hover from their own fill
(--color-input-bg-hover) rather than from the host surface, so hovering a
default button no longer lightens it into the selected tone. Panel.Toolbar
owns the toolbar bar treatment, so a nested Toolbar.Root matches content width
without floating. Cards now carry their padding unconditionally. (e65432c)
-
Rename
Message.ContenttoMessage.Bodyand add a new optionalMessage.Contentwrapper that carries the message's default padding.Card.Rootaccepts agutterprop so a card whose body is a form insets its fields like a standalone form. (51aaffe) -
Add a
Sliderprimitive built on the Radix slider (Slider.Root/Track/Range/Thumbcomposed behind a single themed component), supporting one or more thumbs, horizontal and vertical orientation, and a disabled state.react-ui-form'sForm.Rowgains an additivelabelEndslot that renders trailing content at the end of the label row, so a field can show a live value beside its label without nesting it insideInput.Label(which would change the input's accessible name). (848ba1b) -
Runtime icon resolver:
ThemeProvidermounts a sharedIconRegistrythat ingests the static/icons.svgsprite into an in-DOM defs container and resolves missing icons on demand from a per-icon-set route (Phosphor at/phosphor/{weight}/{name}.svgby default, configurable viaIconSource), so icons referenced only by runtime-loaded plugins render without being present in the build-time sprite.useIconHrefnow returns a same-document#namehref (orundefinedwhile unresolved), and<dx-icon>consumes the same registry via aglobalThis.__dxIconRegistrybridge. Breaking: the unusednoCacheprop is removed fromThemeProvider,withTheme, and<dx-icon>— cross-document sprite URLs are no longer built, so there is nothing to cache-bust. (55bb048) -
Add
Html, a sandboxed renderer for untrusted HTML: sanitized content in a Shadow DOM host, so the document's CSS cannot reach the app while it still flows in the app layout, with remote images blocked by default. Content-specific behaviour is supplied as anHtmlDialect— a plain value carrying CSS, transforms and asrcresolver — rather than baked into the component;emailDialect()is the first of these.plugin-inbox'sHtmlVieweris replaced by that pair, movingcid:attachment resolution into the plugin (useCidResolver) so the shared UI package no longer depends on ECHO.
Email bodies now honour the sender's color-scheme declaration, read from the raw markup before sanitization strips it: a body declaring light is left as authored on a light sheet in dark mode, and anything undeclared is recolored to the app theme regardless of layout (the previous table-layout exemption preserved too little to justify leaving marketing mail glaring white in dark mode). (ba7aabf)
- Add a
Minimapcomponent (@dxos/react-ui-components): a vertical rail of ticks representing anchor markers in a scrollable document, with a wave hover animation, per-marker popover, and brighter ticks for the currently-visible range.
MarkdownStreamController gains scrollTo, getVisibleRange, and onVisibleRangeChange. In plugin-assistant the chat thread now renders a Chat.Minimap rail (one tick per prompt turn, scrolls to the turn on click), and prompt prev/next navigation steps through the prompt range table rather than the xml-tag widget bookmarks. (801b77f)
-
The editor's object picker is now a combobox: the query is typed into a search input in the popover instead of into the document, opted into per trigger via
searchTriggers. In markdown, the picker sorts objects by name and leads with a generic "Add object" that opens the create-object dialog and inserts a link to whatever it creates. Links to internal objects no longer show a raw-URI hover tooltip. (2e10525) -
Masonry no longer flashes a bunched, overlapping stack on the initial render of a large set: unmeasured tiles now use an estimated height so the first layout is already spaced into columns, and the grid stays hidden until the layout settles before fading in (respecting
prefers-reduced-motion). Reflow animation is limited to small add/remove edits — the initial render, bulk data swaps, and resizes snap instead of animating — and a newanimateprop onMasonry.Rootdisables animation entirely. (9ded6b9) -
Clean up inbox operations: remove unused
DeleteEmail,DeleteEvent,SyncDraftEvents,SyncContactsoperations and the deadtool-ids.tsfile. DeprecateExtractContactandExtractMailbox. Add a defensive double-click guard to toolbar action buttons — they now disable while the handler is in-flight. (bb63d91) -
Full-text search across a space in the search plugin — ranked, highlighted results backed by the ECHO FTS index, plus a new
SearchResultList. The mailbox filter now searches messages by subject, sender/recipients, and plain/markdown body (never raw HTML) and shows a best-match highlighted snippet; the query is debounced to avoid re-rendering the list on each keystroke. Shared match/snippet utilities (computeMatchSpans,buildSnippet,Highlighted) moved to@dxos/react-ui-search. (e510f3b) -
Rename
Tabs.Tab→Tabs.ButtonandTabs.IconTab→Tabs.IconButton. Both now honor a caller-suppliedvariantand skip label-alignment classes wheniconOnly. (105dac4) -
Promote
Topicto a first-class domain type.Topicmoves from@dxos/pipeline-emailto@dxos/typesas a Project-style class (inline title/label/icon annotations +makefactory), keeping a sharedTopic.Propsstruct and itsorg.dxos.type.topicDXN. The Topic detail view (TopicArticle) moves to@dxos/plugin-brainand renders via a regular object/article surface.
Breaking: Topic / TopicProps are no longer exported from @dxos/pipeline-email — import from @dxos/types and use the namespace form (Topic.Topic, Topic.Props). No compatibility re-export is left behind. (f0ec728)
-
Introduce
@dxos/link, a low-level infrastructure package holding a unifiedCursorECHO type (org.dxos.type.cursor0.2.0), the relocatedAccessTokentype, and the durable-progress sync machinery.Cursorreplaces@dxos/plugin-connector'sSyncBindingrelation with a flat object whose discriminatedspeccovers both external-source sync (Gmail, Trello, GitHub, Linear, Slack, Discord, Bluesky) and internal feed-to-feed processing (e.g. mailbox fact extraction), so progress now persists across reloads for both.Connection/Connectorstay in@dxos/plugin-connectorand correlate to aCursorvia their sharedAccessTokenrather than a direct relation. This is a breaking change: existingSyncBindingrelations andCursor0.1.0 objects are not migrated and are abandoned on upgrade — external syncs re-bind and feed-to-feed analysis restarts from the beginning. (a49131a) -
Render editor comment highlights as a selection-style layer that fills wrapped lines to the edge (straight left/right edges, rounded only when single-line, 1px padding) and colours the comment text.
comments()now folds in external synchronisation viasubscribe/getCommentsoptions (replacingcreateExternalCommentSync) and requires anid;linkTooltipnow takes an options bag ({ render }). (a31ef40) -
Highlight fenced
mermaidcode blocks in the markdown editor, and addcreateMermaidExtensionsfor documents that are entirely mermaid. (6e4ac74) -
Convert outline items into Task objects: a "Convert to task" action replaces the item with a link to a new Task parented to a project created lazily on first use, and the link navigates to the task in place. Adds the
getItemText,replaceItemWithLink, andsyncLinkLabelseditor commands. Fixes the outliner content column not being centered, which pushed the drag grip outside the document and the line menu inside it. (59a65a8) -
Suggesting mode (Google-Docs-style authoring). In the ambient review view, switching to Suggesting binds the editor to the current user's own suggestion branch: their typing accrues there and renders as character-level tracked changes over main (
trackChanges), while other authors' suggestions overlay against main viasuggestions({ base })+rebaseHunks(so a foreign author no longer strikes your own new text). Accept/reject controls moved into a non-clipped hover popover.@dxos/ui-editorgainstrackChanges,rebaseHunks,computeCharHunks, and abaseoption onsuggestions(). (77fff35) -
Fold the review "Suggesting" mode into the editor view-mode dropdown.
addViewModenow accepts an optionalViewModeItem[](default the three built-in modes), threaded throughEditorToolbarFeatureFlags.viewModes; plugin-markdown establishes aViewModeExtensioncapability that plugin-comments implements to contribute the "Suggesting" entry, and the separate toolbar branch-selector / review-mode dropdowns are removed (the History companion covers branch switching). Single-select dropdowns now render a check on the current value (with radio semantics). Also: an author-coloured change-bar gutter on lines containing suggestions, a fix for comments flashing out of the companion on submit, and a suggestion-overlay perf improvement (compute the base/document character diff once across all authors). (6e624bd) -
Split the
blockseditor extension intoblockOutline(the below-text border boxes — usable on its own),blockSelection(whole-block selection state, highlight, and clipboard), andblockDrag(the gutter grip that drives selection and drag-to-reorder).blocks()composes all three;blockOutlinestands alone, whileblockSelectionandblockDragare a pair (the grip lives inblockDrag). The drag core (createBlockDrag) and selection core (createBlockSelection) are generalized over a document-agnosticBlockOpscontract, shared by markdown blocks and the outliner.
Add document-agnostic whole-block selection: the gutter shows a grip on the caret's block and each selected block; clicking a grip selects the block (shift-click toggles it in a multi-selection). Dragging a grip reorders the block, or the whole selection when it is part of it, and Cut/Copy/Paste operate on the selected blocks. Wire the same selection, drag, and clipboard into the outliner (outlinerDnd).
The drag experience lifts the source block(s) out of the document (collapsing them and their trailing blank line), opens a block-sized placeholder at the drop slot, centers each grip on its line's first row, and matches the floating preview's wrapping to the source. Drags abort on a concurrent edit and start on the primary button only. (392c700)
-
Export design tokens as
@dxos/ui-theme/tokens.css, so stylesheets compiled outside this repo — Composer plugins loaded from the registry — can generate token-backed utilities themselves rather than relying on whichever ones the host happens to bundle. (c58ebb7) -
Add
@dxos/versioning(checkpoints, draft branches, and 3-way merge for automerge-backed ECHO objects) and document revisions and branches in Markdown: named checkpoints with read-only time travel and restore, draft branches (separate Text objects anchored to a parent revision) with 3-way merge-back, a History companion panel, a Versions section in object properties, an editor banner with a branch switcher, agent operations (create-checkpoint, create-branch, merge-branch, get-history), and adiffViewsetting selecting inline, side-by-side, or gutter diff rendering. (dd190a0) -
Worker connections accept an
onPersistentFailureescalation hook (with amaxLeaderFailuresthreshold, exposed asonPersistentWorkerFailureincreateClientServices), invoked after consecutive leader-session failures so apps can surface or recover from a stuck worker connection instead of backing off silently forever. (6ad2084)
Patch Changes
-
Add routed scripts to the scripted test language model (per-session cursors for supervisor/sub-agent scenarios) and restore per-message span publishing from the chat thread (minimap markers and prompt navigation). (bdf9f68)
-
Resolve an object's canonical navigation path through
NavigationOperation.ResolveNavigationTargets, so opening an object from a generic surface (a card, a search result, an agent following a reference) lands where the nav tree shows it — its collection, or its type's sidebar section — instead of the hidden database path every object falls back to. This also fixes the nav tree showing no selection for objects opened from cards. (5b05d75) -
Plugin-declared decks and deck scroll stability. A type can now declare how the deck behaves when one of its objects is the root:
AppAnnotation.DeckAnnotationcarries aDeckSpec(initial planks and a chain of levels),LayoutOperation.Openacceptsroot+levelso opening at a level reuses that level's plank and closes the levels below it, Collections are navigation targets that open their contents as planks, and the mailbox declaresmailbox / message / attachment(meta-click opens a message in its own plank; a message swap carries the open companion along). Deck scrolling is now strictly intent-driven: an in-deck click yields to the navigation it triggers, navigations re-issue if a reflow kills the glide, browser scroll anchoring is disabled on the deck viewport, a companion opening past the trailing edge is revealed by exactly the overflow, and stalecompanionPlanksentries are pruned. (f10b1ce) -
ProgressMeternow shows a live elapsed-time readout for indeterminate tasks (no known total) instead of a perpetually-pulsing bar; the fractional bar and remaining-time ETA render only when a total is known. (717edc0) -
Add
dx space exportanddx space importcommands. Export writes a space archive to disk in either the binary storage-dump format (includes document history) or a JSON snapshot of current object state; import reads an archive of either format back as a new space. (179afc6) -
Fix comment author attribution and reset-device reload.
useIdentitynow seeds its atom with the service's synchronous snapshot so the current identity is available on the first render instead of a transientundefined— a comment sent in that window was stamped with an empty sender and never matched its author, hiding the edit affordance. Duringclient.reset()the worker-reconnect handler now reloads to the origin (fresh boot) rather than the stale current route, andClient.resettingexposes that state. SQLite hypercore storage drains in-flight writes onclose()so a save racing reset teardown can't stall or reject against a torn-down connection. (eec72c5) -
Restore the iframe shell (
shell='./shell.html') client-services connection after the effect-rpc migration. The app now re-serves its services to the shell over effect-rpc (matching the shell'sClientServicesProxyconsumer) instead of the removed protobuf peer, and the shell provides its parent origin upfront so the effect-rpc client can initiate the connection without deadlocking. Fixes apps that embed the external shell iframe hanging on startup. (410a019) -
Use the WebRTC transport for bun as well as node: bump node-datachannel to 0.32.3 (the 0.30.0 darwin-arm64 binary crashed under both runtimes) and remove the obsolete bun memory-transport guard. CLI
halo shareprints the joinable URL and validates--hostas an absolute URL. (d547045) -
Fix an unhandled
SqlErrorwhen a hypercore file load races client teardown. If the SQLite connection is torn down while a backgroundSqliteRandomAccessFileread is in flight (and that file's ownclose()hasn't run yet), the read now falls back to an empty buffer instead of rethrowing "database connection is not open" as an unhandled rejection. (da66270) -
Import ECHO data-access hooks (
useQuery,useObject,useType,usePagination, …) directly from@dxos/echo-reactin Composer plugins and UI packages instead of through the@dxos/react-client/echore-export, decoupling pure ECHO data access from@dxos/react-client. (b8c0825) -
Auto-create a recurring sync Routine when a mailbox or calendar is bound to a connection (new connection, multi-target selection, or reusing an existing connection); the toolbar "Sync" action force-runs it and disables while a sync is already in progress. Fixes a legacy-DXN compatibility gap in
refToEffectSchemaand a bug where cancelling a Gmail sync left its progress monitor stuck at "running". (923d5be) -
Fix the mailbox silently dropping a compose draft, which has no thread. A draft with no
threadIdis now created as a thread of one — keyed on a fresh id — so the mailbox list's whole-thread semi-join and conversation grouping keep it. Also align the JMAPEmailschema with RFC 8621, wherethreadIdis a required, server-set property. (85893fe) -
Fix memoized language model dynamic-value remapping: collect tokens over the normalized prompt so timestamp metadata cannot shift positional ids, and preserve per-pattern regex flags so uppercase-hex UUIDs match. (12fd785)
-
Stop the client-side diagnostics from retaining the whole ECHO client graph. Every
QueryResultImpladded a record to a module-levelQUERIESset that nothing ever pruned, and while the record held no direct reference to the query, it held aStackTrace— which keeps an unformattedError, and V8 retains a captured stack structurally, with a strong reference to each frame's receiver, until.stackis read. The frame fornew QueryResultImpl(...)therefore pinned the query, its query context, the hypergraph, the client, the database and every document loaded through them: one entire client graph per query, for the lifetime of the process. On hosts that never read the diagnostics this was unbounded — a Cloudflare Worker running ECHO operations on a cron trigger OOMed after ~390 invocations.QueryResultCacheis aWeakDictionaryprecisely so results can be collected; this defeated it.
QUERIES now holds weak refs pruned by a FinalizationRegistry, so a query, its diagnostic and its graph collect together. OBJECT_DIAGNOSTICS had the same defect on a longer fuse and now stores the formatted string; being keyed by object id and never evicted, it is also capped at 1,000 entries with oldest-first eviction. StackTrace formats once and releases the Error, making the release deterministic rather than incidental, and documents the retention hazard. (5f08a6a)
-
Report writes that were never sent, and stop a scheduled callback from running concurrently with itself.
UpdateSchedulernow starts its callback from a single site:runBlocking/forceTriggerfunnel into the scheduled runner instead of claiming it themselves, so two passes can no longer each claim part of the shared queue — the loss behind server-side writes arriving without their data.RepoProxy.flush()rejects when a batch could not be sent instead of always resolving, so a short-lived writer whose isolate is disposed the moment flush resolves can fail its operation rather than silently drop the write. (3761762) -
Chats no longer spend a
query-skillscall before everyenable-skills— the available-skills list is already rendered into the system prompt — and project chats pre-bind the artifact-type skills, so creating the artifact you asked for costs fewer tool calls. Deleting an object now also closes planks for the objects it cascade-deletes (e.g. a project's chats), which previously stayed open pointing at removed objects. (4bb7e3b) -
Fix: re-entering Suggesting mode no longer strikes through text typed on main in between. An unedited per-user suggestion branch whose fork point fell behind is retired and re-forked at the current heads; a branch with pending suggestions is preserved. (686fac1)
-
Documents created from the editor's slash/link menu are now filed in the same collection as the document they were created from, instead of the space root. (ac51564)
-
Assigning a nested record read off a detached (never-added) object into a database-backed object now copies it by value, as it already did for records read off database-backed objects. Previously it threw
Object references must be wrapped with \Ref.make``, because the copy-on-assign path only recognized proxies from the database handler; callers had to spread by hand. (a83d98a) -
EchoDatabase.waitUntilHeadsReplicatednow also waits for the client's replica of the space root document to carry the given heads, so a query issued right after it sees the replicated objects instead of racing the client's routing table. (4f24c4e) -
usePagination'sisLoadingnow reflects genuine query settlement instead of clearing on the next microtask regardless of delivery, so consumers can reliably distinguish "still loading" from "loaded and empty" even for async, feed-backed queries. The mailbox article uses this to fix a bug where it could briefly flash the wrong empty-state message (e.g. "No connections configured") while a large mailbox's messages were still loading. (9cde1c6) -
Fix the function bundler's
resolveDirin the built@dxos/edge-compute/nativeentry. It was computed withnew URL('.', import.meta.url).pathname, which Vite's library-mode build treats as an asset reference and base64-inlines as adata:video/mp2t;base64,…data URL. Indistthat leftresolveDirpointing at garbage, so the bundler could not resolve@dxos/compute-runtime/@dxos/functions-runtime-cloudflareand function bundling failed. The directory is now derived viadirname(fileURLToPath(import.meta.url)), which the bundler leaves untouched. (d79482a) -
Publish the HALO Effect service packages (
@dxos/halo,@dxos/halo-adapter-client,@dxos/halo-react) and begin migrating Composer/plugins off direct@dxos/clientHALO access onto them:plugin-clientnow providesIdentity.Service/Space.Servicelayer specs and wraps the app inHaloProvider. (6439417) -
Adopt the triple-slash
echo:///<objectId>form as the canonical local EID.EID.make({ entityId })now emitsecho:///<id>, andEID.parsenormalizes the legacy single-slashecho:/<id>form to it so legacy and freshly-produced EIDs compare equal. The legacy form is still accepted on read. - @dxos/debug@0.11.0
- @dxos/invariant@0.11.0
-
@dxos/node-std@0.11.0 (6a03a30)
-
Send
$survey_completedwith captured user feedback so PostHog survey destinations trigger, and serialize errors logged as context to OTel instead of dropping them. (41d1e4a) -
Fix the daemon watchdog failing to start with
ERR_MODULE_NOT_FOUNDafter the vite/rolldown build migration by importing from the correctdist/libentrypoint. (22fdfa4) -
Fix corruption of large query results containing emoji or other astral characters. The
QueryServiceRPC now encodes its payloads with Effect schemas instead of protobuf, avoiding a@protobufjs/utf8bug that injected a lone surrogate into string fields larger than 8KB and broke object hydration. (114fb98) -
Add an in-app
@dxos/logviewer (new@dxos/react-ui-debugLogPanel) so logs can be filtered, level-configured, and copied without opening DevTools; plugin-debug surfaces it as an R0 companion tab and a status-bar popover, and the devtools performance panel reuses the same component. Make the devtoolssubscribeToFeeds/subscribeToSpacesfeedKeys/spaceKeyspayload fields optional, fixing a Storage-panel schema decode error on empty subscriptions. Reimplement the devtools performancePanelandPanelContaineron the shared@dxos/react-uiPanelprimitive. (b591791) -
Move the
useFlushhook from@dxos/plugin-assistant/hooksto@dxos/react-client/echo. It operates on aSpace, so it belongs with the other space hooks; import it from@dxos/react-client/echoinstead of@dxos/plugin-assistant/hooks. (c9da903) -
Supporting changes for the new plugin-blogger / plugin-typefully feature:
- @dxos/plugin-connector: expose
Connectiontypes via a new./typesexport subpath so provider plugins can consume the connection contract without pulling the full package barrel. -
@dxos/react-ui:
Card.Rootnow accepts and forwardsonKeyDown, enabling keyboard-interactive cards (Enter/Space activation) without a cast. (e0e1a9f) -
useThemeContextno longer throws when noThemeProvideris mounted; it falls back to the default theme (with a one-time warning) so error-reporting surfaces such as the fatal dialog remain renderable. (2fe5a7a) -
Logger panel review follow-ups:
- @dxos/react-ui-debug: each
Logger.Rootrecording session now self-filters via its own parsed filter and registers in a module-level recorder registry that composes the shared@dxos/logconfig (union) and restores it on the last release — concurrent panels with divergent filters no longer clobber each other. The log list gains a per-row checkbox (Copy log then exports only the checked rows), full-line selection styled viaaria-current/dx-current, arrow-key navigation between lines (inner controls opt out of the roving tabindex), Space to toggle expansion, and Enter to toggle the checkbox. Expanded rows render message/context viaJsonHighlighterand error stacks via the sharedErrorStack(clickablevscode://frames). Each log record also retains the derived package (from its source path) for display/export. -
@dxos/react-ui:
ErrorStacknow accepts aclassNamesprop so consumers can style the trace container. (c9651f1) -
Move contexts, hooks, constants and helpers out of React component modules into sibling modules so each component module is a react-refresh boundary. Public package APIs are unchanged; the previously exported names are re-exported from each directory barrel. (37874ce)
-
The inbox message view selector (HTML / Markdown / Plain) now persists across messages and sessions. The choice is stored alongside the other inbox settings (the
loadRemoteImagestoggle) in the plugin's settings store, so it survives reloads instead of resetting to HTML on every open. Also reorganizesuseArticleKeyboardNavigationunderAttentionProvider(no change to the@dxos/react-ui-attentionpublic exports). (3b4a7c8) -
The debug Logger now persists per-file log level overrides across reloads (via a
local-backed react-ui-attention view-state aspect instead of component-local state) and shows the full repo-relative source path — as afilekey in the expanded row's JSON, and as the row tooltip — while the row column keeps showing just the basename. (46ac889) -
Bump CodeMirror packages (
@codemirror/state,@codemirror/view,@codemirror/lang-markdown) to their latest patch releases. (53fde97) -
HeyGen avatar/voice pickers now list only the account's own assets (
/v3/avatars?ownership=private,/v3/voices?type=private) instead of HeyGen's public catalog, with names trimmed (HeyGen returns user-named assets with leading newlines / non-breaking spaces) and sorted alphabetically; list requests are bounded by a timeout so a slow response can't hang the picker.Listbox.ItemContentno longer reserves the leading icon column when noiconis set, so icon-less rows are flush to the edge instead of indented. (277e365) -
The conversation view (
MessageArticle) now renders threads as a Mosaic stack: each message is a tile with its own toolbar, so Reply/Reply All/Forward/AI reply/Delete act on that specific message rather than always targeting the newest one. Body view controls (view mode, load remote images) and collapse-all/expand-all move to a single thread toolbar that applies to the whole conversation, and each message can be individually collapsed to a compact summary. The per-messageMessage.Toolbarno longer includes the view-mode switcher or load-images toggle.
By default only the most recent message is expanded and the rest are collapsed. Replying to a message now records the specific message it answers (parentMessage), so the draft renders directly after that message in the thread rather than always at the bottom, and it is smoothly scrolled fully into view.
Listbox.Item rows with an onClick (not just selectable ones) are now keyboard-focusable and respond to Enter/Space, matching native <button> activation. (2a68c3b)
-
Fix mailbox paging and the list blanking during sync.
usePaginationnow keeps the previously-shown page across a query-identity change instead of resetting to empty + loading, and the virtualizer pagination hook re-armsgetNextafter a page lands and no longer misreads a reordered item as an eviction. The mailbox renders a loading spinner in-flow at the end of the list rather than replacing the whole panel. (0afbf15) -
TagIndexmembership now compares tag ids by their entity id rather than their full (space-absolute) URI, so tags applied to feed objects survive a space export/import — the importer mints a new space id, which previously left every stored tag key unmatchable. Absolute keys already in existing spaces keep resolving (no migration), and a relatively-stored key resolves against an absolute query and vice versa. (96109be) -
Fix shell bundle build failing with ENOENT on a clean checkout. (14848a1)
-
e2ePresetnow defaultstimeoutto 60s. Playwright's 30s default equalled the preset's action bound, leaving a test no budget beyond one slow action — and a storybook-backed suite spends most of it on the story compile the first test pays for, which measured 29.3s against the 30s cap. (bce1dbc) -
Move
DraftMessageout of@dxos/plugin-inboxinto@dxos/types, and move the generic email-sync pipeline stages (excluding theSyncBinding-coupledtoCommitUnit) out of@dxos/plugin-inboxinto@dxos/pipeline-email, so these can be reused without depending on a full app-framework plugin.ConnectionandSyncBindingremain in@dxos/plugin-connector;toCommitUnitandfactsCommit(both coupled toSyncBinding) live in@dxos/plugin-inbox. (6d2afe0) -
Reorganize CodeMirror extensions into themed folders (
core,state,behavior,decoration,language,collab,completion,streaming,structure,demo,debug) with per-folder barrels; the package's public export set is preserved. Fixes the misspelled exported typeCompoetionContext→CompletionContext, de-duplicatesescapeRegExpSourceintoutil(closing a latent tag-escaping bug inextendedMarkdown's mixed parser), and adds anxmlTagscharacterization test suite.xmlTagsblock widgets now keep their portal alive across viewport culls (removing the blank/flicker on scroll-back for known-height embeds).@dxos/ui: adds astringoverload toDomino.offor custom-element tags (e.g.dx-icon);@dxos/plugin-assistantdrops the now-unneededDomino.of(... as any)casts. (a256a87) -
Document versioning: Google-Docs-style suggestion review.
- @dxos/ui-editor:
suggestChanges(inline per-change accept/reject over a proposal) plus word-leveldiffHunks; a multi-authorsuggestions({ sources })overlay andgroupHunksgrouping; thecomments/diff/suggestreview extensions are grouped under a newreview/folder (package barrel exports unchanged). - @dxos/app-framework:
NamePopovermoved to@dxos/app-framework/ui, decoupled from translations via asubmitLabelprop. - @dxos/plugin-markdown: branch/merge/checkpoint exposed as agent skill tools; a
suggestdiff-view mode; the compare/diff overlay is reconfigured through a CodeMirrorCompartmentso switching views no longer remounts the editor (rebinding automerge / losing selection). The branch banner's Compare toggle becomes a three-way[Base | Diff | Branch]view selector — Base shows the parent content at the anchor read-only. - @dxos/plugin-space:
NamePopoverremoved from@dxos/plugin-space/components(relocated to@dxos/app-framework/ui);VersioningState.compare(boolean) becomesview(base | diff | branch). - @dxos/types: new
ContentBlock.Change(a suggested edit —before/after) so a suggestion renders through the message tile. - @dxos/react-ui-thread:
Message.Tilerenders thechangeblock (struck original → proposed text) with Accept/Reject via newonAcceptChange/onRejectChangethread callbacks;CommentThreadis decoupled from@dxos/react-client(metadata/activity/identity injected as props). - @dxos/plugin-review: a unified review companion — comment threads and suggestion cards in one surface.
Suggestionsreactively tracks the document's activekind:'suggestion'branches (one bound probe per branch) and renders each grouped change as a change-block tile, routing Accept/Reject to the durableAcceptChange/RejectChangeops. -
@dxos/plugin-markdown: a
SuggestEditoperation + "Suggest edits" authoring action that find-or-creates the caller's per-author suggestion branch and edits it. (3f1fc67) -
Fix markdown list formatting: toggling between bullet/task/ordered list styles now converts markers in place instead of nesting them, list markers align with the hanging indent, and the outliner block drag shows a full-width preview with a stable empty drop placeholder (no flicker when dragging items with children). (20153c0)
-
Fix XML tag widgets rendering blank after the document is replaced — widget state applied around the reset (for example tool call rows when returning to a chat) now reaches the mounted widget. (a1c89fa)
-
Disable the Tailwind/Vite file watcher in
ThemePluginwhen running under Vitest. Itsserver.watchconfig was a non-null object that overrode the test runner'swatch: null, keeping a live watcher whose per-filefs_eventhandles (registered by Tailwind's@sourcescan) were never released — hanging single-passvitest runteardown so the process never exited. HMR-ignore patterns are retained for interactivestorybook dev/vite dev. (4df6cf3)