JinzhaoTian/git-worktree

git-worktree

Browse Git worktrees and their commit ancestry in a graph — shipped as a DSH right-sidebar tab plugin (dsh-plugin) and as a Codex MCP App.

未分類codexcodex-plugindsh

Git Worktree Graph for Codex

Local MCP plugin for browsing Git worktrees and their commit ancestry. The graph UI is a React MCP App rendered through the host's JSON-RPC postMessage bridge. Right-click a commit to preview rebase or cherry-pick, then confirm an expiring one-use plan.

Two hosts

Codex exposes no docked right-sidebar API, so the view here renders as an MCP App or, for a task tab, through a loopback HTTP server the user opens by URL. DSH exposes a real tab-type system, so the same idea ships as a native right-sidebar tab instead.

RouteContainerStatus
This root projectCodex MCP App, or a loopback browser tabWorking
dsh-plugin/DSH right-sidebar tab, with panes, floating, and Session restoreRead-only first version, not yet run

The DSH bundle owns Git in a Host half and renders the panel as a React component in the application, so it inherits the host theme and needs no separate server, port, or token. Start with dsh-plugin/README.md.

Files

PathPurpose
plugin.json, mcp.jsonPortable plugin identity and local stdio MCP server
.codex-plugin/plugin.json, .mcp.jsonCodex compatibility manifest and MCP configuration
src/server.tsMCP server and UI resource registration
src/browser.tsLoopback HTTP host for a Codex right-side browser tab
src/mcp/git.tsexecFile("git", args) wrapper, repository checks, parsers
src/mcp/tools/worktrees.tsList and create worktrees
src/mcp/tools/status.tsDirty status
src/mcp/tools/log.tsCommit DAG, edges, and refs
src/mcp/tools/operations.tsPreview/apply rebase and cherry-pick
src/shared/types.tsShared data contracts
src/ui/GraphApp.tsx, src/ui/styles.cssShared React/D3 graph and action dialogs
src/ui/index.tsx, src/ui/browser.tsxMCP App and browser-tab entrypoints
scripts/build.mjs, tsconfig.*.jsonBuild configuration
skills/git-graph/SKILL.mdAgent workflow
dsh-plugin/The DSH bundle: Host Git route plus the right-sidebar tab

Build and run

Requires Node 20+ and Git. Run npm install, then npm run build. The bundled MCP config launches node ${PLUGIN_ROOT}/dist/server.js. Invoke git_worktree_list with repoPath pointing to the repository to open the UI. For direct stdio use, set GIT_WORKTREE_REPO to a repository path before starting the server, or pass repoPath to each read tool.

The graph shows the selected worktree's HEAD ancestry (up to 150 commits in the UI), so switching worktrees changes the displayed history. The repository's branches and tags are returned as refs. Worktree selection in the UI changes the view; it does not run git checkout or switch Codex's task checkout.

Open in the Codex right-side tab

Run npm run build, then npm run browser -- --repo /absolute/path/to/repository. The command prints a loopback URL such as http://127.0.0.1:PORT/?session=... and keeps serving while the process runs. Ask Codex to open that URL in the current task's right-side browser tab. The tab uses the same React graph as the MCP App and a local JSON API backed by the same Git functions. The server binds only to 127.0.0.1, fixes the repository at startup, and requires a random session token on API calls. Keep the server running while the tab is open.

This is a task tab beside file and review tabs. It does not install a permanent sidebar view or automatically follow Codex task changes.

MCP Apps attach UI to tool results. A host can show it in a side panel, but a permanently docked Codex right sidebar is not exposed by the documented plugin API. The server tools also work without UI.

History operations

git_rebase_preview and git_cherry_pick_preview require a clean worktree and return a one-use planId expiring in five minutes. The matching apply tool requires confirm: true, rechecks the worktree branch, HEAD, and target ref, then runs Git with argument arrays. If Git reports conflicts, the operation remains in that worktree for manual resolution. Merge commits are rejected for cherry-pick because they require a mainline choice.

All Git calls use child_process.execFile with fixed argument arrays. No shell command strings are used.