Releases: erain/glue
Release list
v1.13.0 — harness quality
The complete harness-quality queue from docs/coding-harness-roadmap.md — eight improvements distilled from source-verified analysis of pi, Cline, Codex CLI, and Gemini CLI, targeting Gemini 3.x first and open-weight OpenRouter/NVIDIA models second.
P0 — wasted-turn killers
- edit_file repair ladder (#338): exact → whitespace → indentation (re-indented replacement) → punctuation-folding → block-anchor matching, over-escape repair, BOM/CRLF preservation, updated-lines echo, instructive errors, lazy-placeholder guard.
- Structured output truncation (#339): head+tail shell capture with omitted counts and a named full-output spool file; read_file offset/max_lines paging with "Use offset=N to continue".
- History hardening (#340):
loop.HardenHistorysynthesizes results for dangling tool calls, drops orphans/empty turns, normalizes call IDs, strips foreign-model artifacts — before every request.
P1 — reliability and cost
- Retry/overflow recovery (#341, ADR-0017): classified loop-level retries with backoff and server retry hints; typed
OverflowError→ compact-once-and-retry in sessions. - Compaction upgrade (#342): structured state snapshot with injection firewall, handoff framing, cumulative file ledger, tool-pair-safe splits, inflation guard.
- Capability registry + tool-owned prompts (#345):
providers.Capabilitiesper provider;coding.SystemPromptassembled from the active toolset (the--codingagent previously ran with no system prompt at all).
P2 — polish
- Next-speaker stall recovery (#343): bounded "Please continue." nudges for Gemini's narrate-then-stop stall, auto-enabled per the registry.
- Loop guardrails (#344): graduated identical-call and consecutive-mistake detectors with typed halt errors.
Default-behavior notes: loop-level retries and guardrails are on by default with opt-outs (RetryPolicy.Disabled, GuardrailPolicy.Disabled); a 429 now retries up to 3× before failing. All changes additive otherwise; full changelog in CHANGELOG.md.
v1.12.0 — goal loop Phase 3: durable, isolated, schedulable goals
Completes the goal-loop roadmap from ADR-0016 (Phase 1 Agent.PursueGoal shipped in v1.10.0, Phase 2 TUI /goal in v1.11.0).
Durable goal state + resume across restarts (#324, PR #325)
Agent.PursueGoalcheckpoints aGoalRecord(objective, status, verified checklist, iterations, usage, summary) asglue/goal:*session metadata — after planning, every checker verdict, and at the terminal state. Cancellation persists as the newGoalPausedstatus;GoalRunningmarks in-flight records.Agent.LoadGoal/Agent.ListGoalsread records back;GoalSpec.StartIterationkeeps resumed maker/checker sessions fresh (iter-4,check-4, …).- TUI:
/goal resumecontinues the most recent unfinished goal even in a new process;/goal listshows recent goals with status, fraction, and age.
Worktree isolation — /goal -w (#326, PR #327)
/goal -w <objective>runs the loop in.glue/worktrees/<goal-id>on branchgoal/<id>— your checkout stays untouched and the result is a reviewable branch, never auto-merged. Resume re-attaches the same worktree (GoalSpec.WorkDir/GoalRecord.WorkDir).
Headless glue goal subcommand (#328, PR #329)
glue goal "<objective>"runs the loop without a TUI, streaming checklist progress to stdout; exit code maps the outcome (0 achieved · 2 blocked · 3 max-iterations · 4 budget-limited · 1 errored) so cron/CI/peggy schedules can branch on it.--list/--resume [id]share the TUI's store;--worktree,--max-iterations,--budget,--yolofor unattended runs.- Verified live end-to-end (gemini): plan → maker → evidence-backed verdict → achieved, exit 0, checkout untouched.
🤖 Generated with Claude Code
v1.11.0 — TUI /goal (goal loop Phase 2)
TUI /goal: drive the goal loop from inside glue run (ADR-0016 Phase 2, #322, PR #323).
/goal <objective>runsAgent.PursueGoalin the background on its own session ids while the chat stays usable: a live goal card in the transcript updates in place per iteration (verified[x]/[ ]checklist with evidence, iteration counter, token usage, last checker verdict), and the status bar gains a◎ goal · iter 2/10 · 1/4 ✓ · 12.3k toksegment.- Subcommands:
/goal status,/goal pause(cancels cleanly, keeps the verified checklist),/goal resume(continues from that checklist without re-planning),/goal clear. - Goal tool calls flow through the same in-card permission prompt as chat turns — pending permission requests are now a FIFO queue, so a concurrent goal + chat request can no longer drop one.
--yolomakes goals fully autonomous. GoalSpec.Checklist(library): seedPursueGoalwith an existing plan — skips planning, respects done flags and evidence. The/goal resumemechanism, and the hook Phase 3 durable resume will reuse.GoalSpec.Permissionnow applies to the planner and checker sessions too (was maker-only) — without this, the checker under an agent with no default permission policy (e.g. the interactive TUI) was denied every side-effecting tool and could not run builds or tests to verify evidence.
🤖 Generated with Claude Code
v1.10.0 — goal loop (loop engineering / /goal)
Loop engineering comes to glue. Agent.PursueGoal turns one persistent objective into an autonomous loop — the /goal pattern (Codex, pi-goal), as a reusable library primitive.
How it works
- Plan — a planner decomposes the objective into a verifiable checklist.
- Maker — a fresh session (Ralph-style, seeded from the durable checklist so memory lives in state, not a growing transcript) works the open items.
- Checker — a separate session with its own model + verifier prompt audits each item against real evidence via structured output, and decides completion. The writer never grades its own homework.
- Decide — stop on
achieved,blocked(no progress),budget_limited, ormax_iterations.
Guardrails are first-class (MaxIterations, NoProgressLimit, TokenBudget); GoalSpec.Emit streams progress.
Built entirely on existing primitives (Session.Prompt, Session.PromptJSON, loop.Run/MaxTurns, Agent.Session) — no new dependencies.
This is Phase 1: the headless primitive. The TUI /goal command (Phase 2) and durable resume + branch isolation (Phase 3) follow. Designed in ADR-0016.
Verified
go build/vet/test ./... green; 7 tests cover every terminal status, the maker/checker call sequence, and event emission.
Full Changelog: v1.9.0...v1.10.0
v1.9.0 — TUI slash-command autocomplete
Type / and the commands come to you. The coding-agent TUI now has inline autocomplete for slash commands, matching the existing @-file picker.
What's new
- Typing
/opens a filtering command popup. ↑/↓navigate ·Tabcompletes ·Esccloses (keeping what you typed).Enterruns a fully-typed or no-argument command immediately, and completes an argument-taking command to/<name>so you can type the argument (e.g./model).- Opens only on a bare slash token (closes once you start typing an argument); mutually exclusive with the
@-file picker. - The command list is now a single source of truth shared by the picker and
/help, so they can't drift.
Verified
go build/vet/test ./... green; new tests cover trigger detection, prefix/alias matching, stable ordering, Tab-complete, Esc-keeps-text, and run-vs-complete Enter behavior.
Full Changelog: v1.8.0...v1.9.0
v1.8.0 — Gemini 3.x thought-signature fix
The headline: Gemini 3.x tool calls now work across turns. The default gemini-3.1-pro-preview returns an opaque thoughtSignature on its function calls and requires it echoed back on replay — without it, the second turn of any tool-using conversation died with 400 … Function call is missing a thought_signature in functionCall parts. That's fixed, verified live with a two-turn tool loop.
Changes
- Round-trip
thoughtSignature+includeThoughts(#311, PR #315) — capture the signature from function-call and thought parts (base64 onloop.ContentPart.Signature) and replay it verbatim; send prior thinking back as realthoughtparts; enableincludeThoughtson Gemini 3.x. This is the actual fix for the 400. - Synthetic
thoughtSignaturefallback (#312, PR #316) — when an active-loop model turn reaches Gemini 3.x without a real signature (compacted or pre-fix history), inject theskip_thought_signature_validatorsentinel so the request still validates. Scoped to the active loop and Gemini 3.x; real signatures are never overwritten. GOOGLE_GENAI_API_VERSIONenv knob (#314, PR #317) — pin the API version (e.g.v1alpha) to reach version-gated preview features without a code change.
Verified
go build/vet/test ./... green; gated live tests TestLiveToolLoopRoundTripsSignature, TestLiveSyntheticSignatureFallback, TestLiveSmoke all pass against gemini-3.1-pro-preview.
Notes
Investigation also closed #313 (schema/Unicode sanitization) as verified-unnecessary: Gemini 3.x accepts array-typed type and recursive $ref via parametersJsonSchema, and Go's encoding/json auto-sanitizes invalid UTF-8 — those JS-harness tricks are no-ops on glue's path.
Full Changelog: v1.7.0...v1.8.0
v1.7.0 — gemini default id correction (gemini-3.1-pro-preview)
Headline
Fix Gemini default id: gemini-3.1-pro-preview (the v1.4.0 default gemini-3.1-pro 404'd because the public id carries the -preview suffix on generativelanguage.googleapis.com v1beta).
Install
go install github.com/erain/glue/cmd/glue@v1.7.0
glue version
glue run --yolo --coding --work .Override paths still work
glue run --model gemini-2.5-proGLUE_MODEL=gemini-2.5-progemini.Options{DefaultModel: "gemini-2.5-pro"}orloop.ProviderRequest{Model: "gemini-2.5-pro"}
Library API
Additive only.
v1.6.0 — wide-terminal cap + glue version
Daily-driver friction round.
Install
go install github.com/erain/glue/cmd/glue@v1.6.0
glue version
glue run --yolo --coding --work .Fixes
-
TUI: cap transcript at 100 cols, center on wide terminals. Conversation no longer stretches edge-to-edge on a 200-col terminal. The viewport and the input box share a single
bodyMaxWidth = 100constant; on anything wider, the conversation column sits centered vialipgloss.PlaceHorizontal. Glamour markdown width inherits the cap. Header + status bar keep full width — they read better edge-to-edge. -
glue versionsubcommand. Prints module version, git revision, build time, and Go toolchain pulled from the linker-embedded build info. Same datago version -m $(which glue)exposes, just reachable as a first-class command so a stale binary is a one-line diagnosis:$ glue version glue v1.6.0 (59b5026706e7) · built 2026-06-08T19:17:43Z · go1.25Also reachable as
--versionand-v.
Library API
Additive only.
v1.5.0 — Catppuccin TUI theme (Mocha + Latte)
Headline
Catppuccin TUI theme. Mocha (dark) and Latte (light) flavors, picked automatically based on your terminal background.
The previous palette mixed Tailwind primaries under one purple accent — saturation levels didn't match, so colors shouted. Mocha/Latte are intentionally pastel: every color sits at similar lightness so the chrome reads as a coherent design system instead of an alert tree.
Install
go install github.com/erain/glue/cmd/glue@v1.5.0
glue run --yolo --coding --work .| role | Mocha (dark) | Latte (light) |
|---|---|---|
| accent | mauve #cba6f7 | mauve #8839ef |
| ink | text #cdd6f4 | text #4c4f69 |
| ok | green #a6e3a1 | green #40a02b |
| err | red #f38ba8 | red #d20f39 |
| warn | peach #fab387 | peach #fe640b |
| border | surface1 #45475a | surface1 #bcc0cc |
Glamour markdown output uses matching JSON style configs (glamour-mocha.json, glamour-latte.json) with chroma syntax highlighting via catppuccin-mocha / catppuccin-latte. On any JSON parse failure the renderer falls back to glamour.WithAutoStyle so a typo can't break the TUI.
Library API
Additive only. No breaking changes.
v1.4.0 — gemini-3.1-pro is the default
Headline
Default model for the gemini provider is now gemini-3.1-pro.
gemini-2.5-flash was removed from generativelanguage.googleapis.com v1beta on the current key surface and started returning 404 on generateContent. gemini-3.1-pro is the unmetered daily-driver target for this project.
Install
go install github.com/erain/glue/cmd/glue@v1.4.0Override paths still work
- CLI:
glue run --model gemini-2.5-pro - Env:
GLUE_MODEL=gemini-2.5-pro - Library:
gemini.Options{DefaultModel: "gemini-2.5-pro"}orloop.ProviderRequest{Model: "gemini-2.5-pro"}
What's not in this release
The Catppuccin TUI theme (#305) is queued as v1.5.0 — landing right after.