Skip to content

GitStudio 1.0.0: sidebar commit rail, live sync UX, store listing + hardened release pipelines - #1

Merged
antonarnaudov merged 89 commits into
mainfrom
claude/ai-mcp-desktop
Jul 14, 2026
Merged

GitStudio 1.0.0: sidebar commit rail, live sync UX, store listing + hardened release pipelines#1
antonarnaudov merged 89 commits into
mainfrom
claude/ai-mcp-desktop

Conversation

@antonarnaudov

Copy link
Copy Markdown
Contributor

What this ships

The 1.0.0 release branch — feature work plus everything needed to publish to real users.

Product

  • Sidebar-native Commits rail: purpose-built commit log for the sidebar — per-row topology hugging, taut curves, mini author avatars on the nodes, scoped search, promote-to-graph.
  • Live sync UX (extension Changes view + desktop Branches view): ahead/behind counts are real Pull/Push buttons with completion-driven spinners; the branch dialog runs fetch/pull in place (menu stays open, per-branch ↑/↓ badges update live); pull a branch without checking it out; copy branch name; backdrop + child-dialog differentiation.
  • git-service: StatusProvider decoupling, per-ref ahead/behind from one for-each-ref, discard/status tests.

Release prep

  • Store listing: new marketplace README with real screenshots (rendered from the actual webview bundles through the engine's own layout), tightened description/keywords/categories/badges, 1.0.0 versions, CHANGELOG.
  • Pipelines hardened per an adversarial audit (11 confirmed findings — details in the commit message): tag↔version guards, --latest=false on extension releases so the desktop auto-updater's /releases/latest can never break, single create-release job (no 4-way matrix race), retired macos-13macos-15-intel, ubuntu-22.04 for AppImage glibc reach, fixed upload globs, pinned no-space artifact names (stable website download URLs), loud-fail store publishes, CI test matrix on all release OSes.
  • macOS in-app update check disabled (no mac feed yet; unsigned builds can't apply updates).

Release plan (after merge)

  1. git tag ext-v1.0.0 && git push origin ext-v1.0.0 → vsix on the Release + Marketplace/Open VSX publish (needs VSCE_PAT/OVSX_PAT secrets).
  2. git tag app-v1.0.0 && git push origin app-v1.0.0 → mac arm64/x64 dmg+zip, windows exe, linux AppImage+deb on the Release, ready for gitstudio.dev.

🤖 Generated with Claude Code

claude and others added 30 commits June 23, 2026 23:39
Create the visual identity for the org/suite. The mark is a merge — two
branches converging into one commit — standing for the brand's promise of
bringing the best of every Git tool together into one free, open project. The
two-toned purple→magenta lanes echo the colored commit graphs that GitLens /
GitKraken gate behind a paywall. Three nodes, every one a real commit. It
builds on Merge Studio's dark-squircle + purple identity but sits one level up
as the umbrella brand.

brand/ contains:
- master app icon (SVG + 1024/512/256/128 PNG) and an org-avatar export
- transparent mark + one-color (white/ink) variants
- horizontal wordmark lockups for dark and light backgrounds (Inter SemiBold,
  text outlined to paths so no font is required to render them)
- favicon (SVG + 32/16 PNG)
- alt/ G monogram mark
- a brand guide (README) and a font-free generate.py that reproduces the marks

Also surface the mark at the top of the main README.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015tmmJ7s9HR29TDLnYM7oPx
The previous mark was just the merge-Y, which reads as "git" but says
nothing about Studio being a full platform/suite. Evolve it into an
isometric **commit cube**: the same two-branches-merging-into-one is now
the cube's three glowing front seams, its corners are commit nodes, and the
whole thing resolves into one solid, faceted object — git's graph built into
a unified platform.

- Rewrite generate.py around commit_cube() (mono + gradient variants); keep
  the G monogram alt.
- Regenerate icon / mark / mono / favicon SVGs and all PNG exports
  (icon 1024-128, avatar, favicons 32/16, mark-512).
- Swap the embedded merge-Y for the cube in both wordmark lockups and
  re-render their PNGs.
- Update brand/README to describe the cube.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015tmmJ7s9HR29TDLnYM7oPx
Iterated on color to fix figure/ground: violet lines on a violet cube were
invisible. The cube body is now a desaturated **slate**, and every merge-Y
line and every commit node is one bright **violet tone** (#A98CFF) so the
branch/merge graph and its commits read clearly and stay unmistakably "git,"
while the cube still reads as one solid platform.

- generate.py: slate face gradients, single-tone violet spine + nodes,
  darker slate squircle background; regenerate all SVGs + PNG exports.
- Re-embed the recolored cube in both wordmark lockups and shift the
  "Studio" text gradient to a violet ramp; re-render wordmark PNGs.
- brand/README: document the slate-body / violet-line palette.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015tmmJ7s9HR29TDLnYM7oPx
Stand up GitStudio as an npm-workspaces repo holding the shared core plus both
front-ends (extension now, desktop reserved):

- packages/engine — pure diff/merge/alignment + conflict markers, copied from
  merge-studio; flattened layout, zero vscode/monaco/fs imports. 34/34 tests green.
- packages/host-bridge — the host-agnostic message protocol.
- packages/webview-ui — the Monaco merge/diff views + ribbons/theme/decorations,
  rewired to import the engine + protocol via @gitstudio/* workspace aliases.
- packages/git-service — placeholder for the M1 git data layer (no vscode import).
- apps/extension — gitstudio.gitstudio shell (onStartupFinished), 3-context esbuild
  (extension + shared webview + monaco worker), dompurify hardening. Builds + packages
  a 1.3 MB .vsix.
- apps/desktop — reserved slot for the Electron app (M13).

Tooling: Apache-2.0 LICENSE + NOTICE, engine-purity guard (scripts/check-engine-purity.sh),
CI + ext-v* release pipeline (Node 22, dual-registry), TS Bundler resolution via package
exports (no baseUrl, TS6-clean).

Gate: npm test green, all 5 workspaces type-check, purity guard passes, .vsix packages.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Host-agnostic Git data layer in @gitstudio/git-service (Node-only, no vscode import):

- GitProcess — bounded spawned-git pool (maxConcurrent=5), args always as an
  array, hardened flags (-c log.showSignature=false -c core.commitGraph=true) +
  GIT_OPTIONAL_LOCKS=0, run() (buffered, resolves on non-zero, AbortError on
  signal) and stream() (pull-based async generator, never buffers stdout
  unbounded), dispose() kills in-flight children.
- LogProvider.streamCommits — git log --parents --date-order with \x1f field /
  \x1e record framing (robust to subjects/bodies with spaces, pipes, quotes,
  tabs, newlines), --all + paging (maxCount/skip) + path filters.
- RefProvider — listRefs (heads/remotes/tags via for-each-ref + stashes) and
  getHead (branch/detached/sha).
- GitContext facade + NodeGitAdapter (HostGitAdapter the desktop app reuses).
- Shared git contracts in @gitstudio/host-bridge/git (CommitRecord/GitRef/
  RepoHead/HostGitAdapter), type-only.

Gate: 10/10 hermetic temp-repo tests pass; type-checks clean; purity guard OK.
Verified live against ../merge-conflict-tests (3 commits, correct parent counts,
all refs + HEAD resolved).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
GitStudio activity-bar container with two native tree views wired to the M1
git-service:

- RepoManager: discovers repos via vscode.git getAPI(1), builds a GitContext per
  repo (root + api.git.path), tracks the active repo by active-editor path, and
  refreshes (400ms-debounced) on repo open/close, repo.state changes, and a
  FileSystemWatcher on .git/{HEAD,MERGE_HEAD,rebase-*,refs/**} (the merge-studio
  op-state trick) for instant updates. Sets the gitstudio.hasRepo context key.
- Commits view: first ~150 commits of HEAD via LogProvider (AbortController
  cancels stale loads), git-commit icon, "<short-sha> · <relative date>"
  descriptions, rich Markdown tooltips, copy-SHA action.
- Branches view: Local / Remotes / Tags collapsible groups from RefProvider,
  current branch flagged, themed icons + upstream tooltips.
- Monochrome currentColor activity-bar icon; viewsWelcome for the no-repo state;
  refresh buttons. .vscodeignore whitelists the icon so it ships.

Pure helper relativeTime extracted + unit-tested (7/7). FileDecorationProvider
deferred to M7, Stashes to M9.

Gate: check-types clean, esbuild builds (13 KB host), .vsix packages (1.31 MB),
purity OK, 7/7 tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
GitLens-grade ambient blame, grounded in a pure tested parser:

- engine/blame/parse.ts — pure parseIncrementalBlame() for `git blame
  --incremental` output: caches commit metadata by sha (later metadata-less
  groups reuse it), expands line groups, handles CRLF/ordering/boundary/previous.
  9 golden tests (captured real output + synthetic). Types live in
  @gitstudio/host-bridge/blame (type-only single source of truth).
- git-service/BlameProvider — blameFile({ rev?, contents?, signal? }); dirty
  buffers blame via `--contents -` over stdin (GitProcess.run gained an optional
  `input`); surfaces the 0000… "Not Committed Yet" sha. Added to GitContext.blame.
  3 hermetic tests.
- extension BlameController: debounced (200ms) current-line inline annotation
  (stale-cancelling), status-bar item → line-actions QuickPick, trusted-markdown
  hover with copy-sha link, full-file annotation toggle with a warm→cool code-age
  heatmap (viewport-limited), per-doc version-keyed cache cleared on edit. One-time
  native git.blame.* disable (never overrides a user value). Settings + keybinding
  (cmd/ctrl+shift+g b).

Gate: engine 43/43, git-service 13/13, extension 7/7, check-types clean, purity OK,
builds + packages. Verified live: app/version.py attributes lines to base vs main.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
engine/graph/layout.ts — computeGraphLayout(commits) assigns each commit a
column + stable color and emits per-row GraphSegments (vertical/diagonal lane
connections) sufficient to render a GitKraken/GitLens-style branch graph:

- active-branches lanes: a commit takes the leftmost lane awaiting its sha (or a
  fresh lane if it's a tip); first parent continues the column, extra parents
  fork new lanes; branches merging in converge into the node's column.
- shared/criss-cross parents reuse the awaiting lane (no duplicate lanes);
  trailing-lane compaction only (interior stability, no jitter); colors cycle
  0..7 and stay stable per lane; deterministic (no Date/random).
- handles linear, fork+merge, octopus (3+ parents), criss-cross, multiple roots,
  and boundary commits whose parents are absent (no crash).

9 golden tests (~40 assertions). Engine 52/52, types clean, purity OK.
Verified on ../merge-conflict-tests (3 rows / 2 columns: main col0, feature col1).

The virtualized Lit webview that renders this (M4b) follows.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A GitKraken/GitLens-grade commit graph rendered in a webview panel, reusing the
M4a lane algorithm:

- webview-ui/graph: <gitstudio-graph> Lit element, virtualized via
  @tanstack/virtual-core (only visible rows in the DOM — smooth at 50k+). 24px
  rows, 14px lane pitch, crisp half-pixel-aligned SVG gutter with cubic-bezier
  S-curves for merges/lane-shifts (gutter.ts), hollow node ring for merges,
  hover lane-focus dimming. Row = [gutter | ref chips | subject | author | date |
  short-sha]. Theme-aware 8-color lane palette (dark/light/HC, live re-color),
  keyboard nav, hover/selected states + accent bar, loading/empty states.
- host-bridge/graphProtocol: type-only host<->webview message union.
- extension/graph: CommitGraphPanel (editor-area singleton, CSP+nonce), streams
  500 commits/page (--all) -> computeGraphLayout -> ref chips by sha, paged
  loadMore, debounced refresh. Commit context actions (checkout, branch/tag here,
  cherry-pick, revert, reset soft/mixed/hard w/ extra hard-confirm, copy
  sha/message) via GitProcess, conflict/stderr surfaced. gitstudio.showCommitGraph
  command + Commits-view title button. 4th esbuild bundle (graph.js 52K).

Gate: check-types clean, purity OK, all 4 bundles build, .vsix packages. Gutter
geometry verified on a diamond DAG (merge fans 2 beziers; columns/nodes correct).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- git-service/HistoryProvider (.history): fileHistory (git log --follow, \x1f/\x1e
  framing), lineHistory (git log -L<a>,<b>:<file> --no-patch, with a patch-parse
  fallback), fileAtRevision (git show rev:path). 5 hermetic tests (incl. a rename
  for --follow). git-service 18/18.
- extension/history:
  - revisionContentProvider — gitstudio-rev TextDocumentContentProvider (filename
    in path for language inference) + openRevisionDiff helper.
  - fileTimelineProvider — registers a native TimelineProvider for scheme file, so
    file history appears in VS Code's built-in Timeline; each entry diffs <sha>~1
    vs <sha>; cursor paging; refresh on repo change.
  - lineHistory — gitstudio.showLineHistory: a re-invokable QuickPick walker over
    the selection's line range (cmd/ctrl+shift+g h, editor context menu).
  - revisionNavigation — openChanges (vs HEAD), openFileAtRevision, back/forward
    revision stepping.
  - reflog — gitstudio.showReflog recovery browser (reuses commit actions); the
    safety-net M8's Undo builds on.

Gate: git-service 18/18, engine 52/52, types clean, purity OK, builds + packages.
Verified live on app/version.py: file history + line-history(L3) + fileAtRevision.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
GitStudio now bundles the JetBrains-style merge + diff, reusing the shared
webview UI (built unchanged) and a portable conflict reader:

- git-service/ConflictProvider (.conflict, vscode-free): getConflictVersions
  reads index stages git show :1/:2/:3 with a parseConflictMarkers fallback
  (engine), getHeadVersion, isConflicted, listConflicts (porcelain=v2 unmerged
  parse). 6 hermetic tests on a real git-merge conflict. git-service 24/24.
- extension: gitstudio.mergeEditor CustomTextEditorProvider (resolves
  base/ours/theirs, classifies content/add-add/deleted-by-us/-them, apply writes
  + stages the result), DiffPanel + gitstudio.compare/openDiff, ported webview
  html (CSP nonce + __JBMERGE__ worker global). AutoOpenConflicts rides
  RepoManager.onDidChange to open newly-conflicted files in the merge editor
  (gitstudio.merge.autoOpen, default on); gitstudio.resolveInMergeEditor for
  manual open. customEditors + menus + setting contributed.

Gate: git-service 24/24, engine 52/52, types clean, purity OK, all webview
bundles build + package. Verified live: a real fixture merge surfaced 7 conflicts;
version.py read from git-stages (hasBase). Fixture restored.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Line-level staging VS Code lacks, plus a daily-driver staging/commit surface:

- engine/staging/applyLineChanges.ts (pure): applySelectedChanges(original,
  modified, ranges) reconstructs index content keeping ONLY selected hunks
  (buildDiffModel-based), preserving CRLF + trailing-newline; computeHunks,
  applyAllChanges. 13 golden tests.
- git-service/StagingProvider (.staging, vscode-free): stageFile/unstageFile/
  discardChanges, stageContent (hash-object -w + update-index --cacheinfo),
  index/headContent, commit (-F - with amend/signoff/author/no-verify). 9
  hermetic tests incl. the killer "stage exactly one line" check.
- extension: Changes view (Merge/Staged/Unstaged groups, colored ThemeIcons for
  status, inline stage/unstage/discard + group-all, opens index/HEAD diffs);
  stageSelectedLines/unstageSelectedLines/stage|unstageHunk commands (editor +
  diff context); Commit webview (auto-grow message, amend prefill, sign-off,
  author override, staged count, Commit + Commit&Push, Enter-to-commit, hooks run).

Gate: engine 65/65, git-service 33/33, types clean, purity OK, builds + packages.
Verified: staging line 0 of a 2-change file stages exactly that line.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- engine/rebase/todo.ts (pure): parseRebaseTodo/serializeRebaseTodo — models the
  6 commit verbs (long+short), passes through comments/exec/label/reset/merge/
  break/update-ref verbatim, byte-for-byte round-trip on unedited todos, EOL +
  trailing-newline preserved. 11 golden tests.
- git-service/SnapshotProvider (.snapshot, vscode-free): capture (HEAD + branch +
  `git stash create` of dirty tree without touching it), restore (reset --hard +
  re-apply stash), isPushed (remote-tracking containment). 7 hermetic tests.
- extension:
  - UndoLedger: runWithUndo() wraps every destructive op (reset/checkout/
    cherry-pick/revert/amend/merge-apply/rebase) with a snapshot + "Undo" toast;
    gitstudio.undo restores, or offers Revert when the change is already pushed;
    showUndoHistory QuickPick; ring buffer in workspaceState; undo on cmd/ctrl+
    alt+z (never hijacks editor undo).
  - Interactive rebase: git-rebase-todo CustomTextEditorProvider (captures even
    terminal `git rebase -i` via GIT_SEQUENCE_EDITOR='code --wait'), reorderable
    Lit-free webview with per-action colors, drag + alt-arrows, summary header,
    Start/Abort; echo-loop guard; conflicts route to the merge editor. New
    rebase.js bundle.

Gate: engine 76/76, git-service 40/40, types clean, purity OK, builds + packages.
Verified: todo round-trips byte-for-byte; squash/drop edits serialize cleanly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nc status

Fills out the suite into a complete daily driver:

- git-service (vscode-free): StashProvider, WorktreeProvider, BranchOps,
  RemoteOps, SyncOps (ahead/behind, push --force-with-lease, pull/fetch),
  TagOps — all on GitContext. 21 new hermetic tests (61 total).
- extension:
  - Stashes view (apply/pop/drop/branch + diff preview, Stash w/ options).
  - Worktrees view (open/add/remove/lock/prune, current marked, tildified paths).
  - Branch/remote/tag context actions on the Branches view (checkout, merge,
    rebase-onto, rename, delete, push, set-upstream, compare, new-branch,
    create-worktree; remote checkout/delete; tag checkout/delete/push).
  - Search & Compare view (search by message/author/file/pickaxe/sha; compare
    A..B refs).
  - Status-bar sync segment ($(git-branch) branch + ahead/behind) → Sync/Push/
    Pull/Fetch/Publish QuickPick.
  Destructive ops (merge/rebase/branch-delete/stash pop+drop) route through the
  Undo envelope. push.forceWithLease setting.

Gate: git-service 61/61, engine 76/76, types clean, purity OK, builds + packages.
7 sidebar views registered.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ize)

Optional, off-until-configured AI that never gates or breaks git:

- engine/ai/gitBrainCore.ts (pure): truncateDiff, buildCommitStyle/Commit/
  Explain/Summarize/PrDescription prompts, Anthropic SSE parser, response
  text extractor. 15 hermetic tests, no network.
- extension/ai:
  - GitBrain facade + GitBrainProvider interface; provider selection by
    gitstudio.ai.provider (auto|anthropic|vscode-lm|off). auto prefers zero-key
    vscode.lm (Copilot), else Anthropic if a key is set, else hidden. Sets
    gitstudio.ai.enabled context key; returns null (never throws) when unavailable.
  - AnthropicProvider: host-side fetch to api.anthropic.com/v1/messages
    (x-api-key + anthropic-version 2023-06-01), no SDK; injected key getter
    (portable); cacheable repo-style system prefix (ephemeral); models
    fast=claude-haiku-4-5, mid=claude-sonnet-4-6, deep=claude-opus-4-8; SSE
    streaming for explain; friendly 401/429/529 handling.
  - VSCodeLmProvider: feature-detected vscode.lm Copilot path (zero key).
  - Key in SecretStorage, NEVER sent to a webview: commit box posts a request,
    host runs GitBrain, posts back only the text.
  - Commands: setApiKey/clearApiKey, generateCommitMessage (sparkle in commit
    box), explainDiff (streamed panel), summarizeChanges; palette-gated.

Gate: 158 tests pass (15 new), types clean, purity OK, builds + packages.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A GitHub-PR-extension-grade flow inside GitStudio:

- engine/forge/parseRemote.ts (pure): remote URL -> {host,owner,repo} for
  git@/https/ssh shapes, .git stripping, github-only gate. 10 golden tests.
- extension/pr:
  - GitHubAuth (VS Code built-in github session, silent-first/interactive-on-
    action, gitstudio.github.connected) + githubApi fetch client (list/detail/
    files/checks, reviews, create, merge, requested_reviewers) with friendly
    401/403/404/422/network handling.
  - Pull Requests view (Waiting for my review / Created by me / All open, CI
    glyphs, checkout/open/review/merge actions, connect-GitHub welcome).
  - Checkout PR (fetch pull/<n>/head, cross-fork) ; PR description webview
    (safe escaped renderer, checks, files->diff, merge/checkout/review).
  - Review mode: one Comments controller + self-managed pending-thread registry;
    inline draft comments -> submit one review (Comment/Approve/Request-changes)
    with comments[{path,line,side,body}]; one-off comment; reviewing context key.
  - Create PR (push w/ upstream, base pick, title/body from commits, optional
    AI-drafted body via GitBrain, draft/ready, 422 handled).
  - defaultMergeMethod setting (squash).

Gate: engine 86/86, git-service 61/61, types clean, purity OK, builds + packages.
parseRemote verified on git@/https/ssh/gitlab/local inputs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The extension is release-ready:

- Manifest coherence: declared a missing command, every command under the
  "GitStudio" category with clear titles/icons, no dup ids. Keybindings migrated
  to one conflict-free Ctrl/Cmd+Alt+G <key> family (B blame, H line-history, D
  open-changes, S/U stage/unstage lines, Z undo — never hijacks Ctrl/Cmd+Z).
  Settings audited (no orphans/missing), menus correctly when-gated, Marketplace
  metadata polished, viewsWelcome empty states.
- Getting Started walkthrough (6 steps) + gitstudio.openWalkthrough, first-run
  auto-open guarded by globalState; brand media wired (no broken links).
- Docs: rewritten Marketplace README (pillars, free-vs-paywall positioning,
  keybinding cheat-sheet, GitBrain + GitHub setup, settings table), updated root
  README (suite status + monorepo layout + build/test), CHANGELOG 0.1.0.
- Design/a11y pass on webviews: :focus-visible rings, prefers-reduced-motion
  guards, ARIA roles/labels (graph grid rows, rebase rows), and theme-token
  colors replacing hardcoded hex (PR panel) across commit box / PR / graph /
  rebase / diff-merge.
- Packaging: .vscodeignore tightened; final gitstudio.vsix (1.53 MB, 18 files,
  gitignored) builds with zero vsce errors/warnings.

Gate: 168 tests pass, types clean, purity OK, builds + packages cleanly.
87 commands / 8 views / 12 settings / 6 keybindings / 1 walkthrough.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…core

The last front-end — a desktop app that REUSES the proven core behind the
host-agnostic seams, not a rewrite:

- main process (Node): BrowserWindow (contextIsolation on, nodeIntegration off),
  app menu, and a DesktopHostBridge of ipcMain.handle endpoints wrapping
  @gitstudio/git-service (GitContext + NodeGitAdapter, unchanged) and
  @gitstudio/engine (computeGraphLayout, diff/merge models): repo open/recent,
  graph:load (paged), commit details, blame, file diff, status, conflicts, and
  graph git actions.
- preload: contextBridge exposes a typed invoke/on surface — no Node leaks.
- renderer: app shell (titlebar + sidebar + graph + details + diff) mounting the
  SHARED <gitstudio-graph> Lit element and the Monaco DiffView/MergeView verbatim;
  a renderer-side bridge adapts the graph protocol to IPC; desktopTheme supplies
  the --vscode-* tokens so all shared UI + CSS render unmodified (dark/light via
  prefers-color-scheme).
- Shared WireRow builder extracted to @gitstudio/host-bridge/graphWire and used by
  BOTH the extension graph panel and the desktop (one transformation, no drift).
- Packaging: electron-builder.yml (mac dmg / win nsis / linux AppImage, appId
  dev.gitstudio.desktop, brand icon) + electron-updater stub + release-desktop.yml
  CI (app-v* tags, 3-OS matrix, guarded signing).

Gate: 176 tests pass (host-bridge +4, desktop +4), check-types clean, purity OK,
all 3 desktop bundles build, extension still builds. electron-builder --dir
produced a launching GitStudio.app (verified).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The autonomous build compiled + unit-tested but was never run; this fixes the
runtime reality and does a real visual pass.

Critical runtime fixes
- Activation cascade: registerTimelineProvider used the `timeline` PROPOSED API,
  which throws for published extensions in stable VS Code/Cursor — it killed every
  feature registered after it (~90% of the suite). Guarded it; added a "GitStudio"
  output channel + fail-loud activation so a single throw can't silently cascade.
- Pull Requests view refresh loop: GitHubAuth.getToken fired onDidChange on every
  call, and the view read the token during refresh → infinite refresh (API hammer).
  Now fires only on a real sign-in/out change.
- Keybindings removed (they collided with Cursor); commands stay on palette/menus.
- Real product icon (themeable commit-cube) + theme-aware wordmark in the walkthrough.

Blame → JetBrains "Annotate" gutter: persistent left column (date · author) on every
line with an age tint + separator rule and a one-click eye toggle (was current-line
only). Stopped swallowing blame errors.

AI is now provider-agnostic + seamless: auto uses Copilot/Cursor via vscode.lm
(zero key); Anthropic (Claude); one OpenAI-compatible provider covers OpenAI/Codex/
OpenRouter and local Ollama/LM Studio (no key for local). `GitStudio: Select AI Model`
picker; ✨ auto commit-message button in the NATIVE Source Control box. + tests.

Visual redesign (coordinated): shared theme-token design system (tokens.css), every
emoji → codicons/inline SVG, manifest command icons. Surfaces restyled to GitLens/
GitKraken/JetBrains bar — commit graph (author avatars, ref chips, refined lanes,
hover/selected), sidebar tree items (themed icons, muted descriptions, rich tooltips),
commit/changes panel, PR description, interactive rebase, 3-pane merge/diff.

Gate: 185 tests pass, types clean, purity OK, all bundles build, .vsix packages,
dev-host activation verified ("registration complete — every section wired").

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Rebuilt GitStudio's Commit sidebar view into a single integrated "commit window"
like VS Code's Source Control — but ours and styled to the design system:

- One webview holds the commit message box (summary/description, Amend, Sign-off,
  author override, ✨ AI generate-message, Commit + Commit&Push, staged count,
  Enter-to-commit) AND the working-tree changes (Merge / Staged / Unstaged groups
  with counts + group actions; per-file stage/unstage/discard on hover; click opens
  the diff).
- Changed files support a tree ⇄ list (flat) layout toggle, computed client-side
  with single-child folder compaction, persisted in globalState.
- Host pushes change state on RepoManager.onDidChange; staging via ctx.staging;
  the AI key never enters the webview.

Removed the now-redundant separate "Changes" tree view cleanly (package.json view +
viewsWelcome + all gitstudio.changes.* commands/menus, and the createTreeView +
ChangesTreeProvider wiring in extension.ts) — one fewer tab, no dangling reference.
changesView.ts stripped to reusable helpers (openChangeDiff, statusLetter,
relativePath). Line-staging editor commands + the native-SCM ✨ button kept.

Gate: types clean, purity OK, builds + packages, no dangling createTreeView,
dev-host activation verified ("registration complete").

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
"Commit" (the changes+message window) next to "Commits" (history) was confusing.
The section that holds the working changes + commit message is now "Changes";
the history list stays "Commits". View id unchanged (gitstudio.commit).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Removed the Enter-to-commit keydown handler and the "Enter to commit" hint +
placeholder text. Enter now behaves as Enter (newline); committing happens only
via the Commit / Commit & Push buttons.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
"Changes" appeared up to 3× (the section header, the toolbar title, and the
unstaged group). Now: the section header is the only "Changes"; the redundant
toolbar title is removed (icons right-align); the staged count moved onto the
Commit button ("Commit 3" / "Amend 2"); groups renamed to distinct labels —
Merge Conflicts / Staged / Unstaged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The commit view read like stock VS Code SCM — flat, no identity. Rebuild it
around a cohesive "Studio" design language (theme-native, no hardcoded chrome):

- Branch/sync header: current branch as an accent pill + ahead/behind/“up to
  date” sync pills (new ahead/behind/upstream wired through the state payload).
- Elevated composer card with focus glow and a live subject-length counter
  that nudges toward the 50/72 convention.
- Pill toggles (Amend / Sign-off / Author) with checked-state accent.
- Tactile primary Commit button (subtle sheen + press), refined split Push.
- Proper "CHANGES" section header with a live total badge + icon toolbar.
- Per-group identity (staged=green, unstaged=amber, merge=red) dots + count pills.
- File rows: status-tinted icon, status accent rail on hover, status badge.
- Calm "Working tree clean" empty state.

git.d.ts: surface ahead/behind on Branch (provided by the built-in Git API).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The graph filled the panel as a bare virtualized list with no framing. Add a
36px header bar that gives it product identity, derived entirely client-side
(no host changes): the current branch as an accent pill (read from the HEAD
row's currentHead ref), the loaded commit count, and keyboard/nav hints that
collapse out on narrow widths. :host becomes a flex column so the scroller and
placeholders fill the remaining height.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Bring the rest of the suite up to the commit-window / graph polish level, all
theme-native (no hardcoded chrome):

- tokens.css: modern radii (6/5 + pill), cubic-bezier easing, theme-native
  elevation surfaces (--gs-surface/-2), softer borders, shadow + glow tokens,
  --gs-fg-subtle / --gs-accent-text. Primary .gs-btn gets the tactile sheen.
- rebase view: matching radii/easing, elevated commit rows, action selects as
  uppercase tinted pills, a stronger header, and the sheened Start-rebase CTA.
- diff/merge toolbar: primary action gets the same sheen + press feedback.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Center the panel on a 940px reading measure so a PR reads like a document on a
wide editor, modernize the radii, and give the primary toolbar actions the
shared sheen + press feedback (secondary stays flat).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Verified the redesign by rendering the real template in a headless harness:
the layout is correct and the branch/sync header, composer counter, and status
badges all read well. Tighten the edges so a narrow sidebar never clips:

- .hint flows as normal text (was display:flex, whose non-wrapping text items
  forced a wide line) so it wraps; kbd is inline-block.
- branch pill shrinks (flex 0 1 auto + min-width:0 ellipsis) and the sync pills
  pin right (flex 0 0 auto), so a long branch name never pushes them off.
- body: overflow-x:hidden as a backstop — the sidebar never scrolls sideways.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The no-repo and empty-history welcome views are the first thing a new user
sees. Make them sell the product — the JetBrains-grade workflow and the real
virtualized branch graph — instead of describing plumbing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
antonarnaudov and others added 28 commits June 28, 2026 19:54
… when collapsed

Terminal: collapsed the per-shell top tabs (Terminal 1/2/3) into ONE "Terminal"
top tab. Opening it shows the shell as the main view with a side list on the
right (VS-Code-style): a "New terminal" button + one row per shell with a kill
(trash) button; the active shell is highlighted. The top bar is now just
Commit details · Output · Terminal. Multiple shells, lazy PTYs, persistence,
and theming all preserved.

Bar: the active-tab underline (and emphasis) no longer shows when the dock is
collapsed — nothing is "open", so the status bar reads as plain tabs.

Verified in headless/real Chrome: Terminal view with side list + kill buttons;
collapsed bar with no underline. Typecheck clean, desktop tests pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…bottom)

The shadow-DOM `.scroll` was content-box (shadow roots don't inherit the
document's global `* { box-sizing: border-box }`), so `height:100%` + its
`padding:12px 14px 18px` made the scroller 30px taller than its host. With
`:host { overflow:hidden }` the bottom 30px was clipped and unreachable — most
visible in the desktop's docked commit-details, where the last changed files
couldn't be scrolled into view. Set the scroller to border-box.

Verified: scroller clientHeight now equals the host height (was host+30); the
last file scrolls fully into view. Affects both the desktop dock and the
extension's graph commit-details panel. Typecheck clean, desktop tests pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…P features

Combines the concurrent desktop overhaul (production hardening, slim
topbar, footer/dock + commit-details docking, terminal view, searchable
ref pickers, new icon — 15 commits) with the AI layer, in-app Assistant,
model connections, and MCP Agent Access. Conflict-free 3-way merge
(my additions were localized to distinct regions of main.ts/renderer.ts/
app.css); verifying compile + behavior next.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e / Codex / Gemini)

Two additions to the model-connection system:

1. Real brand marks for every provider in the "connect a model" gallery and
   connection rows — Anthropic, OpenAI, OpenRouter, Gemini, Groq, Mistral, xAI,
   DeepSeek, Together, Ollama, LM Studio, Azure (Lobehub icon set, MIT). They're
   monochrome currentColor SVGs on a 0 0 24 24 viewBox, embedded (offline + CSP
   safe) and parsed via DOMParser, so they adapt to light/dark/high-contrast and
   stay crisp — same theming discipline as the codicons. renderer/providerLogos.ts
   + a fallback to the catalog codicon for anything unmapped. Verified rendering
   in both themes.

2. Local agent CLIs as first-class providers — a new `wire: "cli"` that drives an
   installed `claude` (Claude Code), `codex`, or `gemini` CLI in non-interactive
   mode using ITS OWN login/subscription (no API key), alongside the BYO-key HTTP
   providers. So "use my Claude Code / Codex" and "use an API key" both work.
   - @gitstudio/ai: Wire += "cli"; three catalog presets; isConnectionUsable
     treats CLI as usable (host verifies the binary); makeProvider defers CLI to
     the host.
   - desktop main/cliProvider.ts: CliProvider implements the Provider interface by
     spawning the CLI (streams stdout, strips ANSI, honors AbortSignal, maps tier→
     --model, runs in the repo dir). supportsTools=false — the CLI is its own
     agent, so the Assistant delegates the goal to it. detectCli() probes
     availability; the settings "Test" confirms the binary instead of spending
     quota.
   - AiBridge routes cli connections to CliProvider, caches per-preset detection
     for the "Ready"/"Not installed" status, and the settings editor hides the
     base-URL/key fields for CLI connections (just optional model overrides + a
     note). CLI presets reuse the vendor brand mark.

233 tests pass; all workspaces typecheck; desktop bundles cleanly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Separate the no-key local options from the API-key providers so it's obvious
what each costs you:
  • Use a local agent  — Claude Code / Codex / Gemini CLI (wire "cli"), tagged
                         "Your login"
  • Run a model locally — Ollama / LM Studio (local servers), tagged "On-device"
  • Connect with an API key — the cloud providers, tagged "No key" where keyless

Each section has an uppercase title + a one-line description, divided by
hairlines. Tiles are grouped by (wire === "cli") / (local) / (cloud) and reuse
the brand logos.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…alls)

The Assistant felt laggy because the agent used a non-streaming model call —
it sat on "Working…" until the whole turn finished, then dumped the answer
(worse with a cold-starting CLI). Now it streams tokens as they're generated.

- Provider.streamChat(): a streaming chat turn WITH tool support — text is
  delivered incrementally via onTextDelta while tool calls assemble from the
  SSE, returning the full ChatResult. Implemented for Anthropic (text_delta +
  input_json_delta / tool_use blocks) and OpenAI-compatible (delta.content +
  delta.tool_calls). Tested with hand-rolled SSE fixtures.
- Agent loop prefers streamChat; a text-only provider (local CLI) streams via
  streamText. Deltas flow through onTextDelta → ai:delta → the renderer.
- Assistant view renders the stream live: a plain-text block with a blinking
  caret appears immediately above a pulsing "Working…", and is swapped for
  rendered Markdown when each step completes. Tool steps close the open text
  block first; multi-step turns each get their own block.
- Tightened the agent system prompt: it now describes its own capabilities and
  answers greetings / "what can you do?" / meta questions directly, WITHOUT
  firing read tools — so a simple question gets an instant streamed reply
  instead of a round of unnecessary git_status/git_log calls.

235 tests pass; all workspaces typecheck; desktop bundles cleanly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The Assistant still stalled on "Working…" for CLI providers because
`claude -p` buffers its whole answer and prints it at the end. Now the
CliProvider runs Claude Code in streaming mode — `--output-format stream-json
--verbose --include-partial-messages` — and parses the newline-delimited JSON
events, emitting each `content_block_delta` text_delta as it arrives. The
`result`/`assistant` text is kept as a fallback only when no token deltas come
through, so older CLIs (or non-streaming ones) still work. Verified against the
real `claude` CLI end to end: tokens stream incrementally (first token ~2.9s,
then live), matching the exact event shapes it emits.

Codex/Gemini keep the buffered path for now (their streaming formats differ).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Verified (by driving the real app over CDP) that the Assistant DOES stream —
the answer text grows live in the DOM. The "stuck" feeling is the silent gap
before the first token: with a local CLI like Claude Code that's an inherent
~3s per-message cold start (it boots the whole agent + loads its big system
prompt before generating), not a streaming bug.

- The "Working…" indicator is now a live elapsed counter ("Thinking… 3s" →
  "Responding… 5s"), so a multi-second model start-up reads as working, not
  frozen.
- New Speed selector in the Assistant header (Fast / Balanced / Deep) maps to
  the connection's fast/mid/deep model, so users can trade quality for a
  snappier first token. The agent now defaults to the "mid" tier (was "deep")
  — a better default for an interactive assistant.

Note: API-key providers (Anthropic/OpenAI/…) stream token-by-token with no
cold start; the CLI's startup latency is unavoidable from outside the process.

235 tests pass; desktop typechecks + bundles cleanly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…peed/thinking)

Keeps the local CLI first-class (no nudge toward APIs) and makes the inherent
cold-start feel like active thinking, plus a real settings surface for the agent.

- The Assistant's wait is now an animated indicator: three pulsing dots + a
  shimmering "Thinking"/"Responding" label + a live elapsed counter — so a
  multi-second CLI start-up reads as working, not frozen.
- New "AI Assistant" settings card (next to AI Models) to modify agent specifics
  like the providers do: Model tier (Fast/Balanced/Deep), Thinking depth
  (Off/Auto/Extended), and default repo access. Persisted in ai-settings.json
  via ai:setAgentConfig; the Assistant header seeds its per-conversation toggles
  from it.
- "Thinking" is threaded end to end (AgentConfig → AgentRunRequest → agent →
  ChatOptions). For the Claude Code CLI it maps to a reasoning directive in the
  prompt ("think hard" / "be concise"); API providers can use it for native
  thinking budgets later.
- Agent default tier is now "mid" (Balanced) instead of "deep".

Verified in the running app over CDP: the animated indicator renders and the
settings card drives the agent. 235 tests pass; typechecks; bundles cleanly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…rom the provider

You no longer set the agent up in Settings — the options live in the Assistant
header and come straight from your connected provider.

- New ai:models channel + AiBridge.listModels(): returns the models the active
  connection's provider offers. HTTP providers are queried live (GET /models,
  or /v1/models for Anthropic, best-effort with a short timeout + key); the local
  CLIs and any failures fall back to a per-preset known catalog; the connection's
  own configured models are always included. e.g. Claude Code → opus/sonnet/haiku.
- The Assistant header now has three live dropdown chips — Model (from the
  provider), Thinking (Off/Auto/Extended), Access (Read/Commits/Everything).
  Each pick is remembered (persisted to the agent config) and applied to runs.
- Explicit model ids are threaded end to end (AgentConfig.modelId →
  AgentRunRequest.modelId → agent → ChatOptions.modelId); every provider now
  uses an explicit id when given, otherwise resolves the tier.
- Removed the separate "AI Assistant" settings card — its controls moved into
  the Assistant, where they belong.

Verified in the running app over CDP: ai:models returns [opus, sonnet, haiku]
for the Claude Code connection and the in-header picker lists them. 235 tests
pass; all workspaces typecheck; desktop bundles cleanly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…calls

The Assistant's per-message latency is Claude Code's cold start, which is
independent of the chosen model/thinking — those only affect generation after
the first token. A meaningful, variable chunk of that start-up is Claude Code
connecting to all of the user's configured (remote) MCP servers on every
`claude -p` invocation. The Assistant only needs Claude Code's built-in tools
(Bash/Read/etc.), so pass `--strict-mcp-config` (with no --mcp-config) to load
none of them. Verified it still streams normally.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add shell integration (OSC 133/633) for zsh+bash and a command-block UX
layer over the existing xterm terminal: per-command status dots in the
gutter, command navigation (Cmd+Up/Down), a hover toolbar to copy the
command / copy its output / re-run it, and auto-named + renamable
sessions. Fully degrades to a plain terminal when integration is
unavailable.

Clean-room: no Warp code is reused (Warp is AGPL and GPU-rendered, so
neither its license nor its terminal are compatible). Only the open
FinalTerm/iTerm2/VS Code OSC 133/633 contract is implemented.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Chats now live in the main process and persist to disk, so a renderer refresh
(or full restart) no longer resets the Assistant — it reconnects to the running
session. And a chat keeps ONE warm Claude Code process, so only the first
message pays the cold start; the rest are fast and remember context.

- main/warmCliSession.ts: one long-lived `claude` process per chat (stream-json
  input/output). First message cold, subsequent ones warm. Idle-disposes after
  5 min and respawns with `--resume <sessionId>` to carry context; survives
  renderer refreshes because it lives in main.
- main/assistantSessions.ts: a ConversationStore that persists each chat's
  transcript + Claude Code session id to userData/ai-sessions.json (capped, MRU),
  tracks the current chat per repo, and owns the warm-process registry.
- AiBridge.chatSend routes a CLI chat through its warm session (bare goal — the
  CLI is its own agent + remembers) and an HTTP chat through the agent loop with
  multi-turn history; both stream + append to the persisted transcript. New
  chat list/get/current/new/delete + ai:chat* IPC.
- agent: optional `history` for multi-turn with stateless (API) providers.
- Assistant UI: restores the last chat on mount (survives refresh), New-chat and
  chat-history controls, lazily creates a chat on first send.

Verified end-to-end over CDP: warm msg 1.5s vs cold 4.6s, context remembered
("42"), and after a renderer refresh the 4-turn chat + warm session + context
all survive (post-refresh reply 1.8s, still "42"). 240 tests pass; typechecks;
bundles cleanly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nt" label

Three Assistant/navigation polish fixes:

- Keep-alive views: navigating away from a non-Monaco view (branches, settings,
  Assistant, and the GitHub sections) now stashes its rendered DOM and restores
  it instantly on return — no rebuild, no skeleton flash, scroll preserved.
  Re-clicking the section you're already on is a no-op. An explicit refresh
  (sync / Cmd+R) still force-rebuilds with fresh data, and a repo switch clears
  the cache. Monaco views keep their dispose lifecycle untouched.
- Live Markdown: the streaming reply now renders Markdown as it arrives
  (throttled to one re-render per frame) instead of showing raw `**asd**` and
  re-parsing only at the end. Verified: `**Rebase**` → <strong>Rebase</strong>
  mid-stream.
- Cold-start clarity: while a local CLI boots its agent (before the first
  token), the indicator reads "Loading the agent" instead of a silent
  "Thinking"; it switches to "Responding" once tokens stream.

Verified end-to-end over CDP. 240 tests pass; typechecks; bundles cleanly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e app

The Assistant moves from a sidebar item to a top-bar launcher (reachable from
every view), and one-shot AI lands where the work happens.

- renderer/aiAssist.ts: a reusable inline-AI toolkit — a ✨ chip, streamTask()
  over the existing ai:task IPC, a streaming result sheet that renders Markdown
  live (throttled per frame) with copy / insert, and streamInto() to write a
  result straight into a textarea. All gated on a connected model.
- Header: an "Assistant" sparkle launcher replaces the sidebar nav item; routes
  to the full Assistant (chats persist + stay warm via keep-alive).
- Changes: "Write commit message" (streams into the commit box from the staged
  diff) + "Review changes" (agent review of the working/staged diff).
- Compare: "Explain" / "Review" the base…head diff.
- Pull Requests: an AI ▾ menu — Explain / Review the PR diff + Draft a comment.
- Issues: "Analyze" (problem / cause / suggested approach) + "Draft a reply"
  straight into the composer.
- New generic `assist` task (free-form, Markdown) powers the non-diff cases
  (issue analysis, comment drafting). Empty-diff guards return a clear
  "No changes to review/explain/summarize." instead of a blank sheet.

Verified over CDP: header launcher routes; Changes chips render; the result
sheet streams real Markdown (14 deltas); empty diffs message cleanly. 240 tests
pass; typechecks; bundles cleanly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Additive, prompt-aware autocomplete dropdown over the xterm prompt:
- Clean-room fuzzy matcher + pure ranking engine (exact > prefix > fuzzy,
  source priority, history recency/frequency), fully unit-tested.
- Sources: command history (deduped), executables on PATH (cached, main),
  cwd files/dirs (read-only IPC), and shell builtins.
- Safety: only shows while at a shell prompt (OSC 133); reads the typed
  line from the buffer and hides when unsure; accepting rewrites only the
  current line via readline keys (Ctrl+A/Ctrl+K) — never submits.
- Keys: ↑/↓ navigate, Tab/Enter accept (Enter passes through to run unless
  you've navigated), Esc closes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Command/history menu (⌘P): a self-owned launcher popup — fuzzy-searchable
quick actions (with keybinding hints) plus recent commands (deduped, with
run counts). Picking a recent command rewrites the prompt line for review;
it never submits and only writes at a prompt. Pure row-builder unit-tested.

Agent mode (⌘I): an in-terminal panel onto the EXISTING AI agent, driven
purely over the existing IPC (ai:agentRun/delta/agentEvent/confirmRequest/
agentConfirm/settings) — zero edits to shared AI files. Streams assistant
text + tool cards, reuses the approval gate, shows the active model
(agent-agnostic), and adds "Insert in terminal" on shell snippets (writes
to the prompt for the user to run — never auto-runs).

Toolbar gains menu + agent buttons; both reuse the existing .assistant-*
styles for a consistent look.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…view)

Addresses findings from a critical self-review, prioritising the safety
contract ("never break or submit a command"):

- Autocomplete accept is now append-only when the suggestion is a prefix
  (safe in any keymap, cursor anywhere); only deletes (via backspaces, not
  emacs Ctrl+A/K) for fuzzy matches AND only when the cursor is at the end
  of input — so trailing text is never lost. Removes the Ctrl+A/Ctrl+K
  assumption entirely (vi-mode safe).
- Input anchor is a marker (not absolute coords), so it survives scrollback
  trimming, reflow and clears; readTyped bails when the anchor is gone.
- Menu/agent/re-run inserts route through replaceCurrentLine (backspace +
  type, never auto-run) and restore terminal focus on close.
- Command blocks: a D only finalizes a command that actually ran (output
  marker set), so an empty Enter / spurious precmd can't overwrite a prior
  command's exit code.
- Re-run now puts the command on the prompt for review instead of
  auto-running (also sidesteps bash compound-command capture limits).
- Key handler calls preventDefault/stopPropagation on consumed keys (Tab no
  longer steals DOM focus; Cmd+P/I don't leak to global/Electron).
- refresh() re-checks at-prompt after the async dir listing (no dropdown
  over a running program).
- PATH executable listing is async (no main-process stall on first open).

Known limitations (documented): bash compound-command *text* capture is
first-segment only (zsh is full-fidelity); first-keystroke-as-paste won't
arm autocomplete for that line; non-default readline keymaps may affect the
rare fuzzy-delete path.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The fuzzy-everything dropdown produced noise: typing "cd" surfaced
config_data / cpuwalk.d / copilotDebugCommand.js, and "git commit --"
offered a file with dashes (HANDOFF-AI-MCP.md). Replace fuzzy subsequence
matching in the inline dropdown with disciplined, shell-like behavior:

- PREFIX matching only (no subsequence) for commands and paths.
- Context-aware: PATH commands + builtins in command position; directories
  only for cd/pushd/rmdir; files+dirs for other args; and for flag tokens
  ("-"/"--") nothing but matching history (no flag specs yet, so no file noise).
- Subcommands (e.g. "git status") complete from whole-line history prefix.
- Don't echo the exact token; skip the dir IPC for flag tokens.

Fuzzy matching stays only where it belongs — the ⌘P command menu (explicit
search). Tests updated to assert the new behavior and guard the two bugs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…tate indicators

- Added `ghListResizer` to gists and issues views for better layout management.
- Updated state indicators in gists to reflect public/private status accurately.
- Enhanced issues view to support deep-linking to specific issues and improved navigation.
- Integrated AI features for analyzing issues and PRs, replacing previous modal implementations.
- Improved notifications handling to allow in-app viewing of external items.
- Refactored project and PR views to streamline navigation and enhance user experience.
- Introduced a new unified read-only item interface for cross-repo notifications.
Reverts the five Warp-terminal commits (415d189, d15d614, 390872b, 8fa3c6b,
69e137c) — command blocks, spec-less prefix autocomplete, command menu, agent
panel, shell integration, completion IPC and the floating toolbar — while
keeping all the concurrent AI/UI work layered around them (resolved the app.css
and terminalDock conflicts in favour of that work). The integrated terminal is
back to a plain xterm.js + node-pty surface.

Also rethemes it to a standard, default terminal palette: neutral cursor (was
the violet accent) and the conventional 16 ANSI colours (was a pastel set).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Updated stroke width and opacity for improved visual clarity in gutter rendering.
- Refactored path rendering logic to separate dimmed and focused lanes for better z-order management.
- Adjusted node rendering for merge commits to enhance visual distinction.
- Tuned lane colors in dark and light palettes for better separation and readability.
- Added new codicons for file, filter, and flat list representations.
…lines

- Marketplace listing: tightened description, categories (SCM/Visualization/AI),
  curated keywords, badges, preview:false; version 1.0.0 (extension + desktop)
- Store screenshots (media/shots/) rendered from the real webview bundles via
  the engine's own layout; excluded from the vsix (served from GitHub)
- New marketplace README + refreshed root README; docs/releases notes for both
  channels; RELEASING.md updated (explicit tag pushes, secrets, invariants)
- Release pipelines hardened per adversarial audit (11 confirmed findings):
  tag<->version guards, ext releases --latest=false so the desktop updater's
  /releases/latest never breaks, single create-release job (no matrix race),
  macos-13 -> macos-15-intel (retired runner), ubuntu-22.04 for glibc reach,
  fixed linux upload globs, pinned no-space artifact names for stable website
  URLs, loud-fail store publishes, CI test matrix on all release OSes
- macOS in-app update check disabled (no mac feed; unsigned can't update)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…e, AI/MCP polish

The accumulated feature branch for 1.0.0:
- Extension: sidebar-native Commits rail (<gitstudio-commit-rail>, per-row
  topology hugging, taut curves, mini author avatars); live Pull/Push pills and
  an in-dialog branch menu (in-place fetch, per-branch ahead/behind badges,
  pull-without-checkout, copy name, backdrop + child-dialog styling)
- Desktop: matching live sync UX in the Branches view (Pull pills, keepOpen
  fetch, branch:pullFf IPC), dialog polish
- git-service: StatusProvider decoupling, ref track counts (%(upstream:track)),
  discard/status tests; shared gutter gains opt-in curveSpan/strokeWidth
- Compare panel, stashes webview, avatar resolution, AI command polish

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… docs

- worktree.test.ts compared basename via split("/") which never splits a
  backslash-separated Windows temp path — first windows CI run caught it
- README + app-v1.0.0 notes now use the pinned artifact names
  (GitStudio-Setup-<v>.exe, GitStudio-<v>-x64.AppImage/.deb) and the accurate
  macOS-manual-update story

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Correctness (12 confirmed, verified):
- desktop discard: untracked files route through 'git clean' (checkout --
  always failed for them); porcelain v1 parse emits BOTH halves of mixed XY
  records so an 'MM' file's newer unstaged edits are no longer invisible
- desktop main: renderer-supplied paths are containment-checked against the
  repo root (conflict resolve/take-side, working-tree reads) — closes an
  arbitrary file read/write primitive; branchPullFf gains safeArg
- git-service: annotated tags peel to the tagged commit (%(*objectname)) so
  their chips actually render; porcelain v2 worktree R/C codes surface
- graph host: empty last page posts a terminating graphAppend instead of
  wedging the webview's 'loading older commits…' tail; reveal pages toward a
  sha the panel hasn't loaded yet (bounded); WIP node + details include
  untrackedChanges (git.untrackedChanges=separate)
- desktop auto-update actually updates (autoDownload=true, install-on-quit) —
  the checker previously downloaded nothing and notified no one
- PR view: branch code-spans no longer backslash-escaped (CommonMark renders
  those literally); big-graph popovers dismiss on Escape from anywhere (parity
  with the rail)
- vsce package: --baseImagesUrl/--baseContentUrl point at apps/extension so
  the store README screenshots don't 404 from the monorepo root

One review finding refuted on re-check: the PR-description fence placeholder
uses NUL sentinels (not spaces), so trim() never breaks it — left as designed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@antonarnaudov
antonarnaudov merged commit 8fdf248 into main Jul 14, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants