Commit 587bde455c5c
Changed files (12)
dots
.claude
skills
Art
workflows
Createskill
workflows
dots/.claude/hooks/lib/claude-paths.ts
@@ -0,0 +1,69 @@
+#!/usr/bin/env bun
+
+import { homedir } from 'os';
+import { resolve, join } from 'path';
+import { existsSync } from 'fs';
+
+/**
+ * Claude Code infrastructure paths
+ *
+ * Defaults to ~/.claude but can be overridden with CLAUDE_DIR env var
+ */
+export const CLAUDE_DIR = process.env.CLAUDE_DIR
+ ? resolve(process.env.CLAUDE_DIR)
+ : resolve(homedir(), '.claude');
+
+export const HOOKS_DIR = join(CLAUDE_DIR, 'hooks');
+export const SKILLS_DIR = join(CLAUDE_DIR, 'skills');
+export const AGENTS_DIR = join(CLAUDE_DIR, 'agents');
+export const HISTORY_DIR = join(CLAUDE_DIR, 'history');
+
+/**
+ * Validate Claude Code directory structure
+ * Called automatically on import
+ */
+function validateClaudeStructure(): void {
+ if (!existsSync(CLAUDE_DIR)) {
+ console.error(`โ CLAUDE_DIR does not exist: ${CLAUDE_DIR}`);
+ console.error(` Expected ~/.claude or set CLAUDE_DIR environment variable`);
+ process.exit(1);
+ }
+
+ if (!existsSync(HOOKS_DIR)) {
+ console.error(`โ ๏ธ Claude hooks directory not found: ${HOOKS_DIR}`);
+ console.error(` This may be expected if hooks haven't been set up yet`);
+ // Don't exit - this is okay for initial setup
+ }
+}
+
+// Validate on import
+validateClaudeStructure();
+
+/**
+ * Get a history file path with proper year-month organization
+ * @param subdir - History subdirectory (sessions, learnings, research, etc.)
+ * @param filename - File name
+ * @returns Full path to history file
+ */
+export function getHistoryFilePath(subdir: string, filename: string): string {
+ const now = new Date();
+ const year = now.getFullYear();
+ const month = String(now.getMonth() + 1).padStart(2, '0');
+
+ return join(HISTORY_DIR, subdir, `${year}-${month}`, filename);
+}
+
+/**
+ * Get current timestamp in YYYY-MM-DD-HHMMSS format
+ */
+export function getTimestamp(): string {
+ const now = new Date();
+ const year = now.getFullYear();
+ const month = String(now.getMonth() + 1).padStart(2, '0');
+ const day = String(now.getDate()).padStart(2, '0');
+ const hours = String(now.getHours()).padStart(2, '0');
+ const minutes = String(now.getMinutes()).padStart(2, '0');
+ const seconds = String(now.getSeconds()).padStart(2, '0');
+
+ return `${year}-${month}-${day}-${hours}${minutes}${seconds}`;
+}
dots/.claude/hooks/capture-tool-output.ts
@@ -0,0 +1,77 @@
+#!/usr/bin/env bun
+
+/**
+ * PostToolUse Hook - Captures tool outputs for history tracking
+ *
+ * Automatically logs interesting tool executions to daily JSONL files
+ * for later analysis and session reconstruction.
+ *
+ * Setup:
+ * Add to PostToolUse in settings.json:
+ * "PostToolUse": ["bun /home/vincent/.claude/hooks/capture-tool-output.ts"]
+ */
+
+import { appendFileSync, mkdirSync, existsSync } from 'fs';
+import { join } from 'path';
+import { CLAUDE_DIR } from './lib/claude-paths';
+
+interface ToolUseData {
+ tool_name: string;
+ tool_input: Record<string, any>;
+ tool_response: Record<string, any>;
+ conversation_id: string;
+ timestamp: string;
+}
+
+// Configuration - which tools to capture
+const INTERESTING_TOOLS = ['Bash', 'Edit', 'Write', 'Read', 'Task', 'NotebookEdit', 'Skill', 'SlashCommand'];
+
+async function main() {
+ try {
+ // Read input from stdin
+ const input = await Bun.stdin.text();
+ if (!input || input.trim() === '') {
+ process.exit(0);
+ }
+
+ const data: ToolUseData = JSON.parse(input);
+
+ // Only capture interesting tools
+ if (!INTERESTING_TOOLS.includes(data.tool_name)) {
+ process.exit(0);
+ }
+
+ // Get today's date for organization
+ const now = new Date();
+ const today = now.toISOString().split('T')[0]; // YYYY-MM-DD
+ const yearMonth = today.substring(0, 7); // YYYY-MM
+
+ // Ensure capture directory exists
+ const dateDir = join(CLAUDE_DIR, 'history', 'tool-outputs', yearMonth);
+ if (!existsSync(dateDir)) {
+ mkdirSync(dateDir, { recursive: true });
+ }
+
+ // Format output as JSONL (one JSON object per line)
+ const captureFile = join(dateDir, `${today}_tool-outputs.jsonl`);
+ const captureEntry = JSON.stringify({
+ timestamp: data.timestamp || now.toISOString(),
+ tool: data.tool_name,
+ input: data.tool_input,
+ output: data.tool_response,
+ session: data.conversation_id
+ }) + '\n';
+
+ // Append to daily log
+ appendFileSync(captureFile, captureEntry);
+
+ // Exit successfully (code 0 = continue normally)
+ process.exit(0);
+ } catch (error) {
+ // Silent failure - don't disrupt workflow
+ console.error(`[capture-tool-output] Error: ${error}`);
+ process.exit(0);
+ }
+}
+
+main();
dots/.claude/hooks/initialize-session.ts
@@ -0,0 +1,105 @@
+#!/usr/bin/env bun
+
+/**
+ * initialize-session.ts
+ *
+ * Session initialization hook that runs at the start of every Claude Code session.
+ *
+ * What it does:
+ * - Checks if this is a subagent session (skips for subagents)
+ * - Sets initial terminal tab title
+ * - Logs session start
+ *
+ * Setup:
+ * Add to SessionStart in settings.json:
+ * "SessionStart": ["bun /home/vincent/.claude/hooks/initialize-session.ts"]
+ */
+
+import { existsSync, mkdirSync, appendFileSync } from 'fs';
+import { join } from 'path';
+import { tmpdir } from 'os';
+import { CLAUDE_DIR, getHistoryFilePath, getTimestamp } from './lib/claude-paths';
+
+// Debounce duration in milliseconds (prevents duplicate SessionStart events)
+const DEBOUNCE_MS = 2000;
+const LOCKFILE = join(tmpdir(), 'claude-session-start.lock');
+
+/**
+ * Check if we're within the debounce window to prevent duplicate notifications
+ */
+function shouldDebounce(): boolean {
+ try {
+ if (existsSync(LOCKFILE)) {
+ const lockContent = Bun.file(LOCKFILE).text();
+ const lockTime = parseInt(await lockContent, 10);
+ const now = Date.now();
+
+ if (now - lockTime < DEBOUNCE_MS) {
+ // Within debounce window, skip this notification
+ return true;
+ }
+ }
+
+ // Update lockfile with current timestamp
+ await Bun.write(LOCKFILE, Date.now().toString());
+ return false;
+ } catch (error) {
+ // If any error, just proceed (don't break session start)
+ try {
+ await Bun.write(LOCKFILE, Date.now().toString());
+ } catch {}
+ return false;
+ }
+}
+
+async function main() {
+ try {
+ // Check if this is a subagent session - if so, exit silently
+ const claudeProjectDir = process.env.CLAUDE_PROJECT_DIR || '';
+ const isSubagent = claudeProjectDir.includes('/.claude/agents/') ||
+ process.env.CLAUDE_AGENT_TYPE !== undefined;
+
+ if (isSubagent) {
+ // This is a subagent session - exit silently without notification
+ console.error('๐ค Subagent session detected - skipping session initialization');
+ process.exit(0);
+ }
+
+ // Check debounce to prevent duplicate notifications
+ if (await shouldDebounce()) {
+ console.error('๐ Debouncing duplicate SessionStart event');
+ process.exit(0);
+ }
+
+ // Set initial tab title
+ const tabTitle = 'Claude Ready';
+ process.stderr.write(`\x1b]0;${tabTitle}\x07`);
+ process.stderr.write(`\x1b]2;${tabTitle}\x07`);
+ process.stderr.write(`\x1b]30;${tabTitle}\x07`);
+ console.error(`๐ Session initialized: "${tabTitle}"`);
+
+ // Log session start to history (optional)
+ const timestamp = getTimestamp();
+ const logDir = join(CLAUDE_DIR, 'history', 'sessions', `${timestamp.substring(0, 7)}`);
+
+ if (!existsSync(logDir)) {
+ mkdirSync(logDir, { recursive: true });
+ }
+
+ const logEntry = `${new Date().toISOString()} - Session started\n`;
+ const logFile = join(logDir, `${timestamp.substring(0, 10)}_session-log.txt`);
+
+ try {
+ appendFileSync(logFile, logEntry);
+ } catch (error) {
+ // Silent failure - don't break session start for logging issues
+ }
+
+ process.exit(0);
+ } catch (error) {
+ console.error('SessionStart hook error:', error);
+ process.exit(1);
+ }
+}
+
+main();
dots/.claude/hooks/README.md
@@ -0,0 +1,198 @@
+# Claude Code Hooks
+
+This directory contains hooks for Claude Code that automate various tasks and capture session information.
+
+Adapted from [Personal AI Infrastructure](https://github.com/danielmiessler/Personal_AI_Infrastructure).
+
+## Installed Hooks
+
+### initialize-session.ts
+
+**Purpose**: Session initialization
+
+**Triggers**: SessionStart event
+
+**What it does**:
+- Detects and skips subagent sessions
+- Sets terminal tab title to "Claude Ready"
+- Logs session start to history
+- Implements debouncing to prevent duplicate triggers
+
+**Setup**:
+```json
+{
+ "hooks": {
+ "SessionStart": ["bun ~/.claude/hooks/initialize-session.ts"]
+ }
+}
+```
+
+### capture-tool-output.ts
+
+**Purpose**: Tool execution logging
+
+**Triggers**: PostToolUse event
+
+**What it does**:
+- Captures outputs from interesting tools (Bash, Edit, Write, Read, Task, etc.)
+- Logs to JSONL files organized by year-month
+- Stores in `~/.claude/history/tool-outputs/YYYY-MM/YYYY-MM-DD_tool-outputs.jsonl`
+- Silent failure - doesn't disrupt workflow
+
+**Setup**:
+```json
+{
+ "hooks": {
+ "PostToolUse": ["bun ~/.claude/hooks/capture-tool-output.ts"]
+ }
+}
+```
+
+**Captured tools**:
+- Bash
+- Edit, Write, Read
+- Task
+- NotebookEdit
+- Skill, SlashCommand
+
+### validate-docs.ts
+
+**Purpose**: Documentation link validation
+
+**Triggers**: Manual or pre-commit
+
+**What it does**:
+- Scans all markdown files for internal links
+- Checks if linked files exist
+- Reports broken links with file:line numbers
+- Exit code 0 if valid, 1 if broken links found
+
+**Usage**:
+```bash
+# Run manually
+bun ~/.claude/hooks/validate-docs.ts
+
+# Add to pre-commit (optional)
+```
+
+## Skipped Hooks
+
+The following hooks from PAI were **not imported** as they require more setup or are not immediately needed:
+
+### capture-session-summary.ts
+**Reason**: Complex - requires parsing conversation output files and generating markdown summaries. Can be added later if needed.
+
+### capture-all-events.ts
+**Reason**: Very comprehensive event logging with agent metadata extraction. More complex than capture-tool-output. Can add if detailed event tracking is needed.
+
+### self-test.ts
+**Reason**: Validates PAI-specific directory structure and configurations. Would need significant adaptation for our setup.
+
+### validate-protected.ts
+**Reason**: Requires `.pai-protected.json` manifest defining protected file patterns. Can add later with custom protection rules.
+
+## Hook Architecture
+
+### Directory Structure
+
+```
+~/.claude/hooks/
+โโโ README.md # This file
+โโโ lib/
+โ โโโ claude-paths.ts # Path utilities
+โโโ initialize-session.ts # Session startup
+โโโ capture-tool-output.ts # Tool logging
+โโโ validate-docs.ts # Link validation
+```
+
+### Helper Library: lib/claude-paths.ts
+
+Provides:
+- `CLAUDE_DIR`: Base directory (~/.claude)
+- `HOOKS_DIR`, `SKILLS_DIR`, `AGENTS_DIR`, `HISTORY_DIR`: Subdirectories
+- `getHistoryFilePath(subdir, filename)`: Generate history file paths
+- `getTimestamp()`: Get formatted timestamp
+- Path validation on import
+
+## Configuration
+
+Hooks are configured in Claude Code settings (`.claude/settings.json` or `.claude/settings.local.json`):
+
+```json
+{
+ "hooks": {
+ "SessionStart": ["bun ~/.claude/hooks/initialize-session.ts"],
+ "PostToolUse": ["bun ~/.claude/hooks/capture-tool-output.ts"]
+ }
+}
+```
+
+Available hook events:
+- `SessionStart`: Session begins
+- `SessionEnd`: Session ends
+- `PreToolUse`: Before tool execution
+- `PostToolUse`: After tool execution
+- `UserPromptSubmit`: After user submits prompt
+- `Stop`: Session stopped
+- `SubagentStop`: Subagent stopped
+- `PreCompact`: Before context compaction
+- `Notification`: System notification
+
+## Requirements
+
+- **Bun**: All hooks use `#!/usr/bin/env bun` shebang
+- Install: `curl -fsSL https://bun.sh/install | bash`
+- Already installed on kyushu system
+
+## History Logging
+
+Hooks that capture data store it in `~/.claude/history/`:
+
+```
+~/.claude/history/
+โโโ sessions/
+โ โโโ YYYY-MM/
+โ โโโ YYYY-MM-DD_session-log.txt
+โโโ tool-outputs/
+ โโโ YYYY-MM/
+ โโโ YYYY-MM-DD_tool-outputs.jsonl
+```
+
+This integrates with the history system documented in `.claude/skills/CORE/history-system.md`.
+
+## Adding More Hooks
+
+To add additional hooks:
+
+1. Create the hook file in `~/.claude/hooks/`
+2. Add shebang: `#!/usr/bin/env bun`
+3. Make it executable: `chmod +x hook-name.ts`
+4. Use `lib/claude-paths.ts` for paths
+5. Add to settings.json under appropriate event
+6. Test manually before enabling
+
+## Troubleshooting
+
+**Hook not running:**
+- Check settings.json syntax
+- Verify file is executable (`ls -la ~/.claude/hooks/`)
+- Check hook output in stderr
+- Verify Bun is installed: `bun --version`
+
+**Permission errors:**
+- Ensure directories exist: `mkdir -p ~/.claude/history/{sessions,tool-outputs}`
+- Check write permissions
+
+**Debugging:**
+- Hooks write to stderr - check terminal output
+- Add debug logging: `console.error('[hook-name] Debug message')`
+- Run manually: `bun ~/.claude/hooks/hook-name.ts`
+
+## Future Enhancements
+
+Consider adding:
+- Session summary generation (port capture-session-summary.ts)
+- Protected file validation (port validate-protected.ts)
+- Custom event logging for specific workflows
+- Integration with external notification systems
+- Automatic documentation generation
dots/.claude/hooks/validate-docs.ts
@@ -0,0 +1,155 @@
+#!/usr/bin/env bun
+
+/**
+ * Documentation Link Validator
+ *
+ * Validates that all internal markdown links point to existing files.
+ * Useful as a pre-commit hook to prevent broken documentation.
+ *
+ * Usage:
+ * bun run ~/.claude/hooks/validate-docs.ts
+ *
+ * Exit codes:
+ * 0 - All links valid
+ * 1 - Broken links found
+ */
+
+import { readFileSync, existsSync } from 'fs';
+import { join, dirname, resolve } from 'path';
+import { Glob } from 'bun';
+
+// ANSI color codes
+const colors = {
+ reset: '\x1b[0m',
+ red: '\x1b[31m',
+ green: '\x1b[32m',
+ yellow: '\x1b[33m',
+ cyan: '\x1b[36m',
+};
+
+interface BrokenLink {
+ file: string;
+ link: string;
+ target: string;
+ line: number;
+}
+
+/**
+ * Extract markdown links from content
+ */
+function extractLinks(content: string): { link: string; line: number }[] {
+ const links: { link: string; line: number }[] = [];
+ const lines = content.split('\n');
+
+ // Match [text](path) style links
+ const linkRegex = /\[([^\]]+)\]\(([^)]+)\)/g;
+
+ lines.forEach((line, index) => {
+ let match;
+ while ((match = linkRegex.exec(line)) !== null) {
+ const link = match[2];
+
+ // Skip external URLs, anchors, and mailto links
+ if (link.startsWith('http://') ||
+ link.startsWith('https://') ||
+ link.startsWith('#') ||
+ link.startsWith('mailto:')) {
+ continue;
+ }
+
+ links.push({ link, line: index + 1 });
+ }
+ });
+
+ return links;
+}
+
+/**
+ * Resolve a link path relative to the file
+ */
+function resolveLink(fromFile: string, linkPath: string, baseDir: string): string {
+ // Remove anchor if present
+ const pathWithoutAnchor = linkPath.split('#')[0];
+
+ // If it starts with ~, expand to home directory
+ if (pathWithoutAnchor.startsWith('~/')) {
+ return resolve(process.env.HOME || '', pathWithoutAnchor.substring(2));
+ }
+
+ // If it's absolute, use as-is
+ if (pathWithoutAnchor.startsWith('/')) {
+ return pathWithoutAnchor;
+ }
+
+ // Otherwise, resolve relative to the file's directory
+ const fileDir = dirname(fromFile);
+ return resolve(fileDir, pathWithoutAnchor);
+}
+
+/**
+ * Validate markdown files in a directory
+ */
+function validateDocs(baseDir: string): BrokenLink[] {
+ const brokenLinks: BrokenLink[] = [];
+
+ // Find all markdown files
+ const glob = new Glob('**/*.md');
+
+ for (const file of glob.scanSync({ cwd: baseDir, absolute: false })) {
+ const filePath = join(baseDir, file);
+
+ // Skip node_modules and hidden directories
+ if (filePath.includes('node_modules') || filePath.includes('/.')) {
+ continue;
+ }
+
+ try {
+ const content = readFileSync(filePath, 'utf-8');
+ const links = extractLinks(content);
+
+ for (const { link, line } of links) {
+ const targetPath = resolveLink(filePath, link, baseDir);
+
+ // Check if target exists
+ if (!existsSync(targetPath)) {
+ brokenLinks.push({
+ file: file,
+ link: link,
+ target: targetPath,
+ line: line,
+ });
+ }
+ }
+ } catch (error) {
+ console.error(`${colors.yellow}Warning: Could not read ${file}${colors.reset}`);
+ }
+ }
+
+ return brokenLinks;
+}
+
+function main(): number {
+ const baseDir = process.cwd();
+
+ console.log(`\n${colors.cyan}๐ Documentation Link Validator${colors.reset}`);
+ console.log(`${colors.cyan} Base directory: ${baseDir}${colors.reset}\n`);
+
+ const brokenLinks = validateDocs(baseDir);
+
+ if (brokenLinks.length > 0) {
+ console.log(`\n${colors.red}โ Found ${brokenLinks.length} broken link(s):${colors.reset}\n`);
+
+ for (const { file, link, line } of brokenLinks) {
+ console.log(` ${colors.yellow}${file}:${line}${colors.reset}`);
+ console.log(` โ ${colors.red}${link}${colors.reset} (not found)\n`);
+ }
+
+ console.log(`\n${colors.red}Documentation validation failed. Please fix the broken links.${colors.reset}\n`);
+ return 1;
+ }
+
+ console.log(`${colors.green}โ
All documentation links are valid${colors.reset}\n`);
+ return 0;
+}
+
+process.exit(main());
dots/.claude/skills/Art/workflows/Mermaid.md
@@ -0,0 +1,164 @@
+# Mermaid Workflow
+
+Create Mermaid diagrams for technical documentation and visualization.
+
+## When to Use Mermaid
+
+Mermaid is ideal for:
+- **Flowcharts**: Process flows, algorithms, decision trees
+- **Sequence diagrams**: API interactions, protocol flows
+- **State diagrams**: System states and transitions
+- **Class diagrams**: Object relationships
+- **Gantt charts**: Project timelines
+- **Git graphs**: Branch and merge visualizations
+
+## Mermaid Diagram Types
+
+### Flowchart (Most Common)
+
+```mermaid
+flowchart LR
+ A[Start] --> B[Process]
+ B --> C{Decision}
+ C -->|Yes| D[Action 1]
+ C -->|No| E[Action 2]
+```
+
+**Directions:**
+- `LR`: Left to Right
+- `TD` or `TB`: Top Down/Top to Bottom
+- `RL`: Right to Left
+- `BT`: Bottom to Top
+
+**Node Shapes:**
+- `[Text]`: Rectangle
+- `(Text)`: Rounded rectangle
+- `{Text}`: Diamond (decision)
+- `([Text])`: Stadium shape
+- `[[Text]]`: Subroutine
+- `[(Text)]`: Cylindrical (database)
+
+### Sequence Diagram
+
+```mermaid
+sequenceDiagram
+ participant Client
+ participant API
+ participant DB
+
+ Client->>API: Request
+ API->>DB: Query
+ DB-->>API: Result
+ API-->>Client: Response
+```
+
+**Arrow types:**
+- `->`: Solid line
+- `-->`: Dotted line
+- `->>`: Solid arrow
+- `-->>`: Dotted arrow
+
+### State Diagram
+
+```mermaid
+stateDiagram-v2
+ [*] --> Idle
+ Idle --> Running: start()
+ Running --> Paused: pause()
+ Paused --> Running: resume()
+ Running --> [*]: stop()
+```
+
+### Class Diagram
+
+```mermaid
+classDiagram
+ class Animal {
+ +String name
+ +int age
+ +makeSound()
+ }
+ class Dog {
+ +String breed
+ +bark()
+ }
+ Animal <|-- Dog
+```
+
+### Gantt Chart
+
+```mermaid
+gantt
+ title Project Timeline
+ dateFormat YYYY-MM-DD
+ section Phase 1
+ Task 1: 2024-01-01, 30d
+ Task 2: 2024-01-15, 20d
+ section Phase 2
+ Task 3: 2024-02-01, 25d
+```
+
+## Best Practices
+
+1. **Keep it simple**: Don't overcomplicate
+2. **Use clear labels**: Make text descriptive
+3. **Logical flow**: Follow natural reading direction
+4. **Group related items**: Use subgraphs when appropriate
+5. **Test rendering**: Ensure it renders correctly
+
+## Common Patterns
+
+### Decision Tree
+
+```mermaid
+flowchart TD
+ Start[User Request] --> Auth{Authenticated?}
+ Auth -->|No| Login[Redirect to Login]
+ Auth -->|Yes| Check{Has Permission?}
+ Check -->|No| Error[Show Error]
+ Check -->|Yes| Process[Process Request]
+```
+
+### API Flow
+
+```mermaid
+sequenceDiagram
+ participant C as Client
+ participant A as API
+ participant D as Database
+
+ C->>A: POST /api/data
+ A->>A: Validate Input
+ A->>D: INSERT data
+ D-->>A: Success
+ A-->>C: 201 Created
+```
+
+### State Machine
+
+```mermaid
+stateDiagram-v2
+ [*] --> Draft
+ Draft --> Review: Submit
+ Review --> Approved: Approve
+ Review --> Draft: Reject
+ Approved --> Published: Publish
+ Published --> [*]
+```
+
+## Output Format
+
+Present Mermaid diagrams with:
+1. Brief description of what it shows
+2. The Mermaid code block
+3. Explanation of key elements
+
+```
+Here's a flowchart showing the deployment process:
+
+[Mermaid diagram code]
+
+The diagram illustrates:
+- [Key element 1 explanation]
+- [Key element 2 explanation]
+```
dots/.claude/skills/Art/workflows/Visualize.md
@@ -0,0 +1,115 @@
+# Visualize Workflow
+
+Create visual content to explain concepts, processes, or relationships.
+
+## Steps
+
+### 1. Understand the Content
+
+Ask:
+- What needs to be visualized?
+- What's the key insight or relationship?
+- Who's the audience?
+- Where will this be used?
+
+### 2. Choose the Right Format
+
+**Mermaid Diagrams** - When you need:
+- Flowcharts (process flows, decision trees)
+- Sequence diagrams (interactions over time)
+- State diagrams (system states and transitions)
+- Class/ER diagrams (relationships)
+- Gantt charts (timelines with tasks)
+
+**Tables** - When you need:
+- Comparisons (side-by-side evaluation)
+- Feature matrices
+- Decision matrices
+
+**ASCII Art** - When you need:
+- Terminal-friendly diagrams
+- Code comment diagrams
+- Simple box-and-arrow layouts
+
+**Structured Text** - When you need:
+- Hierarchies (org charts, file trees)
+- Simple timelines
+- Process steps
+
+### 3. Create the Visualization
+
+Follow these principles:
+- **Clear labels**: Every element should be clearly labeled
+- **Logical flow**: Left-to-right or top-to-bottom
+- **Minimal complexity**: Only include what's necessary
+- **Consistent style**: Use consistent shapes and connections
+
+### 4. Mermaid Syntax Reference
+
+**Flowchart:**
+```mermaid
+flowchart TD
+ A[Start] --> B{Decision}
+ B -->|Yes| C[Action 1]
+ B -->|No| D[Action 2]
+ C --> E[End]
+ D --> E
+```
+
+**Sequence Diagram:**
+```mermaid
+sequenceDiagram
+ participant A as Alice
+ participant B as Bob
+ A->>B: Request
+ B-->>A: Response
+```
+
+**State Diagram:**
+```mermaid
+stateDiagram-v2
+ [*] --> Idle
+ Idle --> Processing: Start
+ Processing --> Complete: Finish
+ Complete --> [*]
+```
+
+### 5. Present and Refine
+
+- Show the visualization
+- Explain what it represents
+- Ask if refinements are needed
+- Iterate based on feedback
+
+## Output Format
+
+Present the visualization with context:
+
+```
+Here's a [type] diagram showing [what]:
+
+[The actual diagram/visualization]
+
+Key elements:
+- [Element 1]: [What it represents]
+- [Element 2]: [What it represents]
+
+This visualization shows [the main insight].
+```
+
+## Examples by Use Case
+
+### Process Flow
+Use flowchart when showing steps and decisions
+
+### System Architecture
+Use flowchart with boxes for components and arrows for data flow
+
+### Comparison
+Use table format for side-by-side evaluation
+
+### Timeline
+Use Gantt chart or ordered list depending on complexity
+
+### Relationships
+Use ER diagram or class diagram for entity relationships
dots/.claude/skills/Art/SKILL.md
@@ -0,0 +1,88 @@
+---
+name: Art
+description: Visual content generation and diagram creation. USE WHEN user needs diagrams, flowcharts, technical visualizations, or any visual content to explain concepts.
+---
+
+# Art
+
+Visual content generation skill for creating diagrams, flowcharts, and technical visualizations to support documentation and communication.
+
+## Purpose
+
+This skill helps create visual content when text alone isn't sufficient. It's particularly useful for:
+- Technical diagrams and architecture visualizations
+- Flowcharts and process diagrams
+- Concept maps and taxonomies
+- Timeline visualizations
+- Comparison charts
+
+## Visual Approach
+
+When creating diagrams, consider:
+- **Clarity**: Make the diagram easy to understand
+- **Purpose**: What insight should the visual provide?
+- **Format**: Which format best serves the content (Mermaid, ASCII, etc.)?
+- **Context**: Will this be in documentation, a presentation, or for quick reference?
+
+## Supported Formats
+
+### Mermaid Diagrams
+Best for:
+- Flowcharts
+- Sequence diagrams
+- State diagrams
+- Class diagrams
+- Gantt charts
+
+### ASCII Art
+Best for:
+- Simple diagrams in plain text
+- Terminal-friendly visualizations
+- Code comments
+
+### Structured Text
+Best for:
+- Comparisons (tables)
+- Hierarchies (indented lists)
+- Timelines (ordered lists)
+
+## Workflow Routing
+
+| Workflow | Trigger | File |
+|----------|---------|------|
+| **Visualize** | "create a diagram", "visualize this" | `workflows/Visualize.md` |
+| **Mermaid** | "mermaid diagram", "flowchart" | `workflows/Mermaid.md` |
+
+## Examples
+
+**Example 1: Architecture Diagram**
+```
+User: "Create a diagram showing the NixOS deployment flow"
+โ Invokes Visualize workflow
+โ Determines Mermaid flowchart is appropriate
+โ Creates flowchart showing: local changes โ build โ deploy โ activate
+```
+
+**Example 2: Comparison Chart**
+```
+User: "Compare stable vs unstable NixOS approaches"
+โ Invokes Visualize workflow
+โ Creates comparison table
+โ Shows trade-offs clearly
+```
+
+**Example 3: Process Flow**
+```
+User: "Show the git commit workflow as a diagram"
+โ Invokes Mermaid workflow
+โ Creates flowchart with decision points
+โ Shows happy path and error handling
+```
+
+## Integration
+
+This skill complements:
+- **Documentation**: Add diagrams to markdown docs
+- **Architecture planning**: Visualize system design
+- **Troubleshooting**: Map out problem flows
+- **Communication**: Explain complex concepts visually
dots/.claude/skills/Createskill/workflows/CreateSkill.md
@@ -0,0 +1,93 @@
+# CreateSkill Workflow
+
+Create a new skill from scratch with proper structure and naming conventions.
+
+## Steps
+
+### 1. Understand the Purpose
+
+Ask the user:
+- What is this skill for?
+- What workflows or tasks should it include?
+- When should this skill be invoked?
+
+### 2. Choose the Name
+
+- Use TitleCase (PascalCase)
+- Examples: `Docker`, `Kubernetes`, `WebDev`, `DataAnalysis`
+- Never use: `docker`, `web-dev`, `data_analysis`
+
+### 3. Create Directory Structure
+
+```bash
+mkdir -p ~/.claude/skills/[SkillName]/{workflows,tools}
+```
+
+### 4. Create SKILL.md
+
+Create `~/.claude/skills/[SkillName]/SKILL.md` with:
+
+```yaml
+---
+name: SkillName
+description: Brief description. USE WHEN user mentions [trigger1], [trigger2], or needs [specific capability].
+---
+
+# SkillName
+
+Brief overview of what this skill provides.
+
+## Workflow Routing
+
+| Workflow | Trigger | File |
+|----------|---------|------|
+| **WorkflowName** | "trigger phrase" | `workflows/WorkflowName.md` |
+
+## Examples
+
+**Example 1: [Use case]**
+```
+User: "[trigger phrase]"
+โ Invokes [WorkflowName] workflow
+โ [What it does]
+```
+```
+
+### 5. Create Initial Workflow
+
+If the user wants workflows, create them in `workflows/` directory using TitleCase naming.
+
+### 6. Verify Structure
+
+Check:
+- โ Directory name is TitleCase
+- โ SKILL.md has valid YAML frontmatter
+- โ Description is ONE LINE with USE WHEN triggers
+- โ Workflow files use TitleCase.md naming
+- โ At least one example is provided
+
+### 7. Present to User
+
+Show the created structure and ask for confirmation or adjustments.
+
+## Output Format
+
+```
+Created skill: [SkillName]
+
+Structure:
+~/.claude/skills/[SkillName]/
+โโโ SKILL.md
+โโโ workflows/
+โ โโโ [WorkflowName].md
+โโโ tools/
+
+Files created:
+- SKILL.md: Main skill definition
+- workflows/[WorkflowName].md: [Description]
+
+Next steps:
+- Add more workflows as needed
+- Test the skill by invoking it
+- Refine USE WHEN triggers based on usage
+```
dots/.claude/skills/Createskill/workflows/ValidateSkill.md
@@ -0,0 +1,96 @@
+# ValidateSkill Workflow
+
+Validate a skill's structure, naming, and compliance with conventions.
+
+## Steps
+
+### 1. Read the Skill File
+
+Read `~/.claude/skills/[SkillName]/SKILL.md`
+
+### 2. Check Directory Naming
+
+- โ Directory name is TitleCase (e.g., `Golang`, not `golang`)
+- โ Directory name matches YAML `name` field
+
+### 3. Validate YAML Frontmatter
+
+Required fields:
+```yaml
+---
+name: SkillName # Must be TitleCase
+description: ... # Must be ONE LINE with USE WHEN triggers
+---
+```
+
+Check:
+- โ `name` field exists and is TitleCase
+- โ `description` field exists and is single line
+- โ Description includes "USE WHEN" or clear triggers
+- โ No syntax errors in YAML
+
+### 4. Validate Markdown Body
+
+Required structure:
+1. โ H1 heading matching the skill name
+2. โ Brief overview paragraph
+3. โ "Workflow Routing" section (if workflows exist)
+4. โ "Examples" section with at least one example
+
+### 5. Check Workflow Files
+
+For each file in `workflows/`:
+- โ Uses TitleCase.md naming (e.g., `Create.md`, not `create.md`)
+- โ Listed in Workflow Routing table
+- โ Has clear structure
+
+### 6. Check Tool Files
+
+For each file in `tools/`:
+- โ Uses TitleCase naming (e.g., `GenerateTool.ts`)
+- โ Is executable (if shell script)
+
+### 7. Generate Compliance Report
+
+## Output Format
+
+```
+Validating skill: [SkillName]
+
+โ Directory Structure
+ โ Name is TitleCase: [SkillName]
+ โ workflows/ directory exists
+ โ tools/ directory exists
+
+โ SKILL.md Frontmatter
+ โ name: [SkillName] (TitleCase)
+ โ description: Single line with triggers
+
+โ SKILL.md Body
+ โ H1 heading matches name
+ โ Has overview section
+ โ Has Workflow Routing table
+ โ Has Examples section
+
+โ Workflows
+ โ All workflows use TitleCase.md
+ โ All listed in routing table
+
+Compliance: PASSED
+
+[If issues found:]
+โ Issues Found:
+ - [Issue 1 description]
+ - [Issue 2 description]
+
+Recommendations:
+ - [How to fix issue 1]
+ - [How to fix issue 2]
+```
+
+## Failure Handling
+
+If validation fails, suggest fixes:
+- Naming issues: Provide correct TitleCase names
+- Structure issues: Show required structure
+- Missing sections: Provide templates
dots/.claude/skills/Createskill/SKILL.md
@@ -0,0 +1,126 @@
+---
+name: Createskill
+description: Skill creation framework for creating, validating, updating, or canonicalizing skills. USE WHEN user wants to create a new skill, validate skill structure, update existing skill, or fix skill compliance.
+---
+
+# Createskill
+
+Systematic skill creation framework for building consistent, well-structured Claude Code skills.
+
+## TitleCase Naming Convention
+
+**All naming must use TitleCase (PascalCase).**
+
+| Component | Format | Example |
+|-----------|--------|---------|
+| Skill directory | TitleCase | `Golang`, `Homelab`, `Createskill` |
+| Workflow files | TitleCase.md | `Create.md`, `UpdateInfo.md` |
+| Reference docs | TitleCase.md | `Guide.md`, `Reference.md` |
+| Tool files | TitleCase.ts | `ManageTool.ts` |
+
+**Wrong (NEVER use):**
+- `createskill`, `create-skill`, `CREATE_SKILL`
+- `create.md`, `update-info.md`, `SYNC_REPO.md`
+
+## Workflow Routing
+
+**When executing a workflow, output this notification directly:**
+
+```
+Running the **WorkflowName** workflow from the **Createskill** skill...
+```
+
+| Workflow | Trigger | File |
+|----------|---------|------|
+| **CreateSkill** | "create a new skill" | `workflows/CreateSkill.md` |
+| **ValidateSkill** | "validate skill", "check skill" | `workflows/ValidateSkill.md` |
+
+## Skill Structure Requirements
+
+### Required Components
+
+Every skill must have:
+
+1. **SKILL.md** - Main skill file with:
+ - YAML frontmatter (name, description)
+ - Clear purpose and scope
+ - Workflow routing table
+ - Usage examples
+
+2. **workflows/** directory - Contains workflow markdown files
+
+3. **tools/** directory - Contains tool scripts (optional)
+
+### YAML Frontmatter Format
+
+```yaml
+---
+name: SkillName
+description: Single-line description. USE WHEN triggers go here.
+---
+```
+
+**Critical Rules:**
+- `name` must be TitleCase
+- `description` must be ONE LINE (no newlines)
+- Include "USE WHEN" triggers in description
+
+### Markdown Body Structure
+
+Required sections in order:
+
+1. **# [Skill Name]** - H1 heading matching the name
+2. **Brief overview** - What this skill does
+3. **Workflow Routing** - Table of workflows
+4. **Examples** - Usage examples (at least one)
+
+## Examples
+
+**Example 1: Create a new skill from scratch**
+```
+User: "Create a skill for managing my Docker containers"
+โ Invokes CreateSkill workflow
+โ Creates skill directory with TitleCase naming
+โ Creates SKILL.md with proper frontmatter
+โ Creates workflows/ and tools/ directories
+โ Generates USE WHEN triggers based on purpose
+```
+
+**Example 2: Validate an existing skill**
+```
+User: "Validate the golang skill"
+โ Invokes ValidateSkill workflow
+โ Checks SKILL.md structure and naming
+โ Verifies TitleCase naming throughout
+โ Verifies USE WHEN triggers are clear
+โ Reports any compliance issues
+```
+
+## Best Practices
+
+### Naming
+- Use TitleCase for all directories and files
+- Keep names descriptive but concise
+- Match skill directory name to YAML `name` field
+
+### Description Field
+- Keep it to ONE LINE only
+- Include clear USE WHEN triggers
+- Focus on when to invoke the skill, not just what it does
+
+### Workflows
+- Name workflows with clear action verbs (Create, Update, Validate)
+- Keep workflows focused on single tasks
+- Use TitleCase.md naming
+
+### Examples
+- Provide at least one concrete example
+- Show the trigger phrase and expected behavior
+- Demonstrate the value of the skill
+
+## Integration
+
+This skill works with your existing skills:
+- References `.claude/skills/` directory structure
+- Follows patterns from CORE, golang, nix, homelab, notes skills
+- Validates against established conventions
dots/Makefile
@@ -25,6 +25,9 @@ claude-skills : ~/.claude/skills
all += claude-agents
claude-agents : ~/.claude/agents
+all += claude-hooks
+claude-hooks : ~/.claude/hooks
+
# Example: Override default rule to generate content instead of copying
# Uncomment and customize this pattern for files that should be generated:
#