# dsh-git-graph A Git commit-graph view for [DeepSeek Harness](https://github.com/deepseek-harness/): a dock button beside the chat input opens the history as a lane graph — branches, merges, refs — plus the worktree list. The agent gets the same topology through two tools. ## Install ```bash dsh plugin --profile web add github:DevViking-Persike/dsh-git-graph ``` Restart `dsh`. A `⎇ grafo` button appears beside the conversation input; type the repository path and press it. Read-only tools are active immediately. ## What you see - **Commit lanes**: each commit is a dot on a colored lane; first-parent lines run straight, merge edges curve between lanes. Branch and tag labels sit beside their commits; the current branch carries `*`. - **Worktrees**: the strip under the graph lists every worktree with its branch, `[detached]`, or `[bare]` state. - **Depth**: the panel loads the newest 200 commits; the `limit` config changes the default. ## Tools | Tool | What it does | |---|---| | `git_graph` | History with lanes, parents, refs, and worktrees as one-line summaries the model can reason over. | | `git_worktree` | Lists worktrees with their branches. | ## Configuration Every field is optional. | Field | Default | Meaning | |---|---|---| | `limit` | `300` | History depth for tools and the route default. | | `route` | `/git-graph` | Path the browser half fetches. | ```yaml - id: dsh-git-graph name: 'dsh-git-graph' config: limit: 500 ``` ## How it works The host half queries `git log --format` (hash, parents, author, timestamp, subject), `for-each-ref`, `symbolic-ref`, and `worktree list --porcelain` through the harness subprocess seam — fixed argv, no shell — assigns lanes newest-first, and serves the same JSON document to both the model tools and one HTTP route. The browser half registers into `conversation.input.dock` and renders the graph as SVG with no build step. Lane assignment follows one rule: **first registration wins a parent's lane**. Walking newest-first, each lane waits for one next commit; when two children name the same parent, the child processed first claims the parent's lane and the other curves into it — the same behavior common commit-graph renderers use, and the property that keeps freed lanes reused instead of growing without bound. ## Safety - Every git invocation is a fixed argv through the subprocess seam; a branch name is data to git, never a flag or a shell fragment. - The HTTP route answers `GET` only and quotes git's own diagnosis (for example `not a git repository`) on failure — never a stack trace. - Both surfaces are read-only: the plugin lists history and worktrees; it never commits, checks out, creates, or removes anything. - Collected output is capped per invocation. ## Known Limitations and Deferred Work - The panel requires typing the repository path; it does not discover the session cwd automatically, because the dock component has no session-scoped path today. - History depth is capped (`limit`, default 300); a very large repository shows its newest slice, not everything. - Ref decorations show local branches, tags, and remotes, but not `HEAD` as its own marker and not stash entries. - No worktree create/remove actions in the panel; those change machine state and would follow the docker plugin's opt-in pattern if added. - Audio/video modalities are irrelevant here; the graph is SVG and the data is text. ## Tests ```bash node --test test/*.test.js ``` 23 tests, no network. Data tests run against a real temporary git repository with real commits and a real merge — a hand-written fixture could agree with the parser while disagreeing with git. Client tests load the module through the real module-loader format with a minimal React fake. ## License MIT — see [LICENSE](LICENSE) and [NOTICE.md](NOTICE.md).