Skip to content

v0.1.8

Pre-release
Pre-release

Choose a tag to compare

@The3eard The3eard released this 20 Apr 12:02

The biggest release since the MVP — everything since v0.1.7-beta ships in one cut. Five phases of feature work plus a deep architecture and performance pass: visual bisect, CLI auth, the full AI stack (three providers, headless background runs in worktrees), GitLab + GitHub forge integration with bundled CLIs, the provider architecture cleanup, and the E2E + tracing infrastructure.

AI Background Worktree Runs (Phase 10)

Launch a headless AI coding run inside a fresh git worktree without opening a terminal. Three entry points: tab bar button, AI Sessions header, and Cmd+Shift+A. Prompt source: free text, saved prompt from .claude/prompts/, or skill from .claude/skills/ (user or project scope). Provider: Claude Code, Codex, or OpenCode. Worktree root configurable (default .beardgit/ai-worktrees); concurrency cap configurable (default 3) with FIFO queueing past the cap.

  • ai-providerAiBackgroundRunInput + AiBackgroundRunStatus + AiTokenUsage types; launch_background trait method with NotSupported default; MockProvider override for tests.
  • claude-code / codex / opencode — headless command builders with provider-specific flags (Claude: --print --output-format stream-json --verbose; Codex/OpenCode: prompt concatenation fallback where skill/prompt flags aren't native).
  • task-runnerTaskKind::AiBackground variant + spawn_with_options with stdin piping (backwards compatible — spawn() unchanged).
  • app-coreAiBackgroundCoordinator with full lifecycle (Queued → Running → Completed / Failed / Cancelled), concurrency cap enforcement, worktree creation via git-engine and cleanup on discard. 6 Tauri commands + 2 settings commands.
  • git-enginecreate_worktree_at helper used by the coordinator.
  • storageAppConfig gains ai_worktree_root, ai_background_concurrency_cap, ai_prompt_auto_accept fields with serde defaults.
  • FrontendCreateBackgroundRunDialog with Free / Saved / Skill tabs, BackgroundRunStatusBadge, BackgroundRunTranscript with ANSI stripping, session detail + list integration, settings card, ~50 i18n keys per locale. aiBackground.ts store wires ai-background-output / ai-background-status events via requestAnimationFrame batching (matches the tasks.ts pattern); merges live runs into aiSessions for unified sidebar display.
  • Testing — 13 tests in app-core::ai_background (coordinator lifecycle + cap + cancel + discard), 5 in ai-provider, 3 per provider for argv builders, 7 vitest tests for the store.

Known follow-ups for a later release: "View changes" button (deferred — merge-editor expects a conflict state, current release ships "Switch to worktree tab" as the review path), toast notification event wiring (i18n keys present), and an end-to-end spec exercising the full dialog (placeholder at e2e/specs/regression/ai-background.spec.ts).

Beta Audit — Performance & Code Quality

A bundled audit pass landing 15 fixes from the beta-audit spec — the highest-leverage cleanup before tagging the release.

Performance (high impact)

  • Cache which::which() results per provider kind on AppState — repeated provider detection no longer hits the filesystem.
  • Replace task polling loops with TaskManager::wait_for_terminal backed by tokio::sync::Notify — no more spin-wait on long-running tasks.
  • Memoise Arc<dyn ForgeProvider> keyed on (provider_index, project_path) — repeated forge lookups skip the construction cost.

Correctness

  • Populate the GitLab label cache so issue labels render with their real colour.
  • Unify MrPr.labels with Issue.labels on Vec<Label>; PillRow now renders the real label colour everywhere.
  • Drop redundant refreshIssueList calls on label / assignee / milestone mutations — the optimistic update already covers it.
  • Route resolve_startup_theme through src/lib/api/tauri.ts for consistency with every other IPC call.
  • Key #each blocks over MR/PR diff files + comment lists for stable Svelte reconciliation.

Code quality

  • Extend the trait-crate purity CI guard to include ai-provider (alongside provider and forge-provider).
  • Share build_gh_upload_args / build_glab_upload_args across crates instead of duplicating the argv shape.
  • Add TaskManager::get_status and a frontend taskById derived map for O(1) status lookup.
  • Move shell_escape into helpers.rs with unit tests.
  • Rename MrPrComment to ForgeComment in TypeScript (deprecated alias kept for one release).
  • Extend MrPrFilter with author / label / text fields, matching IssueFilter.
  • Rename the render:text perf measure to render:badges-and-text to match what it actually measures.

GitLab Provider Polish

  • Per-file +/- countsprojects/:id/merge_requests/{n}/diffs returns the raw patch but no additions/deletions counts. We were hardcoding 0/0, which showed as "+0 -0" beside every file in the MR detail panel. New count_patch_changes parser counts + / - content lines while skipping +++ / --- file headers and @@ hunk headers. 4 unit tests.
  • glab mr list boolean state flags — glab (both 1.46.1 and 1.92.1) does not accept --state <value>; passing --state opened made glab reply "Unknown flag" and our list returned empty. Switched to the boolean form glab actually supports: default → opened, --closed, --merged, --all. Dropped the unused state_to_glab_str helper.
  • Provider-aware sidebar label — sidebar "Merge Requests" now reads "Pull Requests" when the active provider is GitHub. View id stays merge-requests so routing is unchanged; only the label swaps. New sidebar_pull_requests i18n key.
  • MR/PR list errors are surfacedrefreshMrPrList() no longer swallows failures. Errors go to a new mrPrListError store and MrPrList renders them inline with a Retry button instead of an empty list with no explanation.

Settings — Connection Guide

  • "How to connect" guide — collapsible help block in Settings → Connection covering standard gitlab.com / github.com setup (PAT + CLI flows), self-hosted GitLab with OAuth and token fallback, plus troubleshooting for the multi-config warning and the 404-when-self-hosted-points-at-gitlab.com trap.

Distribution

  • macOS x64 dropped from the release matrix — Apple Silicon runners are now the only macOS target. Reduces CI matrix time and avoids the dual-bundle confusion at install time.
  • Bundle formats trimmed.msi, .deb, and .rpm removed from the bundle list. The .dmg, .AppImage, and .exe remain as the supported install paths per platform.
  • First-launch documentation — README now explains the unsigned-build workaround for macOS until code signing lands (Gatekeeper right-click → Open). E2E fixture path no longer pins to a hardcoded location; derived from the working directory at runtime so contributors can run the suite from anywhere.
  • Repository hygiene — AI assistant artifacts (.claude/, .codex/, etc.) untracked from the repo and added to .gitignore.

Forge Integration (Phase 8)

Full daily-dev-workflow parity with GitHub and GitLab web UIs, behind a clean provider abstraction.

MR/PR Enhancements (8.2) — 11 new forge methods. Add/remove labels and reviewers post-creation, mark draft ↔ ready, reopen closed MR/PRs, resolve / unresolve GitLab discussion threads, and check out an MR/PR branch locally via TaskManager-streamed CLI output. The detail panel gains LabelPicker, ReviewerPicker, draft toggle, reopen button, per-comment resolve controls, and a "Checkout locally" action.

Issues (8.3) — Complete issue management as a new sidebar vertical. List / get / create / edit / close / reopen / comment plus assignees, labels, and milestones via 13 new trait methods. New IssueView, IssueList, IssueDetail, CreateIssueDialog, AssigneePicker, MilestonePicker components. Generic shared LabelPicker and Xrefs components plus a new xrefs.ts utility that auto-links #NNN, !MMM, @user, and short SHAs inside any text body.

CI/CD Control (8.4) — Actions on top of the existing Pipelines view. Trigger, retry, retry-failed-only, per-job retry, cancel, and list-workflows via six new CiProvider methods implemented over reqwest. PipelineList gets a "Run Workflow" button and row context menu; PipelineDetail gains action buttons and per-job retry. New TriggerWorkflowDialog with dynamic input form. GitHub PAT workflow scope hint surfaced in provider setup.

Releases (8.5) — Release management as its own vertical. 9 new trait methods including asset upload that streams via TaskManager for non-blocking progress. New ReleaseView, ReleaseList, ReleaseDetail, CreateReleaseDialog, AssetUploadProgress components plus an atomic create_tag_and_release flow that pushes the tag and creates the release in one streamed task. The cross-reference parser is extended to recognise release tags against a live tag cache.

ForgeProvider Trait (8.1) — New forge-provider crate extracts the ForgeProvider trait and shared types (MrPr, Issue, Release, Label, User, Milestone, Comment, …) with a ForgeError enum. cli-provider split into GitHubCli and GitLabCli structs each implementing the trait. build_forge_provider(AppState) → Arc<dyn ForgeProvider>. Zero user-visible change; foundation for 8.2–8.5.

Bundled CLI Binaries (Phase 7.2)

BeardGit now ships gh (v2.62.0) and glab (v1.46.1) as Tauri sidecars on macOS arm64, Linux x64, and Windows x64 — no manual install required. scripts/download-cli-binaries.js pulls pinned binaries from the official release URLs; the Build and Release pipelines fetch the matrix-specific target before tauri-action. resolve_cli_binary() checks the sidecar location first and falls back to the system PATH, so existing installations keep working. Validated end-to-end across all four platforms.

Terminal Enhancements (Phase 7.1)

  • OSC 7 cwd auto-detection — terminals emit their current working directory on every prompt; when the cwd matches an open project path, the terminal tab auto-links to that project's composite tab.
  • AI provider auto-detection — a lightweight polling loop detects when a terminal launches claude, codex, or opencode and updates the tab label plus brand icon dynamically.

UI Polish & Bug Fixes (Phase 7.6)

  • Bisect graph integration — good/bad/current/skipped commits get colored overlays in the canvas graph; right-click a commit for "Mark as good / bad / skip".
  • Worktree lock / unlock — full git worktree lock / unlock wired through git-engine with context menu controls.
  • Worktree "Open in graph" — navigates the graph view to the worktree's branch.
  • AI Config Editor live reload — new watcher::ai_config module picks up external edits to settings.json, agents/*.md, skills/*/SKILL.md, and CLAUDE.md files; the editor refreshes without losing in-progress changes.
  • AI Sessions "Focus" — focuses the linked terminal tab if the session has one; otherwise launches claude --resume <sessionId> in a new PTY terminal.

Infrastructure (Phase 7.5)

  • Log rotationstorage::logging::purge_old_logs() auto-removes beardgit.log.* files older than 7 days on startup (async, non-blocking).
  • Tracing on git writes — 41 #[instrument] spans on git-engine write operations (bisect / operations / conflict / reset / clean / remote / worktree / submodule / interactive_rebase). Sensitive fields (commit bodies, PR descriptions, PAT tokens) excluded via skip(...).
  • Tracing on Tauri commands — 80 #[instrument(name = "cmd::…")] spans across 19 command modules. Hierarchical names make log grepping trivial.

Performance (Phase 7.7)

  • Graph render profiler — six performance.mark pairs around the render loop plus a dev-only FPS overlay toggled with Ctrl+Shift+P. Measurement infrastructure for future optimisations without runtime overhead in production bundles.
  • Interactive terminal pool — 3-deep xterm.js instance pool recycles terminals across tab open/close. Faster tab spawn, lower GC pressure.
  • CodeMirror language cache — module-level Map<string, Extension> short-circuits repeated dynamic imports per file extension. Second-and-subsequent opens of a language are instant.

Code Quality (Phase 7.3)

The remaining items from Phase 6.3 plus anything picked up along the way. Generic <List> component now backs 10 consumers (Branch / Tag / Stash / Reflog / MrPr / Worktree / Submodule / Release / Issue / AiSession). fetchIntoStore / fetchListIntoStore / fetchPageIntoStore helpers consumed by 10 stores. Two residual serde_json::from_str call sites in cli-provider/src/{github,gitlab}/mr_pr.rs swapped for the shared run_json helper.

E2E Testing (Phase 7.4 + follow-up)

Full WebdriverIO + tauri-driver suite covering every major vertical. 9 spec files, ~53 tests: app-launch, navigation, golden-path, and regression suites for graph / branches / staging / terminal / bisect / settings. 6 new page objects, data-testid attributes across the UI, and a Linux e2e-tests job in ci.yml. Follow-up pass in the same release cycle fixed every layer end-to-end: ESM __dirname shim for wdio v9, specs glob resolution, tauri-driver hostname/port, workspace-root binary path, VITE_BEARDGIT_E2E frontend hook, and switching to tauri build --debug --no-bundle so the frontend actually embeds. A new Docker harness (e2e/Dockerfile + npm run e2e:docker) lets macOS contributors run the full suite locally in ~1–2 min per iteration.

Provider Architecture Cleanup (Phase 9)

Pure refactor. provider/lib.rs (883 LOC of trait + types + kind + error) split into traits.rs / types.rs / kind.rs / error.rs / http_helpers.rs / mock.rs; lib.rs is now 43 LOC of re-exports. cli-provider/src/{github,gitlab}.rs (~800 LOC each) converted to directory modules with per-vertical submodules (mr_pr, labels, reviewers, lifecycle, discussions, checkout, issues, releases). The impl ForgeProvider block stays in mod.rs as pure delegation to feature-scoped methods — no file exceeds 400 LOC. A CI grep guard in ci.yml enforces that provider and forge-provider never import reqwest, tokio, tauri, or hyper. Shared HTTP primitives (api_error, retry_after_secs, trim_base_url) extracted into provider::http_helpers and consumed by both gitlab-api and github-api. crates/CLAUDE.md refreshed with the new layout and an "Adding a new forge capability" walkthrough.

Security

  • npm audit --audit-level=moderate clean. Override added for serialize-javascript (wdio transitive dep) that upstream hadn't patched yet.

Tooling

  • npm run e2e:docker (plus :rebuild and :shell) — one-command local E2E.
  • e2e/README.md documents the happy-path authoring pattern so test authors have a template.

Phase 6 — Bisect, CLI Auth, AI Views, Multi-Provider, Code Quality

(Previously drafted as a standalone [0.1.8] release; folded into the unified [0.1.8] cut since it never tagged separately.)

Git Bisect

  • Visual bisect workflow with good/bad/skip controls and progress indicator
  • Auto-bisect mode: provide a test command, BeardGit runs git bisect run and reports the culprit
  • New git-engine bisect module with full lifecycle (start, good, bad, skip, reset, log)
  • 8 new Tauri commands, dedicated store, 2 Svelte components (BisectWorkflow, AutoBisectDialog)

CLI Auth (gh/glab)

  • gh auth status and glab auth status detection — shows CLI login state in Settings
  • Terminal-based login flow: "Login with CLI" opens interactive gh auth login / glab auth login in a PTY tab
  • Unified Authentication settings page combining Token Auth and CLI Auth sections
  • New cli-provider auth module with status parsing and terminal login commands

AI Config Editor

  • Dual file tree (project-scoped + user-scoped) showing all AI config files
  • Editable CodeMirror pane for settings.json, agents, skills, and CLAUDE.md files
  • Create Config dialog for adding new agent/skill/settings files
  • 3 new Tauri commands: ai_get_config_content, ai_save_config_content, ai_create_config_file

AI Sessions

  • Project-scoped session list showing active and recent Claude Code sessions
  • File watcher on ~/.claude/sessions/ with auto-refresh on changes
  • Session metadata: model, start time, duration, token usage, status (active/completed)

AI Worktree Enrichment

  • EnrichedWorktree type combining git worktree data with AI provider status
  • AI badges on worktrees created by Claude Code / Codex / OpenCode
  • Context menu with cleanup action for orphaned AI worktrees

Codex & OpenCode Providers

  • New codex crate: full AiProvider implementation with binary detection, command building, and config discovery
  • New opencode crate: full AiProvider implementation with binary detection, command building, and config discovery
  • Both wired into app-core provider factory with automatic detection
  • Dynamic terminal dropdown: only shows providers detected on the system
  • Codex brand color corrected (#10a37f → #ffffff)

Structured Error Logging

  • Structured file logging via tracing with tracing-appender daily rotation
  • Logs written to ~/.local/share/com.beardgit.app/logs/ (platform-appropriate data dir)
  • New ErrorDialog component with copy-error-to-clipboard and open-log-file actions
  • All dialogs (Confirm, Clean, CreateMrPr, PatchPreview, TagCreate, CreateWorktree) upgraded with error display

Composite Tab Upgrade

  • Multi-segment tabs: N terminals + worktrees per project in a single composite tab
  • Fixed segment ordering: Project → Worktrees → AI Terminals → Terminals
  • Terminal button always adds to the active project's composite tab instead of creating standalone tabs

Code Quality — commands.rs Split

  • Split monolithic commands.rs (3,267 LOC) into 24 feature-based modules under commands/
  • Modules: advanced, bisect, branch, ci, clean, cli_auth, commit, config, conflict, diff, gitignore, graph, helpers, logging, mod, mr_pr, patch, project, provider_auth, reflog, remote, repository, settings, staging, stash, submodule, tag, theme, worktree
  • Extracted shared dialog.css (93 lines) replacing duplicated dialog styles across 7 components
  • New fetchIntoStore utility for consistent store-loading patterns

E2E Test Infrastructure

  • WebdriverIO + tauri-driver configuration for end-to-end testing
  • Fixture repo setup script (e2e/fixtures/setup.sh) for reproducible test environments
  • Page objects: sidebar.page.ts, graph.page.ts
  • Initial specs: app-launch.spec.ts, navigation.spec.ts

Bug Fixes & Polish

  • AI Config file tree correctly distinguishes project vs user scope
  • AI Sessions auto-cleanup on component destroy (watcher unsubscribe)
  • CreateConfigDialog validates file paths and prevents duplicates
  • Store helpers centralized with fetchIntoStore reducing boilerplate across stores