Files
openchamber/packages/web/src/api/git.ts
T
Erman HAVUÇandBohdan Triapitsyn 52ffe9daef feat(git-graph): VS Code-style git graph with commit actions in History modal (#1431)
* feat(types): add parents to GitLogEntry and new commit action types

* feat(git): add parent hashes and --all flag to getLog

* fix(git): move record separator to start of log format string

* feat(git): add checkoutCommit server function and route

* feat(git): add cherryPick server function and route

* feat(git): add revertCommit server function and route

* feat(git): add resetToCommit server function and route

* fix(tests): make git service tests branch-name portable, add error path tests

* feat(client): add checkoutCommit, cherryPick, revertCommit, resetToCommit API wrappers

* feat(git-graph): add lane assignment algorithm with tests

* feat(git-graph): add GitGraphSegment per-row SVG renderer

* feat(i18n): add locale strings for git graph action buttons

* fix(git-graph): handle lane convergence, fix SVG path coords, add connector tests

* feat(git-graph): add ref badges and action buttons to HistoryCommitRow

* fix(git-graph): add loading guards to reset actions, use theme tokens for ref badges

* fix(git-graph): conditional hooks, stale graph log, conflict handling, i18n

* fix(types): replace toBeDefined with toBeTruthy, fix toast API usage

* fix(lint): remove unused variables

* fix(git-graph): fix SVG height causing 150px row spacing

* fix(git-graph): smooth bezier curves, fill row height, round line caps

* fix(git-graph): non-scaling-stroke fixes bezier white spaces, sort curves on top

* fix(git-graph): remove viewBox scaling, match SVG height to actual row height

* fix(git-graph): ResizeObserver tracks actual row height, eliminates SVG height mismatch

* feat(git-graph): replace SVG with Canvas for graph rendering

* fix(git-graph): isolate canvas from flex layout to prevent replaced-element height leak

* feat(git-graph): align action buttons, add confirmation popups for all actions

* fix(git-graph): address code review findings CR-001 through CR-005

- CR-001: VS Code getGitLog now forwards 'all' option and parses %P parents
- CR-002: VS Code bridge/gitService implement checkoutCommit, cherryPick,
  revertCommit, resetToCommit with conflict detection and hard-reset guard
- CR-003: server-side commit hash validated with /^[0-9a-fA-F]{7,40}$/
  in both routes.js and service.js; 12 new rejection tests added
- CR-004: cherry-pick/revert conflict path now refreshes fetchStatus/
  fetchBranches/fetchLog; conflict toast uses i18n keys in all 7 locales
- CR-005: corrected O(n) comment to O(n x lanes)

* fix(i18n): add zh-TW locale and common.language.traditionalChinese key to all locales

upstream/main added zh-TW.ts after branch diverged; CI type-check fails
when PR is merged because zh-TW.ts was missing all gitView.history.actions.*
keys and loadMore/loadingMore. Also adds common.language.traditionalChinese
to en.ts and all 6 non-English files to match upstream en.ts.

* fix: harden git history actions

* feat: split git history graph view

* chore: remove git graph planning docs

---------

Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
2026-05-27 00:13:25 +03:00

78 lines
3.2 KiB
TypeScript

import * as gitApiHttp from '@openchamber/ui/lib/gitApiHttp';
import type {
GitAPI,
CreateGitCommitOptions,
GitLogOptions,
} from '@openchamber/ui/lib/api/types';
export const createWebGitAPI = (): GitAPI => ({
checkIsGitRepository: gitApiHttp.checkIsGitRepository,
getGitStatus: gitApiHttp.getGitStatus,
getGitDiff: gitApiHttp.getGitDiff,
getGitFileDiff: gitApiHttp.getGitFileDiff,
revertGitFile: gitApiHttp.revertGitFile,
stageGitFile: gitApiHttp.stageGitFile,
stageGitFiles: gitApiHttp.stageGitFiles,
unstageGitFile: gitApiHttp.unstageGitFile,
unstageGitFiles: gitApiHttp.unstageGitFiles,
isLinkedWorktree: gitApiHttp.isLinkedWorktree,
getGitBranches: gitApiHttp.getGitBranches,
deleteGitBranch: gitApiHttp.deleteGitBranch as GitAPI['deleteGitBranch'],
deleteRemoteBranch: gitApiHttp.deleteRemoteBranch as GitAPI['deleteRemoteBranch'],
removeRemote: gitApiHttp.removeRemote as GitAPI['removeRemote'],
generateCommitMessage: gitApiHttp.generateCommitMessage,
generatePullRequestDescription: gitApiHttp.generatePullRequestDescription,
listGitWorktrees: gitApiHttp.listGitWorktrees,
validateGitWorktree: gitApiHttp.validateGitWorktree,
createGitWorktree: gitApiHttp.createGitWorktree,
deleteGitWorktree: gitApiHttp.deleteGitWorktree,
validateWorktreeDirectory: gitApiHttp.validateWorktreeDirectory,
canonicalizeWorktreeState: gitApiHttp.canonicalizeWorktreeState,
createGitCommit(directory: string, message: string, options?: CreateGitCommitOptions) {
return gitApiHttp.createGitCommit(directory, message, options);
},
gitPush: gitApiHttp.gitPush,
gitPull: gitApiHttp.gitPull,
gitFetch: gitApiHttp.gitFetch,
listGitStashes: gitApiHttp.listGitStashes,
countGitStashFiles: gitApiHttp.countGitStashFiles,
stashGitChanges: gitApiHttp.stashGitChanges,
applyGitStash: gitApiHttp.applyGitStash,
popGitStash: gitApiHttp.popGitStash,
dropGitStash: gitApiHttp.dropGitStash,
checkoutBranch: gitApiHttp.checkoutBranch,
createBranch: gitApiHttp.createBranch,
renameBranch: gitApiHttp.renameBranch,
getGitLog(directory: string, options?: GitLogOptions) {
return gitApiHttp.getGitLog(directory, options);
},
getCommitFiles: gitApiHttp.getCommitFiles,
getCurrentGitIdentity: gitApiHttp.getCurrentGitIdentity,
hasLocalIdentity: gitApiHttp.hasLocalIdentity,
setGitIdentity: gitApiHttp.setGitIdentity,
getGitIdentities: gitApiHttp.getGitIdentities,
createGitIdentity: gitApiHttp.createGitIdentity,
updateGitIdentity: gitApiHttp.updateGitIdentity,
deleteGitIdentity: gitApiHttp.deleteGitIdentity,
getRemotes: gitApiHttp.getRemotes,
rebase: gitApiHttp.rebase,
abortRebase: gitApiHttp.abortRebase,
continueRebase: gitApiHttp.continueRebase,
merge: gitApiHttp.merge,
abortMerge: gitApiHttp.abortMerge,
continueMerge: gitApiHttp.continueMerge,
checkoutCommit: gitApiHttp.checkoutCommit,
cherryPick: gitApiHttp.cherryPick,
revertCommit: gitApiHttp.revertCommit,
resetToCommit: gitApiHttp.resetToCommit,
stash: gitApiHttp.stash,
stashPop: gitApiHttp.stashPop,
getConflictDetails: gitApiHttp.getConflictDetails,
worktree: {
list: gitApiHttp.listGitWorktrees,
validate: gitApiHttp.validateGitWorktree,
create: gitApiHttp.createGitWorktree,
remove: gitApiHttp.deleteGitWorktree,
},
});