Skip to content

chore: version packages - #1285

Open
github-actions[bot] wants to merge 1 commit into
mainfrom
changeset-release/main
Open

chore: version packages#1285
github-actions[bot] wants to merge 1 commit into
mainfrom
changeset-release/main

Conversation

@github-actions

@github-actions github-actions Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.

Releases

@gemstack/the-framework@1.5.0

Minor Changes

  • 03260d9: feat(framework): context fragment lists BUSINESS_LOGIC.md (Update Context prompt fragment #683)

    The updated Update Context prompt fragment #683 OP adds BUSINESS_LOGIC.md (codebase business logic) to the project context files. CONTEXT_DOCS now lists it beside GOAL.md, so every run is told to read it. A read-only pointer, like GOAL.md and tickets/, so it stays out of the merge-update set: the on-before-mergeable prompt keeps naming exactly the three knowledge-base/ writeback docs.

  • 660adf2: Resuming a stopped build run continues it as a build run (Resuming a stopped build run downgrades it to a prompt run: backlog offer skipped, merge disarmed, draft PR #1467): the run's meta now records the flow it started under (RunMeta.kind), and a --continue-run continuation of a build run re-enters the build flow — the conversation resumes with the message sent verbatim (no re-framing, per --resume-session is silently ignored on a build run #782), while the synthesize framing, the backlog loop and the build ending all run again. Prompt-run continuations and runs recorded before the field keep the direct prompt path unchanged. The continuation also keeps the run's original label instead of being renamed to the resume message.

  • 6a1e75d: The ticket lock is now the .lock.md file the ticketing format defines (Improve lock mechanism #1420), replacing the PENDING placeholder mechanism: the daemon claims a ticket by writing and pushing tickets/<STEM>.lock.md (CLAIMED: <AGENT_ID>) before the agent starts, the fanned-out agent deletes the lock in the same commit as its plan, and the 6-hour staleness release is gone — a lock stands until the work lands or a human lifts it with the dashboard's new Release-lock button (sendReleaseTicketLock). Tickets show a "claimed" badge with the holder while locked.

  • 31da5d7: The routine now closes the loop on quick wins by itself. Bringing tickets across from GitHub joins the rotation, so a new issue becomes a ticket without anyone pressing the button; [Spike & plan] covers every ticket that has no plan yet and ends each one with its own verdict (Effort: and Consensus: keys in the plan's header); and a plan that calls its ticket a consensual quick-win is put on TODO_AGENTS.md by the daemon, under its own priority heading, for the drain to implement. No agent turn is spent re-deciding what the plan already decided. The verdict fails closed: a plan that says nothing, or says something unrecognized, is left for a human.

    Also fixes the ticket priority mapping, which read only the ticket format's words (urgent/high/low) while every real ticket writes a number, so a queued ticket landed at the default priority 5 whatever it said.

  • a0594fe: planned-quick-wins.ts is removed (Improve lock mechanism #1420 discussion): it parsed the pre-Improve lock mechanism #1420 Effort: quick-win / Consensus: consensual plan keys, which the 0-10 format never produces, so it promoted nothing. Quick-win promotion stays a separate task, as the catalog already has it: the [Triage quick] rotation preset picks and queues quick wins, now informed by plans' Effort/Uncertainty. The promotePlans auto-PM seam is gone with it.

  • e733e47: The built-in production-grade checklist is gone (Remove the built-in production-grade checklist gate (black-box principle) — and the set-scope machinery that existed to skip it #1372): a run with no domain preset and no --serve config now ends when the build turn ends — no app-wide review re-prompts, no { blockers } outcome gate looping after the work is done. The principle (agreed on Discord 2026-07-29): the wrapped agent is a clever black box; The Framework doesn't babysit it or tell it "make it production-grade" — quality prompts layered on top can conflict with the agent's own system prompt, and improving the agent is its vendor's job. Reviews still run where the user asked for them: a domain preset's loop drives the checklist as before, and the boot-and-serve gate still mechanically verifies the app runs. A preset with no loop for the build event now reviews nothing instead of falling back to the removed built-in checklist.

    The set-scope signal goes with it: the protocol section, parseScopeVerdict, the scope-verdict event, and the run's small-scope skip existed only to spare trivial runs from that review (Every run pays the production-grade checklist, however trivial the prompt: scope is hardcoded to 'full' #1356/feat: a build that declares small scope skips the production-grade checklist (#1356) #1358), and with no default gate there is nothing to skip. extendPrompt no longer asks for the verdict.

    Two seams moved to keep behavior honest: the budget/quota/decline controls used to be observed by the review phase after the build — with that phase gone the build step and the run now check the abort signal themselves, so a stopped run still ends as stopped instead of settling as done; and the CLI/terminal/dashboard now say plain "done" for a run that configured no review, instead of the misleading "prototype ready".

    Removed exports: PRODUCTION_GRADE_PROMPT, driverChecklist, MISSING_VERDICT_BLOCKER, parseScopeVerdict, ScopeVerdict, the scope-verdict FrameworkEvent, and domainLoopChecklist's fallback option.

  • 5206058: Record the model on the run (Record the model on the run's meta #1438): each leg's session event carries the model id the driver was started with, folded onto RunMeta.model and sessionInfo() (latest leg wins — a continuation may run a different model), shown in the transcript's session line and the run page's session-details strip.

  • a4b519d: Sessions end themselves, and Stop becomes a pause (Sessions don't end themselves: finished work waits for a human to press Stop #1390/Split Stop into distinct actions: pause/resume, cancel, and finish #1391).

    A finished session no longer parks on the human. Once the work and the backlog gate settle, the chat phase drains any message that already arrived and then the run ends at its own natural end — handoff included, so an armed merge fires there (still gated on the agent's ready-for-merge signal, Which session endings run the auto handoff (push / PR / merge)? The verified matrix — and whether Stop-at-a-gate skipping it is the design we want #1363). The "waiting" limbo (settled event) is no longer emitted; the pill flips to done when the session actually ends. A follow-up message reopens the conversation via --resume, exactly like Claude Code web — the composer already did this for ended runs (Resuming a stopped run starts a new run instead of continuing it, and the resume often fails #762). A run whose own terminal dashboard is the only surface keeps the old stay-open park (stayOpenChat), since it has no daemon to resume through.

    Stop keeps its name and icon but is now a pause: it kills the current turn, publishes nothing, and the session stays resumable from the composer — cancel is just a pause never resumed.

    Merge is the second session action (Split Stop into distinct actions: pause/resume, cancel, and finish #1391). On a live run, the ⋮ menu's "Merge when finished" appends a merge control entry: the run arms the full publish ladder and records the human authorization, which the merge gate honors instead of demanding the agent's signal — the session still merges at its own end, and a parked backlog offer resolves to "stop" so one click suffices. On an ended run with an open unmerged PR — the withheld-merge ending, where the agent never signalled and a draft PR was left behind — the action bar's "Merge PR" button merges it directly (sendMergemergeSessionPr), marking the draft ready on the way.

  • 0ce58a3: The settle moment now follows the Unclear UX: what should I do now? #1173 maintainer decisions to the end. A branch with no diff never offers Open PR — GitHub would refuse it with "No commits between main and <branch>" — and when the session left work uncommitted, that work is named right in the bar (Nothing committed — index.html left uncommitted.), with the full list behind the bar's disclosure. The handoff read now carries the pending paths (RunHandoff.pendingFiles) instead of a bare count to make that possible. Unattended runs keep committing their work automatically on the way out, so for them the guard is a rare sight; an attended session parked in the chat can be told to commit right below the message.

    The push setting the launcher gear no longer shows (one Open PR row since fix(dashboard): stop offering a PR that cannot be opened, and make the queue readable (#1164, #1173) #1181) is now really available where the thread said it stays: the-framework.yml accepts autoPushBranch and autoOpenPr beside the other booleans, resolving through the usual layers (flag > yml > default on), narrated like the rest, and feeding the launcher's repo tier. The CLI pair became tri-state to let the file decide when the run says nothing. The postponed Auto commit / Auto push settings split is deliberately not added.

  • 7b903ce: The launcher now warns before a Claude web run on a project Claude Code has not been trusted in (Web runs: ask for Claude Code folder trust in the dashboard instead of sending the user to the CLI #1318): the run would die on the CLI's interactive trust dialog (claude-web: every run fails with 'no cloud session was created' when the project root is not trusted by Claude Code #1314), so the dashboard says so up front and names the one-time fix, instead of the user discovering it through dead runs

Patch Changes

  • 1a018d0: A --run-on actions run that cannot start now fails instead of hanging forever as running. Missing a GitHub origin remote or a GH_TOKEN is caught before the driver starts, but that check sits after run.json has been written and before settleRun owns the run, so giving up there left the status at running with nobody to correct it — and the control tail the run had already wired kept the process alive, so it never exited either. From the dashboard that was a session stuck on "running" forever, with the real reason sitting unread in stderr.log. Both halves are fixed: the abort records an end event carrying the reason and releases the run's handles, and followFile's unref option now covers the fs.watch handle as well as the poll timer, so opting out of holding the process open actually does.

  • 288fa63: An Actions run now falls back to the gh CLI's credential when GH_TOKEN is unset. The framework already opens every one of its PRs through the authenticated gh CLI, but --run-on actions demanded a raw environment variable and failed the run without it — so a machine that could open a PR still could not run a single Actions session, with the credential sitting one gh auth token away. The environment variables stay the override, since CI sets them and must beat whatever gh is logged in as on the runner. When there is no token to be had either way, the run says both ways to fix it and which process needs it: the daemon hands each run its own environment, so exporting the variable in a shell does nothing for a daemon that is already up.

  • a16e72f: An armed auto-merge (Auto-merge #1216) now opens its PR ready instead of draft — GitHub refuses to merge drafts, so the merge half always reported failure. A draft found on the already-open path is marked ready and retried.

  • fbf47c1: New Auto-merge setting (Auto-merge #1216), default off: a session armed for it merges the PR its handoff opens — GitHub auto-merge where the repo allows it, so the PR lands when its checks pass, else merged directly. Reachable as the autoMerge preference (launcher row, per-project overridable), the the-framework.yml key, and the --auto-merge/--no-auto-merge flags. The routine's [Drain queue] job turns it on for its own runs: what it implements was already triaged as consensual quick-win work, so its PRs land themselves and the Goal: let TF fully *autonomously* work on quick-wins #1334 loop closes without a human pressing merge.

  • a3a49bb: The launcher warns when the merge rung is armed on a repo with GitHub auto-merge disabled (UX when GH auto-merge is disabled #1417): the armed merge silently degrades to an immediate direct merge — the PR lands before CI has run (Auto-merge lands before CI runs: repo lacks native auto-merge + a required build check #1406) — so the warning says so before the session is spent and names the fix (enable "Allow auto-merge" in the repo settings + mark a check as required). Never a block. Backed by a new cached gh api repos/{owner}/{repo} read of allow_auto_merge (ghRepoAutoMerge / onRepoAutoMerge); "gh could not say" renders nothing rather than crying wolf.

  • 901ea0a: The auto-merge-disabled warning (UX when GH auto-merge is disabled #1417) can actually render now: its repo probe used gh repo view --json autoMergeAllowed, a field repo view has never had, so the probe always errored into "could not say" and the warning never showed anywhere. The probe is now gh api repos/{owner}/{repo} reading allow_auto_merge; a viewer without push access gets the field omitted, which stays "could not say".

  • 57f4047: A run that produced nothing beyond the framework's own bookkeeping no longer pushes a branch or opens a PR. Every run's branch carries the framework's paper trail (the conversation record swept in by the pre-work commit), and that one commit used to defeat the handoff's emptiness check, so a run that did no work still published a PR of pure bookkeeping. The changed files now decide: a branch whose every change is under .the-framework/ is empty, so the auto-handoff skips it, the Open PR button refuses it, and the panel says the session produced nothing. The bookkeeping itself stays committed; it just no longer counts as work.

  • a0c9db9: A daemon-spawned run no longer dies silently while a choice gate waits for its answer (A daemon run dies silently at the backlog gate: the question outlives the process, and picks are read by nobody #1359). The run had nothing holding the Node event loop at a parked gate — spawned detached with all stdio ignored and --no-dashboard, a driver child per prompt, and a deliberately unref'd control watcher — so the moment requestChoice parked a bare Promise between turns, Node ran out of scheduled work and exited 0 mid-await: no end event, empty stderr, and every pick appended to control.jsonl read by nobody. A gate keepalive (a ref'd idle interval that exists only while a gate or chat wait is parked) now holds the process until the pick arrives or the run is stopped; the watcher itself stays unref'd. And a run that still dies holding a gate no longer asks its question forever: every path that flips a dead running run to stopped writes the end event the process never did (folded through the meta so pendingChoice clears), and the dashboard expires all open gates when a run's end streams in.

  • e60b51a: The CI watch re-arms a failed merge attempt when the PR's head changes (fix CI watch never retries a watched PR's merge after one failed attempt #1484): attemptedMerges is now keyed by head sha, so a watched PR that arrived unmergeable (a stale-branch bookkeeping conflict, say) gets exactly one more attempt once the conflict is resolved and its checks rerun — instead of being skipped for the daemon's lifetime.

  • e72d0dd: A web run's meta now records the cloud session's real URL instead of the generic claude.ai/code entry point (Web run meta keeps the generic claude.ai/code link instead of the session's real URL #1317): the cloud hand-off's result event carries the session link, and the session-update prefers a driver-supplied URL over the --session-link template

  • 2908683: claude-web runs that die on the Claude Code folder-trust dialog now fail with the one-time fix (trust the project root once; run worktrees inherit it) instead of the raw dialog text, and the notice no longer points at the ephemeral worktree path (claude-web: every run fails with 'no cloud session was created' when the project root is not trusted by Claude Code #1314)

  • 7bfba05: Queue claims now see other machines (Queue claims are per-machine: two daemons draining the same queue double-assign an entry #1313): an entry is also claimed when any open PR's TODO_AGENTS.md diff retires it (checked off or removed), so two daemons or a cloud session draining the same queue no longer double-assign an entry whose work is already in an open PR

  • 80d3b2c: A run against an existing codebase no longer opens by telling the agent how to behave (Remove ugly babysitting #1224). The prompt carried four lines of rules (do not re-scaffold or rebuild, do not swap the stack, read the existing code first, make the smallest coherent set of changes) that describe how any capable agent already works. What it cannot infer is that this workspace already holds a project, and that is the first line, so the framing that Support running against an existing project (not just from-scratch) #185 added survives while the instruction not to infantilize it does not.

  • 6b64d67: A run whose child dies at boot no longer shows "Waiting for the session to start" forever. Runs spawn detached with their stdio dropped, so a child that crashed before opening its run store (a dangling workspace link was the observed case) died invisibly: no run.json, no log line, a session page polling for a start that already failed. The daemon's exit handler now writes the minimal failed meta the page needs, dated by the run id, and the child's stderr is captured to a file in its checkout so the run log can quote the actual boot error. A child that wrote its own lifecycle is left alone, and the existing retention rules then keep the failed checkout for inspection.

  • 7ed6031: The launcher warns when a PR/merge rung is armed and gh cannot deliver it (UX when $ gh not available #1419): the handoff publishes through the GitHub CLI, so a missing or logged-out gh used to surface hours later as publishing that silently stopped at the pushed branch. The Preflight the agent CLI before starting a run: missing or logged-out claude/codex fails with zero signal #1326 preflight gains a publish half probing gh --version and gh auth status — warnings that name the fix (brew install gh / cli.github.com, gh auth login), never blocks: the session's own work needs no gh and the push rung is plain git. Probed only while a PR/merge rung is armed on a local run.

  • 11beec4: The per-run quota guard now honors the Usage panel's spend slider when it loosens the gate (fix Per-run quota guard ignores the Usage slider (autoSpendOffset): runs pause while the bar shows room #1490): the line a run pauses at is max(default half-day cushion, autoSpendOffset), read fresh around each between-turns check so dragging the slider unblocks a parked run without a restart. Before, the guard hard-coded the default cushion and a run paused on a window the Usage bar showed as having room — the exact bar/gate disagreement <Quota> component #960 forbids. The slider still never tightens the gate on work the user asked for.

  • 4690f03: The armed-handoff line now owns the merge half (Run header and handoff-armed hide merge arming: header says "draft PR" on a run configured to auto-merge #1382). A run launched with auto-merge advertised "when this ends: push the branch and open a draft PR" and then opened a ready PR and merged it to main unattended — the most consequential thing a run can do was the one thing the line didn't say. The handoff-armed event and the run record's handoff mirror now carry the merge arming (display-only; the merge itself still fires off the run's own config, Auto-merge #1216), the transcript line says "push the branch, open a PR, and merge it", and the dashboard's checkbox relabels to "Open PR & merge". Older journals lack the field and keep their old reading: merge off.

  • 4a7b7c5: The session header's handoff checkbox no longer lies about a push-only run (Trivial run's work is stranded: agent skipped committing, handoff says "session committed nothing", safety commit lands only after the publish decision (#860 redux) #1376). The run writes its handoff-armed state as the very first event — before the live channel attaches — so a live tab folds a stream without it and handoffState's armed-armed fallback showed a ticked "Open PR" on a session the launcher had explicitly set to push-only. The armed pair was already mirrored onto the run record for exactly this reader; the view just never used it. handoffState now takes a seed, and RunView passes the record's mirror — a handoff-armed event in the stream still wins, being newer than any snapshot.

  • 4a7b7c5: A session's uncommitted work no longer strands silently at the handoff (Trivial run's work is stranded: agent skipped committing, handoff says "session committed nothing", safety commit lands only after the publish decision (#860 redux) #1376). The trivial-run repro: the agent wrote a file without committing (its trivial-scope judgment), the pre-handoff commitPendingWork lost git's index.lock race against the daemon's conversation committer — busiest at exactly that moment — and its failure was swallowed, so the handoff judged the branch "committed nothing" and skipped the armed push; teardown's identical commit landed seconds later, leaving the work on a local branch nobody was told about (the Unattended runs leave code on a branch nobody is told about #860 failure shape, back through a new hole). From the dashboard the change simply vanished on Stop. Two fixes: commitPendingWork now retries through transient failures with a short backoff, and the handoff honors its result — a commit that still fails becomes an explicit commit-failed skip ("the session's pending work could not be committed, so nothing was published") instead of a silent wrong "empty" verdict.

  • 9b54b0b: A Claude web run no longer deadlocks on an ambiguous prompt. The system prompt tells the agent to show choices and await on ambiguity, and a cloud session obeyed it into a question nobody attached could answer, spending the session for nothing. A hands-off run's system channel now declares the await gates unavailable in that session, right after the await protocol it amends, so the agent takes the most plausible reading, says which assumption it made, and carries the work through. Worded as availability rather than as a rule, so it deletes itself cleanly once choices become a per-session capability.

  • a7490f8: The dashboard's loopback Telefunc mount now validates the Host header (Validate the Host header on the dashboard's loopback Telefunc mount #1387). Before this, a DNS-rebinding page could reach the daemon's run-starting RPCs from the victim's browser: the origin check passed Origin-less requests, and nothing pinned Host to a loopback name. Requests whose Host is not a loopback address are refused.

  • 7eaaa31: The startup sweep no longer deletes the checkout of a run that never booted (Startup sweep removes the worktree of a run that never booted: a zero-commit branch counts as merged #1325). A run whose child died before it committed anything leaves a branch with no commits, which git branch --merged lists like any landed work, so the sweep removed the checkout and reported the session as merged into the base. That checkout is the evidence of what went wrong, and it was being destroyed for looking like the success it is the opposite of. The local ancestor signal now reclaims a checkout only for a run that finished cleanly; a failed or stopped run, or one whose meta is missing, needs a merged PR to say the work landed. A merged PR still reclaims either way, so nothing that really landed is kept on disk.

  • b1ec5bf: The launcher now shows the whole publish ladder (Launcher: show the publish ladder — Push branch → Open PR → Auto-merge, each gated on the previous (decision needed) #1379): Push branchOpen PRAuto-merge, each enabled only while the rung below it is on. Previously only Open PR and Auto-merge were offered, so unticking Open PR silently meant "push-only" — the launcher read as "publishing off" while the session still pushed the branch. Unticking Push branch now publishes nothing, and handoffFromPreferences treats autoPushBranch as the master rather than letting an armed PR force the push back on. Defaults are unchanged: push and PR on, auto-merge off.

  • ed2a2ab: The live run feed no longer blanks mid-run on a stream reconnect (Dashboard: live run view flickers blank mid-run; white screen for a while after closing a run #1383). Every subscribe replays the whole log before following live, and the client used to clear its feed first — so after a transient channel drop the "stream lost" banner cleared and the transcript sat empty, bannerless, until the replay refilled it. The on-disk tail now sends a wire-only stream-sync marker when its replay is delivered, and a reconnecting client buffers the replay and swaps atomically on it — the feed never shows less than it already showed, the same rule fix(dashboard): an empty archive never replaces the events on screen (#1383) #1402 set for the archive read. In-memory sources (the relay, relayed device runs) send no marker and fall back to a short grace deadline; a reconnect that dies mid-replay drops its partial buffer rather than swapping it in.

  • dd865d8: Auto-merge now requires the agent's word (Which session endings run the auto handoff (push / PR / merge)? The verified matrix — and whether Stop-at-a-gate skipping it is the design we want #1363, rule settled on Sessions don't end themselves: finished work waits for a human to press Stop #1390). An armed merge only runs when the agent declared the session done via setReadyForMerge() — previously the merge fired on config alone, landing work on main that the agent never said was finished. Second check, a temporary safety belt: the session's own TODO_<SESSION_NAME>.agent.md must have no open entries. The global TODO_AGENTS.md queue never withholds a merge — it is decoupled from sessions. A withheld merge is not a skipped handoff: the branch is still pushed and the PR still opens, as a draft, and the handoff event says why the merge did not run. The system prompt's closing instruction is now a required terminal action rather than a suggestion, so agents reliably signal when their work is done.

  • 01aa1ca: A web run's session log no longer dead-ends at "Handed off: …". The bridge mirror now streams into one live boxed row pinned at the tail of the log, right where the hand-off happens, with a "Connecting to the cloud session…" placeholder so a web run never shows dead air. The box is clearly labelled as a best-effort view of the Claude tab rather than merged into ordinary log rows: events.jsonl is durable provenance-clean data, the mirror is a tab scrape, and the boundary stays visible. The scrape is also scrubbed of the claude.ai UI chrome it dragged in (tile-focus hints, "Show message actions", bare model names), matched per line and anchored so a message that merely mentions a model is untouched.

  • 7aedf24: A run's branch is recorded on its meta from the start, and updated when the framework renames the run-id branch after the agent names the session, instead of being stamped only at teardown. Continuing a run re-attaches the recorded branch, so a run whose agent created its own branch is no longer continued on a branch without its previous commits.

  • ec108fc: The AI Queue card now reads the queue with the same rules the sweep drains it by: every markdown list item is an entry, open unless its checkbox is checked. The card's old parser only accepted - [ ] checkbox lines, so a queue written in the link style (- [Title](tickets/x.md) — ...) showed "Nothing queued." while the sweep was happily draining the very same file.

  • ba1fdab: A fanned-out [Spike & plan] run's PR no longer closes its ticket's GitHub issue. The Goal: let TF fully *autonomously* work on quick-wins #1334 lane puts the ticket's issue on the PR title as (fix #42) so an implementing run's squash-merge closes the issue — but the fan-out planners (Goal: fire 10 Spike & plan agents concurrently #1327) carry a pinned ticket too, so their plan-only PRs inherited the closing keyword and auto-closed issues whose work had merely been planned. The daemon now marks those starts planRun (--plan-run), and the title derivation skips the suffix for them; the ticket still rides --ticket onto the run's meta, so the dashboard keeps naming what the run is about.

  • 568a126: A session no longer spends a branch and a worktree on an agent that can never start (Preflight the agent CLI before starting a run: missing or logged-out claude/codex fails with zero signal #1326). Preflight already checked that the picked agent's CLI was installed, but installed is not usable: a logged-out claude resolves on PATH and answers --version exactly like a working one, then dies before the session exists. That is what our first external-user report (Problem with session that does not run / finish #1323) looked like from outside, with run branches piling up across six projects while the dashboard sat on "Waiting for the session to start...".

    Preflight now also asks the CLI whether it is authenticated (claude auth status, codex login status) and warns when the daemon runs as root, where sudo moves HOME and both agents lose their credentials the same way. The daemon runs these before it allocates a run's checkout, so a doomed start is refused with the command that fixes it instead of costing a branch, and the launcher shows the same thing before you press Start, the way it already warns about folder trust (Web runs: ask for Claude Code folder trust in the dashboard instead of sending the user to the CLI #1318). A CLI too old to answer the question is treated as unknown rather than logged out, so an unreadable answer never blocks a setup that works.

  • 0805a80: The conversation committer only passes the pathspecs that actually have something pending. A project with no .the-framework/conversations directory — every project until its first recorded chat — made git add/git commit abort with "pathspec ... did not match any files", so its sessions never committed and the daemon log carried that failure on every poll. Nothing to commit under a pattern is now the ordinary skip it always was, while real git failures are still reported.

  • 3702fab: The triage routines no longer jam after their first run: a pinned branch (the-framework/triage-quick) whose PR was closed or merged is released before the routine fires, instead of tripping the prompt's "triage is already pending" abort forever. An open PR still keeps the branch, and a branch with no PR history is left alone.

  • 665fde2: The session composer's gear now follows what the next action arms (Empty settings dropdown #1172): while a run is live it is dropped entirely (it used to open an empty dropdown), and once the run has ended it returns as "Resume options" — Autopilot, the publish ladder (Push branch / Open PR / Auto-merge) and Browser, the options a Resume continuation actually resolves at start (Resume inherits the run's armed options + lifecycle reminder (#1467) #1469). Prompt-shaping rows and Run on / agent / model stay launcher-only.

  • 152a0d7: The "Copy resume command" action survives a mid-turn Stop (Local run => button to copy claude --resume CLI command disappeared #1322): the session id was only surfaced when a turn's result arrived, so a run stopped (or dying) during a turn — most visibly during its first — never recorded the id and lost its claude --resume handle, making the button appear on some sessions and not others. The Claude driver now announces the id the moment the stream states it (its very first line), and telemetry emits the session-update right then — so the handle exists seconds after launch and no ending can take it away.

  • 4b7b24b: Retire the session-scoped TODO_<slug>.agent.md backlog (Retire the session-scoped TODO_<slug>.agent.md backlog — TODO_AGENTS.md superseded it #1369) — TODO_AGENTS.md superseded it. The [Research] preset (its last writer) now points its TODO_FILE at the flat queue, and the session-scoped machinery is deleted: TODO_FILE_PATTERN and the scoped branch of the backlog lookup are gone, so findTodoBacklog / appendTodoEntry read and write only the flat file (TODO_AGENTS.md, or a legacy tickets/TODO.md / root TODO.md). A leftover session file in a checkout is ignored, not drained. The backlog loop itself (todo-loop.ts) is untouched — it is the TODO_AGENTS.md reader and stays load-bearing.

  • bcb3645: A run whose driver dies to a transient transport error (connection closed mid-response, reset, timeout, overload, 5xx) is no longer lost: the daemon continues the same run in its retained worktree, on its recorded branch, up to twice with a short pause, using the same continue-run machinery that resumes runs after a daemon restart. The queue pin and agent session ride along, so a retried drain keeps its claim and its context. A run that fails on its own terms, or keeps dying after the retries, stays failed.

  • 173d090: A running session's PR badge no longer flashes a predecessor's merged PR: run-scoped git-status reads pick the PR from the branch's history with the run's own start as the cutoff, instead of trusting the newest PR in any state. A reused pinned branch (the-framework/triage-quick) previously dressed every new run in the last closed PR's badge.

  • 5651aef: A run whose build declares small scope skips the production-grade checklist (Every run pays the production-grade checklist, however trivial the prompt: scope is hardcoded to 'full' #1356). The signal protocol gains a set-scope block (small / large / very-large); a small verdict resolves the checklist pass clean without dispatching an agent, with a log saying why. Only an explicit small skips — no verdict (an older prompt, a run without the protocols) keeps the full checklist, so the gate can only ever drop work the agent said was unnecessary.

  • b5fd2a1: The session un-ignore rules in .the-framework/.gitignore are now user-agnostic globs, so the file is written once instead of once per person. Every user who ran a session appended their own three !<email>/... lines to a tracked file: their checkout went dirty, the next safety commit swept the edit into a branch, and two machines doing it near each other conflicted on a delete-vs-modify. One !*/sessions/** rule covers everyone, including people who have not run anything yet. A file that still names users is upgraded to the glob form in place, in the same write that removes the per-user lines, and a file already on the glob form is never written again. Unrelated rules, including the conversations rules, are kept exactly as they are.

  • cd80295: The build prompt now asks for the set-scope verdict (Every run pays the production-grade checklist, however trivial the prompt: scope is hardcoded to 'full' #1356) — a trivial run has no sizing moment of its own, so the optional protocol block went unemitted and the full checklist still ran.

  • 7c4f9eb: Two fixes from the feat(auto-pm): fan [Spike & plan] out to the concurrency, one PENDING-locked ticket per agent (#1327) #1364 post-merge review. The spike-lock commit now pushes to origin's default branch — and only when the checkout is on it; before, it pushed HEAD:<current branch>, which published whatever branch the daemon's checkout happened to be on and left main-forked machines blind to the locks. SPIKE_LOCK_STALE_MS goes from 60 minutes to 6 hours: spiking and planning can take hours, and staleness release is a recovery mechanism that ideally never fires.

  • 035614e: [Spike & plan] now queues plan work for the <COUNT> most important tickets instead of every open one, with COUNT: 10 as the prompt-defined default (Parameterized Spike & plan tickets task #1421). The parameter lives in the prompt itself, following the prompts' own placeholder-footer convention, so changing the default — or overriding it from a derived prompt — is a one-line prose edit.

  • ab10486: A run implementing a ticket now carries the ticket's GitHub issue into its PR title as (fix #42), read off the ticket's GitHub: header (Goal: let TF fully *autonomously* work on quick-wins #1334). The squash-merge commit inherits the title, so merging the PR closes the issue — before, an autonomously merged quick-win left its ticket open.

  • c8be89f: "Trigger routine now" answers with the sweep's real outcome lines again: the RPC read the Telefunc request context after an await, which does not survive one, so every click fell back to the generic "The sweep ran." The reporter is now captured before the sweep runs.

  • 6dd4057: "Trigger routine now" answers ("Trigger routine now" gives no feedback #1433): the RPC was fire-and-forget, so the button flashed for milliseconds and a sweep that ran and refused showed nothing — the stand-down reason (e.g. Spike & plan can never fire while the AI queue has entries #1432's "the queue has work waiting and its routine is switched off") was recoverable only from the source. The RPC now awaits the tick and returns the report's per-project outcome lines; the Routine work card shows them in its note slot (folder-prefixed when several projects answered) and holds "Triggering…" until the sweep resolves. The two previously silent stand-down paths (queue empty on a drain-only sweep, drain routine switched off) now also write daemon log lines like every other stand-down.

  • 1f76652: prompts/system_prompt.md re-synced with System prompt #326 after the issue itself was brought up to date: the Auto-merge requires the agent's setReadyForMerge signal (#1363) #1392 "required" setReadyForMerge terminal block stays, the very-large-scope bullet follows the reviewed <TODO_FILE>/<SHOW_MD> wording, the TODO_FILE glossary line is added, and the obsolete "commit uncommitted changes" step is gone — worktree runs start clean, so the step only produced junk commits.

  • 79508d8: The system channel's tickets bullet names the spec section that actually exists again: Improve lock mechanism #1420 renamed the spec's heading to "Ticketing format", and the bullet still sent agents to follow a "Ticket format" section that was no longer there.

  • 3bda885: Routine and preset runs fired from the dashboard now run unattended, exactly as the auto-PM sweep runs the same routines: choice gates take the recommended option, the run ends at settle, and its armed push+PR handoff fires. Previously a card-fired routine did its work and then parked forever in the stay-open chat loop as "running", its PR never opened and the queue never filled. The stay-open conversation is unchanged for hand-typed prompts, which is what it was built for.

  • f9f8898: Dashboard UX quick wins (Dashboard UX notes: rail width, Docs/History placement, inline choices, composer Stop/Resume #1455): the Recent-sessions rail no longer says "done" while a session is still publishing — the handoff report is folded into the run record (meta version 2) so list surfaces can tell the window apart; the composer's submit slot now holds the session's controls, Claude Code-style — Stop while the run is live, Resume once it was stopped (moved from the action bar), the send ↑ when you type; and the right rail slims from 27rem to 22rem

@gemstack/framework-dashboard@0.5.0

Minor Changes

Patch Changes

  • fbf47c1: New Auto-merge setting (Auto-merge #1216), default off: a session armed for it merges the PR its handoff opens — GitHub auto-merge where the repo allows it, so the PR lands when its checks pass, else merged directly. Reachable as the autoMerge preference (launcher row, per-project overridable), the the-framework.yml key, and the --auto-merge/--no-auto-merge flags. The routine's [Drain queue] job turns it on for its own runs: what it implements was already triaged as consensual quick-win work, so its PRs land themselves and the Goal: let TF fully *autonomously* work on quick-wins #1334 loop closes without a human pressing merge.

  • a3a49bb: The launcher warns when the merge rung is armed on a repo with GitHub auto-merge disabled (UX when GH auto-merge is disabled #1417): the armed merge silently degrades to an immediate direct merge — the PR lands before CI has run (Auto-merge lands before CI runs: repo lacks native auto-merge + a required build check #1406) — so the warning says so before the session is spent and names the fix (enable "Allow auto-merge" in the repo settings + mark a check as required). Never a block. Backed by a new cached gh api repos/{owner}/{repo} read of allow_auto_merge (ghRepoAutoMerge / onRepoAutoMerge); "gh could not say" renders nothing rather than crying wolf.

  • a3dc9ee: The claimed badge (Improve lock mechanism #1420) now names the lock's holder inline — claimed · <agent-id> — instead of hiding it behind the native title tooltip, which needs a 1-2s still hover nobody discovers. The tickets list truncates a long id to keep the dense rows aligned (full id stays in the tooltip); the detail page shows it in full.

  • 417a2a4: Stopping a settled session no longer blanks its view to "This session has no events." until a manual refresh (Dashboard: live run view flickers blank mid-run; white screen for a while after closing a run #1383). When a run ends, the view swaps its live events for the archived log — but the archive read answers [] both for "gone" and for "not archived yet", and a Stop races the archive write, so the swap could replace a populated feed with nothing. An empty archive now counts as not-there-yet: the events already on screen keep their place, and the empty-state line is reserved for a session that truly has no events anywhere.

  • 7ed6031: The launcher warns when a PR/merge rung is armed and gh cannot deliver it (UX when $ gh not available #1419): the handoff publishes through the GitHub CLI, so a missing or logged-out gh used to surface hours later as publishing that silently stopped at the pushed branch. The Preflight the agent CLI before starting a run: missing or logged-out claude/codex fails with zero signal #1326 preflight gains a publish half probing gh --version and gh auth status — warnings that name the fix (brew install gh / cli.github.com, gh auth login), never blocks: the session's own work needs no gh and the push rung is plain git. Probed only while a PR/merge rung is armed on a local run.

  • d5cef3f: Picking Haiku in the launcher now shows a warning under the composer (Warn when Haiku is selected #1439) — never a block: Haiku consistently skips the session-finish protocol (0/5 in the Goal: let TF fully *autonomously* work on quick-wins #1334 model-tier test, every stronger tier passed), so a publishing run ends as an unmerged draft PR needing hand-holding. The warning says so before the session is spent and points at Fable for real work.

  • 4690f03: The armed-handoff line now owns the merge half (Run header and handoff-armed hide merge arming: header says "draft PR" on a run configured to auto-merge #1382). A run launched with auto-merge advertised "when this ends: push the branch and open a draft PR" and then opened a ready PR and merged it to main unattended — the most consequential thing a run can do was the one thing the line didn't say. The handoff-armed event and the run record's handoff mirror now carry the merge arming (display-only; the merge itself still fires off the run's own config, Auto-merge #1216), the transcript line says "push the branch, open a PR, and merge it", and the dashboard's checkbox relabels to "Open PR & merge". Older journals lack the field and keep their old reading: merge off.

  • 4a7b7c5: The session header's handoff checkbox no longer lies about a push-only run (Trivial run's work is stranded: agent skipped committing, handoff says "session committed nothing", safety commit lands only after the publish decision (#860 redux) #1376). The run writes its handoff-armed state as the very first event — before the live channel attaches — so a live tab folds a stream without it and handoffState's armed-armed fallback showed a ticked "Open PR" on a session the launcher had explicitly set to push-only. The armed pair was already mirrored onto the run record for exactly this reader; the view just never used it. handoffState now takes a seed, and RunView passes the record's mirror — a handoff-armed event in the stream still wins, being newer than any snapshot.

  • b1ec5bf: The launcher now shows the whole publish ladder (Launcher: show the publish ladder — Push branch → Open PR → Auto-merge, each gated on the previous (decision needed) #1379): Push branchOpen PRAuto-merge, each enabled only while the rung below it is on. Previously only Open PR and Auto-merge were offered, so unticking Open PR silently meant "push-only" — the launcher read as "publishing off" while the session still pushed the branch. Unticking Push branch now publishes nothing, and handoffFromPreferences treats autoPushBranch as the master rather than letting an armed PR force the push back on. Defaults are unchanged: push and PR on, auto-merge off.

  • ed2a2ab: The live run feed no longer blanks mid-run on a stream reconnect (Dashboard: live run view flickers blank mid-run; white screen for a while after closing a run #1383). Every subscribe replays the whole log before following live, and the client used to clear its feed first — so after a transient channel drop the "stream lost" banner cleared and the transcript sat empty, bannerless, until the replay refilled it. The on-disk tail now sends a wire-only stream-sync marker when its replay is delivered, and a reconnecting client buffers the replay and swaps atomically on it — the feed never shows less than it already showed, the same rule fix(dashboard): an empty archive never replaces the events on screen (#1383) #1402 set for the archive read. In-memory sources (the relay, relayed device runs) send no marker and fall back to a short grace deadline; a reconnect that dies mid-replay drops its partial buffer rather than swapping it in.

  • c1c4b3f: The transcript's kind badges are tinted for scanning (the Dashboard UX notes: rail width, Docs/History placement, inline choices, composer Stop/Resume #1455 colour idea): choice gates amber, clean end / ready-for-merge green, pushed surfaces (view/browser/preview) primary — failure red and the reader's blue turn still win, and the bulk of the log stays muted so the colours stay scannable.

  • fe32c33: The session log now says what a row is by its colour, and opens with the line you wrote. A failure renders red (Show agent error msg in red #1199): both the agent erroring mid-run and the run settling badly, though a stopped run stays neutral because stopping was asked for and is not a fault. Your own turn renders blue (Where can I see the user prompt? #1170), so it reads apart from the agent's work.

    The prompt is also hoisted to the top of the log (Where can I see the user prompt? #1170). It is emitted after the session and system-prompt events, so the one line you wrote used to open three rows down, underneath a char-count summary of a prompt you did not write. Only the first prompt moves; a later turn is part of the conversation and stays where it happened.

  • 550809a: The right rail's Log tab is now History, and every tab says what it holds on hover (What is "Log"? #1145). One word only works for a reader who already knows the system: "Log" was read as agent output or a console stream rather than the project's durable, committed session history. The panel itself now names what it is and where it comes from, and its empty state says no finished sessions rather than no log entries.

  • 568a126: A session no longer spends a branch and a worktree on an agent that can never start (Preflight the agent CLI before starting a run: missing or logged-out claude/codex fails with zero signal #1326). Preflight already checked that the picked agent's CLI was installed, but installed is not usable: a logged-out claude resolves on PATH and answers --version exactly like a working one, then dies before the session exists. That is what our first external-user report (Problem with session that does not run / finish #1323) looked like from outside, with run branches piling up across six projects while the dashboard sat on "Waiting for the session to start...".

    Preflight now also asks the CLI whether it is authenticated (claude auth status, codex login status) and warns when the daemon runs as root, where sudo moves HOME and both agents lose their credentials the same way. The daemon runs these before it allocates a run's checkout, so a doomed start is refused with the command that fixes it instead of costing a branch, and the launcher shows the same thing before you press Start, the way it already warns about folder trust (Web runs: ask for Claude Code folder trust in the dashboard instead of sending the user to the CLI #1318). A CLI too old to answer the question is treated as unknown rather than logged out, so an unreadable answer never blocks a setup that works.

  • ed5a1a5: The Overview's AI Queue card now lets you act on an entry, two ways. An entry that links somewhere is a link: a queued ticket (the [Title](tickets/x.md) style) opens that ticket's own page, and an absolute http(s) target opens in a new tab — an entry pointing anywhere else keeps its title and stays plain text rather than pretending to have a page. And every open entry carries a play button that spins up an agent working on that one entry immediately — the same unattended work the drain sweep would get to, but on your click, with the drain's own vocabulary narrowed to the entry so the agent checks off exactly the line you started. The card previously was read-only: titles you could not open, and no way to start a queued task short of draining the whole queue.

  • 665fde2: The session composer's gear now follows what the next action arms (Empty settings dropdown #1172): while a run is live it is dropped entirely (it used to open an empty dropdown), and once the run has ended it returns as "Resume options" — Autopilot, the publish ladder (Push branch / Open PR / Auto-merge) and Browser, the options a Resume continuation actually resolves at start (Resume inherits the run's armed options + lifecycle reminder (#1467) #1469). Prompt-shaping rows and Run on / agent / model stay launcher-only.

  • 07379c8: Resuming an ended session no longer blanks its transcript, and a stopped session offers a Resume button (Split Stop into distinct actions: pause/resume, cancel, and finish #1391). The flicker had two layers: the continuation bumped the new-run feed reset even though a resume appends to the same journal (nothing truncates, so nothing re-replays), and currentRunEvents sliced the live feed at the resume's second session boundary, hiding the pre-resume transcript until the run ended again. The Resume button is the composer's own continuation with a stock prompt — same run, same branch, same agent conversation — offered when the run ended stopped and reported a session id.

  • 6799642: A resumed session reads as running again: isRunActive and runOutcome now fold over the current session segment instead of the whole feed. The resume fix keeps the full multi-segment transcript on screen, which exposed the stopped segment's end event to the status folds — the pill stayed yellow "stopped" and the ⋮ menu hid "Stop session" while the resumed agent was live, and a resumed run that later finished clean would have stayed "stopped" for ever.

  • 0ce58a3: The settle moment now follows the Unclear UX: what should I do now? #1173 maintainer decisions to the end. A branch with no diff never offers Open PR — GitHub would refuse it with "No commits between main and <branch>" — and when the session left work uncommitted, that work is named right in the bar (Nothing committed — index.html left uncommitted.), with the full list behind the bar's disclosure. The handoff read now carries the pending paths (RunHandoff.pendingFiles) instead of a bare count to make that possible. Unattended runs keep committing their work automatically on the way out, so for them the guard is a rare sight; an attended session parked in the chat can be told to commit right below the message.

    The push setting the launcher gear no longer shows (one Open PR row since fix(dashboard): stop offering a PR that cannot be opened, and make the queue readable (#1164, #1173) #1181) is now really available where the thread said it stays: the-framework.yml accepts autoPushBranch and autoOpenPr beside the other booleans, resolving through the usual layers (flag > yml > default on), narrated like the rest, and feeding the launcher's repo tier. The CLI pair became tri-state to let the file decide when the run says nothing. The postponed Auto commit / Auto push settings split is deliberately not added.

  • 80d5d97: The rail no longer shows a phantom second session when a run finishes as fast as it started. The "starting…" stand-in row waited for a running row to hand over to, but the runs list polls every two seconds, so a session that starts and finishes inside one interval is never once observed running — the stand-in then sat beside the finished session's own row, reading as a duplicate session that was starting, until a 20-second deadline swept it. It now retires on the real signal: the first run to appear that was not in the list when Start was clicked, whatever status it landed in. The deadline stays as the backstop for a start that produces no run at all.

  • 6dd4057: "Trigger routine now" answers ("Trigger routine now" gives no feedback #1433): the RPC was fire-and-forget, so the button flashed for milliseconds and a sweep that ran and refused showed nothing — the stand-down reason (e.g. Spike & plan can never fire while the AI queue has entries #1432's "the queue has work waiting and its routine is switched off") was recoverable only from the source. The RPC now awaits the tick and returns the report's per-project outcome lines; the Routine work card shows them in its note slot (folder-prefixed when several projects answered) and holds "Triggering…" until the sweep resolves. The two previously silent stand-down paths (queue empty on a drain-only sweep, drain routine switched off) now also write daemon log lines like every other stand-down.

  • Updated dependencies [1a018d0]

  • Updated dependencies [288fa63]

  • Updated dependencies [a16e72f]

  • Updated dependencies [fbf47c1]

  • Updated dependencies [a3a49bb]

  • Updated dependencies [901ea0a]

  • Updated dependencies [57f4047]

  • Updated dependencies [a0c9db9]

  • Updated dependencies [e60b51a]

  • Updated dependencies [e72d0dd]

  • Updated dependencies [2908683]

  • Updated dependencies [03260d9]

  • Updated dependencies [660adf2]

  • Updated dependencies [7bfba05]

  • Updated dependencies [80d3b2c]

  • Updated dependencies [6b64d67]

  • Updated dependencies [7ed6031]

  • Updated dependencies [11beec4]

  • Updated dependencies [4690f03]

  • Updated dependencies [4a7b7c5]

  • Updated dependencies [4a7b7c5]

  • Updated dependencies [9b54b0b]

  • Updated dependencies [a7490f8]

  • Updated dependencies [7eaaa31]

  • Updated dependencies [b1ec5bf]

  • Updated dependencies [ed2a2ab]

  • Updated dependencies [6a1e75d]

  • Updated dependencies [dd865d8]

  • Updated dependencies [01aa1ca]

  • Updated dependencies [7aedf24]

  • Updated dependencies [ec108fc]

  • Updated dependencies [ba1fdab]

  • Updated dependencies [31da5d7]

  • Updated dependencies [568a126]

  • Updated dependencies [0805a80]

  • Updated dependencies [3702fab]

  • Updated dependencies [a0594fe]

  • Updated dependencies [e733e47]

  • Updated dependencies [665fde2]

  • Updated dependencies [152a0d7]

  • Updated dependencies [4b7b24b]

  • Updated dependencies [bcb3645]

  • Updated dependencies [173d090]

  • Updated dependencies [5206058]

  • Updated dependencies [5651aef]

  • Updated dependencies [a4b519d]

  • Updated dependencies [b5fd2a1]

  • Updated dependencies [cd80295]

  • Updated dependencies [0ce58a3]

  • Updated dependencies [7c4f9eb]

  • Updated dependencies [035614e]

  • Updated dependencies [ab10486]

  • Updated dependencies [c8be89f]

  • Updated dependencies [6dd4057]

  • Updated dependencies [1f76652]

  • Updated dependencies [79508d8]

  • Updated dependencies [7b903ce]

  • Updated dependencies [3bda885]

  • Updated dependencies [f9f8898]

    • @gemstack/the-framework@1.5.0

@github-actions
github-actions Bot force-pushed the changeset-release/main branch 30 times, most recently from 93e0b6c to 96a5c66 Compare July 28, 2026 08:20
@github-actions
github-actions Bot force-pushed the changeset-release/main branch 29 times, most recently from 4007394 to d4a230e Compare July 30, 2026 18:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

0 participants