GitStudio 1.0.0: sidebar commit rail, live sync UX, store listing + hardened release pipelines - #1
Merged
Merged
Conversation
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>
… 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>
28 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this ships
The 1.0.0 release branch — feature work plus everything needed to publish to real users.
Product
StatusProviderdecoupling, per-ref ahead/behind from onefor-each-ref, discard/status tests.Release prep
1.0.0versions, CHANGELOG.--latest=falseon extension releases so the desktop auto-updater's/releases/latestcan never break, singlecreate-releasejob (no 4-way matrix race), retiredmacos-13→macos-15-intel,ubuntu-22.04for 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.Release plan (after merge)
git tag ext-v1.0.0 && git push origin ext-v1.0.0→ vsix on the Release + Marketplace/Open VSX publish (needsVSCE_PAT/OVSX_PATsecrets).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