AGENT SKILL

diagram-scaffolder

Generate new interactive diagram components for tutorial content. Use when adding a visual diagram, creating architectural illustrations, or building interactive flow visualizations. Use for questions like "add a diagram", "create diagram component", "new visual for module X". Produces a React component, registers it in the barrel export and StepCard parser, and provides the markdown reference syntax.

License 许可
MIT
最近更新
2026-10-22
Stars
★ 21
Forks
6

01 前言 Front Matter

name
diagram-scaffolder
description
Generate new interactive diagram components for tutorial content. Use when adding a visual diagram, creating architectural illustrations, or building interactive flow visualizations. Use for questions like "add a diagram", "create diagram component", "new visual for module X". Produces a React component, registers it in the barrel export and StepCard parser, and provides the markdown reference syntax.

02 资源文件 2

03 SKILL.md 正文

Diagram Scaffolder

This skill generates interactive diagram components that integrate with the tutorial's custom markdown rendering pipeline.

When to Use This Skill

  • When adding a new visual diagram to any tutorial content
  • When creating architectural illustrations (e.g., system diagrams, flow charts)
  • When building interactive visualizations with clickable phases or nodes
  • When a :::diagram <name> block needs a backing React component

Architecture Overview

Adding a diagram requires coordinated changes across 4 files:

1. src/components/diagrams/NewDiagram.tsx    ← React component
2. src/components/diagrams/index.ts          ← Barrel export
3. src/components/StepCard.tsx               ← Parser case + import
4. src/content/**/module-*.md                ← Markdown reference

Data Flow

Markdown: :::diagram my-diagram :::
  → StepCard parseContentBlocks() → { type: 'diagram', diagramName: 'my-diagram' }
    → renderBlock() switch case → <MyDiagram />

Existing Diagrams Registry

Markdown Name Component Used In
file-hierarchy FileHierarchyDiagram Part 3 (Foundation)
mcp-architecture MCPArchitectureDiagram Module A (Advanced)
workflow-comparison WorkflowComparisonDiagram Module B (Advanced)
agent-orchestration AgentOrchestrationDiagram Module C (Advanced)
ai-testing-flow AITestingFlowDiagram Module D (Advanced)
capstone-architecture CapstoneArchitectureDiagram Module E (Advanced)
agentic-loop AgenticLoopDiagram Module G (Terminal)
provider-abstraction ProviderAbstractionDiagram Module G (Terminal)
skill-system-flow SkillSystemFlowDiagram Module G (Terminal)
spec-driven-cycle SpecDrivenCycleDiagram Module G (Terminal)

Naming Conventions

Aspect Convention Example
Markdown name kebab-case data-flow-pipeline
Component name PascalCase + Diagram suffix DataFlowPipelineDiagram
File name Same as component DataFlowPipelineDiagram.tsx

The markdown name and component name must be related by converting kebab-case to PascalCase and appending Diagram.

Component Template

Basic Static Diagram

import { cn } from '@/lib/utils'
import { Card } from '@/components/ui/card'
import { Info } from '@phosphor-icons/react'

interface DiagramNameDiagramProps {
  className?: string
}

export function DiagramNameDiagram({ className }: DiagramNameDiagramProps) {
  return (
    <div
      className={cn('my-6 space-y-4', className)}
      role="figure"
      data-diagram="diagram-name"
      aria-label="Description of what this diagram shows."
    >
      <Card className="p-6 bg-muted/30 border-border">
        <div className="flex items-center gap-2 mb-4 pb-3 border-b border-border">
          {/* Icon + Title */}
          <span className="font-heading font-semibold text-sm text-foreground">
            Diagram Title
          </span>
        </div>

        {/* Diagram content */}
        <div className="font-mono text-sm">
          {/* Visual elements go here */}
        </div>
      </Card>

      {/* Key insight callout */}
      <div className="flex items-center gap-3 p-4 rounded-lg bg-primary/5 border border-primary/20">
        <Info size={20} className="text-primary shrink-0" />
        <p className="text-sm text-foreground">
          <strong>Key insight.</strong> Brief explanation of what makes this important.
        </p>
      </div>
    </div>
  )
}

Interactive Diagram (with clickable phases)

import { useState } from 'react'
import { Card } from '@/components/ui/card'
import { Info } from '@phosphor-icons/react'

type PhaseId = 'phase-a' | 'phase-b' | 'phase-c'

interface PhaseInfo {
  id: PhaseId
  label: string
  icon: React.ReactNode
  color: string
  bgColor: string
  description: string
}

const phases: PhaseInfo[] = [
  {
    id: 'phase-a',
    label: 'Phase A',
    icon: <span>?</span>,
    color: 'text-blue-500',
    bgColor: 'bg-blue-500/10 border-blue-500/30',
    description: 'Explanation of this phase.'
  },
  // ... more phases
]

