Last release today
26 Aug 2026
Ships on a steady schedule
a new release about every 2 weeks
Most releases are documented
notes for 29 of 47 stable releases
Nothing withdrawn
no release was ever pulled
1 years old
157 releases Β· first in 2025
Release timeline
157 releases since 2025Releases
- v0.3.0-beta.20.0.20260826160612-21d420d9ddc826 Aug 2026pre-release
Nothing published for this version
- v0.3.0-beta.20.0.20260825225148-a7d6ce49ed5d25 Aug 2026pre-release
Nothing published for this version
- v0.3.0-beta.20.0.20260825144103-6e495a69d6e025 Aug 2026pre-release
Nothing published for this version
- v0.3.0-beta.20.0.20260825025111-19b8ae06c03925 Aug 2026pre-release
Nothing published for this version
- v0.3.0-beta.2017 Aug 2026pre-release
Release notes
Open source β0.3.0-beta.20 - 2026-08-24
π Features
π Bug Fixes
- Recover ACP sessions after provider disconnects (#454)
Additional notes
Open source βCompozyOS 0.3.0-beta.20 β beta Pre-release
Pre-release
Compare
Choose a tag to compare
- v0.3.0-beta.1917 Aug 2026pre-release
Release notes
Open source β0.3.0-beta.19 - 2026-08-21
π Features
- Add Batuta to marketplace (#432)
- Complete Loop graph engineering and typed inputs (#427)
- Simplify the interface for everyday users (#440)
- Deliver the command palette operating surface (#441)
π Bug Fixes
- Website font style
- Harden Loop runtime and graph execution (#438)
- Use candidate version in release dry-run
- Coalesce redundant ACP tool updates (#442)
- Resolve agent runtime recovery regressions (#447)
- Preserve run-agent session lifecycle (#446)
- Use migration timeout for tail replay
π§ Miscellaneous Tasks
- (mise) Pin Go 1.26.6 (#433)
Release Notes
Features
Agents operate commands without the UI
Everything the palette does is reachable from the CLI, HTTP, UDS, and native tools, with the same reasons and the same gates. An agent supervising CompozyOS discovers a command, checks its contract, targets a client, invokes it, and follows the approval β never depending on a browser. (#441)
- Native tools:
compozy__cmd_palette_listreads the daemon-canonical catalog for the bound workspace, andcompozy__cmd_palette_invokeruns one command withid, optionalargs, and optionalclient. Availability, targeting, single-flight, and approval rules all still apply. - Every refusal is structured and carries the same text the UI row shows:
command_not_found,invalid_argumentsnaming the fields,no_attached_shell,multiple_clientslisting every attachment ID, andalready_running. - HTTP and UDS expose the catalog, clients, invocation, and stream under
/api/cmd-palette/*, plus rank signals, usage, pins, and personalization. Approvals are read and canceled through/api/tools/approvals/{id}. - Configuration parity is complete: bindings, aliases, pins, and personalization resets go through the same validated daemon paths Settings uses, and a change made by an agent reaches connected shells without a restart.
compozy approvals show|cancelis a new top-level verb for the tool-approval lifecycle behind any invocation.
compozy cmd-palette invoke session.new --client <attachment-id> -o json compozy cmd-palette invoke <destructive-id> -o json # returns approval_pending + approval_id compozy approvals show <approval-id> -o json # pending β terminal compozy approvals cancel <approval-id>
Ask the agent when nothing matches
A query with no strong result no longer dead-ends. The palette offers one visually distinct
Ask agent: '<query>'row; pressing Enter creates a session with the workspace's default agent and uses the query as the opening prompt. (#441)- Nothing is sent before Enter. Typing never carries the query to a provider, and a rapid double Enter still creates exactly one session.
- A weak-but-real match keeps both the results and the fallback row; only a query below the served threshold is fallback-only.
- With no workspace default agent, Enter opens the agent picker first. If the session fails to start, the failure names its reason and the palette reopens with your query intact.
- Turn it off in Settings β Palette, or set
fallback_targets = []. Both report the same desired state, and the row disappears immediately.
[cmd_palette] # The current runtime accepts "agent". Use [] to disable the fallback row. fallback_targets = ["agent"]
Batuta in the Marketplace
Batuta v0.1.0-beta.3 ships as a curated community extension, so operators discover and install it from the Marketplace instead of going through the unverified GitHub-install consent flow. (#432)
- Its agent, skill, and Loop are resource-only and vendored for review, pinned to a deterministic archive digest.
- It installs from the
communitytier and still requires explicit enablement before it publishes its resources.
Correct one output, repair one lane
Operators can fix a settled node output without rewriting what actually happened, and can act on a single fan-out cell without disturbing its siblings. (#427)
- Amend output applies to a settled output while its run, node, or cell is parked, and appears only when the node declares an output shape to validate against. It shows the recorded original read-only beside the corrected value and takes a reason.
- Amendments are append-only: the recorded output is never rewritten, the corrected value becomes what resume and downstream reads see, and both stay visible in history and in a diff. Amending does not re-run consumers β pair it with Rerun from here.
- Run detail returns
amendments[]with bounded, redacted values, or a byte-size and content-hash summary for large data. No API reads an amendment's private output reference directly. - The control is available as
compozy loop node amend,POST /loop-runs/:id/nodes/:node/amend, andcompozy__loop_node_amend. --item(oritem_index) pauses, resumes, cancels, or kills one fan-out cell without touching the rest of the window.
compozy loop node amend --run-id <run-id> --node build --item 3 \ --payload '{"artifact":"dist/app-1.4.2.tgz"}' --reason "wrong tag captured"
Every domain opens inside the palette
The palette is not only a launcher β it browses. Sessions, Tasks, Loops, Jobs, Agents, Triggers, Marketplace, Bridges, Knowledge, Vault, Worktrees, Network channels, and Extensions each open as a view without leaving the overlay, and views stack so one selection can push the next. (#441)
- Four view kinds ship: list, detail, grid, and form. Lists carry domain chips with truthful counts and single-select semantics; a chip with zero matches names the filter and clears in one keystroke.
- State badges come from the shared status vocabulary and always pair a glyph with a label β never color alone.
- Selecting a row previews its metadata and sanitized text in a detail pane without stealing focus from the list, and the pane clears when the row disappears from another surface instead of showing stale content.
- Form views traverse typed fields in declared order, block an invalid submit on the first failing field, and discard values when you pop the view.
- Vault rows show names and metadata only. A secret value never enters a view, a preview, or a match highlight.
- A cold open shows a loading state, never a blank list dressed up as empty; an oversized list either scrolls virtually or states the exact
showing N of M. - Views stream patches, so a list already on screen updates in place as the runtime changes.
compozy cmd-palette list --source core -o json | grep palette.view. # palette.view.sessions, .tasks, .loops, .jobs, .agents, .triggers, # .marketplace, .bridges, .knowledge, .vault, .worktrees, # .network-channels, .extensions
Extensions contribute commands and views
An extension can add its own commands and views to the palette from
resources.cmd_palette, beside its tools. CompozyOS validates the contribution duringextension build,extension validate, install, and development reload, and prefixes every local ID with the extension name βcapturefrom thenotesextension becomesext.notes.capture. (#441)- The action union is closed:
toolcalls a tool the same extension owns,viewopens one of its views,navigateopens a CompozyOS app, andurlopens an external link. Extensions cannot declare client operations. - A declarative view names a read-only tool as its source and returns the shared
v1view payload, which the daemon validates before rendering. A mutating, destructive, interactive, or open-world tool is rejected at validation time, so opening a view never starts an approval flow. - A programmable view sets
program: trueand is backed by the publicview.providersurface, with patch streaming for live updates. Start from the template withcompozy extension init notes --template view-provider-ts. - A command can ship a
default_shortcut. If that chord already belongs to something else, the default stays dormant and the conflict is visible in Settings instead of silently stealing the key. - Destructive extension commands must declare themselves and supply confirmation copy; the same approval gates apply to them as to core commands.
resources: { cmd_palette: { commands: [{ id: "capture", title: "Capture note", section: "Notes", icon: "pencil", action: { kind: "tool", tool: "capture_note" }, default_shortcut: "alt+shift+KeyN", }], views: [{ id: "recent", title: "Recent notes", kind: "list", source: { tool: "list_recent" }, }], }, },
Fan-out settles with an honest count
A fan-out can declare how it settles, and a partial result stays partial everywhere it is read instead of being rounded up to success or down to failure. (#427)
strategyacceptswait_all(the default),fail_fast,race, andbest_effort.best_effortrequires both a threshold β a percentage like66%or a count like{ count: 2 }β and an explicitmissing: acceptable.- A collect result is
succeeded,partial, orfailed, and its output carriestotal,succeeded,failed,canceled,coverage_rate, andpartial. - Live counts read through
nodes.<fan-out-id>.progress.*βtotal,succeeded,failed,canceled,running,pending,settled,success_rate,failure_rateβ with the shortprogress.*form inside the fan-out body. Rates are0for an empty collection. - The run page separates lanes that succeeded, lanes that failed, lanes the strategy canceled, and lanes that never materialized because the window did not open them. Partiality is a run-level fact (
completion_state), so it readspartialin the outcome card, the run lists, and a diff. A wide fan-out reports aggregate counts instead of one row per lane. - The fan-out window has no daemon-wide ceiling; logical width stays bounded by each node's positive
max_fan_out. Write-time validation rejects a negativefan_out_width.
- id: inspect_files class: control kind: fan-out collection: "{{ .nodes.changed.output.files }}" bind_as: file strategy: kind: best_effort threshold: 66% missing: acceptable
Loop inputs that know what they point at
A Loop input can declare the kind of thing it accepts, and every surface that edits inputs now validates against the real workspace catalog before anything starts. A wrong agent name, a retired skill, or an unsupported model is caught at the field that caused it instead of failing deep inside a run. (#427, #438)
- New input types:
agent(an exact agent name),refwith a closedref.kindofskill,loop,worktree,session,workspace, orsecret, andruntime({ provider?, model?, reasoning? }, accepting exact custom model IDs). A string-like input may still declareenum, and those choices take precedence over a catalog picker. - Effective values resolve one field at a time: run input, then workspace config, then global config, then the definition default. The daemon validates the winning value immediately before a dry run or a run, including entity existence and runtime support.
- A failure starts no run, creates no task and no external action, and returns the same
input_validationpayload β{ loop, field, kind?, value?, origin, reason }β over HTTP, UDS, CLI, native tools, and the web form, which attaches the reason to that field. - The same typed controls appear wherever Loop inputs are edited: the run form, scheduled automation, event-trigger mappings, fork and amend flows, and human-request answers annotated with
x-compozy-kind. Every surface submits the exact stored identifier β a display label is never treated as a reference. - The run form reuses the canonical runtime selector instead of free-text provider, model, and reasoning fields. From the CLI, a runtime input also accepts the compact
provider/model@reasoningform, with-leaving provider or model unset. compozy loop runprompts in an interactive terminal only for supported required inputs still missing after defaults;--no-promptfails instead, and structured or non-interactive input never prompts, so scripts stay deterministic.- Secret inputs expose Vault reference names and metadata only β a secret value never enters a catalog or an error payload. Two native tools back the new pickers:
compozy__agent_listand metadata-onlycompozy__vault_list. params.runtimebinds a declaredtype: runtimeinput through an exact reference such as{{ .inputs.worker_runtime }}. Provider, model, and reasoning are validated at bind time, while literal runtime objects keep compile-time typo detection, and the resolved runtime recordsinputprovenance.- If a saved reference is no longer listed, the field keeps the exact value visible so the daemon returns a field-level error instead of silently replacing it.
inputs: reviewer: { type: agent, default: code_reviewer } release_token: { type: ref, ref: { kind: secret } } worker_runtime: { type: runtime, default: { provider: codex, model: gpt-5.5-codex, reasoning: high } }
Loops can stop and ask you a question
Two new ways for a Loop to bring a person into a run: an
asknode parks the run until someone answers a question, and areviewblock parks an action node until someone decides on the arguments it is about to run with. Both are answerable from the web run page, the CLI, HTTP, UDS, and native tools, so an agent supervising a Loop never depends on the web UI to unblock it. (#427)compozy loop requestslists what is waiting,compozy loop requestreads one, andcompozy loop respondanswers it. Agents getcompozy__loop_requests,compozy__loop_request, andcompozy__loop_respond.- The run page's Needs you region presents one question at a time β a "Question 1 of N" header steps through several instead of stacking forms. The bounded redacted context preview and the node and generation that asked sit behind a closed Details disclosure.
- The answer form renders only what the daemon authorized. An ask generates its fields from the
expectschema, with enum values as choices and booleans as Yes or No; a review shows the proposed arguments with that node's own decision allowlist, so an unauthorized decision is absent rather than a disabled button. Onedit, the fields arrive pre-filled with the proposed arguments. - An answer that fails the shape comes back with the failure on the field that caused it and the request stays open. A request someone else already answered β or whose run has ended β shows the recorded outcome instead of a form.
- Each fan-out lane carries its own request, named by lane and answerable independently. The waits rail counts pending requests alongside timers and events.
# a review block on an action node review: when: inputs.environment == "production" prompt: "Review the production release" decisions: [approve, edit, reject, respond] responders: { agents: deny } on_reject: { route: repair_release }
compozy loop respond --run-id <run-id> --node publish --decision approve
Loops take one path and tell you why
A Loop graph can now pick exactly one forward path with a
routecontrol node, and a gate verdict can route the same way, instead of forcing authors to encode every choice as nested branches. Each decision is recorded durably, so an operator or an agent reads why a run went the way it did rather than inferring it. (#427)- A
routenode checks its CEL conditions in declaration order and takes the first match, falling back to a mandatorydefault. Every destination must be a unique direct forward edge. - A broken condition fails closed with
predicate_evaluation_failed; it never falls through to the default. - Gate verdicts (
pass,fail,error,timeout,invalid_output) route tocontinue,revise,next_generation,escalate,halt, or an in-body forward target written as{ route: node_id }.approvalaccepts onlyescalateorhalt, so an object route cannot slip past a pending approval. - Run status carries
generations[].route_causesβ the route node or gate, the selected forward node, the lane index, the cause, and the time. It is read from the durableroute_takenevent, so HTTP, CLI, native-tool status, and SSE replay agree.
Migration notes: the
branchgate action is removed and is now rejected at authoring time.- id: classify class: control kind: route routes: - { when: nodes.score.output.value >= 0.8, to: publish } - { when: nodes.score.output.value >= 0.5, to: revise } default: reject
Pin, rename, and bind any command
The palette learns your workspace. Pins float the commands you always want first, ranking signals push the ones you actually use, aliases give a command your own vocabulary, and any command can take a chord β including a system-wide one on the desktop app. (#441)
- Pins and recents are workspace-scoped and shared across every attached client, so a pin made in the desktop shell shows up in the browser tab.
personalization = falseturns ranking and recents off as one desired state. - An alias is 1β32 characters with no whitespace, unique in the workspace, and searchable alongside the command's title.
- Bindings, aliases, and pins are validated against the complete effective keymap. A conflict names the command that currently owns the chord or alias and stores nothing;
--overwritetransfers it as one atomic change. - The desktop shell registers global hotkeys β
meta+shift+Spacesummons CompozyOS with the palette open by default β and reports per-machine truth for each one: active, captured by another app, permission required (with a shortcut into macOS Accessibility settings), or unsupported. A browser tab shows the section disabled with the reason requires desktop shell rather than pretending. - Settings β Palette exposes the agent fallback and personalization; Settings β Layouts β Shortcuts owns the keymap, aliases, and the global section.
compozy cmd-palette pin palette.view.sessions --workspace acme compozy cmd-palette alias set session.new new --workspace acme compozy cmd-palette bind palette.view.tasks meta+shift+KeyY --workspace acme compozy cmd-palette bind palette.summon.global meta+shift+Space --global compozy cmd-palette personalization show --workspace acme -o json
[cmd_palette] personalization = true [cmd_palette.aliases] "session.new" = "new" [window_manager.global_shortcuts] "palette.summon.global" = "meta+shift+Space"
Runtime speed is part of the runtime
speedjoins provider, model, and reasoning as a first-class part of a Loop runtime selection, and reports the same value everywhere it is observed. (#438)- Speed is accepted on Loop runtime inputs, per-node runtimes, Loop defaults, and
config.tomlLoop runtime defaults, and appears in resolved provenance across CLI, HTTP, UDS, native tools, SSE, and web inspection. - The web run form reuses the existing runtime selector's Fast control rather than introducing a parallel concept, and the run inspector shows resolved provenance read-only.
- CompozyOS reports whether speed was applied or is unsupported by the chosen provider instead of inventing support it cannot deliver.
Migration notes: the session creation profile moves to v3 as a hard cut, with no v2 branch.
runtimes: worker: { provider: codex, model: gpt-5.4, reasoning: high, speed: fast } judge: { provider: claude, model: opus, speed: normal }
# the compact CLI form; "-" leaves a field unset, so speed-only intent is -/-:speed=fast compozy loop run --name release --input worker_runtime=codex/gpt-5.4@high:speed=fastThe command palette runs CompozyOS
βK (or ββ§P) opens a palette the daemon owns. Every command β shell actions, window and desktop moves, domain views, settings, and extension contributions β is registered once in the runtime and projected to every surface, so the web app, the desktop shell, the CLI, HTTP, UDS, and native tools read the same catalog with the same availability truth. (#441)
- A row is available or it is not, and the daemon says why. A command that needs an attached shell reports
requires an attached shellin the row itself instead of failing after you press Enter. - Commands that need input collect it inline as typed arguments β
text,password,dropdown,checkboxβ before anything runs. A destructive command carries its own confirmation title and confirm verb. - Execution is single-flight per command: a second invocation while one is still running returns
already_runninguntil the first reaches a terminal result, so a double Enter cannot run something twice. - A destructive command goes through the existing tool-approval path and returns
approval_pendingwith a stable approval ID.compozy approvals show|cancel <id>follows or ends it; approve runs exactly once, deny or cancel ends it with no effect. - A command that acts on a shell targets one attached client. With a single attachment it auto-selects; with several it asks for an explicit client and lists every attachment ID instead of guessing.
- βK on a selected row opens a filterable action panel anchored to that row: the runnable action plus Pin, Set alias, and Set shortcut. Unavailable rows expose only those meta-actions and the daemon's reason.
- The catalog is live. Installing an extension, changing a binding, or pinning from another window updates open palettes without a reload.
compozy cmd-palette list --available=false -o json # every command with the daemon's own reason compozy cmd-palette inspect session.new -o json # action, arguments, execution policy, risk compozy cmd-palette clients -o json # the targeting source of truth
The interface speaks plain words at a legible size
Every end-user surface moved one step up the legibility ramp and one step toward ordinary language. Body text goes from 13.5px to 15px, item titles from 15 to 16, buttons and rows get real height, the radius ladder rebases on 8, and the canvas warms up β so the interface stops asking for a magnifying glass. (#440)
- Home's first run tells the truth. Instead of seven zones filled with zeros, a fresh install shows one heading and the three starts that actually exist. A machine with an agent already running is never told nothing has happened.
- Some labels now use the word people say, while the runtime keeps its canonical noun: the dock reads Connections (bridges) and Permissions (sandbox); Settings reads Remote access (gateway), Notifications (attention), Diagnostics (observability), and groups them under Personal. The old names stay searchable.
- An alias is a label and nothing more. Code, wire payloads, CLI verbs, config keys, and generated references keep the canonical name, and the canonical noun is always one step deeper in the UI.
- "Daemon" leaves the end-user surfaces for "CompozyOS" or "this machine" across gateway, sessions, onboarding, marketplace, automation, tasks, vault, loops, and settings. Sessions get a conversation glyph instead of a terminal one.
- Small caps labels become sentence case by default, with uppercase available as an explicit variant.
- Plain language never hides the machine: install, setup, and
config.tomlstill run through a terminal, and this release makes no claim of a no-terminal path.
compozy bridge list # the dock reads "Connections" compozy gateway status # Settings reads "Remote access"
Time travel β compare, rerun, and fork a Loop run
Durable Loop history became something you can act on.
diffreads what changed,rerunopens a new generation from a settled node in the same run, andforkstarts a linked run from a historical generation without changing its source. (#427)compozy loop diff --run-id <id> --generation 1 --against-generation 2compares two generations;--against-runcompares two runs of the same Loop and marks different pinned definitions. Large values return their byte size and SHA-256 content hash instead of an oversized inline payload.compozy loop rerun --from-node verifyre-runs the selected node and its transitive dependents while unrelated settled cells carry forward;--itemaddresses one fan-out lane. The new generation has originoperator_rerun.compozy loop fork --generation 2pins the source run's executed definition: generation 1 is a settledfork_seedbaseline and generation 2 executes the body with the source inputs plus any validated overrides. Lineage is two-way β the child carriesforked_from, the source listsforks.- In the web UI, Compareβ¦ on an Inspect generation row opens a deep-linkable comparison page whose node rows group by the same
changed / rerun / skipped / carried / verdictvocabulary the CLI prints, and Fork from here pre-fills the source run's declared inputs. Two identical generations render an explicit "nothing changed" state. - Pass
--request-idto retry a rerun or fork after a transport failure: the same key with identical inputs returns the committed result, and a changed request under a reused key returnstimetravel_key_reuse. - Agents need the
loops.timetravelcapability and getcompozy__loop_diff,compozy__loop_rerun, andcompozy__loop_fork. Diff is an ordinary workspace-scoped read. An agent cannot rerun its own executing run, but it may rerun its own terminal run.
compozy loop diff --run-id <run-id> --generation 1 --against-generation 2 compozy loop rerun --run-id <run-id> --from-node verify --reason "retry verification" compozy loop fork --run-id <run-id> --generation 2 --input service=payments
Fixes
A burst of tool updates no longer drops the provider
An ACP provider can emit hundreds of state-equivalent updates for a single tool call. Those duplicates filled the active prompt's bounded event channel, stalled delivery, and disconnected an otherwise healthy provider. CompozyOS now keeps one canonical projection per tool call for the duration of the prompt. (#442, fixes #439)
- Only redundant nonterminal updates are suppressed. A new title, name, kind, input, or prechecked state still comes through, and terminal results and prompt completion keep their order.
- The projection is prompt-scoped and keyed by the current
tool_call_id; it is discarded when the prompt ends and never enters a session, workspace, or global store. - Public event shapes are unchanged β nothing about the session transcript contract moved.
- Verified against 1,100 identical in-progress updates followed by a terminal one: both the original prompt and a follow-up completed with a single call/result pair and no disconnect.
A finished Loop leaves nothing running
A completed or failed Loop run could leave live descendant work behind β including a next-generation source task sitting in
readywith no task run attached. The terminal transaction now drains every open descendant, covering ready-only tasks andneeds_attentionruns, on both normal terminal settlement and coordinator execution failure. (#438)- The public reproduction ends with zero open tasks: the run reports failed, its next-generation task is canceled, and no descendant survives.
A guarded history reference no longer crashes generation 1
A Loop that referenced
previous.*defensively still failed on its first generation, because the history namespace did not exist yet when templates were evaluated. The complete shape ofprevious.*and the generation history namespaces is now defined before evaluation, so documented guarded references validate and generation 1 runs. (#438)- History construction is topology-aware, so a node sees the namespaces its position actually implies.
- Template and materialization failures stay inside the node lifecycle instead of escalating into an opaque coordinator failure.
- Canonical compiler, linter, namespace, coordinator, and control-flow suites cover the behavior.
{{ if .previous.generation }} The prior quality gate returned {{ .previous.verdicts.quality.outcome }}. Blocking issues: {{ .previous.verdicts.quality.blocking_issues }} {{ end }}Fan-out filters actually filter
A
filteron a fan-out node was accepted at authoring time but never applied, so batching andmax_fan_outstill saw the whole candidate list. Each filter is now evaluated against the raw candidate before batching and branch limits. (#438)- The candidate
item, its originalindex, the fan-out alias, and outer fan-out aliases are all available during compilation and evaluation. - Original order and candidate indexes survive filtering.
- Zero matches is a valid zero-branch materialization, not an error.
- A predicate failure routes through the existing
on_eval_errorpolicy instead of being silently ignored.
- id: inspect_files class: control kind: fan-out collection: "{{ .nodes.changed.output.files }}" filter: "item.endsWith('.go')" # now decides what gets batched batch_size: 1 max_fan_out: 8
Four runtime regressions around prompts, permissions, and settlement
A cluster of failures where the runtime reported the wrong thing about its own state. (#447)
- Prompts stop replaying history (fixes #399). Submitting a message sent the entire persisted chat transcript to the session prompt endpoint. Only the newest user message goes now, with its original message ID and retry idempotency preserved.
- Permissions follow the live agent (fixes #415). The observer carried a duplicate permission-mode resolver instead of the resource-backed agent catalog the daemon uses. Live snapshots are built from effective permissions and cached by runtime identity and revision, so a revision change can no longer leave stale permissions in place; a stopped session's fallback snapshot stays deliberately shallow.
- A committed result survives a failed publish (fixes #435). A pre-commit lease failure and a post-commit publication failure looked identical, so an already-settled run could be failed and settled a second time. A claimed run fails only when completion returned no committed run.
- A crashed process is reported as crashed (fixes #436). A non-zero exit code or a signal is now classified as a process failure and maps to the process-exited stop cause. A clean exit with code
0after a transport failure stays on the transport path and keepserror, soagent_crashedmeans the subprocess actually died.
Managed run-agent workers keep their lineage and let go
Two lifecycle bugs in Loop
run-agentactions, both reproduced againstv0.3.0-beta.18: a managed worker lost the trail back to the session that started it, and a worker could outlive the Loop cell it belonged to. (#446, fixes #444 and #445)- A managed worker now records the nearest originating session as informational parent lineage β parent and root are readable from the session β without borrowing or hijacking that origin session.
- When a Loop cell settles successfully, the run-owned worker binding closes and durable terminal cleanup is enqueued in the same atomic step. Cancellation and terminal failure follow the same path, and cleanup cannot run twice.
- A retryable output failure keeps the same worker session active instead of orphaning it, so a retry reuses the worker and only terminal settlement ends it.
- No public API, schema, migration, or config key changed; existing Loop and session reads simply expose corrected stored state.
Recover a Loop-owned task run without losing its place
A Loop worker task run parked in
needs_attentionhad no honest way back. Generic subprocess-health escalation swallowed Loop-owned crashes, andtask run recoverre-enqueued a run that no longer belonged to its Loop. (#447, fixes #437)- A confirmed agent crash inside a Loop-owned task run stays out of the generic escalation path and projects into the Loop's own node control and event model as worker attention.
task run recovernow fails the parked source run, creates and links a child run, and rebinds it to the exact same Loop node and item with the next attempt and epoch β all atomically. Workspace, runtime selection, designation, worktree, network, capabilities, and metadata stay attached to that cell, and attention plus death-streak state is cleared.- Recovery diagnostics point where they should: a run that needs attention names
task run recover, while an active run names cancellation. - No schema, migration, or config key changed β recovery reuses the existing
wait_interventionattention flag and the existing Loop event vocabulary.
compozy task run recover <run-id> --reason "operator recovery" -o json
Removing the suggested Home folder no longer breaks the desktop
Onboarding seeded every daemon registration into the selectable project draft, including the internal operator-home registration that Global runs on. Removing the suggested Home folder deleted that registration and left a desktop where dock apps took focus but opened nothing. (#440)
- Onboarding now partitions project workspaces from the operator home, so that row can never be seeded, added, or deleted as a project.
- The fix is covered by the canonical onboarding suite, with three cases that fail against the previous behavior.
The daemon owns a managed worker's outcome
A managed Loop worker session could call complete or fail and race the daemon's own validated action result, so what a generation recorded depended on which side got there first. The daemon is now the single terminal authority for managed workers. (#438)
- A worker session may heartbeat while it holds the lease, but terminal settlement calls are denied by session lineage.
- A generation settles as succeeded only with schema-valid structured output; an invalid capture terminates as
invalid_outputinstead of passing. - The exact validated object round-trips through inline and content-addressed storage, including downstream template and CEL hydration, so a large output no longer loses required fields.
Additional notes
Open source βCompozyOS 0.3.0-beta.19 β beta Pre-release
Pre-release
Compare
Choose a tag to compare
- v0.3.0-beta.1817 Aug 2026pre-release
Release notes
Open source β0.3.0-beta.18 - 2026-08-18
π Bug Fixes
- Daemon path resolution
π§ͺ Testing
- Fix cases failing
Additional notes
Open source βCompozyOS 0.3.0-beta.18 β beta Pre-release
Pre-release
Compare
Choose a tag to compare
- v0.3.0-beta.1714 Aug 2026pre-release
Release notes
Open source β0.3.0-beta.17 - 2026-08-18
β»οΈ Refactoring
- Unify PRD and TechSpec into a single spec pipeline (#397)
π Features
- Add first-class worktree support (#388)
- Close the loops UI visual-contract parity gap (#406)
- Unify zero-inventory empty states for jobs, triggers, and tasks (#409)
- Redesign workspaces overview as command-tab switcher (#410)
- Redesign trigger detail into the When/If/Then rule page (#411)
- Session attachments β paste, drop, and picker to multimodal agents end to end (#412)
- Add Agent Plugins ingestion to extensions (#419)
- Add session attention and orchestration parity (#422)
- Replace Tauri with Electron and unify updates (#424)
π Bug Fixes
- Guard autonomous memory extractor writes (#396)
- Write $ENV interpolation in pi runtime models.json apiKey (#404)
- Authorize daemon-owned loop effects (#407)
- Retain terminal loop effect results in web (#408)
- Bound desktop runtime health checks (#414)
- Preserve loop goal session lineage (#420)
- Support resource-only extension development (#423)
π§ͺ Testing
- Preserve loop claim tokens in daemon fixtures (#418)
Release Notes
Breaking Changes
The desktop app is now Electron
The Tauri/Rust desktop host is replaced by an Electron shell with a narrow preload boundary, and updating became one durable daemon-owned operation exposed identically through the CLI, HTTP, UDS, Settings, and the menubar. The app provisions the bundled daemon from an empty home, or attaches to a compatible daemon that is already running without taking ownership of it, keeping single-instance focus, deep links, safe navigation boundaries, page zoom, window geometry recovery, diagnostics, logs, and the owned-versus-attached quit contract. (#424)
- Runtime and App are separate update tracks with operation progress, holder-aware blocked state, staged-next-launch state, apply and cancel actions, and truthful absence when a track is unsupported.
- A keyboard-accessible menubar indicator appears only when an update is actionable and navigates to Settings. The renderer holds no desktop-only update authority, and the SPA behaves the same in a browser and in the app.
- Desktop artifacts are planned, inventoried, and channel-checked as one release authority, with notarization and signing input checks and packaged smokes provisioned from empty isolated homes. On macOS the ZIP and on Linux the AppImage are the updater artifacts; DMG and DEB are install artifacts only.
Migration notes: this is a hard cut with no compatibility bridge. The Tauri runtime, commands, permissions, capabilities, fixtures, generated bindings, Cargo dependencies, build configuration, scripts, config keys, docs, and tests are deleted rather than deprecated. Install the app from the artifacts published with this release. The installed-app update walk from one beta to the next was not verified for this build, so the App track must be proven by a release owner across a fresh beta pair before it is treated as delivered.
Features
Agent Plugins install as extensions
CompozyOS ingests Agent Plugins 1.0.0 packages as extensions with no Compozy-specific manifest. A portable plugin contributes skills plus local or remote MCP servers while keeping the existing extension lifecycle, trust, isolation, diagnostics, Marketplace, CLI, HTTP, UDS, native-tool, and Web management surfaces. (#419)
- Manifest discovery and validation are strict: fixed-location skills and MCP configuration, closed schemas, deterministic diagnostics, native-manifest precedence, and safe rejection of unsupported components.
- Portable skills and stdio or streamable-HTTP MCP servers are synthesized into the canonical extension model, with absolute
PLUGIN_ROOTandPLUGIN_DATAexpansion, single-token stdio commands, package-root working directories, remote-header bindings, URL policy, and secret redaction.
Migration notes: end-to-end delivery is claimed only for the provider paths proven end to end, Claude Code and Hermes. OpenClaw's current ACP bridge advertises
session_mcp=false, so CompozyOS fails closed instead of pretending to deliver session MCP servers.Attention: know which session needs you
CompozyOS has one daemon-owned attention model. Pending input, permission requests, finished-unseen sessions, operator presence, notification delivery, and cross-workspace session discovery are runtime state instead of per-surface guesses. Orchestrator agents get structured wait, spawn, stop, approve, clarify-answer, prompt-cancel, and notify controls across native tools, CLI, HTTP, and UDS, so an agent supervising other agents no longer polls a shell or depends on the web UI to act. (#422)
- The global catalog persists canonical attention revisions, pending interactions, seen and settled state, and cursor-stable attention ordering.
- Presence leases, attention summaries and events, sanitized interaction discovery, generalized waits, prompt cancellation, operator notifications, and session wake propagation are available on every transport, with deterministic CLI exit behavior.
- Desktop shortcuts moved to a daemon-owned, configurable keymap, and the command palette gained nested views including an attention-first Sessions view.
First-class Git worktrees
Git worktrees are runtime objects across the daemon, Web desktop, CLI, HTTP and UDS, native tools, extensions, configuration, generated contracts, and documentation: create, adopt, discover, inspect, reconcile, dismiss, and safely remove isolated checkouts. Sessions, Task runs, fan-out workers, and Loop environments bind to an exact worktree without losing the parent workspace's config, skills, agents, or memory. (#388, #410)
- The new worktree domain owns Git capability detection, canonical repository identity, naming and placement, per-repository mutation locking, and durable lifecycle state.
- Creation is a phased
pending β readyoperation with recorded ownership checkpoints, bootstrap copy and setup support, cancel-safe rollback, and boot recovery. - Adoption verifies the linked checkout, the common Git directory, main-checkout exclusion, and repository identity before registering it. Discovery merges Git-known checkouts with durable records without turning a discovered row into an adopted worktree.
- Removal fences the record as removing, rechecks session activity and Git safety under the repository lock, preserves branches and history, and requires an explicit second step for dirty or unique-unpushed work.
- Finishing work runs through a truthful assisted-exit ladder for commit, push, pull request, merged evidence, and cleanup. Dismissed tombstones release their reserved name, exit actions resolve caller references to canonical record ids, and CLI mutation output keeps worktree identity.
Loops UI and empty catalogs match their design contract
Every Loops surface adopts the approved visual contract's locked review decisions, collapse and section grammar, icon budget, and truthfulness rules, rendering only daemon-backed data and adding no helper copy. Jobs, Triggers, and Tasks share one zero-inventory empty state with the same composition, density, and icon grammar. (#406, #409)
- Automation suggestions and task templates are empty-state affordances again: they render only in the unfiltered zero-inventory state instead of sitting above a populated Jobs catalog.
- The three catalogs compose the same components and differ only in icon, title, support line, action, and panel content.
Session attachments: paste, drop, or pick
The session composer accepts images (PNG, JPEG, WebP) and files (PDF, Markdown, plain text) by paste, drag-and-drop, or file picker. Attachments persist before the prompt is accepted, ride the prompt as provider-neutral references, and reach multimodal agents as protocol-conformant ACP content blocks gated by the capabilities that agent negotiated at initialization. Saving a screenshot to disk and describing its path is no longer the workaround. (#412)
- The daemon keeps the agent's prompt capabilities from the initialize handshake instead of discarding them, so unsupported content is refused in place rather than sent to an agent that never advertised it.
- Attachments render durably in the transcript across reload, live streaming, recap, and archive, and they are deleted with their session.
- The capability gate lives inside the composer's attachment strip. Steering a running prompt stays text-only.
The workspace switcher works like Command-Tab
The fullscreen workspaces overview is rebuilt as a Command-Tab style switcher over the live shell: a glass tile strip, a frosted focus plate, an identity caption, an always-visible vertical worktree menu, a full keyboard model, and a registered
β§βWshortcut. It switches workspace identity only; window arrangements stay with the Desktops overview. (#410)Migration notes: the previous 264 px dossier grid, with its member stacks, path footers, and "Enter β" row, is deleted rather than kept behind a flag.
Trigger detail is a rule page
A trigger now reads as the rule it is, not as a job inspector with the cron stripped out: a plain-language sentence of what the trigger does, a labeled Enable switch opposite it as the only accent on the page, one When / If / Then card, a single-open Recent-runs accordion, a four-card rail, and an Inspect sheet for runtime internals. (#411)
Migration notes: the shared automation detail panel is jobs-only again, and triggers render through their own component family.
Fixes
Autonomous extraction stays out of curated memory
The autonomous memory extractor could write operational chatter into curated memory, and a generated slug collision could overwrite an unrelated entry. The deterministic scanner now rejects Memory v2 operational identifiers β
memory_propose, nativecompozy__memory_*tool names, controller event names, and scanner rule IDs β and extractor, provider, and dreaming candidates no longer update an existing memory solely because their generated slug collides. Explicit filename-collision updates from direct CLI or user writes keep working. (#396)Loop runs keep their lineage, permissions, and results
Three Loop defects that broke supervision of long runs are fixed. (#420, #407, #408)
- Loop-owned Goal sessions retain the trusted provenance of the session that started the current or nearest ancestor Loop Run, so session catalogs and the Web group Goal work below its originating session. The relationship stays informational: Goal sessions remain
type=systemwith no inherited TTL, auto-stop, spawn budget, or permission narrowing, provenance is derived server-side within the same workspace, and spawn limits still count only contiguous spawned ancestry. (#420) - Daemon-owned terminal tool effects are authorized correctly. The native policy path treated the synthetic
loop-effectaudit label as an authored workspace agent and failed the lookup before the declared tool could run. The trusted daemon actor kind is now preserved through policy resolution, the label survives for attribution, and workspace policy still denies foreign targets. (#407) - Terminal effect results stay visible in run details. The Web hook closed its event stream as soon as it received the terminal status, so a later retained or live effect-results frame never reached the run timeline, and reloading repeated the race. Successful and denied effect results now arrive in order while replacement, deactivation, navigation, and unmount keep the normal cleanup path. (#408)
Pi providers receive the secret, not its variable name
CompozyOS wrote a Pi credential slot's target environment name, such as
ZAI_API_KEY, straight into the sessionmodels.jsonapiKeyfield. Pi reads a bare uppercase value as a literal API key, so the provider received the variable name instead of the secret, the upstream request failed, and the session could finish without an assistant message. The Pi runtime now writes$ZAI_API_KEY-style references, which Pi resolves from the secret CompozyOS already injects into the provider process. (#404)Migration notes: this covers the built-in
pi_acpbound-secret providers β z.ai, OpenRouter, Moonshot/Kimi, xAI, MiniMax, Mistral, Groq, and Vercel AI Gateway.Resource-only extensions need no toolchain
An extension that ships only declared resources β agents, skills, Loops, automations, layouts β can now use
build,dev,reload, anddev --watchwithout installing a Go or TypeScript toolchain. The passive build path validates and publishes those resources without running build or describe subprocesses, and active development links project them into the linked workspace while preserving deterministic generations, atomic reload, and last-good fallback. The Go and TypeScript paths are unchanged, and the resource-only path fails closed. (#423)The desktop stays responsive with a large session catalog
Long-running sessions with a large internal session catalog put the macOS desktop into a request-and-reload feedback loop that made it unusable. The two-second liveness probe now targets a bounded
GET /api/status/identitysurface over HTTP and UDS instead of the full status aggregate, and internal sessions stop inflating the public catalog. (#414)- Memory-extractor, auto-title, and dream sessions no longer publish wake events to the public session catalog.
- Built-in background agents, including
dreaming-curator, resolve through effective workspace configuration instead of being reported as missing workspace-authored agents. - The identity contract ships in OpenAPI and the generated TypeScript types.
Additional notes
Open source βCompozyOS 0.3.0-beta.17 β beta Pre-release
Pre-release
Compare
Choose a tag to compare
- v0.3.0-beta.16.0.20260817011222-5c5789e35f6d17 Aug 2026pre-release
Nothing published for this version
- v0.3.0-beta.16.0.20260815213455-1c6f5d9ec4e015 Aug 2026pre-release
Nothing published for this version
- v0.3.0-beta.16.0.20260815042039-a35eda6d3a2e15 Aug 2026pre-release
Nothing published for this version
- v0.3.0-beta.16.0.20260815011917-d5ff80056f5515 Aug 2026pre-release
Nothing published for this version
- v0.3.0-beta.16.0.20260814235430-818455a8ba4b14 Aug 2026pre-release
Nothing published for this version
- v0.3.0-beta.16.0.20260814214124-6fb2afe0802514 Aug 2026pre-release
Nothing published for this version
- v0.3.0-beta.16.0.20260814002849-598ed807c1b414 Aug 2026pre-release
Nothing published for this version
- v0.3.0-beta.16.0.20260813235425-288719529ed613 Aug 2026pre-release
Nothing published for this version
- v0.3.0-beta.1613 Aug 2026pre-release
Release notes
Open source β0.3.0-beta.16 - 2026-08-14
β»οΈ Refactoring
- Add global workspace toggle (#368)
π Bug Fixes
- Harden desktop startup and diagnostics (#343)
- Resolve desktop and session usability issues (#351)
- Recover canceled Loop coordinators on restart (#353)
- Resolve extension-published agents for session command catalogs (#350)
- Eliminate persistent performance bottlenecks (#354)
- Reject automation trigger events no producer emits (#358)
- Read loop watch-events with a stream-global cursor (#356)
- Prevent session timeline render loops (#361)
- Align update artifacts with release policy (#363)
- Canonicalize desktop runtime manifests (#364)
- Validate desktop bundles before release
- Make release publication atomic
- Defer npm publication safely
- Harden release recovery
- Isolate release publishers
- Make release artifacts reproducible
- Align release automation contracts
- Reject invalid agent names (#367)
- Resolve extension agent skills and missing config paths (#372)
- Include extension tools in hosted MCP bootstrap (#373)
- Use conventional release triggers
- Resolve main lint regressions
- Parse nanosecond daemon timestamps
- Validate release workflow tools by type
- Preserve awaited child loop state (#391)
- Use exact Cursor ACP model values (#392)
- Preserve dead session history (#393)
- Validate desktop release smoke wiring
- Validate public CLI version command
- Clarify missing config path errors (#401)
π§ͺ Testing
- Align dead session recovery coverage
Additional notes
Open source βCompozyOS 0.3.0-beta.16 β beta Pre-release
Pre-release
Compare
Choose a tag to compare
- v0.3.0-beta.15.0.20260813171917-f0def437cb0313 Aug 2026pre-release
Nothing published for this version
- v0.3.0-beta.1513 Aug 2026pre-release
Nothing published for this version
- v0.3.0-beta.14.0.20260814015722-d87bfc40effd14 Aug 2026pre-release
Nothing published for this version
- v0.3.0-beta.14.0.20260814002849-598ed807c1b414 Aug 2026pre-release
Nothing published for this version
- v0.3.0-beta.14.0.20260813133702-887e6ee6097713 Aug 2026pre-release
Nothing published for this version
- v0.3.0-beta.1413 Aug 2026pre-release
Release notes
Open source βCo-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
- v0.3.0-beta.13.0.20260812203742-26f7b488cd0912 Aug 2026pre-release
Nothing published for this version
- v0.3.0-beta.13.0.20260812160655-714b7347ba8912 Aug 2026pre-release
Nothing published for this version
- v0.3.0-beta.1311 Aug 2026pre-release
Release notes
Open source β0.3.0-beta.13 - 2026-08-11
π Bug Fixes
- Publish staged GitHub release drafts
- Repair release integration contracts
Additional notes
Open source βCompozyOS 0.3.0-beta.13 β beta Pre-release
Pre-release
Compare
Choose a tag to compare
- v0.3.0-beta.12.0.20260811051847-9ddda07f162111 Aug 2026pre-release
Nothing published for this version
- v0.3.0-beta.1211 Aug 2026pre-release
Release notes
Open source βCompozyOS 0.3.0-beta.12 β beta Pre-release
Pre-release
Compare
Choose a tag to compare
- v0.3.0-beta.11.0.20260811035656-cc4ae610445311 Aug 2026pre-release
Nothing published for this version
- v0.3.0-beta.11.0.20260811022412-623fe9b42e6c11 Aug 2026pre-release
Nothing published for this version
- v0.3.0-beta.1111 Aug 2026pre-release
Nothing published for this version
- v0.3.0-beta.10.0.20260811022412-623fe9b42e6c11 Aug 2026pre-release
Nothing published for this version
- v0.3.0-beta.1010 Aug 2026pre-release
Nothing published for this version
- v0.3.0-beta.9.0.20260811004838-2faedf5094c811 Aug 2026pre-release
Nothing published for this version
- v0.3.0-beta.910 Aug 2026pre-release
Nothing published for this version
- v0.3.0-beta.810 Aug 2026pre-release
Release notes
Open source βCompozyOS 0.3.0-beta.8 β beta Pre-release
Pre-release
Compare
Choose a tag to compare
- v0.3.0-beta.78 Aug 2026pre-release
Release notes
Open source βCompozyOS 0.3.0-beta.7 β beta Pre-release
Pre-release
Compare
Choose a tag to compare
- v0.3.0-beta.67 Aug 2026pre-release
Release notes
Open source βCompozyOS 0.3.0-beta.6 β beta Pre-release
Pre-release
Compare
Choose a tag to compare
- v0.3.0-beta.5.0.20260805192115-b07086a94edf5 Aug 2026pre-release
Nothing published for this version
- v0.3.0-beta.55 Aug 2026pre-release
Nothing published for this version
- v0.3.0-beta.4.0.20260805000713-7e630c6025b05 Aug 2026pre-release
Nothing published for this version
- v0.3.0-beta.44 Aug 2026pre-release
Nothing published for this version
- v0.3.0-beta.3.0.20260801175133-226137ec68ce1 Aug 2026pre-release
Nothing published for this version
- v0.3.0-beta.31 Aug 2026pre-release
Nothing published for this version
- v0.3.0-beta.2.0.20260729210752-854fa2d3611f29 Jul 2026pre-release
Nothing published for this version
- v0.3.0-beta.2.0.20260729183252-c36e31b3014329 Jul 2026pre-release
Nothing published for this version
- v0.3.0-beta.2.0.20260729153638-cab82e4353ea29 Jul 2026pre-release
Nothing published for this version
- v0.3.0-beta.2.0.20260729145554-49ffbce20b4e29 Jul 2026pre-release
Nothing published for this version
- v0.3.0-beta.2.0.20260729040417-3bccc48808e529 Jul 2026pre-release
Nothing published for this version
- v0.3.0-beta.2.0.20260729032543-29dad495ecc129 Jul 2026pre-release
Nothing published for this version
- v0.3.0-beta.229 Jul 2026pre-release
Nothing published for this version
- v0.3.0-beta.128 Jul 2026pre-release
Nothing published for this version
- v0.2.16-0.20260728051713-fc9c1d14e6b328 Jul 2026pre-release
Nothing published for this version
- v0.2.1517 Jul 2026
Release notes
Open source βπ Features
- Cy-capture-decisions β skill-only extension for durable decision capture (#237)
π Bug Fixes
- Recover stalled and wedged multi-runs (#230)
- Share parallel task status enum (#241)
- Surface progress and bound the reviews-fix daemon start (#236)
- Package cy-qa-workflow as a module and make host.tasks.create v2-aware (#234)
- Correct Kiro CLI ACP model handling (#226)
- Isolate sync tests and clarify ignore checks (#248)
- Isolate task artifacts and add complexity runtime defaults (#250)
Additional notes
Open source βπ Features
- Cy-capture-decisions β skill-only extension for durable decision capture (#237)
π Bug Fixes
- Recover stalled and wedged multi-runs (#230)- Share parallel task status enum (#241)- Surface progress and bound the reviews-fix daemon start (#236)- Package cy-qa-workflow as a module and make host.tasks.create v2-aware (#234)- Correct Kiro CLI ACP model handling (#226)- Isolate sync tests and clarify ignore checks (#248)- Isolate task artifacts and add complexity runtime defaults (#250)
π Documentation
- Add v0.2.15 release highlights
- v0.2.1415 Jul 2026
- v0.2.1310 Jul 2026
- v0.2.1210 Jul 2026
- v0.2.113 Jul 2026
Release notes
Open source βπ Features
- Agentic runs (#212)
- Simplify repo-level default setup overrides (#90)
- Support COMPOZY_HOME env override for home directory (#216)
π Bug Fixes
- Parallel execution (#217)
- Specifying the model on ACP (#215)
- Worktree management (#223)
- Restore run TUI elapsed timer across retry, failure, cancel, and remote paths (#221)
Additional notes
Open source βπ Features
- Agentic runs (#212)- Simplify repo-level default setup overrides (#90)- Support COMPOZY_HOME env override for home directory (#216)
π Bug Fixes
- Parallel execution (#217)- Specifying the model on ACP (#215)- Worktree management (#223)- Restore run TUI elapsed timer across retry, failure, cancel, and remote paths (#221)
π Documentation
- Update skills- Add v0.2.11 release notes
- v0.2.11-0.20260702034248-73ced7f4881b2 Jul 2026pre-release
Nothing published for this version
- v0.2.1018 Jun 2026
Release notes
Open source ββ»οΈ Refactoring
- Tui redesign (#201)
π Features
- Worktree-backed parallel multi-run for tasks run --multiple (#200)
- Add Devin CLI agent support (#204)
π Bug Fixes
- Reviews watch bug
Additional notes
Open source ββ»οΈ Refactoring
- Tui redesign (#201)
π Features
- Worktree-backed parallel multi-run for tasks run --multiple (#200)- Add Devin CLI agent support (#204)
π Bug Fixes
- Reviews watch bug
π Documentation
- Release notes
π¦ Build System
- Skeeper config (#206)- Converge skeeper sidecar lock to main branch