Skip to content

Release 0.234

0.234.13: new file bytes leave no old version to find

  • A file whose bytes change (editor save, upload replace, the disk watcher) drops everything made from the old bytes at write time: summary, entities, text, schema digest, extract markers, embedding and chunks. The “migrated” supersede mark goes too, so search no longer sends agents to a page made from the old bytes.
  • Fix: upsertFile rebuilt the node’s data, so every editor save dropped the per-file indexing: 'metadata' flag and an excluded file went to full indexing. It merges now.
  • A re-extract that finds no facts retires the node’s live facts.
  • The upload route takes replace=true to write new bytes over a taken name in place: same node, so links and history hold.

0.234.12: Mammouth as a chat provider

mammouth-chat is an OpenAI-compatible adapter for the Mammouth aggregator (one key, many model families), chat only. A static catalog carries the published models and per-1M rates, and the adapter reports cost from it; uncatalogued ids stay unpriced. Live discovery appends new chat ids and feeds models:drift. docs/ai-workers.md.

0.234.7: headless onboarding, the setup code and the terminal wizard

While no account existed, signup made its caller the owner, so a box on a public address belonged to whoever reached it first.

  • The setup code. scripts/install.sh makes MANTLE_SETUP_CODE (four groups of five, about 99 bits, never rotated), prints it while the brain is unclaimed, and --setup-code prints it again. Signup needs it while no account exists and a code is set (403 reason: 'setup-code', audited). Unset changes nothing. bootstrap-state answers { firstRun, setupCodeRequired }. Contract: BootstrapStateDTO, SignupBody, SignupRefusedReason.
  • The terminal wizard. scripts/onboard.sh (box wrapper) and pnpm -C server/web onboard walk the wizard’s own steps (lib/onboarding-steps.ts, now shared with the onboarding route) with a default for every prompt, resumable either way with a GUI client. Secrets come hidden or on stdin, never in argv. onboard.sh ships with the release scripts, and the updater installs a script the box lacks at start.
  • Core shape is derived on every start from the box’s compose files and profiles (lib/compose-shape.ts); Tika is optional only on a core box without helpers.
  • Fix: a short follow-up on the member chat failed with “That did not go through”: the query enrichment read the owner’s messages, which a team turn may not. The team turn now passes the member’s own thread.
  • Fix: publish-contract fails unless every published version is visible on npm (it polls for up to 40 minutes).
  • Client pair: jackdaw v0.6.214 (the Setup code field).
  • docs/onboarding.md section 8, self-hosting.md, security.md, scripts.md, configuration.md.

0.234.6: the app inspect-to-focus overlay is gone

The Select element mode reacted only to [data-app-region] elements, which apps never reliably carried. share-ui drops the inspect and select bridge messages, the AppSandbox inspect props and the overlay script. Appsmith is no longer told to mark regions.

0.234.5: a stable brain id

  • Migration 0226 (0226_brain_identity): one row, a random uuid made by the migration and never changed. Not a secret.
  • GET /api/auth/whoami answers it as brainId, and so do device-login, the client code verify (device mode), token refresh and pair claim (the last two also gain loginId).
  • Every push payload carries brainId and the loginId the device was enrolled for, so a phone with several logins opens the right one. v stays 1.
  • db-restore.sh --new-brain gives a brain made from another brain’s dump its own id. A plain restore keeps the dump’s id and says so.
  • docs/mobile-companion-backend.md (contract v1.1), deploy.md, scripts.md, backups.md.

0.234.3: “Team apps may use” becomes External access

The switch on one outside tool (mcp or http) now follows the app’s sharing: a member running a team or public app, anyone running a client-level app, and a contact on a contact-share link past the code gate. An open link still runs no tool, and no built-in ever runs on a link. The app must still declare the tool; the confirmation and clearing rules are unchanged. A contact’s call lands in the share’s trail as tool. Migration 0225 (0225_tool_external_access) renames tools.team_apps to external_access; PUT /api/tools/:id/external-access, ToolDTO.externalAccess, api_tool_update external_access. No alias.

