Skip to content
Ironflow is pre-1.0: APIs can change between releases. Pin a version. What is ready →

Ironflow Desktop v0.25.0

Ironflow Desktop v0.25.0 turns git worktrees into workspaces: the rail recognises existing checkouts, groups them under their project, and can create a sibling worktree from HEAD or remove one, with a dirty tree or another workspace’s claim blocking the delete. The engine details popup gains the Start/Stop control its rows describe, the engine rebinds its last port when it is free, and the concurrency cap moves to a single home and rises from 4 to 10. Push gets honest about destinations: the first push of a branch reads Publish and says where it is going, and a push can no longer land on a branch you did not name.

  • Git worktrees as workspaces. The app probes whether a folder is a repository root or a linked checkout, groups checkouts under their project in the rail with a worktree mark, and keeps engine data under the repository root. “New worktree from HEAD…” creates a sibling worktree as a new workspace (#2256, #2339)
  • Deleting a workspace can remove its checkout. “Workspace and checkout” is the default, a dirty tree blocks it, and the dialog names ignored files before anything is deleted, because git worktree remove takes a gitignored .env or node_modules without listing them. A checkout another workspace still points at cannot be removed, and a tree that cannot be read counts as a refusal, never as clean (#2339)
  • Start/Stop on the engine details popup. The button calls the same handler the workspace tile’s context menu picks, so the two cannot drift on what counts as running, and the popup stays open through the transition, so the rows below are how you watch the engine come up or go down (#2330)
  • Port stability for the supervised engine. The engine asks for the port it bound last time and falls back to an ephemeral one only when that port is taken, so anything pointed at it from outside the supervised dev command (a second checkout, a test run, a worker) no longer needs re-pointing on every restart. “Restart on a new port” joins the workspace tile’s context menu for when the stability is the wrong thing (#2330, #2331)
  • Ahead-of-base in the Files view. A branch with no upstream now reads “3 ahead of main” instead of stopping at “no upstream”. The base resolves origin/HEAD, then main, then master, matching what the Changes view measures against (#2339)
  • Discard all in the Changes header. One icon button, behind the existing confirm dialog, discards each path in sequence (#2343)
  • The concurrency cap has one home and a new default. maxConcurrent, the cap that makes booting one engine stop another, goes from 4 to 10, and the default stops being spelled five times: it lives in shared/engineCap.ts, read by the supervisor, the launch path, the snapshot fallback and the settings form, so the dialog can no longer open on a number the supervisor is not enforcing. ADR 0040 amended (#2330)
  • Approving a read approves its directory for the session. An agent that writes scratch files to the temp directory and reads them back cost one permission modal per file; approving a read now grants its directory until the session ends, and the card names that directory before the click. Reads only, one directory deep rather than recursive, and never persisted, so a new session starts empty (#2340)
  • The Changes header is one row of icons. A Plus/Minus toggle replaces the select-all checkbox and the Stage all / Unstage all text buttons, and status entries sort by path once in main, so staging an untracked file no longer jumps it to the top of the list (#2343)
  • Attached chat images render inline and smaller, at half the previous max height, instead of one block per image (#2338)
  • Push can no longer write to a branch you did not name. push() took its destination from the upstream config, which could build a refspec landing a feature branch on a differently-named branch, silent, exit 0, past branch protection. It now refuses a destination whose name differs from the current branch, refuses a local “remote”, and otherwise pushes the branch to its own name; with no upstream it publishes origin/ (#2339)
  • The first push says Publish. Creating a branch on the remote is a different operation from advancing one that exists, so the button splits them the way VS Code does, and both titles spell out the destination (#2339)
  • The turn rail no longer crashes the chat workroom with “Maximum update depth exceeded” while a turn streams. Its measure effect depended on a store-derived array that got a new identity per token and called setState synchronously from a passive effect; it now keys on a stable string of turn IDs (#2341)
  • Long attachment names truncate in the Context dock instead of painting over the “Turn N” column (#2340)

Download the latest release