Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added apps/desktop/build/icon-mac.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified apps/desktop/build/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions apps/desktop/electron-builder.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ publish:
# converts it to .icns / .ico per platform automatically.
mac:
category: public.app-category.developer-tools
# macOS needs the padded variant (824px art in a 1024 canvas, Apple's icon
# grid). The full-bleed build/icon.png used for win/linux gets scaled
# edge-to-edge into the dock slot and renders bigger than every other app.
icon: build/icon-mac.png
# dmg is the human download; zip is REQUIRED for electron-updater to deliver
# macOS auto-updates (it can't update from a .dmg).
target:
Expand Down
10 changes: 6 additions & 4 deletions apps/desktop/esbuild.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,12 @@ function copyStaticAssets() {
// text. The top-bar mark is an inline currentColor SVG in the renderer, so it
// needs no asset here.
const brand = {
"brand/gitstudio-icon-512.png": "icon.png",
// Light-tile sibling of the dock mark, so the dock icon can theme-swap at
// runtime (main's `appearance:dockIcon` picks light/dark per the app theme).
"brand/gitstudio-icon-light-512.png": "icon-light.png",
// Both tiles are macOS-padded (824px art inset in a 1024 canvas, per Apple's
// icon grid) — a full-bleed square is scaled edge-to-edge into the dock slot
// and renders visibly bigger than every neighbouring app. macOS can't carry
// appearance variants in an .icns, so main swaps these at runtime.
"brand/gitstudio-icon-mac-1024.png": "icon.png",
"brand/gitstudio-icon-light-mac-1024.png": "icon-light.png",
"brand/gitstudio-icon.svg": "brand-icon.svg",
"brand/gitstudio-icon-light.svg": "brand-icon-light.svg",
"brand/gitstudio-wordmark-light.svg": "brand-wordmark-light.svg",
Expand Down
2 changes: 1 addition & 1 deletion apps/desktop/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "gitstudio-desktop",
"version": "1.0.0",
"version": "1.0.1",
"private": true,
"license": "Apache-2.0",
"description": "GitStudio — the native cross-platform desktop app (Electron). Reuses @gitstudio/engine, git-service, webview-ui, and host-bridge behind host-agnostic seams.",
Expand Down
27 changes: 21 additions & 6 deletions apps/desktop/src/main/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,19 +173,34 @@ async function createWindow(): Promise<void> {
await mainWindow.loadFile(join(__dirname, "../renderer/index.html"));
}

/** The dock/window brand mark for a theme variant (dev/window icon; electron-builder
* embeds the packaged icon separately). Light theme gets the light-tile mark. */
/**
* The dock/window mark for an appearance.
*
* macOS cannot carry light/dark variants inside an `.icns`, so an Electron app
* has to adapt the dock icon itself (`app.dock.setIcon`) — which only works if
* BOTH tiles are properly designed. The light tile used to be the dark mark's
* artwork dropped onto a pale background unchanged: its light-violet lanes and
* near-white node cores disappeared, and the nodes that straddle the cube's
* edge simply vanished. It is now re-tuned (deep brand-violet lanes and rings,
* white cores) so it reads on the pale tile.
*
* Both files are the macOS-padded variant (824px art inset in a 1024 canvas per
* Apple's icon grid) — a full-bleed square gets scaled edge-to-edge into the
* dock slot and renders visibly bigger than every neighbouring app.
*/
function iconPath(variant: "dark" | "light"): string {
return join(__dirname, variant === "light" ? "../renderer/icon-light.png" : "../renderer/icon.png");
return join(
__dirname,
variant === "light" ? "../renderer/icon-light.png" : "../renderer/icon.png",
);
}

/** Brand icon for the window `icon:`; electron-builder embeds the platform icon,
* this is the dev/window one. Tracks the OS scheme so it isn't visibly wrong. */
/** Window/dev icon for the current OS appearance. */
function appIcon(): string {
return iconPath(nativeTheme.shouldUseDarkColors ? "dark" : "light");
}

/** Swap the macOS dock icon to the given brand variant (best-effort). */
/** Swap the macOS dock icon to the given brand tile (best-effort). */
function setDockIcon(variant: "dark" | "light"): void {
try {
app.dock?.setIcon(iconPath(variant));
Expand Down
Binary file added apps/desktop/src/renderer/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 7 additions & 3 deletions apps/desktop/src/renderer/styles/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -578,9 +578,13 @@ html.is-mac .topbar { padding-left: 78px; }
* themes); the merge-Y lanes + nodes are the violet accent (legible on both). */
.topbar-mark { width: 26px; height: 26px; display: block; color: var(--vscode-foreground); }
.topbar-mark svg { display: block; }
.topbar-mark .bm-cube { stroke: currentColor; stroke-opacity: 0.42; }
.topbar-mark .bm-lane { stroke: var(--gs-accent-ink, var(--gs-accent)); }
.topbar-mark .bm-node { fill: var(--gs-accent-ink, var(--gs-accent)); }
/* The mark is painted in the wordmark's violet→magenta gradient, so the glyph
and the logotype read as one brand. Faces carry the same gradient at low
opacity — depth from opacity, never a second hue. */
.topbar-mark .bm-face { fill: url(#bm-grad); }
.topbar-mark .bm-cube { stroke: url(#bm-grad); stroke-opacity: 0.55; }
.topbar-mark .bm-lane { stroke: url(#bm-grad); }
.topbar-mark .bm-node { fill: url(#bm-grad); }
.topbar-switch {
display: inline-flex;
align-items: center;
Expand Down
37 changes: 28 additions & 9 deletions apps/desktop/src/renderer/ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -430,29 +430,48 @@ export function isBenignError(message: string, source?: string): boolean {
return false;
}

/** The GitStudio brand mark, inline so it tracks the theme with no asset swap.
* The merge-Y lanes terminate in ringed nodes: each node — the three ends and
* the centre — is punched with a real hole (an SVG mask cuts through both the
* node and the lane beneath, so the bar background shows through on any theme),
* giving the lines that "open eyelet" look at every tip, not just the centre. */
/**
* The GitStudio brand mark, inline so it tracks the theme with no asset swap.
*
* This is the activity-bar glyph's recipe, in colour: three translucent
* isometric FACES give the cube a real 3D body (the flat silhouette-only mark
* it replaced read as a wireframe), a soft silhouette closes it, and the
* merge-Y — two branches converging into one commit, then down — is the bold
* signature on top. Every node (the three tips and the centre) is punched with
* a real hole by an SVG mask that cuts through the node AND the lane beneath,
* so the bar shows through: the "open eyelet" look, on any theme.
*
* The paint is the wordmark's violet→magenta gradient, so the mark and the
* logotype are visibly the same brand.
*/
export function brandMark(): HTMLElement {
const s = el("span", "topbar-mark");
s.innerHTML =
'<svg viewBox="0 0 24 24" width="26" height="26" fill="none" aria-hidden="true">' +
"<defs><mask id=\"bm-holes\">" +
"<defs>" +
'<linearGradient id="bm-grad" x1="0" y1="0" x2="1" y2="1">' +
'<stop offset="0%" stop-color="#A98CFF"/>' +
'<stop offset="100%" stop-color="#C160EF"/>' +
"</linearGradient>" +
'<mask id="bm-holes">' +
'<rect x="0" y="0" width="24" height="24" fill="#fff"/>' +
'<circle cx="4.05" cy="7.4" r="0.88" fill="#000"/>' +
'<circle cx="19.95" cy="7.4" r="0.88" fill="#000"/>' +
'<circle cx="12" cy="21.2" r="0.88" fill="#000"/>' +
'<circle cx="12" cy="12" r="1" fill="#000"/>' +
"</mask></defs>" +
'<g mask="url(#bm-holes)">' +
'<path class="bm-cube" d="M12 2.8 L19.95 7.4 L19.95 16.6 L12 21.2 L4.05 16.6 L4.05 7.4 Z" stroke-width="1.4" stroke-linejoin="round"/>' +
'<path class="bm-lane" d="M12 12 L4.05 7.4 M12 12 L19.95 7.4 M12 12 L12 21.2" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>' +
// The 3D body: top / right / left faces, each a different opacity of the
// same gradient — depth without a second colour.
'<path class="bm-face" d="M12 2.8 L19.95 7.4 L12 12 L4.05 7.4 Z" fill-opacity="0.16"/>' +
'<path class="bm-face" d="M19.95 7.4 L19.95 16.6 L12 21.2 L12 12 Z" fill-opacity="0.34"/>' +
'<path class="bm-face" d="M12 12 L12 21.2 L4.05 16.6 L4.05 7.4 Z" fill-opacity="0.24"/>' +
'<path class="bm-cube" d="M12 2.8 L19.95 7.4 L19.95 16.6 L12 21.2 L4.05 16.6 L4.05 7.4 Z" stroke-width="1.1" stroke-linejoin="round"/>' +
'<path class="bm-lane" d="M12 12 L4.05 7.4 M12 12 L19.95 7.4 M12 12 L12 21.2" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/>' +
'<circle class="bm-node" cx="4.05" cy="7.4" r="2.2"/>' +
'<circle class="bm-node" cx="19.95" cy="7.4" r="2.2"/>' +
'<circle class="bm-node" cx="12" cy="21.2" r="2.2"/>' +
'<circle class="bm-node" cx="12" cy="12" r="2.5"/>' +
'<circle class="bm-node" cx="12" cy="12" r="2.6"/>' +
"</g>" +
"</svg>";
return s;
Expand Down
7 changes: 4 additions & 3 deletions apps/extension/.vscodeignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ tsconfig.json
*.vsix
media/*.svg
!media/activitybar.svg
# Store screenshots are served from GitHub (vsce rewrites relative README image
# links to raw.githubusercontent.com) — keep them out of the vsix.
media/shots/**
# media/shots/** MUST ship: the walkthrough renders these as step media, and
# walkthrough images are loaded from INSIDE the extension (unlike README images,
# which vsce rewrites to absolute GitHub URLs). Excluding them = a walkthrough
# of broken image boxes.
38 changes: 38 additions & 0 deletions apps/extension/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,44 @@ All notable changes to **GitStudio** are documented here. This project adheres t
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.0.1] - 2026-07-14

The 1.0.0 walkthrough advertised features that silently did nothing. This is the
repair release.

### Fixed
- **Pull no longer demands a rebase.** A plain `git pull` ran with no
reconciliation strategy; since git 2.34 that is a hard error on divergent
branches (*"Need to specify how to reconcile divergent branches"*), which we
surfaced verbatim. Because the pull aborted, no merge was attempted — so
conflicts, and the 3-pane merge editor, never appeared either.
- **The 3-pane merge editor opens.** Clicking a conflicted file in the Changes
view used to open a plain 2-way diff; the merge editor was only reachable from
VS Code's built-in SCM view.
- **Inline blame no longer stacks** on top of VS Code's built-in blame or
GitLens. The duplicate check tested a setting's *default* instead of its
effective value, so the one annotation that actually overlapped was never
detected — while the only branch that fired silently rewrote your global
settings. GitStudio now asks, and never edits another extension's settings on
its own.
- **File & line history work.** Per-file history had no working UI at all (it
was routed through a *proposed* API that threw at activation). Added
**GitStudio: Show File History**. Line history no longer re-opens its picker on
top of the diff it just opened, and history/blame commands no longer no-op
silently when there is no active editor.
- **Staging is visible and honest.** The Staged group no longer disappears when
empty; committing with nothing staged offers *Stage All & Commit* instead of
failing with "unknown error"; rows no longer snap back between groups; Discard
reads as destructive; and a conflicted file's action says **Mark as Resolved**.
- **The walkthrough works.** Every button now runs a command that does something
from the walkthrough, the AI step points at the real Connect AI panel
(zero-key Copilot/Cursor, OpenAI-compatible, or a local agent CLI), and the
merge step no longer starts a destructive interactive rebase.
- **History, blame, and merge work on Windows** — a path helper never matched a
Windows `\` path, so those features silently did nothing there.
- **The macOS dock icon** is no longer oversized (it now carries Apple's icon
margin) and no longer swaps to a white tile that washed the mark out.

## [1.0.0] - 2026-07-14

The first stable release: the whole extension loads **instantly**, the commit
Expand Down
Binary file modified apps/extension/media/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading