2026 03 21 Git Operations Graph And Components Design

Documentation for Plans

S254: Git Operations — Graph Visualization, Sub-Components & Multi-App Integration

Date: 2026-03-21 Session: 254 Agent: Claude Code (claude-opus-4-6) Branch: session-252-255 (shared concurrent session)


1. Mission

Build a groundbreaking git graph visualization using a "Metro + Living Intelligence" visual paradigm, extract all UI into fine-grained reusable components within the @libs-structural/git-operations library, and wire the library into gograb-admin and vitto-studio alongside the existing gograb-dev integration.


2. Design Decisions

Decision Choice Rationale
Visual style Metro + Living Intelligence Metro thick lines and station dots for unique aesthetic; living behavior (glow, fade, density) communicates meaning through visual language
Orientation Vertical Natural page scroll, commit details alongside nodes, works in narrow panels (vitto-studio dock)
Interaction Progressive disclosure Click = inline expand (diff stats). "Full detail" button = slide-out panel with complete diff and file preview
Sub-components 6 fine-grained + graph as star Maximum reusability across apps with different layouts
Template filtering Role-gated smart filter Executive/developer can toggle; admin/user always filtered — platform-wide convention
vitto-studio Studio dock panel Fits the workspace tool pattern (file tree, module tree), not observatory AI tabs
gograb-admin New "Platform" nav group No platform section exists yet; create one with git-operations as first entry

3. Architecture

3.1 Component Tree

All components live in libs/libs-structural/git-operations/src/lib/components/:

components/
├── git-graph/                        ★ Star component
│   ├── git-graph.component.ts
│   ├── git-graph.component.html
│   ├── git-graph.component.scss
│   ├── git-graph-lane.util.ts          # Pure fn: lane assignment algorithm
│   └── git-graph-renderer.util.ts      # Pure fn: SVG path/node generation
├── git-repo-card/
│   ├── git-repo-card.component.ts
│   ├── git-repo-card.component.html
│   └── git-repo-card.component.scss
├── git-branch-sidebar/
│   ├── git-branch-sidebar.component.ts
│   ├── git-branch-sidebar.component.html
│   └── git-branch-sidebar.component.scss
├── git-file-browser/
│   ├── git-file-browser.component.ts
│   ├── git-file-browser.component.html
│   └── git-file-browser.component.scss
├── git-commit-list/
│   ├── git-commit-list.component.ts
│   ├── git-commit-list.component.html
│   └── git-commit-list.component.scss
├── git-server-metrics/
│   ├── git-server-metrics.component.ts
│   ├── git-server-metrics.component.html
│   └── git-server-metrics.component.scss
└── git-commit-detail-panel/
    ├── git-commit-detail-panel.component.ts
    ├── git-commit-detail-panel.component.html
    └── git-commit-detail-panel.component.scss

3.2 Data Flow

3.3 Component Inputs

git-graph:                commits, branches, selectedSha, templateFilter, compact, onCommitClick, onBranchSwitch
git-repo-card:            repo, onSelect
git-branch-sidebar:       branches, selectedBranch, features, onSwitch, onMerge, onDelete, onCreate
git-file-browser:         files, features, searchQuery, onFileSelect
git-commit-list:          commits, expandedSha, diff, features, onToggle
git-server-metrics:       metrics
git-commit-detail-panel:  diff, visible, onClose

4. Git Graph — The Star Component

4.1 Data Model

New types in git-operations.types.ts:

interface GitCommitNode {
  // From GitCommitInfo
  sha: string;
  shortSha: string;
  message: string;
  author: string;
  date: string;
  // NEW — from backend enrichment
  parentShas: string[];
  // Computed by lane algorithm
  laneIndex: number;
  color: string;
  isHead: boolean;              // tip of a branch
  isMerge: boolean;             // parentShas.length > 1
  branchName?: string;          // if this commit is a branch tip
  age: 'recent' | 'active' | 'aging' | 'old';
  // Optional enrichment
  filesChanged?: number;
  insertions?: number;
  deletions?: number;
  templateOnly?: boolean;       // true if commit only touches core libs
}

interface GitGraphLane {
  branchName: string;
  color: string;
  column: number;
  active: boolean;              // false = stale (dashed, faded)
  lastCommitDate: string;
}

4.2 Lane Assignment Algorithm

Pure function in git-graph-lane.util.ts:

  1. Walk commits top-to-bottom (newest first)
  2. First commit gets lane 0 (main line)
  3. When a commit has a parent not in the current lane, fork: assign next available column
  4. When a merge commit appears (2+ parents), mark the merging lane as "closing" — draw merge path back to target lane
  5. Reuse closed lane columns to keep the graph narrow
  6. Staleness: if a lane's last commit is >7 days old (old tier), mark active: false. Lanes in aging tier (2d–7d) remain active: true with solid lines but their commit nodes render at reduced opacity per the age tier rules. Only old (>7d) lanes get the dashed/faded treatment.