export function DiagramNameDiagram() {
  const [activePhase, setActivePhase] = useState<PhaseId>('phase-a')
  const selected = phases.find(p => p.id === activePhase) || phases[0]

  return (
    <div
      className="my-6 space-y-4"
      role="figure"
      data-diagram="diagram-name"
      aria-label="Description. Click each phase to learn more."
    >
      {/* Phase nodes */}
      <Card className="p-6 bg-muted/30 border-border">
        <div className="flex items-center gap-2 mb-4 pb-3 border-b border-border">
          <span className="font-heading font-semibold text-sm text-foreground">
            Diagram Title
          </span>
          <span className="ml-auto text-xs text-muted-foreground">
            Click a phase to explore
          </span>
        </div>
        <div className="flex items-center justify-center gap-2 py-4 overflow-x-auto">
          {phases.map(phase => (
            <button
              key={phase.id}
              onClick={() => setActivePhase(phase.id)}
              className={`flex flex-col items-center gap-1.5 p-3 rounded-xl border-2 transition-all duration-200 min-w-[80px]
                ${activePhase === phase.id
                  ? `${phase.bgColor} border-opacity-100 scale-105 shadow-lg`
                  : 'bg-muted/30 border-border hover:border-muted-foreground/50'
                }`}
            >
              <div className={`p-2 rounded-lg ${phase.bgColor} ${phase.color}`}>
                {phase.icon}
              </div>
              <div className="font-semibold text-xs text-foreground">{phase.label}</div>
            </button>
          ))}
        </div>
      </Card>

      {/* Phase detail */}
      <Card className="p-4 bg-muted/30 border-border">
        <div className="flex items-start gap-3">
          <div className={`p-2 rounded-lg ${selected.bgColor} ${selected.color} shrink-0`}>
            {selected.icon}
          </div>
          <div>
            <h4 className="font-semibold text-foreground">{selected.label}</h4>
            <p className="text-sm text-muted-foreground mt-1 leading-relaxed">
              {selected.description}
            </p>
          </div>
        </div>
      </Card>

      {/* Key insight */}
      <div className="flex items-center gap-3 p-4 rounded-lg bg-primary/5 border border-primary/20">
        <Info size={20} className="text-primary shrink-0" />
        <p className="text-sm text-foreground">
          <strong>Key insight.</strong> Explanation.
        </p>
      </div>
    </div>
  )
}

Design Patterns

Color System

Use Tailwind's color utility classes with opacity modifiers:

Phase backgrounds: bg-{color}-500/10
Phase borders:     border-{color}-500/30
Phase text:        text-{color}-500

Standard phase colors across diagrams:

  • Blue (blue-500) — input, start, user action
  • Violet (violet-500) — thinking, reasoning, AI processing
  • Amber (amber-500) — decision points, warnings
  • Emerald (emerald-500) — execution, success, output
  • Cyan (cyan-500) — data flow, feedback
  • Rose (rose-500) — stop, error, terminal state

Icons

Use Phosphor Icons (@phosphor-icons/react) with weight="duotone" and size={22} for phase nodes:

import { Brain, Code, Eye, Wrench, Lightning } from '@phosphor-icons/react'

Accessibility

Every diagram must have:

  • role="figure" on the root element
  • data-diagram="kebab-name" for testing
  • aria-label describing what the diagram shows
  • Keyboard-accessible interactive elements (use <button>, not <div onClick>)

Responsive Design

  • Use overflow-x-auto on horizontal flow layouts
  • Use flex-wrap or stack vertically on mobile for dense diagrams
  • min-w-[80px] on phase nodes to prevent squishing

Step-by-Step: Adding a New Diagram

Step 1: Create the component

Create src/components/diagrams/YourDiagram.tsx using one of the templates above.

Step 2: Export from barrel file

Add to src/components/diagrams/index.ts:

export { YourDiagram } from './YourDiagram'

Step 3: Register in StepCard.tsx

3a. Add import at top of src/components/StepCard.tsx:

import {
  FileHierarchyDiagram,
  // ... existing imports ...
  YourDiagram
} from './diagrams'

3b. Add case in the renderBlock function's case 'diagram': switch:

case 'diagram':
  switch (block.diagramName) {
    // ... existing cases ...
    case 'your-diagram':
      return <YourDiagram key={idx} />
    default:
      return null
  }

Step 4: Reference in markdown

In the tutorial/advanced/terminal content file:

:::diagram your-diagram
:::

Validation

PowerShell: Verify all diagrams are connected

