|
| 1 | +<script setup lang="ts"> |
| 2 | +type CV = boolean | 'partial' | 'soon' |
| 3 | +interface Row { |
| 4 | + category?: boolean; label: string; note?: string; highlight?: boolean |
| 5 | + gw?: CV; gk?: CV; fork?: CV; sm?: CV; ghd?: CV; gb?: CV; tower?: CV |
| 6 | +} |
| 7 | +
|
| 8 | +// Competitor data fact-checked July 2026. Order matches the deep-dive pages, |
| 9 | +// with Tower appended (it has no deep dive but is in the landscape). |
| 10 | +const COLS = [ |
| 11 | + { key: 'gw', name: 'GitWand', sub: 'Free · MIT', gw: true }, |
| 12 | + { key: 'gk', name: 'GitKraken', sub: 'Free / ~$5/mo Pro' }, |
| 13 | + { key: 'fork', name: 'Fork', sub: '$59.99 · Native' }, |
| 14 | + { key: 'sm', name: 'Sublime Merge', sub: '$99 · Native' }, |
| 15 | + { key: 'ghd', name: 'GitHub Desktop', sub: 'Free · Electron' }, |
| 16 | + { key: 'gb', name: 'GitButler', sub: 'Free · Tauri/Rust' }, |
| 17 | + { key: 'tower', name: 'Tower', sub: '$69/yr · Native' }, |
| 18 | +] as const |
| 19 | +
|
| 20 | +const ROWS: Row[] = [ |
| 21 | + { category: true, label: 'Workflow' }, |
| 22 | + { label: 'Free & open source', gw: true, gk: false, fork: false, sm: false, ghd: true, gb: true, tower: false }, |
| 23 | + { label: 'Native app (no Electron)', gw: true, gk: false, fork: true, sm: true, ghd: false, gb: true, tower: true }, |
| 24 | + { label: 'Linux support', gw: true, gk: true, fork: false, sm: true, ghd: false, gb: true, tower: false }, |
| 25 | + { label: 'CLI tool', gw: true, gk: true, fork: false, sm: false, ghd: false, gb: true, tower: false }, |
| 26 | + { label: 'VS Code extension', gw: true, gk: true, fork: false, sm: false, ghd: false, gb: false, tower: false }, |
| 27 | +
|
| 28 | + { category: true, label: 'Conflict resolution' }, |
| 29 | + { label: 'Deterministic auto-resolve', gw: true, gk: 'partial', fork: false, sm: false, ghd: 'partial', gb: false, tower: false, highlight: true }, |
| 30 | + { label: 'Confidence score per hunk', gw: true, gk: false, fork: false, sm: false, ghd: false, gb: false, tower: false, highlight: true }, |
| 31 | + { label: 'Decision trace per hunk', gw: true, gk: false, fork: false, sm: false, ghd: false, gb: false, tower: false, highlight: true }, |
| 32 | + { label: 'Zero-impact merge/rebase preview', gw: true, gk: false, fork: false, sm: false, ghd: false, gb: false, tower: false, highlight: true }, |
| 33 | + { label: 'Predict rebase & cherry-pick', gw: true, gk: false, fork: false, sm: false, ghd: false, gb: false, tower: false, highlight: true }, |
| 34 | + { label: 'Scratch-worktree resolution', gw: true, gk: false, fork: false, sm: false, ghd: false, gb: false, tower: false, highlight: true }, |
| 35 | +
|
| 36 | + { category: true, label: 'Power Git' }, |
| 37 | + { label: 'Interactive rebase', gw: true, gk: true, fork: true, sm: true, ghd: false, gb: true, tower: true }, |
| 38 | + { label: 'Split commit by hunks', gw: true, gk: false, fork: false, sm: true, ghd: false, gb: false, tower: false }, |
| 39 | + { label: 'Worktrees', gw: true, gk: true, fork: true, sm: false, ghd: true, gb: false, tower: true }, |
| 40 | + { label: 'Virtual / stacked branches',gw: false, gk: false, fork: false, sm: false, ghd: false, gb: true, tower: false }, |
| 41 | + { label: 'Multi-repo workspaces', gw: true, gk: true, fork: true, sm: false, ghd: false, gb: false, tower: 'partial' }, |
| 42 | + { label: 'Cross-repo dashboard', gw: true, gk: true, fork: false, sm: false, ghd: false, gb: false, tower: false }, |
| 43 | +
|
| 44 | + { category: true, label: 'Code review & forges' }, |
| 45 | + { label: 'In-app PR/MR review', gw: true, gk: true, fork: 'partial', sm: false, ghd: 'partial', gb: 'partial', tower: false }, |
| 46 | + { label: 'GitHub · GitLab · Bitbucket · Azure', gw: true, gk: true, fork: true, sm: false, ghd: false, gb: false, tower: true }, |
| 47 | + { label: 'Inline CI check annotations', gw: true, gk: true, fork: false, sm: false, ghd: false, gb: false, tower: false }, |
| 48 | +
|
| 49 | + { category: true, label: 'AI & agents', note: 'GitWand uses the coding-agent CLIs you already have (Claude Code, Codex, opencode…). No built-in model, no account.' }, |
| 50 | + { label: 'Launch coding agents in-app', gw: true, gk: true, fork: false, sm: false, ghd: false, gb: true, tower: 'partial' }, |
| 51 | + { label: 'MCP server for AI agents', gw: true, gk: true, fork: false, sm: false, ghd: false, gb: true, tower: false }, |
| 52 | + { label: 'AI conflict explanation', gw: true, gk: 'partial', fork: false, sm: false, ghd: 'partial', gb: false, tower: false }, |
| 53 | + { label: 'AI commit messages', gw: true, gk: true, fork: true, sm: false, ghd: true, gb: 'partial', tower: true }, |
| 54 | +] |
| 55 | +
|
| 56 | +function ic(v?: CV) { return v === true ? '✓' : v === 'partial' ? '~' : v === 'soon' ? 'soon' : '✗' } |
| 57 | +function cc(v?: CV) { return v === true ? 'y' : v === 'partial' ? 'p' : v === 'soon' ? 's' : 'n' } |
| 58 | +</script> |
| 59 | + |
| 60 | +<template> |
| 61 | + <div class="cmp-block"> |
| 62 | + <div class="cmp-wrap"> |
| 63 | + <table class="cmp"> |
| 64 | + <thead> |
| 65 | + <tr> |
| 66 | + <th></th> |
| 67 | + <th v-for="c in COLS" :key="c.key" :class="{ 'cmp-gw': c.key === 'gw' }"> |
| 68 | + {{ c.name }}<span>{{ c.sub }}</span> |
| 69 | + </th> |
| 70 | + </tr> |
| 71 | + </thead> |
| 72 | + <tbody> |
| 73 | + <template v-for="r in ROWS" :key="r.label"> |
| 74 | + <tr v-if="r.category" class="cmp-cat"> |
| 75 | + <td :colspan="COLS.length + 1">{{ r.label }}<span v-if="r.note" class="cmp-note">{{ r.note }}</span></td> |
| 76 | + </tr> |
| 77 | + <tr v-else :class="{ 'cmp-hl': r.highlight }"> |
| 78 | + <td class="cmp-feat">{{ r.label }}<span v-if="r.highlight" class="cmp-uniq">GitWand</span></td> |
| 79 | + <td v-for="c in COLS" :key="c.key" :class="{ 'cmp-gw': c.key === 'gw' }"> |
| 80 | + <span :class="'c-' + cc((r as any)[c.key])">{{ ic((r as any)[c.key]) }}</span> |
| 81 | + </td> |
| 82 | + </tr> |
| 83 | + </template> |
| 84 | + </tbody> |
| 85 | + </table> |
| 86 | + </div> |
| 87 | + <p class="cmp-legend"><span class="c-y">✓</span> yes <span class="c-p">~</span> partial <span class="c-n">✗</span> no · Fact-checked July 2026 — spot something off? <a href="https://github.com/devlint/GitWand/issues">open an issue</a>.</p> |
| 88 | + </div> |
| 89 | +</template> |
| 90 | + |
| 91 | +<style scoped> |
| 92 | +.cmp-block{ |
| 93 | + --purple:#8B5CF6;--green:#10B981; |
| 94 | + --bg:#0c0c1a;--border:rgba(124,58,237,0.18);--border-soft:rgba(255,255,255,0.08); |
| 95 | + --text:#e2e8f0;--muted:#94a3b8; |
| 96 | + margin:24px 0;font-family:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif; |
| 97 | +} |
| 98 | +.cmp-wrap{overflow-x:auto;border:1px solid var(--border);border-radius:12px;background:var(--bg);} |
| 99 | +.cmp{width:100%;border-collapse:collapse;font-size:13.5px;min-width:760px;color:var(--text);} |
| 100 | +.cmp th,.cmp td{padding:11px 13px;text-align:center;border-bottom:1px solid var(--border-soft);} |
| 101 | +.cmp thead th{color:var(--muted);font-weight:700;vertical-align:top;} |
| 102 | +.cmp thead th span{display:block;font-size:11px;font-weight:500;opacity:0.7;margin-top:3px;} |
| 103 | +.cmp thead th.cmp-gw{color:var(--purple);} |
| 104 | +.cmp-feat{text-align:left;font-weight:500;color:var(--text);} |
| 105 | +.cmp-uniq{margin-left:8px;font-size:10px;color:var(--purple);border:1px solid var(--border);border-radius:6px;padding:1px 6px;white-space:nowrap;} |
| 106 | +.cmp-gw{background:rgba(124,58,237,0.09);} |
| 107 | +.cmp-cat td{text-align:left;font-weight:700;font-size:12px;text-transform:uppercase;letter-spacing:0.05em;color:var(--muted);background:rgba(255,255,255,0.02);padding-top:18px;} |
| 108 | +.cmp-note{display:block;text-transform:none;letter-spacing:0;font-weight:400;font-size:12px;color:var(--muted);margin-top:4px;} |
| 109 | +.cmp-hl{background:rgba(124,58,237,0.03);} |
| 110 | +.c-y{color:var(--green);font-weight:700;} |
| 111 | +.c-n{color:var(--muted);opacity:0.45;} |
| 112 | +.c-p{color:#fbbf24;} |
| 113 | +.c-s{font-size:11px;color:var(--purple);} |
| 114 | +.cmp-legend{font-size:12.5px;color:var(--muted);margin:10px 2px 0;} |
| 115 | +.cmp-legend a{color:var(--purple);} |
| 116 | +</style> |
0 commit comments