0.234.1: reopen puts a task back where it was

When a task moves into done, its old status is kept in data.status_before_done. reopen: true on PATCH /api/tasks/:id and task_update takes it back there (or to open). Contract, additive: TaskRow.statusBeforeDone, TreeItemMeta.reopensTo.

0.234.0: the apps audit fixes

The rest of the apps audit of 2026-10-02, on top of Phases 0 to 4.

  • An imported package gets no tools. A .mantleapp is a file from anywhere, and its declared tools used to be granted at once. Import now installs with an empty allowlist and answers requestedToolSlugs (this brain has them) and droppedToolSlugs (it does not), for the owner to grant with app_tools_set. app_import always waits for the owner in a client turn.
  • History pruning runs in one statement under the lock, so a row added meanwhile (a pre_delete) is never pruned with its file. It also keeps a byte budget: APP_SNAPSHOT_AUTO_MAX_MB per app (default 1024) and TABLE_HISTORY_MAX_MB per table (default 512), the newest always kept.
  • Restores. A data restore works when the live file is lost (the undo snapshot keeps the code only). A code restore no longer changes the live tools; it names the restored code’s tools as declaredTools when they differ. A full restore and an undelete keep the snapshot’s draft. A seed batch holds the registry row lock, so a restore waits for it.
  • Schema versions declared by app_db_schema_set, the import route and apps:push start past the database’s own version (after a data restore or an undelete a new schema used to be skipped).
  • Export dirty marks. Every app write also stamps last_write_at, and a sync clears the mark only when no write came after its read. Migration 0223 (0223_app_table_exports_last_write).
  • Builds. A build of source that changed meanwhile is not staged; the build step builds again (twice at most).
  • The error log is bounded per caller (10 rows a minute each, 30 for all non-owner callers together, 2000 a day per app), the reaper drops error rows after 14 days and past the newest 2000, and app_errors fences its rows as untrusted visitor data. Migration 0224 (0224_app_access_log_error_idx): a partial index for the error rows.
  • Imports stream the upload to a spool file, check the size before reading, and take a turn from one per-process limit (two at a time). A zip with more than 16 entries is refused before parsing. A step that fails after the install drops the half-made app.
  • Backups hard-link the two history trees instead of copying them; the table history copies run in a SQL child, off the event loop.
  • Lows. Entry checks use Object.hasOwn. The Recently deleted and History lists read from the row, not the code JSON (migration 0224, 0224_apps_audit_lows, adds the file count, source size and draft flag). A tool confirmation ticket is used once. The nightly app-trash-purge also sweeps work files a crash left behind after an hour.
  • share-ui: AppSandbox refuses a second tool confirmation while one is open, and the browser-dialog fallback shows the start and the end of a long input.

0.234.0: app_export and app_import, the package as a brain file

  • app_export / app_import (owner only, group apps, also on MCP): an agent saves an app as a .mantleapp file under /files (folder exports) and makes a new app from one; the Appsmith prompt teaches them with app_duplicate and app_errors.

0.234.0: table history (apps first-class, Phase 4)

  • Every table commit keeps the version it replaces (a hard link, no copy) on the table’s history; the newest 20 per table, plus the owner’s own snapshots (never pruned, within APP_SNAPSHOT_MAX_MB). Migration 0222 (0222_node_snapshots_table_commit) adds the commit trigger.
  • Restore puts a version into the table’s draft; review, then commit (or commit: true). The commit keeps what it replaced, so a restore is undone the same way.
  • Tools (owner only, group tables, also on MCP): table_history, table_snapshot_create, table_snapshot_restore and table_snapshot_delete (both confirm-gated). table_commit and POST /api/tables/:id/commit take a note.
  • Routes: GET/POST /api/tables/:id/history, DELETE …/history/:sid, POST …/history/:sid/restore, GET …/history/:sid/download.
  • The table backup copies the history; app-trash-purge also clears a deleted table’s history after 30 days. The Ledger agent and the table_authoring skill teach the history. docs/tables.md section 4.