# Find all :::diagram references in content
$diagramRefs = Select-String -Path "src/content/**/*.md" -Pattern "^:::diagram\s+(\S+)" -AllMatches |
  ForEach-Object { $_.Matches.Groups[1].Value } | Sort-Object -Unique

# Find all registered cases in StepCard
$stepCard = Get-Content "src/components/StepCard.tsx" -Raw
$registeredCases = [regex]::Matches($stepCard, "case '([^']+)':") |
  ForEach-Object { $_.Groups[1].Value } | Sort-Object -Unique

# Find all exports in index.ts
$indexExports = Select-String -Path "src/components/diagrams/index.ts" -Pattern "export \{ (\w+) \}" |
  ForEach-Object { $_.Matches.Groups[1].Value }

Write-Host "`n=== DIAGRAM AUDIT ===" -ForegroundColor Cyan
Write-Host "`nMarkdown references:" -ForegroundColor Yellow
$diagramRefs | ForEach-Object {
  $inSwitch = $registeredCases -contains $_
  $status = if ($inSwitch) { "OK" } else { "MISSING CASE" }
  $color = if ($inSwitch) { "Green" } else { "Red" }
  Write-Host "  :::diagram $_ — $status" -ForegroundColor $color
}

Write-Host "`nExported components:" -ForegroundColor Yellow
$indexExports | ForEach-Object { Write-Host "  $_" }

Write-Host "`n=== END AUDIT ===" -ForegroundColor Cyan

Build Check

npm run build

A missing import or unregistered diagram will cause a build error or silently render nothing (default: return null). Always verify the diagram renders in the browser after adding it.

Checklist

Before completing a new diagram:

  • [ ] Component file created in src/components/diagrams/
  • [ ] Named export (not default export)
  • [ ] Exported from src/components/diagrams/index.ts
  • [ ] Imported in src/components/StepCard.tsx
  • [ ] Switch case added in renderBlock → case 'diagram':
  • [ ] role="figure", data-diagram, and aria-label present
  • [ ] Interactive elements use <button> for keyboard access
  • [ ] Horizontal layouts have overflow-x-auto
  • [ ] Renders correctly in both light and dark themes
  • [ ] Referenced in markdown with :::diagram name / :::
  • [ ] npm run build succeeds

04 同仓库更多 Skills

microsoft
microsoft/learn-ai-native-dev

version-checker

Validate that tutorial content references current tool versions, APIs, CLI commands, and features. Use when reviewing content for outdated information, checking deprecations, verifying feature availability, auditing tool references, or updating stale version numbers. Covers GitHub Copilot (VS Code + CLI), Claude Code, VS Code settings, MCP, and Agent Skills standard.

Skill与智能体开发
★ 21
microsoft
microsoft/learn-ai-native-dev

tutorial-content-qa

Comprehensive quality assurance for AI-Native development tutorials across all tracks (Foundation, Advanced, Terminal). Use when reviewing content for accuracy, clarity, consistency, and completeness. Use for proofreading, checking errors, auditing content, or running QA checks before publishing.

内容创作者
★ 21
microsoft
microsoft/learn-ai-native-dev

track-generator

Generate new example tracks for the AI-Native tutorial. Use when creating new industry examples, adding a new track, building project templates, or expanding learning paths. Use for questions like "add a track for healthcare", "create new example", "new industry template". Produces consistent ExampleTrack data with all required fields including projectName, requirements, colorCoding, taskExamples, and verification examples matching the TypeScript interface in exampleTracks.ts.

★ 21
microsoft
microsoft/learn-ai-native-dev

exercise-scaffolder

Generate consistent, high-quality coding exercises for AI-Native development tutorials. Use when creating hands-on exercises, coding challenges, practice problems, quizzes, labs, or skill-building activities. Use for questions like "create an exercise", "add practice activity", "build a challenge for Part X". Includes starter templates, solution patterns, hint progressions, and verification criteria.

Skill与智能体开发
★ 21
microsoft
microsoft/learn-ai-native-dev

docs-sync

Diff src/ and .github/ against docs/ to detect drift between code and design spec. Use when auditing the docs folder, after merging structural changes (adding paths/modules/diagrams/syntax/agents/skills/hooks), or before a release. Use for questions like "is docs in sync?", "what changed since the last docs update?", "find docs drift". Produces a structured report with proposed edits — does not modify docs/ directly.

★ 21
microsoft
microsoft/learn-ai-native-dev

content-track-scaffolder

Scaffold a complete new content track (like Foundation, Advanced, or Terminal) with all required files — data parser, page components, routes, markdown content, and navigation. Use when adding a new learning path, creating a new track, or expanding the tutorial with a new module series. Use for questions like "add a new track", "create learning path for X", "scaffold track pages".

内容创作者
★ 21