```html

Building a Multi-Site Technical Blog Generator with Auto-Publishing via Claude Code Hooks

What Was Done

Created an automated technical blog generation system that captures development session transcripts and publishes granular technical posts to four independent tech blogs:

  • tech.queenofsandiego.com
  • tech.sailjada.com
  • tech.dangerouscentaur.com
  • tech.burialsatseasandiego.com

The system automatically captures everything worked on during development sessions and publishes detailed technical posts immediately upon session completion, with integration into the Ship's Papers navigation menu on the main sites.

Technical Architecture

Three-Layer System

Layer 1: Session Capture via Stop Hook

Created /Users/cb/.claude/hooks/tech_blog_stop.sh that executes when any Claude Code session ends. This hook:

  • Extracts the session JSONL transcript from Claude's session storage
  • Identifies which site project the session belongs to (qos, jada, dc, bats)
  • Passes the transcript to the blog generator
  • Handles errors gracefully with detailed logging to /tmp/tech_blog_logs/

Layer 2: Blog Generation via Python

Wrote /Users/cb/Documents/repos/tools/tech_blog_generator.py which:

  • Parses Claude session transcripts in JSONL format
  • Extracts tool use events (file writes, edits, commands run)
  • Filters out sensitive data (credentials, API keys, secrets)
  • Generates detailed HTML posts with exact file paths, function names, and infrastructure details
  • Creates posts in 600-1200 word range with proper structure (What Was Done / Technical Details / Infrastructure / Key Decisions)
  • Timestamps each post and maintains metadata

Layer 3: Infrastructure Deployment

Created /Users/cb/Documents/repos/tools/tech_blog_init.py to provision cloud infrastructure for each blog:

  • S3 Buckets: Named tech-{site}-blog (e.g., tech-qos-blog) for static HTML content
  • CloudFront Distributions: Configured with appropriate SSL certs and origin access control
  • DNS Integration: Route53 for qos and jada; Namecheap for dangerouscentaur; GoDaddy for burialsatseasandiego
  • CNAME Records: Points tech.[domain].com to CloudFront distribution

Certificate Strategy

Leveraged existing AWS Certificate Manager wildcard certificates:

  • *.queenofsandiego.com wildcard cert for tech.queenofsandiego.com
  • *.sailjada.com wildcard cert for tech.sailjada.com
  • Requested new cert for tech.dangerouscentaur.com via ACM (validated via Namecheap CNAME)
  • Requested new cert for tech.burialsatseasandiego.com via ACM (validated via GoDaddy DNS)

Infrastructure Details

CloudFront Configurations

Each distribution was configured with:

  • S3 origin with Origin Access Control (OAC) for security
  • Gzip compression enabled for HTML/CSS/JS
  • Cache behavior: 3600 second TTL for index.html, 31536000 for versioned assets
  • Security headers (X-Content-Type-Options, X-Frame-Options, Referrer-Policy)
  • HTTP/2 and HTTP/3 (QUIC) support enabled

DNS Integration

Route53 Managed Zones (queenofsandiego.com, sailjada.com):

CNAME record: tech → d[distribution-id].cloudfront.net

Namecheap (dangerouscentaur.com):

Created CNAME alias in Namecheap dashboard pointing to CloudFront distribution. Validated ACM certificate by adding GoDaddy-provided CNAME validation record.

GoDaddy (burialsatseasandiego.com):

Added ACM DNS validation CNAME record directly via GoDaddy API integration, then created tech subdomain CNAME pointing to CloudFront.

S3 Bucket Configuration

Each tech blog bucket includes:

  • Index document: index.html (auto-generated blog index)
  • Error document: 404.html
  • Public read ACL disabled (all access via CloudFront)
  • Versioning enabled for rollback capability
  • Server-side encryption (SSE-S3) enabled

Integration with Ship's Papers

Updated the Ship's Papers navigation menu in /Users/cb/Documents/repos/sites/queenofsandiego.com/index.html to include a "Tech Blog" dropdown link pointing to /tech/. The navigation structure uses semantic HTML with proper ARIA attributes for accessibility.

Session Capture Mechanism

Claude Code sessions automatically write transcripts to ~/.claude/sessions/ in JSONL format. The Stop hook:

  1. Reads $CLAUDE_SESSION_FILE environment variable (set by Claude Code)
  2. Parses the JSONL file, filtering for tool_use entries
  3. Extracts file modifications, commands run, and reasoning
  4. Invokes tech_blog_generator.py with the transcript data
  5. Generator produces HTML post and uploads to appropriate S3 bucket
  6. Invalidates CloudFront cache to serve latest content

Sensitive Data Filtering

The generator specifically redacts:

  • AWS access keys, secret keys, session tokens
  • API keys and OAuth tokens
  • Database passwords and connection strings
  • Email addresses and personal identifiers (unless part of public-facing content)
  • File paths containing .aws/, .claude/ credentials directories
  • Environment variables containing SECRET, KEY, TOKEN, PASSWORD

The redaction preserves technical value