• v1.6.13 Stable

    nntrivi2001 released this 2026-09-18 03:22:49 +00:00 | 188 commits to main since this release

    The pipelines now stop and ask at the two points where being wrong is cheap to fix, and stop paying for reviews the diff does not need.

    Intake actually asks. The default 8-node template declared agenthub stage intake for its intake node — a stage report with no work attached — so "intake" was a label a run walked past without ever asking a question. It now declares /superpowers:brainstorming (and detects it; that rule moves off plan), and both ship-feature and ship-feature-lane make the brainstorm mandatory, asked with AskUserQuestion and waited on, never answered on the user's behalf.

    The plan is approved before it is code. After it is written and adversarially challenged, it goes to the user: approve / revise / change approach. Implementation does not start without that approval, and work that turns out to need a different approach comes back for a fresh one.

    Review is scoped, native, and a loop. Reviewers are picked from git diff --name-only: Claude Code's own code-review always; a domain reviewer only for a layer the diff actually touched, and only once the change is big enough to have seams. Review ends on a clean pass over the current diff, not on one pass having happened.

    The gate asks the user, and a NO-GO goes back by size. Nothing is claimed done — and in the lane pipeline nothing is published, publishing being outward-facing — until the user accepts. A defect returns to implement; a wrong approach returns to plan. Nothing carries a NO-GO forward with a note about it.

    A real stall, fixed. ship-feature had no waiting rule, and a session sitting at the gate invented one with ScheduleWakeup — a /loop-only primitive that paces nothing here and is refused outright when auto mode cannot reach its safety classifier. The rule the lane skill already had now exists in both.

    Cost, measured in what each agent is for. The suite run leaves its agent (nothing is judged there, so nothing is delegated), and backend-reviewer drops from opus to sonnet like its frontend twin — both read a scoped diff against a fixed checklist, and the senior gate above them is still opus.

    Also: KEEP_RETIRED_ROOTS drops to 1, so a plugin-cache install keeps the running build plus one rollback copy instead of two (~130 MB each). And a sweep of the docs skill: doc-map told agents not to recreate the removed translations and then, three lines later, to mirror every README change into them; the mapping still carried +VN+CN and the punctuation left behind; Procedure jumped 2 → 6; Verify required scripts/doc-coverage.sh, which does not exist in this repo.

    Downloads
  • v1.6.12 Stable

    nntrivi2001 released this 2026-09-18 02:45:50 +00:00 | 190 commits to main since this release

    Removing a lane now deletes only the dashboard's record of it.

    A lane's worktree is the user's, not the dashboard's. remove used to tear down what the lane pointed at: git worktree remove --force, a branch delete, and a drop of the lane's own database. One mis-click on a row cost a whole branch's unpushed code, for a row that was the only thing AgentHub actually owned. It now stops the run and the stack, clears AgentHub's own runtime bookkeeping under LANES_ROOT/.state/lane<slot>/, and deletes the row. The working tree, its branch, git's worktree records and the database stay exactly where they are — deleting them is yours to do by hand, when you mean to.

    Fixes #28 — "Lane action failed: lane is not listed as a worktree in …". Removal used to route through assertDestroyable, whose third check demands the lane's directory appear in git worktree list; a managed lane git no longer listed answered ENOTWORKTREE and could never be dropped from the dashboard at all. Removal no longer asks git anything, so no preflight blocker stops it, and the unpushed-commits force-gate applies to reset alone — nothing remove does can discard a commit.

    The UI follows: one label for both lane kinds ("Delete lane record"), copy that says what survives, and no Force checkbox on removal. removeWorktree/removeLaneData remain as guarded primitives; no route calls them any more.

    Downloads
  • v1.6.11 Stable

    nntrivi2001 released this 2026-09-17 16:20:19 +00:00 | 192 commits to main since this release

    Fixes the quota check for the account you are actually logged into, and stops making you ask one row at a time.

    The live account is read from the CLI. An OAuth refresh token is single use, so every refresh Claude Code performs on its own account retires the copy stored in that account's saved profile — which made the profile you would try first the one guaranteed to fail, with a raw invalid_grant. The usage call now matches a profile against the live credentials and uses what the CLI is holding. That token is never refreshed and .credentials.json is never written: rotating it would log you out of your own terminal.

    Clearer answers for the two remaining failures. An expired live token says to use Claude Code once so the CLI refreshes it; a genuinely spent refresh token says to activate the account and save the profile again, instead of echoing Anthropic's 400.

    Opening the Profiles modal now loads every account's quota at once. Comparing accounts is the only reason the panel exists. Credentials are still not rewritten on a whim: the live account costs a plain read, and any other profile is refreshed only once its token has actually expired, which leaves it valid for hours of further opens. Each row resolves on its own, so one superseded account still lets the rest report.

    Downloads
  • v1.6.10 Stable

    nntrivi2001 released this 2026-09-17 15:22:15 +00:00 | 194 commits to main since this release

    Per-profile Claude quota in the Profiles modal, plus three fixes where a write reached disk but did not look like it had.

    Check quota per auth profile (#19) — each saved profile now reports how much of its account's quota is spent, which is the only number that decides which one is worth switching to. It is a button, never a poll: a non-active profile's token is normally expired, so answering refreshes it, and a refresh rotates the credentials written back to disk. The token is sent to Anthropic and nowhere else; what leaves the server is two percentages and two reset times.

    A settings patch that changes nothing now writes nothing (#20) — opening the config panel used to take a timestamped backup even when the patch was a no-op, quietly growing a backup directory inside every lane. A lane's git exclude also picks up .claude/.cc-config-backups/.

    A lane's router pick stops reverting (#21) — the apply route was the only mutating lane route that never broadcast its lane, so the client's cached row kept the old profile: the picker looked right until you switched lanes and back. Also guarded against an apply that resolves after you have moved on painting its result onto the lane now on screen.

    Add-lane closes itself (#27) — worktree mode left the dialog up after a clean setup with a dead confirm button. It now closes when nothing failed, and keeps the summary with a real Close when something did.

    Downloads
  • v1.6.9 b0e8368c1d

    nntrivi2001 released this 2026-09-17 09:17:53 +00:00 | 196 commits to main since this release

    A pipeline run is what you declared, and reload types two commands, not one

    A backwards DETECTION no longer opens a new pipeline run. runs is the denominator every rate on the Workflows page's pass-rate panel is read against, and until now any backwards move started one. Stage detection bounces by design — a single feature reads implement → tests → implement as the session edits, runs the suite and edits again — so one feature was recorded as five or six runs, and a lane in constant use reported a handful of passes scattered across dozens of phantom ones. A backwards move now opens a run only when it is declared (agenthub stage, or a codex lane's ingest-driven declaration); a backwards detection continues the run in flight. Reaching the pipeline's last node still closes the run for either, since work after done is new work however it was observed. Replayed over this repo's own lane, the rule takes a 26-run history down to the 5 features that actually shipped through it.

    Nothing else about the panel moved: a pass is still a declaration, detections still render as the grey "reached, not declared" bar, and the GET /api/lanes/pipeline-stats payload is unchanged. If your lane's rates read low, that is the honest answer — a session that works without calling agenthub stage leaves detections, not passes.

    /reload-plugins and /reload-skills reach a pane as two commands again. They were typed back to back, and Claude Code opens its slash-command menu the moment / is typed, so the Enter that follows lands on that menu instead of submitting. The second command was appended to the line still sitting in the composer and the pane submitted the single string /reload-plugins/reload-skills — which Claude Code runs as /reload-plugins with an argument, so skills were never reloaded and a stray prompt turn was left in the scrollback. Reproduced and fixed against a live pane: the two sends are now a second apart (SETTLE_MS in server/lib/cc-reload.js), which makes reloadOpenSessions async rather than block the event loop for it, and the detached Update all worker got the same pause. POST /api/cc-config/reload therefore takes about a second longer to answer.

    Fixes #26 and #25.

    Downloads
  • v1.6.8 02ee46c862

    nntrivi2001 released this 2026-09-17 08:11:04 +00:00 | 198 commits to main since this release

    Drag your lanes into order, name them, and read the diff

    The lane strip is yours to arrange. Drag a tile onto another to move it there, or press Alt+←/→ with a tile focused — the keyboard path, since HTML5 drag-and-drop has no touch gesture and does not auto-scroll an overflowing strip. The order is a per-viewer preference, not a lane fact: it persists to localStorage (agenthub.workspace.laneOrder) exactly like the split-view layout beside it and writes nothing server-side, so GET /api/lanes and agenthub lanes keep answering in id order. A lane the stored order has never seen lands at the end rather than wherever a stale index would put it; a stored id whose lane is gone is skipped.

    A lane can be renamed in place. Click its name in the detail header (a pencil appears on hover) — Enter saves, Escape and clicking away cancel, and an empty name clears the title, which puts the lane's cwd back in its place. Renaming is display-only: a managed lane's branch name was slugified from its title once, at creation.

    "Lane 23 ·" is gone. The word cost a third of the tile's top row and said nothing; the bare #23 stays, because that number is how the CLI addresses a lane (agenthub stage --lane 23).

    The uncommitted-files tooltip is now a real panel. GET /api/lanes/:id/git returns files as {path, status, added, deleted} records instead of raw porcelain lines, with per-file line deltas from one extra git diff --numstat HEAD (staged and unstaged together). Hover — or focus, or tap — the N modified · N untracked text on a lane card and you get one row per file: the status letter colour-coded, the directory truncated before the filename ever is, and each row's +N −M aligned under a total. It is portalled to the document body, so the Workspace's own scroll box cannot clip it, and it stays open while the pointer travels into it. added/deleted are null where git has no delta to report — an untracked file (its content is deliberately not read off disk; a lane mid-build can have a 100 MB artifact), a binary file, a rename, or a repo with no commit to diff against.

    Bad input to PATCH /api/lanes/:id is a 400, not a 500. Renaming made a lane column reachable from a text field for the first time, so the guard is column-wide rather than a special case: any non-scalar patch value (links excepted — it is stored as JSON) is rejected with EBADFIELD, and the SQLITE_CONSTRAINT family maps to 400 as well. A title is trimmed and capped at 200 characters, and null clears it rather than violating the NOT NULL.

    Upgrade note

    GET /api/lanes/:id/git's files changed shape — it was an array of raw git status --porcelain strings and is now an array of records. Anything parsing those strings needs updating; nothing in AgentHub itself did outside the lane card.

    Downloads
  • v1.6.7 b5ca531800

    nntrivi2001 released this 2026-09-17 06:27:13 +00:00 | 200 commits to main since this release

    The files behind a lane's counts, and a header-free Workspace

    Lane git facts now name the files, not just count them. GET /api/lanes/:id/git returns files — the raw git status --porcelain lines the dirty/untracked counts were already parsed from — and the lane card hovers them as a tooltip on its N modified · N untracked text. The list is capped at 20 (a lane mid-npm install would otherwise ship thousands of paths through a polled endpoint) and the tooltip appends … +N when the cap bit; the counts themselves are never capped. No new endpoint and no extra subprocess: those lines were being counted and thrown away.

    Workspace loses its page header. The title and the four counters (lanes, running, needs you, dead) said a second time what the lane strip already shows lane by lane — its own liveness dot, its own ⚠ marker — so they only cost a row of height on a screen whose point is the terminal. GET /api/lanes still returns counts for other callers.

    Add lane is now the lane strip's first tile instead of a header button — dashed border, no liveness dot — because creating a lane is the same kind of act as picking one, and it reads as the empty slot at the head of the row.

    The Tools menu (agents install / mcp sync / sync-base check) moves onto the lane-detail header row, beside the pipeline picker and the Model select. All three of its actions run against one lane's cwd, so it belongs next to the lane it acts on — and not in Settings, where it would need a lane picker just to say which.

    docs/LANES.md was updated to match (the /git response shape and its cap, and the Workspace anatomy section).

    Downloads
  • v1.6.6 2fe1dcd46f

    nntrivi2001 released this 2026-09-17 04:40:09 +00:00 | 203 commits to main since this release

    A leaner run panel and lane detail

    Lane card drops the progress bar and its percent — the pipeline map right below it already draws the same number as named, coloured nodes, so the bar was a worse second telling of it.

    Split view toggle (Workspace) swaps the "1 pane" / "2 pane" / "4 pane" text buttons for the conventional square / two-column / 2×2-grid icons most apps use for this layout. The words are still there for assistive tech and hover, as aria-label/title.

    Run setup merges the fresh-vs-resume source picker onto the same row as Working directory / Model / Permission mode / Thinking effort, instead of a row above them: settings on the left, New session / Resume existing session on the right. The session picker for an active resume still gets its own row, since it only shows up in that one state.

    "Run Claude" header goes from a two-row title + wrapped blurb to a single row (smaller icon and title), with the blurb trimmed to one short sentence and hidden below sm, where it would wrap again anyway.

    docs/LANES.md was updated to match (split-view description, the lane-card field list, and agenthub stage's progress-bar wording).

    Downloads
  • v1.6.5 229002cc2b

    nntrivi2001 released this 2026-09-17 03:03:27 +00:00 | 205 commits to main since this release

    A compact lane detail panel

    The Workspace lane panel spent four rows saying what fits in two.

    Strip tile — the stage badges move onto the id row; the progress bar and percent are gone. The detail panel's pipeline map right below shows the same progress with the stage names attached, so the tile was spending two rows to repeat it worse.

    Lane detail — the pipeline picker, stage badges, feature picker, router select and the remove button merge into the single header row instead of a second row under it. The pipeline's name is no longer interpolated into laneHeader either: the picker beside it already says it. The git block collapses from four lines to one (branch · head · subject · N modified) and drops the cwd, which the header above it already spells out.

    AI Router is now labelled Model — LaneRouterRow moves out of LaneCard into that header row (it is now exported). A finished apply reports as a ✓/⚠ marker with the message in a tooltip, rather than a wrapped sentence that pushed every row below it down for the life of the selection. A failed apply still reverts the select, same as before.

    Dropped: the tracker / dev QC / CI wait badge row

    Two of those three toggles have no consumer at all — the ticketer and the dev-QC agent are not built — so the badges could never be anything but decoration, and the row cost card height to say nothing. Gone with them: useLaneIntegrations, the api.lanes.integration client wrapper, and the integrations.* strings.

    agenthub lanes integration and GET /api/lanes/:id/integrations/:name are untouched — they are now the only readouts, and ci_wait's real consumer (agenthub lanes ci status) is unaffected.

    docs/LANES.md was updated to match.

    Downloads
  • v1.6.4 5ab674f134

    nntrivi2001 released this 2026-09-16 04:29:34 +00:00 | 207 commits to main since this release

    Test an AI Router before you save it

    POST /api/ai-routers/test sends one Anthropic-style message, capped at a single output token, to <baseUrl>/v1/messages with a 15s timeout — the same wire shape a claude lane's env keys use, so a router that answers the test is a router the lane can actually talk to.

    A reachable router is HTTP 200 whatever it replies: the result {ok, status, message} carries the router's own words rather than a verdict of ours, and status is null when nothing answered at all. A 401 from the endpoint is a successful test that reports an auth failure, not a failed request.

    Network errors report error.cause, because node's fetch collapses every transport failure — DNS, refused connection, TLS — into the same useless "fetch failed" string.

    Security: a stored key only ever goes to the endpoint it was stored against

    Sending a blank apiKey falls back to the saved profile's key only while baseUrl is unchanged; change the URL and the request is refused with EBADKEY. Without that rule the route would be a way to make the server POST a saved API key to any URL a browser names.

    Re-point a live lane's AI Router from its card

    The lane card's AI Router select switches a running lane through POST /api/lanes/:id/router/apply — never a lane PATCH, because the database column and the lane's on-disk config have to move together or the row claims a router the lane has never heard of.

    • A failed apply reverts the select, so the control never shows a router the lane isn't on.
    • The select is hidden when native is the only profile — nothing to switch between.

    docs/API.md and docs/LANES.md were updated to match.

    Model pricing: Claude Opus 5 priced, Sonnet 5 corrected, retired models dropped

    This release also carries a pricing fix that landed on main between 1.6.3 and 1.6.4.

    • Claude Opus 5 had no pricing row at all, so every token it burned was costed at $0 — the pattern list stopped at the 4.x Opus family and nothing matched claude-opus-5. It is now priced at 5/25 per MTok, fast mode 10/50, the same shape as Opus 4.8.
    • Sonnet 5's launch discount expired 2026-08-31 and the discounted rate became the published standard, so the row's 3/15 standard rate started overcharging the day after. 2/10 is now the standard rate and no model ships an introductory rate today.
    • Fable / Mythos 5.1 fell through to the claude-fable-5% row, which caches at $1/MTok against 5.1's $0.25. They get their own rows — and that overlap is only resolvable if the lookup prefers the more specific pattern, so matchPricing now orders by pattern length descending instead of taking whichever row happened to be inserted first.
    • Claude 3.x, Opus 4/4.1 and Sonnet 4 are retired from the defaults. Because the startup top-up only ever adds missing rows, they are also pruned once from existing databases, guarded by PRAGMA user_version so a model you deliberately re-add in Settings survives later restarts.

    Only rates are deleted — recorded token usage is never touched, and Reset Defaults still restores the full current set. docs/DATABASE.md was updated to match.

    Downloads