Skip to main content

Component Overview

Work-Wiki provides three complementary visualization components, each operating at a different granularity:
┌─────────────────────────────────────────────────────────────────────────────────┐
│                     THREE VISUALIZATION COMPONENTS                              │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│   COMPONENT 1: GitBlameViewer                                                   │
│   Granularity:  LINE-LEVEL                                                      │
│   View:         Who wrote each line?                                            │
│   AI Extension: AI attribution per commit line                                  │
│                                                                                 │
│   COMPONENT 2: GitDiffViewer                                                    │
│   Granularity:  HUNK-LEVEL                                                      │
│   View:         What changed in each hunk?                                      │
│   AI Extension: AI attribution per diff hunk                                    │
│                                                                                 │
│   COMPONENT 3: GitBranchDiagramViewer                                           │
│   Granularity:  COMMIT-LEVEL                                                    │
│   View:         Branch history with micro-saves                                 │
│   AI Extension: Micro-save badges + Draft nodes                                 │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

GitBlameViewer: Line-Level Attribution

Architecture

┌─────────────────────────────────────────────────────────────────────────────────┐
│                     GITBLAMEVIEWER ARCHITECTURE                                 │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│   Key Methods:                                                                  │
│   ├── loadData()              - Fetch blame + AI attribution                    │
│   ├── render()                - Render blame table                              │
│   ├── fetchWorkWikiAttributions() - Load AI data async                          │
│   ├── getIndicatorColor()     - 4-tier color mapping                            │
│   └── renderLine()            - Render individual line                          │
│                                                                                 │
│   Data Flow:                                                                    │
│                                                                                 │
│   ┌─────────────┐     invoke()    ┌─────────────────┐                           │
│   │ loadData()  │────────────────▶│  git_blame      │                           │
│   └──────┬──────┘                 │  (Tauri cmd)    │                           │
│          │                        └────────┬────────┘                           │
│          │ Phase 1                         │                                    │
│          ▼                                 │                                    │
│   ┌─────────────┐                          │                                    │
│   │  render()   │◀─────────────────────────┘                                    │
│   └──────┬──────┘                                                               │
│          │                                                                      │
│          │ Phase 2 (async)                                                      │
│          ▼                                                                      │
│   ┌─────────────────────────────┐     invoke()    ┌─────────────────────────┐   │
│   │ fetchWorkWikiAttributions() │────────────────▶│ work_wiki_get_ai_       │   │
│   └──────────────┬──────────────┘                 │ attributions_batch      │   │
│                  │                                └────────────┬────────────┘   │
│                  │                                             │                │
│                  ▼                                             │                │
│   ┌─────────────┐                                              │                │
│   │  render()   │◀─────────────────────────────────────────────┘                │
│   │  (with AI)  │                                                               │
│   └─────────────┘                                                               │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

Two-Phase Data Loading

┌─────────────────────────────────────────────────────────────────────────────────┐
│                     TWO-PHASE DATA LOADING                                      │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│   PHASE 1: Immediate (Core Blame Data)                                          │
│                                                                                 │
│       async loadData() {                                                        │
│         // 1. Fetch core blame data from git                                    │
│         this.data = await invoke('git_blame', {                                 │
│           filePath: this.filePath,                                              │
│           repoPath: this.repoPath                                               │
│         });                                                                     │
│                                                                                 │
│         // 2. Render IMMEDIATELY (user sees data fast)                          │
│         this.render();  // <-- Phase 1 complete                                 │
│       }                                                                         │
│                                                                                 │
│       │ t=50ms                                                                  │
│       ▼                                                                         │
│                                                                                 │
│   PHASE 2: Deferred (AI Attribution)                                            │
│                                                                                 │
│       // Non-blocking: fetch AI attributions and re-render                      │
│       this.fetchWorkWikiAttributions(                                           │
│         this.data.commits.map(c => c.hash)                                      │
│       ).then(() => {                                                            │
│         this.render();  // <-- Phase 2 re-render with AI data                   │
│       });                                                                       │
│                                                                                 │
│       │ t=150ms                                                                 │
│       ▼                                                                         │
│                                                                                 │
│   Timeline:                                                                     │
│       t=0ms       loadData() called                                             │
│       t=50ms      git_blame returns, Phase 1 render                             │
│       t=50ms      fetchWorkWikiAttributions() starts (async)                    │
│       t=150ms     AI data arrives, Phase 2 re-render                            │
│                                                                                 │
│   User Experience:                                                              │
│       - Blame data visible in 50ms                                              │
│       - AI indicators appear 100ms later                                        │
│       - No blocking, no spinner for AI data                                     │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

Agent Tooltip Display