4.3 SVG Rendering

Pure functions in git-graph-renderer.util.ts that take GitCommitNode[] and GitGraphLane[] and return SVG element descriptors:

Element Rendering
Branch lines <path> with stroke-width: 5, stroke-linecap: round, stroke-linejoin: round (metro thick)
Glow filter <feGaussianBlur> — intensity based on commit age
Station dots Hollow circles: fill: background, stroke: branchColor, stroke-width: 2.5
Merge nodes Filled ring: outer fill: mergeColor + inner cutout (interchange station)
Stale branches stroke-dasharray: 6 4, reduced opacity (0.25)
Merge paths Bezier curves with Q control points for smooth lane-to-lane bends
Fade gradient Older commits progressively reduce opacity: 1.0 → 0.3
Pill labels <rect rx="10"> + <text> for branch names at branch tips

SVG column width: 20px + (laneCount × 28px). Each commit row: 32–48px tall depending on age tier.

4.4 Living Intelligence Rules

Age Tier Criteria Visual Treatment
recent < 4 hours Full glow filter, bright color, rich commit card
active 4h – 2 days Soft glow, normal color, standard row
aging 2d – 7d No glow, reduced opacity (0.7), compact row
old > 7 days No glow, faded (0.35), minimal row

Template-aware commits: If templateOnly: true, the commit renders one age tier older (e.g., recent → active). For non-executive/developer roles, template-only commits are hidden entirely.

4.5 Interaction Model


5. Sub-Components

5.1 git-repo-card

Overview card for a repository in the grid view.

5.2 git-branch-sidebar

Branch list with role-gated management actions.

5.3 git-file-browser

Grouped file tree with search and template filtering.

5.4 git-commit-list

Non-graph commit list for use outside graph context.

5.5 git-server-metrics

Host metrics strip for Hetzner infrastructure.

5.6 git-commit-detail-panel

Slide-out detail panel for full commit inspection.


6. Template-Aware Filtering

6.1 Template Core Paths

New file models/git-template-paths.config.ts:

export const TEMPLATE_CORE_PATHS = [
  'libs/core/',
  'libs/libs-foundational/',
  'libs/libs-ui/',
  'libs/libs-ui-core/',
  'libs/libs-ux/',
  'libs/libs-ai/',
  'libs/libs-api/',
  'libs/libs-dev-tools/',
  'libs/libs-private/',
  'libs/theme-system/',
] as const;

export function isTemplatePath(filePath: string): boolean {
  return TEMPLATE_CORE_PATHS.some(p => filePath.startsWith(p));
}

export function isTemplateOnlyCommit(files: { path: string }[]): boolean {
  return files.length > 0 && files.every(f => isTemplatePath(f.path));
}

6.2 Role Gating

New flag in GitOpsFeatureFlags:

canViewTemplateSources: boolean
  executive: true
  developer: true
  admin: false
  user: false

Component behavior:

6.3 Platform Convention

This pattern (TEMPLATE_CORE_PATHS + canViewTemplateSources flag) is designed to be promoted to a shared foundational location when other libs that show platform files need it. For S254, it lives in git-operations as the first consumer.


7. App Integration

7.1 gograb-dev (Refactor existing)

7.2 gograb-admin (New)

7.3 vitto-studio (New dock panel)


8. Backend Enrichment

8.1 Commit History — Add parentShas

File: APIs/sandbox-orchestrator/src/app/git/git.service.ts (lines 527-551)

Change: The current implementation uses git.log([branch, '--max-count=...']) with default log fields. We need to switch to custom format to include %P (parent SHAs).

Important: simple-git's LogOptions does NOT support { [branch]: true } as a dynamic key for branch filtering. The branch must be passed via the second argument array or customArgs. Keep the existing array-based approach and add --format manually:

// Approach: keep the working array-based git.log() pattern, add --format
const formatStr = '--format={"hash":"%H","shortHash":"%h","message":"%s","author":"%an","date":"%ai","parentHashes":"%P"}';
const result = await git.raw([
  'log',
  branch,
  `--max-count=${limit}`,
  formatStr,
]);

// Parse JSON lines (one per commit)
const commits = result
  .trim()
  .split('\n')
  .filter(Boolean)
  .map(line => {
    const entry = JSON.parse(line);
    return {
      sha: entry.hash,
      shortSha: entry.shortHash,
      message: entry.message,
      author: entry.author,
      date: entry.date,
      parentShas: entry.parentHashes ? entry.parentHashes.split(' ').filter(Boolean) : [],
    };
  });

