Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
89 commits
Select commit Hold shift + click to select a range
d79e36d
Add GitStudio brand kit: logo, wordmark, and favicon
claude Jun 23, 2026
9b84a63
Redesign GitStudio mark: commit cube (platform-grade logo)
claude Jun 24, 2026
ab2897d
Recolor commit-cube mark: slate body + single violet commit-graph lines
claude Jun 24, 2026
aabecbe
Add GitStudio logo SVG file with gradient and glow effects
antonarnaudov Jun 24, 2026
8e7c3f6
M0: workspace scaffold + shared core extraction
antonarnaudov Jun 25, 2026
08bef0a
M1: git-service data layer (GitProcess pool + Log/Ref providers)
antonarnaudov Jun 25, 2026
e6c71a0
M2: extension shell — activity bar + Commits & Branches tree views
antonarnaudov Jun 25, 2026
5d9a549
M3: Blame pillar — inline/status-bar/hover + full-file heatmap
antonarnaudov Jun 25, 2026
76edf6c
M4a: pure commit-graph lane algorithm (pvigier active-branches)
antonarnaudov Jun 25, 2026
90d9fa2
M4b: virtualized commit-graph webview (the flagship)
antonarnaudov Jun 25, 2026
30dbe3d
M5: file & line history + revision navigation
antonarnaudov Jun 25, 2026
bfb815f
M6: fold in side-by-side Diff + 3-pane Merge editor
antonarnaudov Jun 25, 2026
2920ad1
M7: hunk/line staging + Changes view + commit box
antonarnaudov Jun 25, 2026
e8cc8ea
M8: interactive rebase editor + universal reflog Undo envelope
antonarnaudov Jun 25, 2026
2cd25fa
M9: branches/remotes/stash/tags/worktrees ops + Search & Compare + sy…
antonarnaudov Jun 25, 2026
e5da0a7
M10: GitBrain — optional BYO-key AI (commit messages, explain, summar…
antonarnaudov Jun 25, 2026
39165b9
M11: in-editor Pull Request review (GitHub first)
antonarnaudov Jun 25, 2026
01622e2
M12: polish + release prep (walkthrough, docs, a11y, manifest audit)
antonarnaudov Jun 25, 2026
4fdae45
M13: native cross-platform desktop app (Electron) reusing the shared …
antonarnaudov Jun 25, 2026
c482beb
Post-handoff: make the extension actually work, then redesign the UI
antonarnaudov Jun 25, 2026
7c445c2
Unified Commit window: message + changes in one view, tree/list toggle
antonarnaudov Jun 25, 2026
ebd3800
Rename the unified commit window section "Commit" -> "Changes"
antonarnaudov Jun 25, 2026
338eb49
Commit window: Enter is a newline, commit is button-only
antonarnaudov Jun 25, 2026
274cd5f
Commit window: kill the duplicated "Changes" labels, tidy groups + count
antonarnaudov Jun 25, 2026
1d8d427
Redesign the Commit window into a real product surface
antonarnaudov Jun 25, 2026
9972fa8
Commit graph: add a real product header (branch · count · nav hints)
antonarnaudov Jun 25, 2026
d896708
Propagate the "Studio" language: shared tokens, rebase, diff chrome
antonarnaudov Jun 25, 2026
b042ffe
PR description panel: reading measure + tactile toolbar
antonarnaudov Jun 25, 2026
8771a34
Commit window: harden against narrow-sidebar overflow
antonarnaudov Jun 25, 2026
0bf9523
First-run welcome: warmer, more confident onboarding copy
antonarnaudov Jun 25, 2026
c3216fc
Sidebar icon: use the real brand mark (faithful mono reduction)
antonarnaudov Jun 25, 2026
1d00832
Use real VS Code Codicons in the commit window (not hand-drawn SVGs)
antonarnaudov Jun 25, 2026
da67c20
Commit graph: real Codicons in the header + ref chips
antonarnaudov Jun 25, 2026
87987f2
Rebase view: real Codicons (chevrons + drag gripper)
antonarnaudov Jun 25, 2026
4ea97ad
PR description panel: real Codicons (status, branches, checks, files)
antonarnaudov Jun 25, 2026
3f9b285
Commit details: git-service provider + shared inspect panel
antonarnaudov Jun 25, 2026
86af028
GitKraken commit graph: dock the details panel + CHANGES column (+ fi…
antonarnaudov Jun 25, 2026
ced4d66
Commits view: click a commit → open the graph + reveal its details
antonarnaudov Jun 25, 2026
231a973
Commit graph: author avatars ON the nodes (GitKraken-style)
antonarnaudov Jun 26, 2026
2697b4c
Desktop: GitKraken graph parity (avatars, headers, CHANGES column) + …
antonarnaudov Jun 26, 2026
5d2a6d4
Commit graph toolbar: live search with match highlight + nav + refresh
antonarnaudov Jun 26, 2026
b75996d
Commit graph: GitKraken-style WIP "uncommitted changes" node
antonarnaudov Jun 26, 2026
c5a5d56
Desktop: link the bundled stylesheet (fixes the completely unstyled UI)
antonarnaudov Jun 26, 2026
afb898b
Desktop: adopt the shared commit-details panel (full extension parity)
antonarnaudov Jun 26, 2026
4dfc3fe
Desktop: branded welcome + full-screen repo view + repo/branch switch…
antonarnaudov Jun 26, 2026
bcd7725
Desktop: enhance theme handling and UI consistency with dynamic backg…
antonarnaudov Jun 27, 2026
eaa6b12
feat: add integrated terminal dock and terminal panel
antonarnaudov Jun 28, 2026
7e31e36
feat(ai+mcp): shared AI layer, agent loop, and a standalone MCP server
antonarnaudov Jun 28, 2026
ddc53e1
Desktop: production hardening — security, reliability & accessibility…
antonarnaudov Jun 28, 2026
2918db0
Desktop: polish pass — consistent time tooltips, terminal a11y, actio…
antonarnaudov Jun 28, 2026
0fd04c5
feat(desktop): in-app AI Assistant + model connections + MCP Agent Ac…
antonarnaudov Jun 28, 2026
9c5d9bb
docs: handoff notes for the AI/MCP build + two-branch merge plan
antonarnaudov Jun 28, 2026
1a4869c
Desktop: fix issues from adversarial self-review
antonarnaudov Jun 28, 2026
983a21a
Desktop: fitting icons on git-native empty states
antonarnaudov Jun 28, 2026
7132527
Desktop: slim PyCharm-style topbar, header search across sections, co…
antonarnaudov Jun 28, 2026
52d8467
Desktop: search on the left, slimmer footer, commit details docked in…
antonarnaudov Jun 28, 2026
b0566b4
Desktop: fix docked commit-details (lag, double-scroll, space, diff-o…
antonarnaudov Jun 28, 2026
99a0af9
Desktop: searchable branch/tag picker for the Run-workflow ref field
antonarnaudov Jun 28, 2026
ab19b94
Desktop: ref picker floats above (native popover) + slicker footer tabs
antonarnaudov Jun 28, 2026
2704c35
Desktop: dock body overlays the view content when open (doesn't push …
antonarnaudov Jun 28, 2026
335df93
Desktop: dock bar rises ON TOP of the panel when open, drops to the b…
antonarnaudov Jun 28, 2026
390a111
Desktop: single VS-Code-style Terminal view + no active-tab underline…
antonarnaudov Jun 28, 2026
369c2c8
webview-ui: fix commit-details scroller overflow (couldn't reach the …
antonarnaudov Jun 28, 2026
07b7bbe
Add new SVG icon for GitStudio with gradient effects and glow filter
antonarnaudov Jun 28, 2026
38ea2df
merge: bring in the desktop UI/hardening rework alongside the AI + MC…
antonarnaudov Jun 28, 2026
c7b68ce
chore: reconcile package-lock after merge (npm install)
antonarnaudov Jun 28, 2026
8d0a2cb
feat(ai): real provider brand logos + local CLI providers (Claude Cod…
antonarnaudov Jun 28, 2026
6fc357d
feat(ai): group the "connect a model" gallery into 3 sections
antonarnaudov Jun 28, 2026
d94b275
fix(ai): stream the Assistant's responses (no more long "Working…" st…
antonarnaudov Jun 28, 2026
bd2c912
fix(ai): stream local CLI responses live (Claude Code token-by-token)
antonarnaudov Jun 28, 2026
3feddca
feat(ai): live "Thinking… Ns" counter + Assistant speed selector
antonarnaudov Jun 28, 2026
4336759
feat(ai): animated "thinking" indicator + configurable agent (model/s…
antonarnaudov Jun 28, 2026
eb9b89a
feat(ai): pick the Assistant's model directly in the UI, propagated f…
antonarnaudov Jun 28, 2026
c8fc7d5
perf(ai): skip the user's MCP servers in the Assistant's Claude Code …
antonarnaudov Jun 28, 2026
415d189
feat(desktop): Warp-style terminal command blocks on xterm.js
antonarnaudov Jun 28, 2026
f33f670
feat(ai): persistent Assistant chats with a warm per-chat session
antonarnaudov Jun 28, 2026
65a9224
feat(ux): keep-alive views, live-Markdown streaming, "Loading the age…
antonarnaudov Jun 28, 2026
4b4c47e
feat(ai): AI Assistant launcher in the header + inline ✨ AI across th…
antonarnaudov Jun 28, 2026
d15d614
feat(desktop): terminal autocomplete (history, PATH, cwd paths)
antonarnaudov Jun 28, 2026
390872b
feat(desktop): terminal command menu + in-terminal agent mode
antonarnaudov Jun 28, 2026
8fa3c6b
fix(desktop): harden terminal autocomplete/menu/agent (adversarial re…
antonarnaudov Jun 29, 2026
69e137c
fix(desktop): make terminal autocomplete prefix-based + context-aware
antonarnaudov Jun 29, 2026
02c2d6d
feat: enhance gists and issues views with list resizer and improved s…
antonarnaudov Jun 30, 2026
c7a51e6
revert(desktop): remove the Warp terminal; raw terminal + default colors
antonarnaudov Jun 30, 2026
bf8d6b7
Enhance graph rendering and styling
antonarnaudov Jul 4, 2026
913b93f
release: prep 1.0.0 — store listing, screenshots, docs, hardened pipe…
antonarnaudov Jul 14, 2026
c6bf792
feat(suite): sidebar commit rail, live sync UX, status engine, compar…
antonarnaudov Jul 14, 2026
9d3440f
fix(ci): windows-safe worktree test; correct pinned artifact names in…
antonarnaudov Jul 14, 2026
185a9f8
fix: apply confirmed findings from the pre-merge adversarial review
antonarnaudov Jul 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
63 changes: 63 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
name: CI

on:
push:
branches: [main]
pull_request:

jobs:
# Tests run on every OS the release workflows build on — otherwise a tagged
# release is the FIRST time the suite ever executes on windows/mac, and a
# failure there yields a half-published release instead of a red PR.
test:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-14, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: '22'
cache: npm

- run: npm ci

- name: Type-check
run: npm run check-types

- name: Test
run: npm test

build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: '22'
cache: npm

- run: npm ci

- name: Engine purity guard
run: npm run check-purity

- name: Package extension (smoke-test the build)
run: |
npm run package
npx @vscode/vsce package -o gitstudio.vsix --no-dependencies \
--baseImagesUrl https://github.com/GitStudioHQ/gitstudio/raw/HEAD/apps/extension \
--baseContentUrl https://github.com/GitStudioHQ/gitstudio/blob/HEAD/apps/extension
working-directory: apps/extension

- uses: actions/upload-artifact@v4
with:
name: gitstudio-vsix
path: apps/extension/gitstudio.vsix

- name: Build desktop bundles (smoke-test)
run: npm run build --workspace apps/desktop
132 changes: 132 additions & 0 deletions .github/workflows/release-desktop.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
name: Release Desktop

# Builds the GitStudio desktop (Electron) app for macOS (Apple Silicon + Intel),
# Windows, and Linux and uploads the per-OS installers (.dmg / .exe / .AppImage /
# .deb) to the GitHub Release when an `app-v*` tag is pushed.
#
# Cut a release:
# 1. bump "version" in apps/desktop/package.json
# 2. git tag app-v1.0.0 && git push origin app-v1.0.0
#
# Structure: ONE create-release job makes the Release (so four matrix jobs never
# race `gh release create` against each other), then the per-OS build jobs only
# upload assets. Desktop releases stay the repo's "latest" release — the in-app
# auto-updater resolves /releases/latest, and extension (`ext-v*`) releases are
# created with --latest=false so they can never hijack that pointer.
#
# Code-signing/notarization are OPTIONAL: electron-builder builds UNSIGNED when
# the CSC_*/APPLE_* secrets are absent. With no secrets you still get working
# (unsigned) installers attached to the Release.

on:
push:
tags:
- 'app-v*.*.*'
workflow_dispatch:

permissions:
contents: write

jobs:
create-release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: "Guard: tag matches package.json version"
if: startsWith(github.ref, 'refs/tags/')
working-directory: apps/desktop
run: |
node -e '
const v = require("./package.json").version;
const tag = process.env.GITHUB_REF_NAME.replace(/^app-v/, "");
if (v !== tag) {
console.error(`Tag app-v${tag} != package.json version ${v}`);
process.exit(1);
}'

- name: Create the GitHub Release (once, before the matrix)
if: startsWith(github.ref, 'refs/tags/')
env:
GH_TOKEN: ${{ github.token }}
run: |
if gh release view "${GITHUB_REF_NAME}" >/dev/null 2>&1; then
echo "Release ${GITHUB_REF_NAME} already exists."
exit 0
fi
NOTES="docs/releases/${GITHUB_REF_NAME}.md"
if [ -f "$NOTES" ]; then
gh release create "${GITHUB_REF_NAME}" --latest \
--title "GitStudio ${GITHUB_REF_NAME#app-v}" --notes-file "$NOTES"
else
gh release create "${GITHUB_REF_NAME}" --latest --generate-notes \
--title "GitStudio ${GITHUB_REF_NAME#app-v}"
fi

build:
needs: create-release
strategy:
fail-fast: false
matrix:
include:
# Build each mac arch NATIVELY (macos-14 = Apple Silicon, macos-15-intel
# = x64; macos-13 was retired by GitHub in Dec 2025) so node-pty's
# per-arch prebuild loads without cross-compiling.
#
# NOTE: mac deliberately does NOT upload latest-mac.yml. Both arch runners
# emit an identically-named latest-mac.yml, so a --clobber upload would
# leave the Release with ONE arch's feed and mis-update the other; the
# app skips update checks on macOS instead (see autoUpdate.ts). Windows/
# Linux are single-arch, so their feeds are safe.
- os: macos-14
artifact: 'apps/desktop/release/*.dmg apps/desktop/release/*.zip'
- os: macos-15-intel
artifact: 'apps/desktop/release/*.dmg apps/desktop/release/*.zip'
- os: windows-latest
artifact: 'apps/desktop/release/*.exe apps/desktop/release/*.yml apps/desktop/release/*.blockmap'
# ubuntu-22.04 (not -latest): the AppImage links the build host's glibc,
# so building on 24.04 (glibc 2.39) breaks Ubuntu 22.04/Debian 12 users.
# No *.blockmap here — AppImage/deb don't emit one, and a non-matching
# glob would fail the upload.
- os: ubuntu-22.04
artifact: 'apps/desktop/release/*.AppImage apps/desktop/release/*.deb apps/desktop/release/*.yml'
runs-on: ${{ matrix.os }}
env:
# electron-builder reads these; when absent it builds UNSIGNED (it does not
# fail). Provide them as repo secrets to enable signing/notarization.
CSC_LINK: ${{ secrets.CSC_LINK }}
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
WIN_CSC_LINK: ${{ secrets.WIN_CSC_LINK }}
WIN_CSC_KEY_PASSWORD: ${{ secrets.WIN_CSC_KEY_PASSWORD }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
GH_TOKEN: ${{ github.token }}
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: '22'
cache: npm

- name: Install (workspace root)
run: npm ci

- name: Type-check
run: npm run check-types --workspaces --if-present

- name: Test
run: npm test

- name: Build bundles (main / preload / renderer)
run: npm run build --workspace apps/desktop

- name: Build installer (electron-builder)
working-directory: apps/desktop
run: npx electron-builder --publish never

- name: Upload installers to the GitHub Release
if: startsWith(github.ref, 'refs/tags/')
shell: bash
run: gh release upload "${GITHUB_REF_NAME}" ${{ matrix.artifact }} --clobber
115 changes: 115 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
name: Release Extension

# Publishes the GitStudio extension to the VS Code Marketplace and Open VSX when
# an `ext-vX.Y.Z` tag is pushed, then attaches the .vsix to the GitHub Release.
# (The desktop app has its own channel: `app-v*` tags -> .github/workflows/release-desktop.yml.)
#
# One-time setup — add two repo secrets:
# VSCE_PAT Azure DevOps PAT, scope "Marketplace > Manage", for publisher `gitstudio`
# OVSX_PAT Open VSX access token (namespace `gitstudio` must exist)
#
# Cut a release:
# 1. bump "version" in apps/extension/package.json (+ a CHANGELOG entry)
# 2. git tag ext-v1.0.0 && git push origin ext-v1.0.0
#
# The .vsix is attached to the Release BEFORE publishing, so even a failed
# publish leaves a downloadable artifact; the publish steps FAIL LOUDLY when a
# secret is missing (a silent green run that shipped nothing cost us a launch).
# After adding the missing secret, re-run via workflow_dispatch — it rebuilds
# and publishes the current package.json version without needing a new tag.

on:
push:
tags:
- 'ext-v*.*.*'
workflow_dispatch:

permissions:
contents: write

jobs:
release:
runs-on: ubuntu-latest
defaults:
run:
working-directory: apps/extension
env:
VSCE_PAT: ${{ secrets.VSCE_PAT }}
OVSX_PAT: ${{ secrets.OVSX_PAT }}
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: '22'
cache: npm

# The tag names the release, but vsce/electron-builder ship whatever is in
# package.json — a mismatch publishes the WRONG version under this tag.
- name: "Guard: tag matches package.json version"
if: startsWith(github.ref, 'refs/tags/')
run: |
node -e '
const v = require("./package.json").version;
const tag = process.env.GITHUB_REF_NAME.replace(/^ext-v/, "");
if (v !== tag) {
console.error(`Tag ext-v${tag} != package.json version ${v}`);
process.exit(1);
}'

- name: Install (workspace root)
run: npm ci
working-directory: .

- name: Type-check
run: npm run check-types --workspaces --if-present
working-directory: .

- name: Test
run: npm test
working-directory: .

# --baseImagesUrl: vsce's default rewrite of relative README images uses
# the repo ROOT (https://github.com/…/raw/HEAD/media/…), but this is a
# monorepo — the images live under apps/extension. Without this flag every
# store screenshot 404s.
- name: Package
run: |
npm run package
npx @vscode/vsce package -o gitstudio.vsix --no-dependencies \
--baseImagesUrl https://github.com/GitStudioHQ/gitstudio/raw/HEAD/apps/extension \
--baseContentUrl https://github.com/GitStudioHQ/gitstudio/blob/HEAD/apps/extension

# `--latest=false` is load-bearing: the desktop app's auto-updater reads
# /releases/latest, and an extension release marked "latest" would point
# it at a tag with no latest.yml feed (update checks 404 forever).
- name: Attach .vsix to the GitHub Release
if: startsWith(github.ref, 'refs/tags/')
env:
GH_TOKEN: ${{ github.token }}
run: |
NOTES="../../docs/releases/${GITHUB_REF_NAME}.md"
if [ -f "$NOTES" ]; then
gh release create "${GITHUB_REF_NAME}" gitstudio.vsix --latest=false \
--title "GitStudio extension ${GITHUB_REF_NAME#ext-v}" --notes-file "$NOTES" \
|| gh release upload "${GITHUB_REF_NAME}" gitstudio.vsix --clobber
else
gh release create "${GITHUB_REF_NAME}" gitstudio.vsix --latest=false --generate-notes \
|| gh release upload "${GITHUB_REF_NAME}" gitstudio.vsix --clobber
fi

- name: Publish to VS Code Marketplace
run: |
if [ -z "$VSCE_PAT" ]; then
echo "::error::VSCE_PAT secret is missing — Marketplace publish did NOT run. Add the secret, then re-run this workflow (workflow_dispatch)."
exit 1
fi
npx @vscode/vsce publish --packagePath gitstudio.vsix

- name: Publish to Open VSX
run: |
if [ -z "$OVSX_PAT" ]; then
echo "::error::OVSX_PAT secret is missing — Open VSX publish did NOT run. Add the secret, then re-run this workflow (workflow_dispatch)."
exit 1
fi
npx ovsx publish gitstudio.vsix
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
node_modules/
dist/
out/
release/
*.vsix
.DS_Store
.vscode-test/

# IDE dependency-graph plugin artifacts
.dependencygraph/
71 changes: 71 additions & 0 deletions HANDOFF-AI-MCP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Handoff — AI + Agents + MCP (overnight build)

## What shipped

Two features the user asked for, built and verified overnight:

1. **Connect any AI model in the app** + AI/agent capabilities that leverage
your own subscriptions/keys (or a local model).
2. **A first-class MCP server** exposing this repo's Git capabilities to any
outside agent, used wisely (least-privilege).

Both reuse **one shared tool catalog** (`@gitstudio/ai/gitTools`), so the in-app
agent and the MCP server stay in lockstep.

See [`docs/ai-and-agents.md`](docs/ai-and-agents.md) and
[`apps/mcp/README.md`](apps/mcp/README.md).

## ⚠️ Two branches — why, and how to merge

While I was working, **a second Claude session was concurrently editing the
desktop app** (a security/theme hardening pass: `cloneUrl.ts`, `security.test.ts`,
`theme-boot.js`, and edits to `renderer.ts` / `main.ts` / `gitBridge.ts` /
`app.css`). To avoid silently clobbering its work, I split the build:

- **`claude/redesign-masterpiece`** (the shared branch) got the **collision-free
foundation** — commit `7e31e36`:
- `packages/ai` (`@gitstudio/ai`) — providers, catalog, connections, tasks,
agent loop, shared git-tool catalog.
- `packages/git-service/GitToolHost.ts` — the tool host over a real repo.
- `apps/mcp` (`gitstudio-mcp`) — the standalone MCP server.
- **`claude/ai-mcp-desktop`** (this branch, from `7e31e36`) got the **desktop
integration** — commit `0fd04c5` — built in an isolated git worktree so it
never raced the other session: `main/aiBridge.ts`, `main/mcpConfig.ts`,
`renderer/{assistant,aiSettings}.ts`, plus minimal edits to `renderer.ts`,
`main.ts`, `shared/ipc.ts`, `styles/app.css`, `package.json`.

### To land everything

```bash
# 1. Let the other session commit its desktop changes on claude/redesign-masterpiece.
# 2. Merge this branch in:
git checkout claude/redesign-masterpiece
git merge claude/ai-mcp-desktop
# 3. Expect conflicts in the files BOTH sessions touched:
# renderer.ts (nav tab + settings cards + route — small, localized),
# main.ts (AiBridge construct + ai:* handlers — one contiguous block),
# app.css (AI styles appended at the very end),
# shared/ipc.ts (AI channels/events/types — contiguous blocks).
# My additions are deliberately localized + contiguous to keep these easy.
# 4. npm install (reconciles the lockfile: new @gitstudio/ai dep edges)
# 5. npm run check-types && npm test && (cd apps/mcp && npm run build)
```

The worktree lives at `/tmp/gitstudio-ai-wt` (throwaway; remove with
`git worktree remove /tmp/gitstudio-ai-wt` after merging).

## Status

- **Tests:** 232 pass in the main repo (16 ai + 73 git-service incl. 5 new
tool-host + 13 mcp + the rest). Desktop typechecks (main + renderer) and
bundles cleanly. (Running git-service tests *inside the /tmp worktree* falsely
fails on a `tsx`+symlink path quirk — they pass in the real checkout.)
- **Verified end-to-end:** the MCP server over real stdio (initialize →
tools/list → tools/call → resources/read), read-only vs `--write` gating.
- **Not done (deliberate, to limit merge pain):** deep inline ✨ buttons in the
commit composer / diff views — the Assistant already covers those flows
("draft a commit", "summarize my changes") in one surface. The task functions
exist in `@gitstudio/ai/tasks` and `ai:task` IPC is wired, so adding inline
buttons later is small.
- Nothing here gates Git: with no model connected, the AI affordances stay
hidden and the app behaves exactly as before.
Loading
Loading