Changelog

Every Catenary release, newest first. Found a bug? Send feedback or write to support@thecatenary.app.

1.1.0

October 6, 2026
Catenary 1.1.0 is the IDE for orchestrating terminals and AI agents. The same work session now has two views you can switch between at any time with Ctrl/Cmd+Alt+S, without restarting a single process: TerminalMap, a focused grid of terminals and splits in the style of cmux/Ghostty, and the spatial Canvas, the infinite desk where panels float and wires connect agents.

TerminalMap & Sessions Cockpit

  • TerminalMap layout. A docked grid of terminals, splits and tabs that coexists with the Canvas: switching views never touches node geometry, and PTYs, browsers and editors stay alive across the switch.
  • Sessions Cockpit in the sidebar. A compact Sessions | Files activity bar, one card per work session with three visual levels over seven agent states, "Hide from Cockpit", archiving, and a global attention bell with Jump to Unread across workspaces.
  • Session cards that say what is happening. A card shows your last prompt and the tool the agent is running right now. The bell lights only when an agent is blocked (an approval, a failure or an explicit request); a finished reply turns the card green without ringing.
  • Splits and Split Zoom. Split the focused terminal right or down (⌘D / ⇧⌘D on macOS, Alt+Shift+D / Alt+Shift+H on Windows and Linux, where Ctrl+D belongs to the shell) and maximize one pane with Split Zoom (Ctrl/Cmd+Shift+Enter) without touching the layout.
  • Terminals close immediately, cmux/Ghostty style. Clicking ✕ on a terminal, a split or a whole group closes it without a confirmation modal, for any process or agent.
  • Welcome screen with two cards. First launch offers TerminalMap or Canvas side by side, followed by a short, skippable tour. A standalone terminal starts in your home folder with no folder picker.
  • Predictable working directories. New splits, worktree terminals and Home terminals resolve their CWD from their origin, tracked via OSC 7, with a safe fallback when a folder has disappeared.

Editor & Local LSP Engine

  • Shared local LSP engine for TypeScript and Python. typescript-language-server and pyright run under a supervisor with automatic restart, pooled per workspace and worktree, feeding completion with auto-import, hover, go to definition, references, rename, diagnostics and semantic tokens into Monaco.
  • Buffer sync between editor, disk and agents. A shared DocumentService versions every open buffer; when an agent writes to a file you have unsaved changes in, the editor offers Compare / Replace / Keep Buffer instead of silently overwriting.
  • Follow Link in Monaco. Ctrl+Click on http://, https:// and mailto: links opens them in your default browser.
  • Rich previews. Markdown with GFM tables, task lists, Mermaid diagrams and KaTeX, and native Jupyter notebooks (.ipynb) with Matplotlib/Plotly and Pandas outputs.
  • Clickable file links in the terminal. path:line:col jumps straight to that position in the editor.
  • Richer syntax colors. Destructured variables and imported names in TypeScript/JavaScript, and the expressions inside Python f-strings, now get their semantic colors.

Extensions Hub & MCP Observability

  • Extensions Hub. Installed, Install and MCP tabs in one sidebar hub, with per-workspace controls.
  • MCP observability. The MCP tab lists servers declared in .mcp.json and .pi/mcp.json (name, transport and executable only — never args, env or secrets) next to live Catenary MCP connections and observed ports.
  • Native catenary mcp server, registered automatically. Installed agents (Claude Code, Codex, Antigravity and others) get the catenary_* tools with no setup: open files, create tasks and worktrees, split terminals, request attention, delegate work, and query the shared LSP engine (definition, references, hover, symbols, diagnostics).

Terminal Robustness

  • Safe monospace fonts. Proportional faces are filtered out of the font list, installed fonts are offered from the system, and a monospace fallback stack is always guaranteed.
  • PTY backpressure. The PTY pauses at 256 KB of unparsed output and resumes at 64 KB, acknowledged by xterm's write callback, with a watchdog so a terminal can never freeze on missing acks.
  • WebGL recovery. A lost WebGL context is retried with backoff before falling back to the DOM renderer.
  • No flicker when switching sessions. A terminal that comes back into view repaints before its first frame, so switching between sessions stays instant and clean.

Settings & Feedback

  • Import your preferences. Bring settings and keybindings over from VS Code, Cursor or Ghostty (Command Palette → Import Preferences), with a preview, conflict warnings and one-click undo.
  • Send Feedback. Help → Send Feedback… opens a short form on thecatenary.app. The app itself still sends nothing.

Multi-Agent Ergonomics

  • Zero-config delegation. Agents in the same session reach each other with catenary ask without a confirmation card or a visible wire; catenary ask --no-wait hands work off without blocking.
  • Structured inbox. Delegated messages are deduplicated, expire after 24 hours and are acknowledged explicitly, keeping "delivered" and "done" as distinct states.
  • Clean worktrees in one click. The task instruction is optional, the button switches between Launch Task and Create Worktree, tabs show a branch chip, and agent trust applies only to worktrees created inside the authorized project.

Earlier versions

1.0.xAugust 29, 2026

1.0.0

August 29, 2026

Added

  • The shipped code is V8 bytecode, not source (Fase 2.4). The main process is compiled to .jsc and the plain-JavaScript bundle is removed from the package. npx asar extract used to hand over 1.7 MB of readable TypeScript-derived source — including the Ed25519 licence verification and the trial expiry, which meant defeating either one was a text edit. Those now run from bytecode inside the main process.

    Stated plainly, because it is worth being honest about: this is not encryption. String literals survive in the V8 constant pool and bytecode can be disassembled by someone determined. What it removes is casual source copying and the one-line patch. The preload script is deliberately left as plain JavaScript — compiling it would require turning off the renderer's OS sandbox, and the preload holds nothing but a list of IPC channel names.

  • A one-click Windows installer. Double-click, a progress bar, the app opens — no wizard, no Next/Next/Finish, and no UAC prompt, because Catenary installs per-user rather than for the whole machine. It carries the official icon throughout (installer window, progress bar, uninstaller) and creates the Desktop and Start Menu shortcuts. Named Catenary-Setup-<version>.exe.
  • The EULA and the Privacy Policy ship with the app, under resources/legal/. The terms someone agreed to now live on their machine rather than only on a website that can change or go offline.
  • Free vs Pro licensing (Fase 2.2): Catenary now has a plan. A Pro key is verified offline with Ed25519 — no server call, no phone-home, and the app stays fully functional without a network.

    The 7-day Pro trial is claimed, not granted: a fresh install runs on Free from the first second, and the clock only starts when you ask for it — from the invitation that appears when you meet a free limit, or from Settings → License. No card, once per machine. Because it can only ever be started once and there is no way back, asking for it opens a confirmation that names the date the trial would end before you spend it, rather than starting the clock on a single click. That way the days are spent while you are actually pushing against something, instead of draining during a week you never opened the app.

    Day 8 is a screen rather than a silence. If the trial left more projects open than Free allows, Catenary reopens the one you were last in and closes the rest — closed, never deleted: they wait under Recent, the screen names them, and every file, canvas, branch and worktree is untouched. From there you work one project at a time, or get Pro to keep them side by side. The same reconciliation runs whenever the app starts over its limit, so a plan is never enforced in one direction only, and a Recent entry you cannot open right now says so with a lock instead of failing on the click.

    The free plan is the whole product, in small: canvas, terminals, editor, browser, git and wires between agents are unlimited on every plan. What Pro buys is scale — more projects open at once, more tasks running in parallel, bigger teams. On Free one agent commands at most two helpers, and that single rule is the same number everywhere it shows up: two Maestro recruits, and a three-node squad (a leader plus two). Four of the five built-in squads fit under it; the five-agent Enterprise squad carries a PRO badge, shown only to users who are actually on the free plan.

    Meeting a limit opens an invitation that names what just happened rather than a generic upsell, and never interrupts work in progress. It offers three doors in the order they cost: Get Pro is the button, I have a key sits beside it, and the trial is a quiet link off to the side — an offer, not the answer the wall volunteers first.

    Changing plan is a moment, not a relabelled row: activating a key or claiming the trial dims the room, and the mark arrives with a shockwave, the trial naming the date it ends and a purchase naming the person it was sold to.

    Which plan you are on is always visible: a small tag sits beside the version in the sidebar foot — FREE, PRO TRIAL · 3d, or PRO — so the trial countdown runs somewhere you actually walk past, instead of only inside Settings. Clicking it opens a plain comparison: what every plan gets unlimited (canvas, terminals, editor, browser, git, and the wires between agents) stated first and without columns, then the five places Free and Pro genuinely differ. Those five rows are generated from the same numbers the app enforces, so the table cannot drift from docs/legal/PLAN-LIMITS.md. A Pro user clicking their own tag gets their licence, not a sales table.

    License… sits in the app menu, the command palette and its own Settings section, where the plan is a card — what you have, what it comes with, and, on a trial, how much of it is left as a bar. A paid plan can also raise the Maestro ceiling (2–10) there. That ceiling exists on Pro too and is not a paywall: a maestro opens agents on its own initiative, each one spending your API credits, so it stands alongside the approval card and the action throttle as a cost brake.

    Plan limits are documented in docs/legal/PLAN-LIMITS.md, which EULA clause 4.1 now incorporates by reference.

  • 1-Click Agent Task (worktree automation): a ⚡ New Agent Task pill now leads the canvas toolbar (Cmd/Ctrl+Shift+N, also in the command palette). It opens a prompt-first modal: you describe what the AI should do, and the branch name writes itself from that description — "Criar modal de login" becomes feature/login-modal, "Faça a Issue #42" becomes fix/issue-42. The branch field is always visible and always editable, and it stops following the prompt the moment you touch it.

    Confirming creates an isolated git worktree, pans the canvas to a clear patch, draws the task's own territory there, and starts the chosen workforce inside it — a single agent (Claude Code, Codex, …), a plain terminal, or a whole Squad, picked through the real Squads dialog rather than a smaller copy of it. The prompt is delivered once the agent CLI is actually listening, so it reaches the agent instead of the shell it booted from — and the delivery is verified against the terminal's own screen rather than assumed, then re-sent until the text is really in the composer. A CLI that takes five seconds to attach its input reader (Antigravity on Windows) used to swallow the prompt silently and leave an empty > behind; now the Enter is only pressed once the words are there. A squad leader gets its role prompt in front of the goal, in the same single message.

    Setup rápido (on by default) makes the new checkout usable in about a second: node_modules is linked from the source checkout, the .env family is copied (copied, not linked — a task branch must not rewrite your main checkout's secrets), and the repo's own .catenary/setup.sh runs if the team committed one. All three are best-effort: none of them can fail the worktree.

  • Task island controls on the canvas: each task territory carries a control pill — the branch, a live status dot (working / waiting on you / done), Review Diffs, and Create PR ▾. Review Diffs opens a Monaco diff per changed file against the merge base with the base branch, so it shows everything the agent did (committed or not) and nothing the base branch did meanwhile. Create PR pushes and opens GitHub's own PR form, which renders the repo's pull_request_template.md; the dropdown holds local merge, push, copy branch name, and discard.
  • ACTIVE TASKS in the Explorer: a collapsible section above the file tree lists every running task worktree with its status badge and teleports the camera to that island in one click. It renders nothing at all when there are no task worktrees, so an ordinary single-branch project is unchanged.
  • Autonomous agent terminals: the New Agent Terminal picker gained an "Agente autônomo" checkbox, and the recruit approval card a matching one. A terminal created with it ticked launches its agent CLI with permission prompts bypassed, so the agent edits files and runs commands without someone accepting each one. The picker's command footer rewrites itself as you tick the box, so the flag is always read rather than promised.

    Autonomy is chosen at creation and nowhere else: a CLI fixes its permission mode when it starts, so a switch offered afterwards could only mark something invisible until a future restart. A node whose terminal is autonomous shows a badge beside the Maestro one — an indicator, not a control.

    The mark survives an app restart (and a session resume) via the machine-local session.json, deliberately not the committed workspace.json, so cloning a project never inherits someone else's bypass.

    Per-agent flags: --dangerously-skip-permissions for Claude Code and Antigravity (read from the installed CLIs), plus --dangerously-bypass-approvals-and-sandbox (Codex), --always-approve (Grok), --auto (OpenCode) and --force (Cursor) from each project's docs.

  • In-App Toast Notification System: Added a lightweight, accessible floating toast system (toastStore.ts + ToastContainer.tsx) with auto-dismiss timers, custom actions, and theme-adaptive styling across main and detached dock windows for non-fatal errors (file injection errors, file tree operations).
  • Maestro & Process Lifecycle Hygiene: Added automatic cleanup of pending approval cards (dismissApprovalsForMaestro) and immediate release of recruit slots (forgetRecruited) when a Maestro or recruited terminal exits, dies, or is closed. Recruited terminals cleanly decouple into independent user terminals if their maestro is closed.
  • Terminal Render Scale Stability: Resolved DPR / display density re-derivation timing during canvas zoom transitions and display changes in TerminalPanel.
  • CI Workflow Trigger: Updated .github/workflows/ci.yml to trigger automated builds and test suites on both main and catenary branches.

Changed

  • Every panel belongs to a branch, and master is always one of them. A terminal, editor or browser created on empty canvas belongs to the primary worktree — because that is the checkout it is running against — instead of belonging to nothing. A branch is selected from the moment a project opens, and clicking any panel moves the whole app into that panel's branch: what a new terminal inherits, which panels stand at full strength, and which files the Explorer shows. Panels on other branches step back a little (opacity only — never hidden, never disabled, still one click away); the focus lens keeps its own, much stronger dim for when you deliberately ask to study one island.

    The Explorer follows the branch: click into a task island and the tree shows that worktree's files. Source Control and Search deliberately stay on the workspace root — a project-wide search that silently narrowed to one checkout would be a search that lies about its scope.

  • The canvas is flat again. The topographic "territory" relief painted behind each branch's panels is gone, along with its WebGL2 shader, CPU fallback, pocket-mask flood fill and context-loss recovery. It answered "which panels belong together" with a picture of ground, and competed with the panels for the eye on a surface whose whole job is to show panels. That question is now answered by the branch pill above each island and by the opacity of the panels themselves. Settings → Canvas → Worktree territories is now Branch pills and keeps the same switch, so anyone who had turned it off stays off.
  • No more operating-system confirm boxes. Every window.confirm — delete a file or folder, discard a worktree, merge a branch, remove a workspace, delete a saved layout, clear imported passwords — is now an in-app modal in Catenary's own chrome, with Enter to confirm and Escape to cancel. The native dialog painted a white card with OS buttons on top of a dark canvas and blocked the renderer thread, which stopped every terminal from drawing until it was answered. Two of these (merge, discard) could not ask at all through a component, so they now go through confirmDialog() — a promise any store or hook can await.
  • ACTIVE TASKS moved to the base of the Explorer, under the file tree, with its own divider and a capped height that scrolls internally. A dozen branches no longer squeeze the tree into a sliver, and the section still disappears entirely on a project that has never launched a task.

Fixed

  • "Agent finished • N files changed" never fired inside a task branch. A worktree is checked out at <repo>/.cate/worktrees/<branch>/…, and the filter that hides Catenary's own machine-local state rejected anything with a .cate segment — which is every file an agent writes in a task island. Paths are now judged from inside their checkout, so an agent working in a worktree gets the same offer as one working in the root, while state files and build churn (even inside a worktree) stay filtered out.
  • Review Diffs compared against the wrong base. It always diffed against the primary branch, so a task cut from develop reported everything develop did as if the agent had written it. The ref a worktree was created from is now recorded and used, falling back to the primary branch for a branch cut from HEAD. The dropdown's "Local Merge to …" keeps naming the primary branch, which is where the merge actually goes.

Point releases

1.0.5

September 12, 2026

Fixed

  • Canvas: drop of docked tabs onto canvas vanishing or teleporting (BUG-001). When a tab was dragged from the dock bar onto the canvas, coordinate translation and drop handlers could lose reference to the target position, causing the panel to either vanish or teleport to arbitrary canvas coordinates. Normalized the drop flow and position calculation across dock-to-canvas transitions.
  • Windows: Codex CLI hooks silently failing under PowerShell (BUG-002). On Windows, PowerShell requires the call operator (&) to execute command wrappers. Codex hook definitions in .codex/hooks.json now prepend & to the wrapper script path, restoring real-time hook dispatch on Windows terminals.
  • Antigravity: transcript watcher leak on terminal close. Closing a terminal running Antigravity left the transcript watcher polling in the background. Terminal close lifecycle now disposes the transcript watcher and cleans up active conversation bindings.
  • Codex: touched files extraction in PostToolUse hook payload. Codex passes the patch content within the command property of tool_input. The hook parser now inspects args.command and raw string payloads in apply_patch events, enabling the "Agent finished • N files changed" banner to offer modified files on the canvas.

Added

  • Editor Breadcrumbs navigation bar. Added interactive path breadcrumbs to EditorPanel with folder hierarchy, full path tooltips, and one-click path copying.
  • Canvas: drag-and-drop files open as full Monaco Editor. Dropping files from the sidebar file tree or OS file manager onto the canvas now instantiates full editable Monaco Editor panels instead of static card blocks.

1.0.4

September 6, 2026

Fixed

  • macOS: Apple Silicon architecture isolation in packaging pipeline (cachedDataRejected). In electron-builder.yml, target definitions previously hardcoded arch: [x64, arm64], causing electron-builder to ignore the CLI architecture flags and compile both architectures on every CI runner. The Intel runner finished last and overwritten the ARM64 DMG on GitHub Releases with an artifact containing x64-compiled V8 bytecode (.jsc), which Apple Silicon rejected at launch with Error: Invalid or incompatible cached data (cachedDataRejected). The configuration now omits the hardcoded arch list, ensuring each CI runner packages exclusively its native architecture.
  • macOS: the app was killed at launch on Apple Silicon (EXC_BAD_ACCESS (SIGKILL (Code Signature Invalid))). Flipping the Electron fuses rewrites bytes inside Electron Framework, invalidating the ad-hoc signature it ships with — and on an unsigned build (no Developer ID certificate) electron-builder skipped signing altogether, so nothing repaired it. On arm64 every __TEXT page is hash-checked on fault, so the process died inside electron::fuses::IsRunAsNodeEnabled() before any window appeared, and Gatekeeper reported the download as "damaged". Packaging now re-signs the bundle ad-hoc immediately after the fuse flip (electronFuses.resetAdHocDarwinSignature), and the release workflow verifies the .app's signature before the dmg and zip are uploaded.
  • Licensing UI seat limit description. Corrected the footer note in Settings → License from "on any number of their own machines" to "on two of your own computers at a time", strictly aligning with EULA §4.4 and the backend database enforcement.
  • Trial prompt hidden for active Pro users. In Settings → License, the prompt suggesting to start the 7-day trial is now conditionally rendered only for unpaid users (!isPaid), preventing active Pro subscribers from seeing redundant trial offers.

Added

  • Confirmation dialog before removing a license. Clicking "Remove license" now presents a destructive confirmation prompt (confirmDialog, layer MODAL_Z.confirm) explaining that the machine will revert to the Free plan, release its seat on the license server, and preserve the key for future activation.
  • Automated package manager release pipeline. Added scripts/write-checksums.mjs and scripts/render-packaging.mjs to generate SHA-256 sidecars and populate package manifests (packaging/) for Homebrew, Arch Linux AUR, and Windows Winget, wired to trigger on release publish.

1.0.3

September 5, 2026

Fixed

  • Multi-agent Squad reliability and state isolation in shared worktrees. When multiple agents (e.g. Enterprise Full Squad) operate concurrently in the same worktree directory, the Antigravity transcript watcher now correlates transcripts per terminal using an input-ledger (noteTerminalInput) rather than indexing purely by directory (cwd). This eliminates turn-event broadcasting, cross-terminal hijacking, and false (busy) status deadlocks during inter-agent communication (catenary ask).
  • Turn liveness TTL in agent presence detection. agentScreenDetector now expires stale hookTurnActive state to waitingForInput after 120 seconds of terminal output silence and missing lifecycle events, preventing silent UI status freezes if a background CLI drops a turn event.
  • Fast failure diagnostic on unresponsive peers. catenary ask now surfaces a peer-stale diagnostic with recent screen tail after 45 seconds of target silence rather than blocking indefinitely in a 20-minute poll loop.
  • Dev mode build resolution. Fixed Rollup external module resolution for bufferutil and utf-8-validate during development bundling.

1.0.2

September 5, 2026

Added

  • Server-backed 7-day trial protection with offline cryptographic verification. The 7-day trial is now anchored to the server's Postgres clock via an anonymous hardware hash (machineId), preventing clock alteration and reinstallation resets. The server issues an Ed25519-signed token (CATE-TRIAL-1-...) verified offline by the app, maintaining 100% offline resilience after the initial claim.
  • Grace period for unconfirmed license activations. Offline license activations receive a 30-day grace period to confirm their seat with the server, protecting legitimate offline use while preventing indefinite offline license sharing.
  • Electron Fuses hardening. Packaged builds now enforce embedded ASAR integrity validation (enableEmbeddedAsarIntegrityValidation), enforce loading strictly from the ASAR archive (onlyLoadAppFromAsar), and restrict main process debug inspection in production.
  • macOS: Apple HIG squircle icon grid and custom branded dark DMG installer. The macOS icon now includes standard continuous squircle padding (~18% margin on the 1024x1024 canvas), eliminating the fallback grey rounded-rectangle frame drawn by macOS Finder. The macOS DMG installer window is now styled with a custom dark canvas background (build/background.png), large 128px icons, and a glowing curved catenary wire connecting the app to /Applications.

1.0.1

September 4, 2026

Fixed

  • macOS: compile and package per CPU architecture to fix Intel V8 bytecode cache rejection. The main process bundle is compiled to V8 bytecode (.jsc), which is architecture-specific. In 1.0.0, both arm64 and x64 DMGs were packaged from a single Apple Silicon build, causing Intel Macs and x64 Rosetta processes to crash at startup with Error: Invalid or incompatible cached data (cachedDataRejected). The release pipeline now compiles and packages on native runners for each architecture (macos-latest for arm64 and macos-15-intel for x64), explicitly suffixes artifacts with their target architecture (Catenary-<version>-arm64.dmg and Catenary-<version>-x64.dmg), and merges auto-update metadata.