|
| 1 | +# 203 - Git Worktree Mapper |
| 2 | + |
| 3 | +```rig |
| 4 | +import { agent, p, s, defineTool } from "rig"; |
| 5 | +
|
| 6 | +const parseWorktreePorcelain = defineTool("parseWorktreePorcelain", { |
| 7 | + description: "Parse the porcelain output of git worktree list into structured entries", |
| 8 | + parameters: s.object({ output: s.string }), |
| 9 | + handler({ output }) { |
| 10 | + const entries: Array<{ path: string; branch?: string; state: string }> = []; |
| 11 | + const blocks = output.trim().split("\n\n"); |
| 12 | + for (const block of blocks) { |
| 13 | + const lines = block.split("\n"); |
| 14 | + const pathLine = lines.find((l) => l.startsWith("worktree ")); |
| 15 | + const branchLine = lines.find((l) => l.startsWith("branch ")); |
| 16 | + const isLocked = lines.some((l) => l.startsWith("locked")); |
| 17 | + const isBare = lines.some((l) => l.startsWith("bare")); |
| 18 | + const entry: { path: string; branch?: string; state: string } = { |
| 19 | + path: pathLine ? pathLine.replace("worktree ", "") : "", |
| 20 | + state: isLocked ? "locked" : isBare ? "bare" : "clean", |
| 21 | + }; |
| 22 | + if (branchLine) entry.branch = branchLine.replace("branch refs/heads/", ""); |
| 23 | + if (entry.path) entries.push(entry); |
| 24 | + } |
| 25 | + return entries; |
| 26 | + }, |
| 27 | +}); |
| 28 | +
|
| 29 | +// Agent role: map all git worktrees and summarize active vs total count. |
| 30 | +const gitWorktreeMapperV2 = agent({ |
| 31 | + model: "small", |
| 32 | + instructions: p`Get all git worktrees: ${p.bash("git worktree list --porcelain 2>/dev/null || echo ''")}. Use the parseWorktreePorcelain tool to parse the output into structured entries. For each worktree check if there are uncommitted changes (set state to dirty). Count all worktrees for totalCount and non-bare ones for activeCount.`, |
| 33 | + output: s.object({ |
| 34 | + worktrees: s.array(s.object({ |
| 35 | + path: s.string, |
| 36 | + branch: s.optional(s.string), |
| 37 | + state: s.enum("locked", "bare", "clean", "dirty"), |
| 38 | + })), |
| 39 | + summary: s.object({ |
| 40 | + totalCount: s.int, |
| 41 | + activeCount: s.int, |
| 42 | + }), |
| 43 | + }), |
| 44 | + tools: [parseWorktreePorcelain], |
| 45 | +}); |
| 46 | +
|
| 47 | +export default gitWorktreeMapperV2; |
| 48 | +``` |
0 commit comments