Skip to content

feat: harden GitGood and expand Git workflows - #36

Merged
erwin-wee merged 17 commits into
mainfrom
fix/audit-all
Oct 2, 2026
Merged

erwin-wee merged 17 commits into
mainfrom
fix/audit-all

Conversation

@erwin-wee

Copy link
Copy Markdown
Owner

Summary

Implements the agreed GitGood audit improvements and fixes all ten findings from the subsequent local-branch review.

  • Harden repository file access, secret storage/logging, settings sync, shell templates, IPC, AI inputs, and release publishing.
  • Add commit graphs, multiple GitHub accounts/windows, reflog undo, bisect, stacked branches, customizable shortcuts, MCP integration, clone options, repository groups/pins, PR auto-merge, and external diff/merge tools.
  • Improve AI with client-isolated cancellation, per-feature models, OpenAI-compatible providers, usage reporting, prompt caching, and repository/worktree opt-outs.
  • Improve startup, code splitting, syntax loading, accessibility, server reconnect/update handling, and background-server integration.
  • Split renderer actions and core handlers by domain; update documentation and archive completed OpenSpec changes.
  • Enable unit, fixture, and smoke suites on Linux, Windows, and macOS; harden release CI and add dependency updates.

Review fixes

  • Undo restores the pre-operation commit for pull-with-rebase and consecutive rebases.
  • Release uploads enumerate files inside downloaded version directories.
  • Secret-file filtering decodes Git-quoted paths and considers both sides of renames.
  • Concurrent AI jobs remain individually cancellable and correctly counted as active.
  • Linked worktrees inherit the main repository's AI policy and GitHub account.
  • Agent command placeholders are validated against the selected shell's actual quoting rules.
  • Stack publishing resolves a real publishing remote and preserves local tracking relationships.
  • Update installation checks every open repository/client.
  • Shortcut resets require consent before displacing another binding.
  • Compare preserves rename metadata and displays actual changed lines.

Verification

Latest local verification:

  • Typecheck passed; lint: 0 errors, 16 existing hook-dependency warnings.
  • Unit: 1,028 passed, 1 skipped.
  • Fixture: 358 passed, 3 skipped.
  • Electron smoke: 36/36 scenarios passed.
  • Desktop, renderer, headless server, and MCP builds passed.
  • Additional runtime checks exercised nested release assets (including spaces), hostile shell filenames, concurrent AI requests, real Git undo/rename cases, and the shortcut-reset consent UI.

PR CI will validate the latest branch on all three platforms.

Scope and limitations

  • GitLab support and i18n were explicitly deferred.
  • Code-signing/notarization wiring is present, but signing certificates and Apple credentials still need to be supplied.
  • Native managed-service installation on macOS/Windows and live external AI providers were not exercised on this Linux workstation.

…er fixes

Security (audit #1-11, #14, #15, #19):
- Repo-controlled files feeding AI/templates/config are read through a
  symlink-refusing, repo-confined reader; symlink diffs show link text.
- toFsPath confines repo-relative paths; repo.readFile/writeFile check the
  physical parent too.
- secrets.json / server token written 0600 (dir 0700); logger redacts
  secrets, never logs the server token, log file 0600; corrupt JSON stores
  are kept as *.corrupt-<ts> instead of being overwritten.
- Error explanations scrub the failed command; scrubSecrets moved to
  src/shared/secrets.ts.
- Settings sync only uses private gists holding the settings file and
  re-checks visibility before upload; custom agent command is machine-local.
- Trust prompt grants trust only for the command it displayed.
- gitgood://review/rerun links carry a single-use token; links without one
  ask for confirmation before uploading anything.
- Custom agent templates must quote {file} in double quotes.
- AI palette inspect commands use per-command option allowlists and run
  diffs with --no-ext-diff --no-textconv.
- Ref/branch arguments starting with '-' are refused in the main process.
- IPC accepted only from the app's own top-level frame; navigation limited
  to the exact entry document.

Server / web (#7, #23, #27, #38-40):
- /gitgood-bridge.js refuses cross-site fetches and sends CORP same-origin.
- Repo indicators use a light porcelain-v2 read with bounded concurrency.
- Web folder picker rendered by the app's Dialog.
- Managed background server on macOS (LaunchAgent) and Windows (HKCU Run
  key + --gitgood-server, no elevation).
- Web tabs back off when reconnecting, show a Reconnecting banner, and offer
  a reload after a server upgrade.

UX (#24, #28-30): error boundary with Reload/Copy details, AA-contrast diff
gutter, forced-colors styles, resizable History file pane.

Release / CI (#12, #13, #20, #58-62): SHA-pinned actions, read-only build
jobs and a separate publish job, installer fails closed on unverifiable
checksums and gains --uninstall, signing wired to optional secrets,
release script refuses to skip the CI gate silently, Dependabot, ESLint
react-hooks lint, Node 24 CI, universal mac / win arm64 / Linux deb
targets, Electron 44.5.1 and @anthropic-ai/sdk 0.131.
…l features

AI (audit #16, #17, #32-37):
- ai.cancel(feature) cancels only that feature, and in server mode only the
  calling client's job; backend copy is feature-neutral.
- Per-feature token usage (incl. cache reads, CLI cost when reported) kept in
  a machine-local ai-usage.json and shown in Options -> AI.
- Prompt caching: cached system prompt and shared review context block.
- Per-feature model overrides (modelFor), OpenAI-compatible provider
  (json_schema with json_object fallback, key stored like the Anthropic key).
- Secret-shaped files are never uploaded; secret patterns scrubbed from
  read-only AI inputs (not conflict resolution).
- Per-repository AI opt-out (context menu toggle or .gitgood/config.json
  "ai": false), enforced centrally in main; ai.cancel is never blocked.
- Resolver and suggestion writes go through the symlink-safe repo writer;
  repo.readFile/writeFile refuse symlinked leaves.

UX / performance (#18, #21, #22, #25, #26):
- git/gh minimum versions checked (2.30 / 2.40) with Setup note + banner.
- Heavy dialogs/views lazy-loaded and highlight.js grammars loaded on
  demand: main renderer chunk 931 kB -> 635 kB (58 chunks).
- `gitgood <path>` opens or adds the repository; folders can be dropped
  onto the window to add them (desktop).
- Commit summary keystroke measured at 0.4 ms median with 2,500 changed
  files, so it stays in the store.

Features (#45, #47, #48, #50-52): Compare "Files changed", PR auto-merge,
commit sign-off / skip hooks / commit.template prefill, external diff and
merge tools, clone options (depth, single branch, blobless, sparse,
submodules), pinned repositories and custom groups.

Also: agent-review-handoff smoke scenario uses the quoted "{file}" template.
…hortcuts, MCP

- History commit graph with branch lanes (incremental per page, --date-order
  while shown; hidden during search/filters and on phones; toggle in View
  menu, filter popover and Options).
- Multiple GitHub accounts: list/switch/sign out/add in Options -> Accounts;
  per-repository account injects that account's token (memory only) into gh
  and git network operations.
- Startup: git commands wait only for the git probe; gh/claude/gpg/ssh/lfs
  probes resolve independently.
- Multiple windows: File -> New Window and "Open in New Window"; each window
  is its own client (repo, watcher, progress); app-wide events broadcast.
- Undo history (reflog) dialog with restore/branch/checkout, "Undo last Git
  operation", and a bisect flow with Good/Bad/Skip/Reset banner.
- Stacked branches: stack markers, rebase --update-refs option, Push stack,
  PR base prefill.
- Rebindable keyboard shortcuts with conflict handling, part of portable
  settings.
- stdio MCP server (latest review, request re-review, open repository)
  registered by the gitgood-review plugin.
- Lazy chunks preload on idle and render directly once loaded (no 300 ms
  first-open delay); smoke scenarios wait for lazily mounted content.
The scan only needs git but waited for every tool probe (gh auth, gh api
user), which can take 15 s when gh is slow. The conflicts smoke scenario
now polls for the dialog instead of relying on a 300 ms sleep.
…penspec changes

README features are grouped under headings and cover the new features;
server mode documents running where repositories live (WSL2, remote VM).
CHANGELOG.md reconstructs 0.1.0-0.3.2 plus Unreleased; SECURITY.md covers
private reporting and the server-mode threat model. ARCHITECTURE and
AI-FEATURES describe the new modules. 19 completed openspec changes are
archived and their deltas synced into openspec/specs; the 9 tasks that
still need live verification stay open with notes.
@erwin-wee
erwin-wee merged commit 5d1eeb2 into main Oct 2, 2026
3 checks passed
@erwin-wee erwin-wee mentioned this pull request Oct 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant