Pr/solid rewrite - #2
Merged
Merged
Conversation
The commit workflow (ChangesView, stage/unstage, commit, push/pull) was fully implemented on both the webview and the message-handler side but the tab switcher was commented out, leaving it unreachable. - Timeline.tsx: re-enable <TimelineTabs> - useTimelineState.ts: default activeTab to "changes" - volta: pin node 22 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
When the timeline view is docked in the bottom panel the Popover was taller than the viewport and got pushed off the top edge. Make the Paper a flex column capped at the viewport height, let the branch list shrink, and add marginThreshold so MUI keeps it within bounds. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ayout The React/vite webview rendered blank when docked in the panel. Replace WebviewHtmlService with an inlined (no bundle, nonce CSP) UI that mirrors GitHub Desktop: repository / branch / sync toolbar, Changes + History tabs, filter, per-file checkboxes with status squares, commit box, and a unified diff pane on the right. Backend: add commitFiles (stage + commit a pathspec), discardFiles, and getWorkingDiff message handlers. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- global [hidden] rule so .tabpane display:flex no longer defeats it (Changes and History were rendering on top of each other) - hide the right pane and let the left column go full-width when no file is selected, instead of showing an empty "No file selected" block Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- send updateAccounts (active account login/avatar) on refresh and show the GitHub avatar image in the commit box, falling back to initials - give #fileList a min-height and make the Changes pane scroll, so the file list stays visible even when the view is docked in a short panel - shrink the default Description height; pin the commit box to the bottom - check newly appeared changed files by default, preserve prior choices Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Match GitHub Desktop's tighter spacing: shorter toolbar (42px), smaller tab/label/input fonts, less padding everywhere, 20px avatar, 30px min Description. File list keeps flex priority with a small 44px floor; hide filter / summary rows entirely when there are no changes. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The branch dropdown was fed git.branch().all, which includes remotes/origin/* tracking refs. Selecting one ran `git checkout remotes/origin/dev` and detached HEAD. - git-operations: expose local branches plus remote-only branches by their short name, never the remotes/<remote>/<name> form - message-handler: strip any remotes/<remote>/ prefix before checkout Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The old `git branch -vv` bracket parser missed the tracking branch in
some formats (and could false-positive on brackets in commit subjects),
so a published branch showed "Publish branch / not on the remote yet".
Use `git rev-parse @{upstream}` and `git rev-list --left-right --count`.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Show "Publish branch" only when a remote exists, git reported no upstream, and there is nothing ahead/behind. Any uncertain state (status not yet received) now falls back to "Fetch origin". Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The timeline webview was rebuilt as a self-contained vanilla HTML/JS view (webview-html.service.ts). The old React app (bootstrap.tsx -> app/App.tsx -> components/Timeline/**), its hooks, the mock git.service, the DI/domain layers, and the unregistered changes/history tree providers were still built but never loaded. Removed. Kept: app/bridge.ts and app/components/CommitDetailPanel/** (used by the commit-detail and history-explorer bundles), and the History Explorer feature untouched. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
MessageHandlerService (944 lines, 40-case switch, god object) is replaced by: - GitClientFactory / AccountGitClientFactory: single owner of git client creation and credentials. withAuth() injects the token via ephemeral GIT_CONFIG_* env vars, so it is never written to .git/config and there is no shared remote URL to race on (fixes the token-leak + race bugs). - InboundMessage / OutboundMessage: discriminated unions, no `any`, no casts. - MessageRouter: Map<command, handler>; adding a command no longer edits a switch (Open/Closed). - Cohesive services, each with one reason to change: SyncService, WorkingTreeService, BranchService, CommitActionsService, PullRequestService, DiffService, RepositoryDataService (read model). - Ports (RepositoryContext, Notifier, Browser, WebviewChannel, Refresher) with VS Code adapters — services no longer import `vscode` or simpleGit. - TimelineController: composition root + the one place that recomputes and broadcasts state. Behaviour changes: - pull / merge / revert / cherry-pick now detect conflicts and emit a `mergeConflict` message instead of swallowing the error. - publish uses authentication (was a plain client -> first publish failed). - commit only clears the input on a `commitSucceeded` ack. - branch activity is one `for-each-ref` call, not one `git log` per branch. - the provider debounces refresh (400ms) so save-all triggers one recompute. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Replace the two-line sync cell (value + sub-label span) with a single value plus a title tooltip; shrink toolbar font/padding. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Rewire the features that existed in the old React timeline onto the vanilla webview, now that the backend handlers are reachable again: - History rows: right-click context menu (checkout / branch-from / tag / cherry-pick / revert / reset / copy SHA / view on GitHub). - Branch dropdown: "New branch…" (with a Bring-changes / Stash choice when the working tree is dirty) and "Create pull request…". - History: "Load more commits" button + scroll-to-bottom paging, wired to loadMoreCommitsResponse with de-duplication. - commitSucceeded ack clears the commit inputs; a failed commit keeps them. - mergeConflict switches to the Changes tab and shows a warning bar. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Remove FileIconInfo / CommitDetailFile / the untyped WebviewMessage from the timeline interfaces barrel (superseded by the discriminated unions in messages.ts); document the survivors. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- 50px toolbar with stacked label/value cells (Current repository / Current branch / sync) and a sub-line on the sync cell. - 41px tabs with an accent underline on the active tab. - Roomier file rows (28px) with filled octicon-style status squares. - Commit box on its own chrome panel: 28px avatar, rounded inputs, full-width accent "Commit to <branch>" button, taller description. - Larger empty states, softer menus (8px radius, deeper shadow), accent-tinted diff gutters, consistent 6px control radius. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
New backend services (SOLID: one responsibility each, wired via the router): - WorkingTreeService.amend / undoLastCommit — amend rewrites HEAD (warns when it is already on a remote); undo is `reset --soft HEAD~1`. - ConflictService — markResolved / continue / abort, driving whichever of merge / cherry-pick / revert / rebase is detected in the git dir (detection shared with the read model via git-operation-state.ts). - StashService — push (with untracked) / apply / pop / drop. - RepositoryDataService now reports operation, conflicted paths, canUndo and the stash list in the snapshot; the controller broadcasts updateOperation + updateStashes on every refresh. Webview: - Commit box: "Amend last commit" checkbox (prefills the last message) and an "Add co-authors" field that appends Co-Authored-By trailers. - History tab: an "Undo <last commit>" bar when undo is safe. - Conflict bar with Abort / Continue (Continue enabled once no file is left conflicted); conflicted files show "Mark resolved". - Branch dropdown: "Stash all changes" and the list of existing stashes with pop / delete. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
SOLID backend rewrite, GitHub Desktop-style UI, and the undo / amend / co-authors / conflict-resolution / stash features. Version bump so the packaged .vsix installs over 1.1.13. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Toolbar back to a single 32px row (icon + value + caret), no stacked label — the 50px two-line cells were unusable at sidebar width. - .tabpane clips and #fileList is the only scroller (min-height:0), so the commit box stays pinned and reachable however short the panel is. - Trim commit-box padding / description height. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- #pane-changes is now one scroll container; the commit box is position:sticky so it stays in view but the whole pane (file list OR the "no changes" message) scrolls, even with an empty working tree. - Toolbar 30px, tabs 32px, smaller "no local changes" block — less wasted vertical space in a narrow sidebar. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Squashes a branch of work on the timeline webview: - Removed the dead React timeline (superseded by the vanilla webview). - Split the 944-line MessageHandlerService into cohesive services behind a MessageRouter and typed message unions; credentials now go through GitClientFactory.withAuth (ephemeral env, never written to .git/config), fixing a token-leak and a remote-URL race. - Reworked the webview to match GitHub Desktop; compact toolbar, single scroll on the Changes pane. - New: commit context menu, new-branch (bring/stash), create PR, load more history, undo last commit, amend, co-authors, conflict resolution (mark resolved / continue / abort), stash management. Released as 1.2.2. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Delete the unused History Explorer webview (never registered in contributes.views): provider, React app, types, vite entry. - Drop the 8 githubDesktop.commit.* commands from package.json — declared but never registered (the actions run via webview messages). - Remove the unused @tanstack/react-query dependency. - Rewrite docs/overview.md for the current SOLID architecture. Release 1.2.3. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Force-push: - SyncService.forcePush() uses --force-with-lease behind a confirm. - The sync cell shows a "Diverged ↑N ↓M" state when the branch and its upstream have both moved; clicking it (or right-clicking any sync state) opens a menu: Fetch / Pull / Push / Force-push origin. Compare branches: - BranchService.compare() runs `git log <branch>..HEAD` and the reverse, emitting branchComparison. - The branch dropdown gets a "⇄" button per branch; it opens a compare view in the History tab with the two divergent commit lists and an exit control. A refresh leaves compare mode. Extracted commit-log.ts (COMMIT_LOG_FORMAT / parseCommitLogLine / logRange / formatRelativeTime) and reused it in loadMoreCommits. Release 1.3.0. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…sign) Reworked the webview to follow image-1.png (the actual app): - Toolbar: two-line cells (small label + bold value) at 50px, like the app — "Current repository / <name>", "Current branch / <branch>", "<sync action> / Last fetched …" with the ahead/behind badge. Falls back to a 34px single line when the view is narrow (sidebar). - Right pane: the rich "No local changes" state — big heading, subtitle and action cards (Push/Publish/Pull as the primary card, Create pull request, View on GitHub). When there are changes it shows the diff (or a "select a file" hint); hidden entirely in narrow mode. - Commit form: co-authors is now a person-icon toggle, "Amend" checkbox next to it; a "Committed … · Undo" bar sits under the form in both tabs (replaces the History-only undo bar). - New openRepoOnGitHub message + PullRequestService.openRepo(). Fix: renderToolbar no longer writes #commitBranch (updateCommitBtn owns the button label and was replacing that node, making renderToolbar throw and freezing the sync cell on "Fetch origin"). Verified layouts with headless-Chrome screenshots (wide panel + narrow sidebar, empty + dirty tree). Release 1.4.0. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Single 30px toolbar row (icon + value + caret), no stacked labels; 28px tabs; tighter commit box. The two-line GitHub Desktop toolbar wastes too much vertical space in the VS Code panel. Release 1.4.1. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Bug: withAuth() set GIT_CONFIG_* / GIT_TERMINAL_PROMPT through simple-git's
.env(), which trips its unsafe-env guard ("Use of GIT_CONFIG_COUNT is not
permitted…"), breaking every authenticated push/pull/fetch. Now the token
rides on `-c http.https://github.com/.extraheader=…` (not on .env, not in
.git/config), and GIT_TERMINAL_PROMPT=0 is set once at activation.
Repository picker: the "Current repository" cell now lists every tracked
repo (filterable, with paths) and switches the active one in-session, plus
"Add local repository…" (folder picker) and "Clone repository…". New
RepositoryContext.list/setActive/addLocal/clone + updateRepositoryList
message.
Release 1.4.2.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
RepositoryContext.setActive is now async: if the picked repo isn't already a workspace folder it runs `vscode.openFolder` (same window), so choosing a repo in the "Current repository" list also switches the editor to it. If it's already open, it just switches the in-session active repo without a reload. Release 1.4.3. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
#pane-changes is a flex column again: conflict/filter/select-all are fixed headers, #fileList is the only scroller, the commit box and the "Committed … · Undo" bar are fixed footers. No more sticky overlay with file rows sliding behind the form. Release 1.4.4. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Revert the flex-footer approach: #pane-changes scrolls as one column, the file list has no inner scroll, and the commit form + undo bar flow right after it. Nothing is sticky or overlaid — scrolling the pane moves the files and the form together. Release 1.4.5. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
listBranches now returns local branches current-first, then by reflog checkout order (true MRU), then by last commit date; remote-only branches after. The "Current branch" picker follows that order. Release 1.5.0. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ne pane The separate React/MUI webview duplicated what the timeline right pane already does. Commit detail (header, changed-files list, per-file diff with a back link) now renders inline in the right pane, vanilla like the rest. Removed: src/webviews/commitDetail, src/webviews/app, vite.webview.config.ts, and deps @mui/*, @emotion/*, react, react-dom, @octokit/auth-oauth-device (dead), axios (dead), dayjs (dead). Build is now webpack-only. Bundle 600KB+ -> 298KB; vsix -> 258KB. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Rewrote the diff view to match VS Code's diff editor: dual line-number gutters (old/new), a sign column, and token-level intra-line highlighting that marks the exact words changed between a removed line and its replacement (LCS over word tokens). Hunk headers show the function context. Colors come from --vscode-diffEditor-* so it tracks the active theme. The same renderer backs working-tree diffs and per-file commit diffs. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…down The branch dropdown gains a "Branches / Pull requests" toggle. The PR tab fetches open PRs via the GitHub REST API (new GitHubApi port, backed by the account manager's Octokit) and lists them most-recently-updated first, with author, head branch and draft/fork markers. Selecting one runs `git fetch origin pull/<n>/head:pr/<n>` (works for same-repo and fork PRs) and checks out the local pr/<n> branch. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Drop esModuleInterop, baseUrl/paths and jsx — all vestigial now that the React webview is gone. Fixes the editor's "option is deprecated" warnings. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Member
|
Really glad to see someone take this on so aggressively — the SOLID refactor, the webview rewrite, and the git-flow features (force-push, stash, conflict resolution, PR checkout) are a huge amount of ground covered in one PR. Nice work. Two features I'd love to see added on top of this:
Really appreciate the effort here — thank you! |
Collaborator
Author
|
Thanks for the kind words and the feedback — really appreciate it! Both of those are great suggestions, I'll get them added tomorrow:
Will ping this thread once they're in. |
Adds "Merge into current branch..." to the branch dropdown: pick a source branch from a filterable list and it merges into the current branch via BranchService.merge (already handled conflicts, just had no UI trigger). Addresses feedback from satyamlohiya on the SOLID-rewrite PR. BranchService.merge now guards against the direction mistake it's easy to make when the current branch is the destination: merging the default branch (repo.defaultBranch, falling back to "main") into anything requires an explicit confirm, since it's often a sign you meant to merge the other way. Merging into a non-default current branch gets a lighter, non-blocking warning instead. The second request from the PR review (view changed files for a commit) was already covered: clicking a commit in History shows its file list and per-file diffs in the right pane.
Collaborator
Author
|
Just pushed both of these:
Let me know if anything looks off! |
satyamlohiya
added a commit
that referenced
this pull request
Sep 17, 2026
The SOLID rewrite (#2) removed vite/React and consolidated the build into a single webpack compile step, but ci.yml and release.yml still used pnpm and called the now-nonexistent "build-webview" script, breaking CI on every push since the merge. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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.
Summary
SOLID rewrite of the backend + replacement of the React UI with a vanilla
webview modelled on the GitHub Desktop app, plus a series of git-flow
features. 32 commits, linear history on top of
main(0 commits behind).Architecture
(working-tree, sync, branch, commit-actions, conflict, stash, diff,
pull-request, repository-data) behind ports & adapters — services no
longer touch
vscodeorsimple-gitdirectly, everything is mockable.TimelineController).Webview
HTML/CSS/JS view, layout aligned with the GitHub Desktop app.
@octokit/auth-oauth-device (sign-in now uses the native
vscode.authenticationAPI). Build is webpack-only. Bundle ~600 KB → 298 KB.word-level intra-line highlighting.
Git security
-c http.extraheaderinstead of writing the tokeninto
.git/config.GIT_TERMINAL_PROMPT=0.Features
--force-with-lease), branch comparison, undo last commit,amend, co-authors, conflict resolution (continue/abort/mark resolved),
stash (push/apply/drop).
Removed
Open questions
to 1.7.0) — happy to drop those or handle them separately.
repository.urlin package.json still points at the oldSatyam-2001/GitHub-Desktopfork.features) if that's easier to review.