Impact: Additive change, no breaking changes. Existing consumers ignore the new parentShas field. Uses git.raw() instead of git.log() to avoid simple-git's LogOptions limitations with custom format + branch filtering.


9. Files Summary

New Files (24 source files)

Path Purpose
git-operations/src/lib/components/git-graph/git-graph.component.ts Graph container
git-operations/src/lib/components/git-graph/git-graph.component.html Graph template
git-operations/src/lib/components/git-graph/git-graph.component.scss Graph styles
git-operations/src/lib/components/git-graph/git-graph-lane.util.ts Lane algorithm
git-operations/src/lib/components/git-graph/git-graph-renderer.util.ts SVG generation
git-operations/src/lib/components/git-repo-card/git-repo-card.component.ts/html/scss Repo card (3 files)
git-operations/src/lib/components/git-branch-sidebar/git-branch-sidebar.component.ts/html/scss Branch sidebar (3 files)
git-operations/src/lib/components/git-file-browser/git-file-browser.component.ts/html/scss File browser (3 files)
git-operations/src/lib/components/git-commit-list/git-commit-list.component.ts/html/scss Commit list (3 files)
git-operations/src/lib/components/git-server-metrics/git-server-metrics.component.ts/html/scss Metrics strip (3 files)
git-operations/src/lib/components/git-commit-detail-panel/git-commit-detail-panel.component.ts/html/scss Detail panel (3 files)
git-operations/src/lib/models/git-template-paths.config.ts Template path filter
vitto-studio/src/lib/panels/git-graph-panel.component.ts Studio dock panel wrapper
gograb-admin/.../git-operations/admin-git-operations.component.ts Admin page component

Modified Files (9)

File Change
git-operations/src/lib/models/git-operations.types.ts Add GitCommitNode, GitGraphLane, extend GitCommitInfo with parentShas
git-operations/src/lib/models/git-operations-role.config.ts Add canViewTemplateSources flag to all tiers; set admin.showServerMetrics: false
git-operations/src/index.ts Export new components, template config, new types
git-operations/src/lib/services/git-operations-api.service.ts Update getCommitHistory return type to include parentShas
APIs/sandbox-orchestrator/src/app/git/git.service.ts Add %P custom format for parent SHAs
apps/gograb-dev/.../git-operations.component.ts/html/scss Refactor to compose library sub-components
apps/gograb-admin/src/app/app.config.ts + app.routes.ts + admin-main-shell.component.ts Add provider, route, nav group
apps/gograb-ai/src/app/app.config.ts (studio providers) Add provideGitOperations()
libs/libs-structural/vitto-studio/src/lib/config/studio-dock-panels.config.ts Register studio-git-graph dock panel

10. Edge Cases


11. Implementation Ordering

The following dependency order must be followed:

  1. Models first: Update git-operations.types.ts (add GitCommitNode, GitGraphLane, parentShas on GitCommitInfo) and git-operations-role.config.ts (add canViewTemplateSources, change admin.showServerMetrics). Create git-template-paths.config.ts. All components depend on these types compiling.
  2. API service: Update git-operations-api.service.ts return type for getCommitHistory.
  3. Backend: Update sandbox-orchestrator/git.service.ts to return parentShas.
  4. Pure utilities: git-graph-lane.util.ts and git-graph-renderer.util.ts — no Angular dependencies, highly testable.
  5. Sub-components: Can be built in parallel — git-repo-card, git-branch-sidebar, git-file-browser, git-commit-list, git-server-metrics, git-commit-detail-panel.
  6. Star component: git-graph — depends on lane util, renderer util, and the commit detail panel.
  7. Index exports: Update src/index.ts to export all new components, types (GitCommitNode, GitGraphLane), and template config utils (isTemplatePath, isTemplateOnlyCommit, TEMPLATE_CORE_PATHS).
  8. App integrations: gograb-dev refactor, gograb-admin page + nav + route, vitto-studio dock panel. These depend on all library components being built.

12. Diff Stats Loading Strategy

Commit diff stats (filesChanged, insertions, deletions, file list) are loaded lazily on click, NOT pre-fetched:

13. Admin Nav Group Definition

New nav group to add to adminNavGroups in admin-main-shell.component.ts:

{
  id: 'platform',
  label: 'Platform',
  items: [
    { id: 'git-operations', label: 'Git Operations', icon: 'commit', route: '/platform/git-operations' },
  ],
}

This creates the Platform section in admin sidebar. Future platform tools (deployment status, environment config, etc.) can be added here.


14. Constraints