[0.47.1] - 2026-08-16
Fixed
- Fix slow
mount()initialization for layouts that specify a checked-out revision withat, and allow concurrentmount()calls to initialize in parallel
[0.47.0] - 2026-08-14
Changed
- Breaking: Change the app-mount Bash default working directory from
/home/userto/
[0.46.0] - 2026-08-13
Changed
- Breaking: Replace the
mesa.fs.mount({ repos })mount syntax with the newmesa.fs({ layout, ... }).mount(...)syntax - Breaking: Remove
FsMountReposOptions.mount()now only acceptscacheandtelemetry; passttlandauthorstomesa.fs()instead - Breaking: Change
repo()to select a checkout revision with theatfield instead ofbookmark/changeId
Added
- Add
branchedFromtorepo()to fork a new change the first time the mount opens the repo
Removed
- Breaking: Removed the async
mesa.resolveOrg()method. The organization slug is now available synchronously viamesa.org.slug. - Breaking: Remove
orgfrom the TypeScript SDK constructor and resource methods; the SDK derives the organization from the credential - Breaking: Remove
vcsUrloption from the client configuration - Breaking: Replace all singular
authoroptions with a pluralauthors
Fixed
- Fix
repo()atpins being overridden when the organization’s configuration forks the repo on open
[0.45.0] - 2026-08-11
Changed
- Point package source and issue links to the public SDK repository
- Breaking: Remove top-level
RepoConfig.bookmark,RepoConfig.changeId, andRepoConfig.readOnly(and the deprecatedFromRevisiontype). Useat/branchedFromandmodeinstead - Breaking: Resolve
fs.change.new({ bookmark })(andedit/ mountat.bookmark) strictly againstrefs/heads/<name>. A string that is not a bookmark no longer falls through server-side revspec resolution to a change id; passchangeIdto fork from a change
Added
- Add mount
RepoConfigfieldsmode,at, andbranchedFromto open an existing revision or fork a new revision at mount time (create change → optionalas.bookmark→ publish checkout; omitas.bookmarkfor an anonymous tip)
Removed
- Breaking: Remove API-key authentication from the SDK, including
apiKey,MESA_API_KEY, legacy HS256 token minting, andMissingApiKeyError; useprivateKeyorauth.accessTokeninstead
[0.44.1] - 2026-08-09
Changed
- Split native filesystem write batches to the server-advertised VCS operation and message-size limits
[0.44.0] - 2026-08-07
Changed
- Resolve the organization for
auth.accessTokenlocally from its JWT issuer and reject opaque or malformed tokens instead of making an implicit/whoamirequest - Limit signing-key token and commit attribution to 100 ordered authors
- Deprecate the
apiKeyclient option, theMESA_API_KEYenvironment fallback, and theapiKeysresource in favor of private keys, and theorgclient option (the organization is derived from the credential); API keys remain supported - Change native addon loading to fail with the actionable
Unable to load mesafs-napi native addonerror (original failure attached ascause) when the package is installed but no platform binary is present
Added
- Allow private-key authentication to carry ordered commit authors, with explicit authors required for token creation, commit writes, and mounts
- Add custom mount layouts, created by calling
mesa.fs({ layout, ttl }) - Add
token()andlayout()on the FS mount definition for serializing a token and layout file that can be passed into a sandbox - Add
fs.change.checkpoint({ repo, message? })to flush pending writes (serializing concurrent writes and tree mutations in the same repo), optionally describe the current change, create a new descendant change, and advance bookmarks onto that descendant (requires the checkout to already be on a bookmark). Concurrent bookmark-tip races raise a retryable conflict (distinct from not-on-a-bookmark and from a half-applied checkout failure). Omitmessageto preserve the existing description; passmessage: ''to clear it; any other string overwrites. ReturnsCheckpointResultwithsavedChangeOid(saved change) andactiveChangeOid(now-active empty descendant)
[0.43.0] - 2026-08-02
Added
- Allow private keys to authenticate normal SDK requests and MesaFS mounts with
new Mesa({ privateKey }). Private-key clients can also mint scoped access tokens locally withtokens.create(), and those tokens can authenticate another client throughauth.accessToken - Add repository ID restrictions to locally signed access tokens with
mesa.tokens.create({ repo_ids: [...] })
Changed
- Breaking: Require REST and native filesystem bookmark moves to advance history by default; pass
allow_backwardsorallowBackwardsto permit intentional backward or sideways moves - Breaking: Change
Mesa.apiKeyfromstringtostring | undefined; it remains a string for API-key clients and is undefined for private-key and access-token clients
[0.39.0] - 2026-07-08
Added
- Add structured tag filter objects to
mesa.repos.list(), with$-prefixed case-insensitive operators ($and,$or,$not,$eq,$in,$contains,$starts_with,$ends_with,$exists) and case-insensitive tag matching
Deprecated
- Deprecate legacy comma-separated repo tag filters in favor of structured tag filter objects
[0.38.0] - 2026-06-22
Fixed
- Fix files written through the SDK transiently disappearing during bursts of writes
[0.37.0] - 2026-06-17
Fixed
- Repeated filesystem operations on the same repository are now dramatically faster
[0.36.0] - 2026-06-09
Added
- Add
mesa.tokens.create()to sign a self-expiring access token (JWT) locally from an API key, scoped to a subset of the key’s scopes and to repositories given as fullorg/reponames. Signing is local with no network call; attl_secondsoutside 1 second to 24 hours raisesInvalidOptionsError - Add a
ttloption (seconds) tofs.mount()to set how long the mount lasts. The mount signs one access token for that lifetime and expires with it. Defaults to 1 hour, capped at 24 hours - Add
MesaFileSystemConfig.credentialas the preferred name for the bearer-credential field, which accepts an access token (JWT) or an API key - Add
MissingCredentialErroras the preferred name for the error thrown when theMesaconstructor is given no API key (andMESA_API_KEYis unset)
Changed
fs.mount()now signs a short-lived access token locally from your API key instead of creating an ephemeral API key on the server. No server-side credential is created or left behind, and the mount expires on its own when the token does
Deprecated
- Deprecate
MesaFileSystemConfig.apiKeyin favor ofcredential. TheapiKeyfield is still accepted; supply exactly one (credentialwins if both are set) - Deprecate
MissingApiKeyErrorin favor ofMissingCredentialError. The old name is retained as an alias of the same class, soinstanceofchecks under either name keep working
Removed
- Remove the automatic API key cleanup that ran on process exit;
fs.mount()no longer creates server-side keys
[0.35.0] - 2026-06-07
Changed
- Change
mesa.fs.mount()native addon loading to use the@mesadev/mesafs-napipackage while keepingMESA_NAPI_PATHas a local override
[0.34.0] - 2026-06-01
Added
- Changes in Mesa are now realtime by default. Concurrent editors mounted on the same change will see one another’s modifications within a few seconds.
- Add
MesaFileSystem.subscribe(handler)for filesystem invalidation callbacks across mounted changes. Callunsubscribe()on the returned subscription to stop.
Removed
- Remove the experimental
multiplayerfilesystem APIs.
[0.33.0] - 2026-05-26
Added
- Add per-repo
readOnly?: booleantoRepoConfiginfs.mount(...). Whentrue, the mesa daemon rejects writes to that repo withEROFS, so a single mount can carry a mix of writable and read-only repos.
Changed
- Change responses now report parent change IDs instead of commit SHAs of prior versions of the same change.
Removed
- Breaking: Remove the mount-wide
mode?: 'ro' | 'rw'option fromfs.mount(...)andMesaFileSystem.create(...). SetreadOnlyon eachRepoConfiginstead. The minted API key always carriesreadandwritescopes; read-only enforcement is performed client-side by the mesa daemon
[0.32.0] - 2026-05-22
Added
- Add
multiplayer.subscribe()for event-emitter style multiplayer event streaming. Returns aMultiplayerSubscriptionthat emitsremote-change(withgeneration) andpeers-changed(withcount) events. Call.unsubscribe()to stop. - Add
multiplayer.watch()forAsyncIterable-based multiplayer event streaming. YieldsMultiplayerEventobjects and supportsAbortSignalfor cancellation.
[0.31.0] - 2026-05-21
Added
- Add
setMetadata/getMetadata/clearMetadataonMesaFileSystemfor reading and writing per-file metadata as plain key/value pairs (e.g.{ origin: 'notion:page_foo' }).setMetadatamerges per key; passingnullor an empty string as a value deletes that key, so one call can mix sets and deletes.getMetadatareturns all keys including the read-onlyorg/repo.clearMetadataremoves every key on a path.
Changed
- Breaking: Rename the
client.repos.content.get(...)metadata surface fromxattrstometadata. Responses now exposemetadata?: Record<string, string>instead ofxattrs?, and directory listings filter viametadatakey/value pairs instead ofxattrpairs.
[0.30.0] - 2026-05-19
Added
- Respond to
client.repos.content.get(...)with optionalxattrs?: Record<string, string>metadata for files, symlinks, directories, and directory entries when present. - Add
xattrfilters toclient.repos.content.get(...)directory listings, returning entries that match all supplied xattrname:valuepairs. - Add
messagesupport tofs.change.new(...)for setting the description of a newly created mounted-filesystem change.
Changed
mesa.changes.create(...)andmesa.changes.patch(...)now accept empty string descriptions. Omitmessageon create to create a change with no description, or omit it on patch to preserve the existing description; pass""to create or update a change with no description.mesa.bookmarks.merge(...)now acceptsmessage; omit it to use the generated merge description, or pass""to create the merge with no description.
[0.29.3] - 2026-05-18
Fixed
- Make every
mesa.fswrite durable before the operation returns
[0.29.2] - 2026-05-17
Added
- Add
mesa.bookmarks.get({ repo, bookmark })for direct bookmark lookup by name, and addglobfiltering tomesa.bookmarks.list({ repo, glob }) - Add optional
ref_globsfilters tomesa.repos.syncUpstream(...): omit it to sync all supported branches and tags, or pass branch/tag glob strings such as{ branches: "main" }
[0.29.1] - 2026-05-16
Fixed
- Fix
mesa.fs.mount()native addon loading by restoring platform package entrypoints and falling back to directmesa-napi.noderesolution
[0.29.0] - 2026-05-15
Added
- Add
VIRTUAL_ROOT_CHANGE_IDexport for referencing the virtual-root sentinel change id from@mesadev/sdk - Add
mesa.repos.syncUpstream({ repo, direction })for triggering an sync with a repository’s upstream. Returns thesyncrow; the worker processes it asynchronously. Readrepo.upstream.latest_sync, callmesa.repos.getUpstreamSync({ repo, syncId }), listmesa.repos.listUpstreamSyncs({ repo }), or subscribe tosync.{queued,in_progress,completed,failed}webhooks - Add
mesa.repos.{getUpstreamSync, listUpstreamSyncs}for reading repository upstream sync history mesa.repos.createandmesa.repos.updateaccept anupstream: { url, auth? }field to add or replace the repository upstream. Theauthpayload is inline:{ kind: 'token', token, token_username? }or{ kind: 'username_password', username, password }.mesa.repos.updateacceptsupstream: nullto remove. Repository responses include theupstreamconfiguration withlatest_sync; secrets are never returned- Surface
sync.queued,sync.in_progress,sync.completed, andsync.failedwebhook event types
Changed
- Resolving the default bookmark of a freshly created (never-written-to) repo continues to return the virtual root sentinel
change_id. The server-side lazy-seed behavior is transparent to SDK consumers — the first write through any path advances the bookmark to a real change (MES-1387)
Fixed
- Fix REST API errors to throw human-readable
MesaApiErrorinstances while preserving structured response metadata
Removed
- Breaking: Remove the public
mesa.rawgenerated REST operation namespace; use@mesadev/restdirectly for low-level REST access
[0.28.2] - 2026-05-07
Added
- Add
fs.change.current({ repo })to query the currently active change on a mounted repo. ReturnsChangeInfowithchangeIdandcommitOid.
[0.28.1] - 2026-05-06
Changed
- Rename
SIGNATURE_HEADERexport fromx-depot-signaturetox-mesa-signature. Consumers verifying webhook signatures must update to match the new header name. - Coordinate
MesaFileSystemcache budgets across instances in a single process;disk_cache.max_size_bytes: nullnow auto-sizes against system resources instead of being unbounded
Fixed
- Fix
rgand other tools that resolve/..by clampingresolve_pathat the filesystem root.
[0.28.0] - 2026-05-03
Added
- Added support for conflicts in the FS interfaces. Conflicting files render
jj-style conflict semantics.
Fixed
- Surface
LOCK_CONFLICTinstead ofINTERNAL_ERRORon concurrent bookmark writes. - Fixed race condition in cache deallocation theoretically causing crashes.
[0.27.0] - 2026-04-30
No user-facing changes.[0.26.0] - 2026-04-29
Changed
- Breaking: Rename “upstreams” to “remotes” across all SDK interfaces.
Fixed
- Fix repo list cache not being exercised through the SDK codepath, hitting an uncached API on every call.

