AGENTS.md - Guide for Agentic Software Development
Project Overview
Ioannis Diamantidis's personal blog — a software development blog built with Jekyll (Ruby static site generator) using the minima theme and styled with a combination of SCSS and Tailwind CSS. The site is hosted on GitHub Pages and deployed automatically via GitHub Actions.
- Technology Stack: Jekyll + minima theme + Tailwind CSS (standalone CLI) + Ruby + Node.js
- Language: English
- Hosting: GitHub Pages (
diamantidis.github.io) - Deployment: Automatic via GitHub Actions on merge to
sourcebranch - Branching:
sourcebranch contains the Jekyll project;masterbranch contains the built site
Project Structure
/
├── _layouts/ # Jekyll layout templates
│ ├── compress.html # HTML compression layout
│ ├── default.html # Base layout (compress wrapper)
│ ├── home.html # Home page with paginated posts
│ ├── page.html # Static pages
│ ├── post.html # Blog posts
│ └── tips.html # Tips collection items
├── _includes/ # Reusable HTML components
│ ├── head.html # HTML head with meta, CSS, analytics
│ ├── header.html # Site header with navigation
│ ├── footer.html # Site footer
│ ├── favicon.html # Favicon links
│ ├── icons.html # SVG icons
│ ├── post-subheader.html # Post metadata (date, tags)
│ ├── tips-subheader.html # Tips metadata
│ ├── posthog.html # PostHog analytics (production only)
│ └── telemetry-deck.html # TelemetryDeck analytics (production only)
├── _pages/ # Static pages
│ ├── about.md # About page
│ ├── archive.md # Post archive
│ ├── tags.md # Tags page
│ └── tips.md # Tips listing page
├── _posts/ # Blog posts (Markdown)
├── _tips/ # Tips collection (short-form content)
├── _scss/ # SCSS stylesheets
│ ├── custom.scss # Custom styles + CSS variables
│ └── minima/ # Minima theme overrides (syntax highlighting)
├── assets/
│ ├── main.scss # Main SCSS entry point (imports minima theme + custom)
│ ├── css/
│ │ ├── input.css # Tailwind CSS input file (@tailwind directives + @apply rules)
│ │ └── main.css # Compiled Tailwind CSS output (gitignored, generated by CLI)
│ ├── socialIcon.png # Default social sharing image
│ ├── tips/ # Tip-specific assets
│ └── [post dirs]/ # Per-post image assets
├── .github/
│ └── workflows/
│ ├── ci.yml # CI: build + Danger prose lint on PRs
│ └── github-pages.yml # Build & deploy to GitHub Pages on push to source
├── _config.yml # Jekyll configuration
├── tailwind.config.js # Tailwind content paths config
├── Dangerfile # Danger + prose linting rules
├── package.json # Node.js dependencies (tailwindcss) + scripts
├── Gemfile # Ruby dependencies (Jekyll plugins)
└── .ruby-version # Ruby version (3.3.4)
Key Features
- Pagination: Jekyll Paginate V2 with 7 posts per page
- Dark Mode: Automatic via CSS custom properties (
prefers-color-schememedia query) - Tips Collection: Short-form content at
/tips/using Jekyll collections - Analytics: TelemetryDeck and PostHog (production environment only)
- CI/CD: GitHub Actions CI with Danger + proselint for prose linting on PRs
- SEO: jekyll-sitemap, jekyll-feed, and jekyll-seo-tag
- Prose Linting: Danger-prose checks spelling and prose style on every PR
- Buy Me a Coffee: Support widget integrated in page head
- HTML Compression: Custom compress layout for minified HTML output
How to Run the Website
Prerequisites
- Ruby 3.3.4 (see
.ruby-version) - Node.js 22.2.0
- Bundler (Ruby gem manager)
Installation
# Install Ruby dependencies
bundle install
# Install Node.js dependencies (Tailwind CSS)
npm install
Running the Development Server
Terminal 1: Watch and rebuild CSS on changes
# Start CSS watcher and save PID
nohup npm run dev:css > css-watch.log 2>&1 &
echo $! > .css-watcher.pid
echo "CSS watcher started with PID: $(cat .css-watcher.pid)"
# Check CSS build logs anytime:
tail -f css-watch.log
Terminal 2: Run Jekyll server
# If port 4000 is available:
nohup bundle exec jekyll serve --host 0.0.0.0 > jekyll.log 2>&1 &
echo $! > .jekyll.pid
echo "Jekyll started with PID: $(cat .jekyll.pid)"
# If port 4000 is busy, use alternative port:
nohup bundle exec jekyll serve --host 0.0.0.0 --port 4001 --livereload-port 35731 > jekyll.log 2>&1 &
echo $! > .jekyll.pid
echo "Jekyll started with PID: $(cat .jekyll.pid)"
# Check Jekyll logs anytime:
tail -f jekyll.log
# The site will be available at:
# http://0.0.0.0:4000 (or your chosen port)
Development Workflow
- Start CSS watcher in Terminal 1 (creates .css-watcher.pid)
- Check port availability in Terminal 2
- Start Jekyll server on available port (creates .jekyll.pid)
- Open browser to the displayed local URL
- Make changes to files
- Jekyll will auto-reload with
--livereload(default behavior) - When done, stop servers using the PID files created in steps 1 and 3
Stopping the Development Server
IMPORTANT: Only stop processes that you started. Never kill processes you did not start.
When you're done with testing and verification, stop the servers you started:
Option 1: Kill using PID files (Recommended - Safest)
If you started servers using the instructions above (which create PID files):
# Kill Jekyll using saved PID
if [ -f .jekyll.pid ]; then
kill $(cat .jekyll.pid) && rm .jekyll.pid
echo "Jekyll stopped"
fi
# Kill CSS watcher using saved PID
if [ -f .css-watcher.pid ]; then
kill $(cat .css-watcher.pid) && rm .css-watcher.pid
echo "CSS watcher stopped"
fi
Tailwind CSS Setup
This project uses the Tailwind CSS standalone CLI (not PostCSS or jekyll-postcss).
- How it works: The Tailwind CLI reads
assets/css/input.css, processes@tailwindand@applydirectives, and outputs compiled CSS toassets/css/main.css - Content paths: Configured in
tailwind.config.js— scans_posts/,_pages/,_includes/,_layouts/, and root HTML/MD files - Input file:
assets/css/input.css— contains@tailwinddirectives and@layer utilitieswith@applyrules - Output file:
assets/css/main.css— gitignored, generated by the CLI - Dev script:
npm run dev:css— watches for changes and rebuilds automatically - Build script:
npm run build:css— minified output for production - CI/CD:
npm run build:cssruns beforejekyll buildin both CI and deploy workflows
Verifying Changes with Playwright MCP
Important Navigation Principle: Always navigate through the UI starting from the home page. Never open URLs directly. This ensures you test the actual user flow.
Smoke Test Workflow
1. Navigate to Home Page
- Use
playwright_browser_navigateto go tohttp://127.0.0.1:4000(or your chosen port) - Use
playwright_browser_snapshotto verify the page structure - Verify blog post listings are present
2. Navigate to a Blog Post
- Use
playwright_browser_snapshotto see available post links - Use
playwright_browser_clickto click on a post title - Use
playwright_browser_snapshotto verify the post page loaded with title, content, and metadata
3. Verify Static Pages
- Navigate back to the home page
- Click on navigation links (About, Archive, Tags, Tips)
- Use
playwright_browser_snapshotto verify each page loads correctly with expected content
Conceptual Test Flow
1. Navigate → Home page (http://127.0.0.1:4000)
2. Snapshot → Verify home page structure and post listings
3. Click → A blog post title
4. Snapshot → Verify post page loaded (title, content, metadata)
5. Navigate back → Home page
6. Click → About page link
7. Snapshot → Verify about page content
8. Navigate back → Home page
9. Click → Archive page link
10. Snapshot → Verify archive page content
Tips for Verification
- Always use snapshots to understand the current page state before interacting
- Take screenshots at key points for visual verification
- Verify both structure (elements exist) and content (text is correct)
- Check that code blocks and syntax highlighting render properly in posts
Git Workflow with gh-cli
All Git operations should use the GitHub CLI (gh) for consistency.
Branching Model
sourcebranch: Development branch containing the Jekyll project sourcemasterbranch: Auto-generated from CI — contains the built static site. Never edit directly.- All work happens on feature branches off of
source
Commits - Small Iterations
- Make small, focused commits: Each commit should represent one logical change
- One change per commit: Don't mix unrelated changes
- Clear commit messages: Describe what and why, not just what
# Stage specific changes
git add path/to/specific/file
# Commit with descriptive message
git commit -m "Add dark mode support for post code blocks"
# Repeat for next logical change
git add another/file.md
git commit -m "Update about page with new bio section"
Creating Pull Requests
After pushing changes to a remote branch, create a PR against source:
# Push your branch
git push -u origin your-branch-name
# Create PR with plan and tests
gh pr create \
--base source \
--title "Add responsive image component to posts" \
--body "## Plan
- Implement responsive image component in posts
- Add lazy loading for post images
- Update existing posts to use new component
## Tests
- Manual verification: Home page loads correctly
- Playwright smoke test: PASS
- Home page navigation works
- Blog post page loads with content
- Static pages (About, Archive, Tags) render correctly
- Visual verification: Images display correctly
- CI checks: Danger prose lint passes"
PR Structure Template
Title: Clear, descriptive title summarizing the change
Body:
-
Plan section:
- What this PR accomplishes
- Key changes and implementation decisions
- Any important context
-
Tests section:
- Manual verification performed
- Playwright smoke test results (PASS/FAIL)
- Specific steps verified
- CI check results (Danger prose lint)
After PR Creation
- Monitor CI/CD checks via GitHub Actions (build + Danger lint)
- Fix any prose linting issues flagged by Danger
- Respond to any review feedback
- Squash commits if requested before merge
Useful gh-cli Commands
# List PRs
gh pr list
# View PR details
gh pr view <PR_NUMBER>
# Check PR status
gh pr status
# Merge PR (after approval)
gh pr merge <PR_NUMBER>
Best Practices for Agents
- NEVER kill processes you didn't start — Only stop processes that you initiated
- Run
npm run dev:cssbefore starting Jekyll in development to watch Tailwind CSS changes - Always check port availability before starting Jekyll server
- Use background processes with PID files and log files for Jekyll
- Navigate through UI for Playwright tests, never direct URLs
- Make small commits representing single logical changes
- Write descriptive commit messages explaining the "why"
- Create PRs against
sourcebranch — never targetmasterdirectly - Verify changes with Playwright smoke test before marking work complete
- Check CI results — Danger will flag prose issues on PRs
- Use snapshots to understand page state before interactions
- Don't edit
masterbranch — it's auto-generated from CI - Tailwind classes go in
assets/css/input.cssvia@applydirectives in@layer utilities, not in HTML templates directly