┌─────────────────────────────────────────────────────────────────────────────────┐
│                     AGENT TOOLTIP DISPLAY                                       │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│   Visual Example:                                                               │
│                                                                                 │
│   ┌─────┬────────────┬────────┬───────────────────────────────────┐             │
│   │ AI% │ Author     │ Time   │ Line Content                      │             │
│   ├─────┼────────────┼────────┼───────────────────────────────────┤             │
│   │ ◉   │ abc1234    │ 2h ago │ export function authenticate() {  │             │
│   └─────┴────────────┴────────┴───────────────────────────────────┘             │
│     ↑                                                                           │
│     └── Hover shows: "AI: 67% (Claude, Gemini)"                                 │
│                                                                                 │
│   Implementation:                                                               │
│       title="AI: ${aiPct}%${agentNames ? ' (' + agentNames + ')' : ''}"         │
│                                                                                 │
│   Example Values:                                                               │
│       aiPct = 67                                                                │
│       agentNames = "Claude, Gemini"                                             │
│       Result: "AI: 67% (Claude, Gemini)"                                        │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

GitDiffViewer: Hunk-Level Attribution

hunkMeta Coordinate System

The GitDiffViewer introduces a novel coordinate system for hunk attribution:
┌─────────────────────────────────────────────────────────────────────────────────┐
│                     HUNKMETA COORDINATE SYSTEM                                  │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│   Problem: How to uniquely identify a hunk for AI attribution lookup?           │
│                                                                                 │
│   Diff lines have no inherent identity:                                         │
│   - Multiple files may have same line content                                   │
│   - Line numbers change between versions                                        │
│   - Hunk headers alone aren't unique across files                               │
│                                                                                 │
│   Solution: hunkMeta = { filePath, hunkIndex }                                  │
│                                                                                 │
│   ┌─────────────────────────────────────────────────────────────────────────┐   │
│   │  File: src/auth.ts                                                      │   │
│   ├─────────────────────────────────────────────────────────────────────────┤   │
│   │                                                                         │   │
│   │  diff --git a/src/auth.ts b/src/auth.ts                                 │   │
│   │  @@ -1,5 +1,8 @@                                                        │   │
│   │     hunkMeta = { filePath: "src/auth.ts", hunkIndex: 0 }                │   │
│   │  +import { validateToken } from './auth';                               │   │
│   │  +import { refreshToken } from './refresh';                             │   │
│   │   function authenticate() {                                             │   │
│   │  @@ -20,3 +23,5 @@                                                      │   │
│   │     hunkMeta = { filePath: "src/auth.ts", hunkIndex: 1 }                │   │
│   │  +  const token = getToken();                                           │   │
│   │  +  validateToken(token);                                               │   │
│   │                                                                         │   │
│   └─────────────────────────────────────────────────────────────────────────┘   │
│                                                                                 │
│   ┌─────────────────────────────────────────────────────────────────────────┐   │
│   │  File: src/api.ts                                                       │   │
│   ├─────────────────────────────────────────────────────────────────────────┤   │
│   │                                                                         │   │
│   │  diff --git a/src/api.ts b/src/api.ts                                   │   │
│   │  @@ -1,3 +1,4 @@                                                        │   │
│   │     hunkMeta = { filePath: "src/api.ts", hunkIndex: 0 }                 │   │
│   │  +import { fetchData } from './fetch';                                  │   │
│   │                                                                         │   │
│   └─────────────────────────────────────────────────────────────────────────┘   │
│                                                                                 │
│   Cache Key Format: "${filePath}:${hunkIndex}"                                  │
│                                                                                 │
│   Examples:                                                                     │
│   ├── "src/auth.ts:0"  -->  First hunk in auth.ts                               │
│   ├── "src/auth.ts:1"  -->  Second hunk in auth.ts                              │
│   └── "src/api.ts:0"   -->  First hunk in api.ts                                │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

GitBranchDiagramViewer: Commit-Level

Micro-Save Badge

┌─────────────────────────────────────────────────────────────────────────────────┐
│                     MICRO-SAVE BADGE ANATOMY                                    │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│   SVG Structure:                                                                │
│                                                                                 │
│   <g class="micro-save-badge" transform="translate(x, y-7)">                    │
│     ├── <rect>   Pill-shaped background (rounded corners)                       │
│     │            Semi-transparent fill with colored border                      │
│     │                                                                           │
│     ├── <text>   Count display                                                  │
│     │            Centered with text-anchor="middle"                             │
│     │            Capped at "99+" for very high counts                           │
│     │                                                                           │
│     └── <title>  Native SVG tooltip                                             │
│                  "Work-Wiki: N micro-save(s) before this commit"                │
│                                                                                 │
│   Width Calculation:                                                            │
│       1-9    --> 18px (single digit)                                            │
│       10-99  --> 22px (double digit)                                            │
│       100+   --> 28px (shows "99+")                                             │
│                                                                                 │
│   Visual Examples:                                                              │
│       [2]   <-- gray (1-3 saves, subtle)                                        │
│       [7]   <-- green (4-10 saves, normal)                                      │
│       [18]  <-- yellow (11-25 saves, complex)                                   │
│       [42]  <-- accent (25+ saves, major)                                       │
│       [99+] <-- accent (100+ saves, capped)                                     │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

Draft Branch Node

The Draft Node represents uncommitted work - the “future” of the codebase:
┌─────────────────────────────────────────────────────────────────────────────────┐
│                     DRAFT NODE VISUAL STRUCTURE                                 │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│   ┌─────────────┐   ┌─────────────────────────────────────────────────┐         │
│   │             │   │                                                 │         │
│   │     ◐       │   │  .draft-node-info                               │         │
│   │             │   │  ┌───────────────────────────────────────────┐  │         │
│   │ (half-moon) │   │  │                                           │  │         │
│   │             │   │  │  DRAFT                                    │  │         │
│   └─────────────┘   │  │  .draft-node-title                        │  │         │
│   .draft-node-icon  │  │                                           │  │         │
│                     │  │  3 files | +145 -23                       │  │         │
│                     │  │  .draft-node-stats                        │  │         │
│                     │  │                                           │  │         │
│                     │  │  [AI] 8  [H] 4                            │  │         │
│                     │  │  .draft-node-attribution                  │  │         │
│                     │  │                                           │  │         │
│                     │  └───────────────────────────────────────────┘  │         │
│                     │                                                 │         │
│                     └─────────────────────────────────────────────────┘         │
│                                                                                 │
│   .draft-node-connector                                                         │
│   ┌─────────────────────────────────────────────────────────────────┐           │
│   │    :                                                            │           │
│   │    : (dashed line connecting to HEAD)                           │           │
│   │    :                                                            │           │
│   └─────────────────────────────────────────────────────────────────┘           │
│                                                                                 │
│   Half-Moon Icon Meaning:                                                       │
│   ├── Full circle  = Complete (committed)                                       │
│   ├── Half circle  = In progress (uncommitted)                                  │
│   └── Empty circle = Planned (future)                                           │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

Cross-Component Patterns

Consistent 4-Tier Color System

All three viewers implement the same color thresholds:
┌─────────────────────────────────────────────────────────────────────────────────┐
│                     4-TIER COLOR SYSTEM COMPARISON                              │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                 │
│   GitBlameViewer & GitDiffViewer (AI Percentage):                               │
│       0-25%  AI  -->  green                                                     │
│       26-50% AI  -->  yellow                                                    │
│       51-75% AI  -->  accent                                                    │
│       76-100% AI -->  purple                                                    │
│                                                                                 │
│   GitBranchDiagramViewer (Micro-Save Count):                                    │
│       1-3   saves  -->  gray                                                    │
│       4-10  saves  -->  green                                                   │
│       11-25 saves  -->  yellow                                                  │
│       25+   saves  -->  accent                                                  │
│                                                                                 │
│   Note: Different thresholds for count vs percentage,                           │
│         but same color vocabulary!                                              │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

Map-Based O(1) Caching

All three viewers use the same caching pattern:
ViewerCache PropertyKey Format
GitBlameVieweraiAttributionCachecommit_hash
GitDiffViewerhunkAttributionsfilePath:hunkIndex
GitBranchDiagramViewercommitWorkCountscommit_hash

Two-Phase Rendering

All three viewers implement the same pattern:
┌───────────────────────────────────────────────────────────────────────┐
│  TWO-PHASE RENDERING PATTERN                                          │
├───────────────────────────────────────────────────────────────────────┤
│                                                                       │
│  loadData()                                                           │
│       │                                                               │
│       ├──► PHASE 1: Core data (immediate)                             │
│       │         │                                                     │
│       │         ├── invoke('core_command', ...)                       │
│       │         │                                                     │
│       │         └── render()  ─► User sees data immediately           │
│       │                                                               │
│       └──► PHASE 2: AI attribution (deferred, non-blocking)           │
│                 │                                                     │
│                 ├── fetchWorkWikiData(...)  ─► Runs async             │
│                 │                                                     │
│                 └── .then() → render()  ─► Re-render with AI data     │
│                                                                       │
│  Result: Fast initial load, AI data appears without blocking          │
│                                                                       │
└───────────────────────────────────────────────────────────────────────┘

Component Comparison

AspectGitBlameViewerGitDiffViewerGitBranchDiagramViewer
GranularityLineHunkCommit
Cache Keycommit_hashfilePath:hunkIndexcommit_hash
Primary VisualAI % indicatorHunk AI badgeMicro-save badge
Novel FeatureAgent tooltiphunkMeta coordinateDraft node (half-moon)
Default AI DisplayEnabledEnabledDraft: Enabled

THE CENTER

Key Findings

  1. All viewers use two-phase rendering - Non-blocking UX
  2. Consistent 4-tier color vocabulary - Unified visual language
  3. Map-based O(1) caching everywhere - Performance
  4. hunkMeta is a novel coordinate system - Unique contribution
  5. Draft node uses half-moon icon - Intuitive “in progress”
  6. Agent names in tooltip - Native browser tooltip