Files
wiki/TASK.md

27 KiB

Markdown Blog - Tasks

To Do

  • Newsletter signup
  • Draft preview mode

Current Status

v2.2.1 ready. ES module compatibility fix for configure-fork.ts. Fixed __dirname is not defined error when running npm run configure. Added fileURLToPath import to create ES module equivalent of __dirname. Script now works correctly with "type": "module" in package.json.

Completed

  • ES module compatibility fix for configure-fork.ts

    • Fixed __dirname is not defined error when running npm run configure
    • Added fileURLToPath import from url module
    • Created ES module equivalent of __dirname using import.meta.url
    • Updated files.md, changelog.md, changelog-page.md, TASK.md
  • Footer content via markdown page (footer.md)

    • Created content/pages/footer.md for managing footer content via markdown sync
    • Footer content syncs with npm run sync without redeploy needed
    • Falls back to siteConfig.footer.defaultContent when page not found
    • Updated Home.tsx and Blog.tsx to fetch footer page by slug
    • Updated files.md, changelog.md, changelog-page.md, FORK_CONFIG.md with documentation
  • CLAUDE.md and Claude skills documentation

    • Created CLAUDE.md in root with project instructions for Claude Code
    • Created .claude/skills/ directory with three focused skill files
    • frontmatter.md: Complete frontmatter syntax and all 25+ field options
    • convex.md: Convex patterns specific to this app (indexes, idempotent mutations, conflict prevention)
    • sync.md: How sync commands work and content flow from markdown to database
    • Updated sync-discovery-files.ts to automatically update CLAUDE.md during sync
    • Updated files.md, changelog.md, changelog-page.md, TASK.md with feature documentation
  • Image lightbox for blog posts and pages

    • Added ImageLightboxConfig interface to siteConfig.ts with enabled option
    • Created ImageLightbox component in BlogPost.tsx with backdrop, close button, keyboard support
    • Updated img renderer to add click handler and clickable cursor when lightbox enabled
    • Added CSS styles for lightbox backdrop, image, close button, and caption
    • Added imageLightboxEnabled to Dashboard config generator
    • Updated documentation: docs.md, setup-guide.md, files.md, changelog.md, changelog-page.md
    • Images show pointer cursor and hover effect when lightbox is enabled
    • Lightbox closes on backdrop click, Escape key, or close button
    • Alt text displayed as caption in lightbox
    • Default configuration: enabled: true (lightbox active by default)
  • Stats page configuration option for public/private access

    • Added StatsPageConfig interface to siteConfig.ts with enabled and showInNav options
    • Updated App.tsx to conditionally render /stats route based on config
    • Updated Stats.tsx to check if enabled and show disabled message if not
    • Updated Layout.tsx to hide stats nav item when disabled
    • Default configuration: enabled: true (public), showInNav: true (visible in nav)
    • Follows same pattern as NewsletterAdmin for consistency
    • Updated files.md with stats page configuration notes
    • Updated changelog.md with v1.43.0 entry
    • Updated TASK.md with completed task
  • Honeypot bot protection for contact and newsletter forms

    • Added honeypot state and hidden field to ContactForm.tsx
    • Added honeypot state and hidden field to NewsletterSignup.tsx
    • Hidden "Website" field for contact form bot detection
    • Hidden "Fax" field for newsletter signup bot detection
    • Bots receive fake success message (no data submitted)
    • CSS positioning (position: absolute, left: -9999px) hides fields from users
    • aria-hidden="true" and tabIndex={-1} for accessibility
    • Different field names per form to avoid pattern detection
    • Updated files.md with honeypot protection notes
    • Updated changelog.md with v1.42.0 entry
  • Blog heading styles for home intro content

    • Added generateSlug, getTextContent, HeadingAnchor helper functions to Home.tsx
    • Updated ReactMarkdown components to include h1-h6 with blog-h* classes
    • Added clickable anchor links (#) that appear on hover for each heading
    • Automatic ID generation from heading text for anchor navigation
    • Added blog styling for lists (blog-ul, blog-ol, blog-li), blockquotes (blog-blockquote), horizontal rules (blog-hr), and links (blog-link)
    • Updated files.md, changelog.md, changelog-page.md, TASK.md with feature documentation
    • Home intro headings now match blog post typography and spacing
  • Synced home intro content via markdown file (home.md)

    • Created content/pages/home.md (slug: home-intro) for homepage intro text
    • Home.tsx fetches content from Convex via getPageBySlug query
    • Added textAlign frontmatter field for pages (left/center/right, default: left)
    • Added featuredTitle to siteConfig.ts for configurable featured section title
    • Full markdown support with links, headings, lists, blockquotes, horizontal rules
    • External links automatically open in new tab
    • Fallback to siteConfig.bio if home-intro page not found (loading/error states)
    • Content syncs with npm run sync (no redeploy needed for homepage text changes)
    • Updated convex/schema.ts with textAlign field
    • Updated convex/pages.ts with textAlign in queries and mutations
    • Updated scripts/sync-posts.ts to parse textAlign from frontmatter
    • Updated src/styles/global.css with home-intro-content styles
    • Updated files.md, changelog.md, TASK.md documentation
  • HTTP-based MCP Server on Netlify

    • Created netlify/edge-functions/mcp.ts with JSON-RPC 2.0 implementation
    • Added @modelcontextprotocol/sdk dependency to package.json
    • Configured Netlify rate limiting (50 req/min public, 1000 req/min authenticated)
    • Implemented optional authentication via Authorization header
    • Added /mcp edge function route to netlify.toml
    • Created blog post "How to Use the MCP Server" with fork setup instructions
    • Updated documentation (docs.md, setup-guide.md, files.md, changelog.md, README.md)
    • Added MCP configuration to siteConfig.ts
    • Seven tools implemented: list_posts, get_post, list_pages, get_page, get_homepage, search_content, export_all
    • CORS support for MCP clients
    • Manual JSON-RPC implementation (no SDK dependency on Deno runtime)
  • Newsletter CLI improvements

    • Updated newsletter:send to call scheduleSendPostNewsletter mutation directly
    • Added newsletter:send:stats command for weekly stats summary
    • Created scheduleSendStatsSummary mutation in convex/newsletter.ts
    • Created send-newsletter-stats.ts script
    • Verified all AgentMail features use environment variables (no hardcoded emails)
    • Updated documentation (docs.md, files.md, changelog.md, changelog-page.md, TASK.md)
    • Created blog post "How to use AgentMail with Markdown Sync"
  • showImageAtTop frontmatter field for posts and pages

    • Added showImageAtTop optional boolean field to convex/schema.ts for posts and pages
    • Updated scripts/sync-posts.ts to parse showImageAtTop from frontmatter
    • Updated convex/posts.ts and convex/pages.ts queries and mutations to include showImageAtTop
    • Updated src/pages/Post.tsx to conditionally render image at top when showImageAtTop: true
    • Added CSS styles for .post-header-image and .post-header-image-img
    • Updated src/pages/Write.tsx to include showImageAtTop in POST_FIELDS and PAGE_FIELDS
    • Updated documentation: docs.md, how-to-publish.md, using-images-in-posts.md, files.md
    • Image displays full-width above post header with rounded corners
    • Default behavior: image only used for OG and featured cards when showImageAtTop not set
  • Blog page featured layout with hero post

    • blogFeatured frontmatter field for posts to mark as featured on blog page
    • BlogHeroCard component for the hero featured post (first blogFeatured post)
    • Featured row displays remaining blogFeatured posts in 2-column grid with excerpts
    • Regular posts display in 3-column grid without excerpts
    • getBlogFeaturedPosts query returns all published posts with blogFeatured: true
    • PostList component updated with columns prop (2 or 3) and showExcerpts prop
    • Schema updated with blogFeatured field and by_blogFeatured index
    • sync-posts.ts updated to parse blogFeatured frontmatter
    • Hero card displays landscape image, tags, date, title, excerpt, author info, and read more link
    • Featured row shows excerpts for blogFeatured posts
    • Regular posts hide excerpts for cleaner grid layout
    • Responsive design: hero stacks on mobile, grids adjust columns at breakpoints
    • CSS styles for .blog-hero-section, .blog-hero-card, .blog-featured-row, .post-cards-2col
    • Card images use 16:10 landscape aspect ratio matching Giga.ai style
    • Footer support on blog page via siteConfig.footer.showOnBlogPage
  • AI Chat Write Agent (Agent) integration

    • AIChatView component created with Anthropic Claude API integration
    • Write page AI Agent mode toggle (replaces textarea when active)
    • RightSidebar AI chat support via frontmatter aiChat: true field
    • Per-session, per-context chat history stored in Convex (aiChats table)
    • Page content context support for AI responses
    • Markdown rendering for AI responses with copy functionality
    • Error handling for missing API keys with user-friendly messages
    • System prompt configurable via Convex environment variables
    • Anonymous session authentication using localStorage session ID
    • Chat history limited to last 20 messages for context efficiency
    • Title changes to "Agent" when in AI chat mode on Write page
    • Toggle button text changes between "Agent" and "Text Editor"
    • SiteConfig.aiChat configuration with enabledOnWritePage and enabledOnContent flags
    • Schema updated with aiChats table and aiChat fields on posts/pages tables
    • sync-posts.ts updated to handle aiChat frontmatter field
    • Documentation updated across all files
  • Fixed AI chat scroll prevention in Write page

    • Added viewport height constraints (100vh) to write-layout to prevent page-level scrolling
    • Updated write-main with max-height: 100vh and overflow: hidden when AI chat is active
    • Added min-height: 0 to flex children (write-ai-chat-container, ai-chat-view, ai-chat-messages) for proper flex behavior
    • Input container fixed at bottom with flex-shrink: 0
    • Sidebars (left and right) scroll internally with overflow-y: auto
    • Delayed focus in AIChatView (100ms setTimeout) to prevent scroll jump on mount
    • Added preventScroll: true to all focus() calls in AIChatView
    • Toggle button preserves scroll position using requestAnimationFrame
    • useEffect scrolls to top when switching to AI chat mode
    • Messages area scrolls internally while input stays fixed at bottom (ChatGPT-style behavior)
  • Custom homepage configuration feature

    • Added HomepageConfig interface to siteConfig.ts
    • Updated App.tsx to conditionally render homepage based on config
    • Updated Post.tsx to accept optional props for homepage mode (slug, isHomepage, homepageType)
    • Back button hidden when Post component is used as homepage
    • Original homepage route accessible at /home when custom homepage is set
    • SEO metadata uses page/post frontmatter when used as homepage
    • Updated configure-fork.ts to support homepage configuration
    • Updated FORK_CONFIG.md with homepage documentation
    • Updated fork-config.json.example with homepage option
    • All existing features (sidebar, footer, right sidebar) work correctly with custom homepage
  • Image support in footer component with size control

    • Footer sanitize schema updated to allow width, height, style, class attributes on images
    • Footer image component handler updated to pass through size attributes
    • CSS styles added for footer images (.site-footer-image-wrapper, .site-footer-image, .site-footer-image-caption)
    • Images support lazy loading and optional captions from alt text
    • Security verified: rehypeSanitize sanitizes style attributes to remove dangerous CSS
    • Updated files.md, changelog.md with image support documentation
  • Customizable footer component with markdown support

    • Footer component created (src/components/Footer.tsx) with ReactMarkdown rendering
    • Footer configuration added to siteConfig.ts (FooterConfig interface with defaultContent)
    • Footer content can be set in frontmatter footer field (markdown) or siteConfig.defaultContent
    • Footer can be enabled/disabled globally and per-page type
    • showFooter and footer frontmatter fields added for posts and pages
    • Footer renders inside article tag at bottom for posts/pages
    • Footer maintains current position on homepage
    • Updated Home.tsx to use Footer component with defaultContent
    • Updated Post.tsx to render Footer inside article based on showFooter
    • Added CSS styles for site-footer (.site-footer, .site-footer-content, .site-footer-text, .site-footer-link)
    • Updated schema.ts, posts.ts, pages.ts with showFooter and footer fields
    • Updated sync-posts.ts to parse showFooter and footer frontmatter
    • Updated Write.tsx to include showFooter and footer in frontmatter reference
    • Sidebars flush to bottom when footer is enabled (min-height ensures proper extension)
    • Updated files.md, changelog.md with footer feature documentation
  • Fixed right sidebar default behavior: now requires explicit rightSidebar: true in frontmatter

  • Pages/posts without rightSidebar frontmatter render normally with CopyPageDropdown in nav

  • Fixed TypeScript errors: Added rightSidebar to syncPosts and syncPostsPublic args validators

  • Right sidebar feature with CopyPageDropdown support

  • RightSidebar component created

  • Three-column layout CSS (left sidebar, main content, right sidebar)

  • Right sidebar configuration in siteConfig.ts

  • rightSidebar frontmatter field for posts and pages

  • Updated Post.tsx to conditionally render right sidebar

  • Updated schema.ts, posts.ts, pages.ts to handle rightSidebar field

  • Updated sync-posts.ts to parse rightSidebar frontmatter

  • Updated Write.tsx to include rightSidebar option

  • Responsive behavior: right sidebar hidden below 1135px

  • CopyPageDropdown automatically moves from nav to right sidebar when enabled

  • Font family configuration system with siteConfig integration

  • Added FontContext.tsx for global font state management

  • Monospace font option added to FONT SWITCHER (IBM Plex Mono)

  • CSS variable --font-family for dynamic font updates

  • Write page font switcher updated to support serif/sans/monospace

  • Fork configuration support for fontFamily option

  • Documentation updated (setup-guide.md, docs.md)

  • Font preference persistence with localStorage

  • SiteConfig default font detection and override logic

  • Plain text code blocks now wrap text properly instead of horizontal overflow

  • Updated inline vs block code detection logic in BlogPost.tsx

  • Added pre-wrap styling for text blocks via SyntaxHighlighter props

  • RSS feed validation errors fixed by standardizing URLs to www.markdown.fast

  • Updated index.html meta tags (og:url, og:image, twitter:domain, twitter:url, twitter:image, JSON-LD)

  • Updated convex/rss.ts and convex/http.ts SITE_URL constants

  • Updated public/robots.txt, public/openapi.yaml, and public/llms.txt with www URLs

  • RSS exclusions confirmed in netlify.toml for botMeta edge function

  • Discovery files sync script (sync-discovery-files.ts)

  • Automated updates for AGENTS.md and llms.txt with current app data

  • New npm scripts: sync:discovery, sync:discovery:prod, sync:all, sync:all:prod

  • Fork configuration updated to support gitHubRepo config

  • Backward compatibility for legacy githubUsername/githubRepo fields

  • Documentation updated across all files with new sync commands

  • Homepage post limit configuration (homePostsLimit in siteConfig.postsDisplay)

  • Optional "read more" link below limited post list (homePostsReadMore config)

  • Customizable link text and destination URL

  • CSS styling for read more link with hover effects

  • Conditional rendering logic to show link only when posts are limited

  • Tag pages at /tags/[tag] route with view mode toggle

  • Related posts component for blog post footers (up to 3 related posts by shared tags)

  • Tag links in post footers now navigate to tag archive pages

  • Open in AI links (ChatGPT, Claude, Perplexity) re-enabled using GitHub raw URLs

  • gitHubRepo configuration in siteConfig.ts for AI service URL construction

  • by_tags index added to posts table in convex/schema.ts

  • New Convex queries: getAllTags, getPostsByTag, getRelatedPosts

  • Sitemap updated to include dynamically generated tag pages

  • Documentation updated with git push requirement for AI links

  • Mobile responsive styling for tag pages and related posts

  • Fixed sidebar border width consistency using box-shadow instead of border-right

  • Hidden sidebar scrollbar while maintaining scroll functionality

  • Added top border and border-radius to sidebar wrapper using CSS variables

  • Updated CSS documentation for sidebar border implementation

  • Fixed mobile menu breakpoint to match sidebar hide breakpoint (1024px)

  • Mobile hamburger menu now shows whenever sidebar is hidden

  • add MIT Licensed. Do whatevs.

  • Blog page view mode toggle (list and card views)

  • Post cards component with thumbnails, titles, excerpts, and metadata

  • View preference saved to localStorage

  • Default view mode configurable in siteConfig.blogPage.viewMode

  • Toggle visibility controlled by siteConfig.blogPage.showViewToggle

  • Responsive grid: 3 columns (desktop), 2 columns (tablet), 1 column (mobile)

  • Theme-aware styling for all four themes

  • Raw markdown files now accessible to AI crawlers (ChatGPT, Perplexity)

  • Added /raw/ path bypass in botMeta edge function

  • Sitemap now includes static pages (about, docs, contact, etc.)

  • Security headers added to netlify.toml

  • Link header pointing to llms.txt for AI discovery

  • Preconnect hints for Convex backend

  • Fixed URL consistency in openapi.yaml and robots.txt

  • Write conflict prevention: increased dedup windows, added heartbeat jitter

  • Visitor map styling: removed box-shadow, increased land dot contrast and opacity

  • Real-time visitor map on stats page showing live visitor locations

  • Netlify edge function for geo detection (geo.ts)

  • VisitorMap component with dotted world map and pulsing dots

  • Theme-aware colors for all four themes (dark, light, tan, cloud)

  • visitorMap config option in siteConfig.ts to enable/disable

  • Privacy friendly: no IP addresses stored, only city/country/coordinates

  • Documentation updated: setup-guide, docs, FORK_CONFIG, fork-config.json.example

  • Author display for posts and pages with authorName and authorImage frontmatter fields

  • Round avatar image displayed next to date and read time on post/page views

  • Write page updated with new frontmatter field reference

  • Documentation updated: setup-guide.md, docs.md, files.md, README.md, AGENTS.md

  • PRD created: prds/howto-Frontmatter.md with reusable prompt for future updates

  • GitHub Stars card on Stats page with live count from repository

  • CopyPageDropdown AI services now use raw markdown URLs for better AI parsing

  • ChatGPT, Claude, and Perplexity receive /raw/{slug}.md URLs instead of page URLs

  • Automated fork configuration with npm run configure

  • FORK_CONFIG.md comprehensive guide with two options (automated + manual)

  • fork-config.json.example template with all configuration options

  • scripts/configure-fork.ts for automated updates

  • Updates all 11 configuration files in one command

  • GitHub contributions graph on homepage with theme-aware colors

  • Year navigation with Phosphor icons (CaretLeft, CaretRight)

  • Click graph to visit GitHub profile

  • Configurable via siteConfig.gitHubContributions

  • Theme-specific contribution colors for all 4 themes

  • Mobile responsive design with scaled cells

  • Public /write page with three-column layout (not linked in nav)

  • Left sidebar: Home link, content type selector, actions (Clear, Theme, Font)

  • Center: Writing area with Copy All button and borderless textarea

  • Right sidebar: Frontmatter reference with per-field copy buttons

  • Font switcher to toggle between Serif and Sans-serif fonts

  • Font preference persistence in localStorage

  • Theme toggle icons matching ThemeToggle.tsx (Moon, Sun, Half2Icon, Cloud)

  • Content type switching (Blog Post/Page) updates writing area template

  • Word, line, and character counts in status bar

  • Warning banner about refresh losing content

  • localStorage persistence for content, type, and font

  • Redesign /write page with three-column Cursor docs-style layout

  • Add per-field copy icons to frontmatter reference panel

  • Add refresh warning message in left sidebar

  • Left sidebar with home link, content type selector, and actions

  • Right sidebar with frontmatter fields and copy buttons

  • Center area with title, Copy All button, and borderless textarea

  • Theme toggle with matching icons for all four themes

  • Redesign /write page with wider layout and modern Notion-like UI

  • Remove header from /write page (standalone writing experience)

  • Add inline theme toggle and home link to Write page toolbar

  • Collapsible frontmatter fields panel

  • Add markdown write page with copy option at /write

  • Centralized font-size CSS variables in global.css

  • Base size scale with semantic naming (3xs to hero)

  • Component-specific font-size variables

  • Mobile responsive font-size overrides

  • Open Graph image fix for posts and pages with frontmatter images

  • Dedicated blog page with configurable display options

  • Blog page navigation order via siteConfig.blogPage.order

  • Centralized siteConfig.ts for site configuration

  • Posts display toggle for homepage and/or blog page

  • move home to the top of the mobile menu

  • Fork configuration documentation in docs.md and setup-guide.md

  • "Files to Update When Forking" section with all 9 configuration files

  • Backend configuration examples for Convex files

  • Site branding updates across all AI discovery files

  • Fork documentation added to README.md

  • Blog post updated with v1.9.0 and v1.10.0 features

  • Scroll-to-top button with configurable threshold

  • Scroll-to-top documentation in docs.md and setup-guide.md

  • Mobile menu with hamburger navigation for mobile and tablet

  • Generate Skill feature in CopyPageDropdown

  • Project setup with Vite + React + TypeScript

  • Convex schema for posts, viewCounts, siteConfig, pages

  • Build-time markdown sync script

  • Theme system (dark/light/tan/cloud)

  • Default theme configuration (tan)

  • Home page with year-grouped post list

  • Post page with markdown rendering

  • Static pages support (About, Projects, Contact)

  • Syntax highlighting for code blocks

  • Open Graph and Twitter Card meta tags

  • Netlify edge function for bot detection

  • RSS feed support (standard and full content)

  • API endpoints for LLMs (/api/posts, /api/post)

  • Copy Page dropdown for AI tools

  • Sample blog posts and pages

  • Security audit completed

  • TypeScript type-safety verification

  • Netlify build configuration verified

  • SPA 404 fallback configured

  • Mobile responsive design

  • Edge functions for dynamic Convex HTTP proxying

  • Vite dev server proxy for local development

  • Real-time stats page at /stats

  • Page view tracking with event records pattern

  • Active session heartbeat system

  • Cron job for stale session cleanup

  • Stats link in homepage footer

  • Real-time search with Command+K shortcut

  • Search modal with keyboard navigation

  • Full text search indexes for posts and pages

  • Featured section with list/card view toggle

  • Logo gallery with continuous marquee scroll

  • Frontmatter-controlled featured items (featured, featuredOrder)

  • Featured items sync with npm run sync (no redeploy needed)

  • Firecrawl content importer (npm run import)

  • /api/export endpoint for batch content fetching

  • AI plugin discovery at /.well-known/ai-plugin.json

  • OpenAPI 3.0 spec at /openapi.yaml

  • AGENTS.md for AI coding agents

  • Static raw markdown files at /raw/{slug}.md

  • View as Markdown option in CopyPageDropdown

  • Perplexity added to AI service options

  • Featured image support with square thumbnails in card view

  • Improved markdown table CSS styling

  • Aggregate component integration for efficient stats counting (O(log n) vs O(n))

  • Three aggregate components: pageViewsByPath, totalPageViews, uniqueVisitors

  • Chunked backfilling mutation for existing page view data

  • Aggregate component registration in convex.config.ts

  • Stats query updated to use aggregate counts

  • Aggregate component documentation in prds/howstatsworks.md

  • Sidebar navigation anchor links fixed for collapsed/expanded sections

  • Navigation scroll calculation with proper header offset (80px)

  • Expand ancestors before scrolling to ensure target visibility

  • Removed auto-expand from scroll handler to preserve manual collapse state

  • Collapse button event handling improved to prevent link navigation

  • Heading extraction updated to filter out code blocks

  • Sidebar no longer shows example headings from markdown code examples

  • Mobile menu redesigned with left-aligned navigation controls

  • Hamburger menu order changed (hamburger, search, theme toggle)

  • Sidebar table of contents integrated into mobile menu

  • Desktop sidebar hidden on mobile when sidebar layout is enabled

  • SidebarContext created to share sidebar data between components

  • Mobile menu typography standardized with CSS variables

  • Font-family standardized using inherit for consistency

  • showInNav field for pages to control navigation visibility

  • Pages can be published but hidden from navigation menu

  • Defaults to true for backwards compatibility

  • Pages with showInNav: false remain accessible via direct URL, searchable, and available via API

  • Hardcoded navigation items configuration in siteConfig.ts

  • Add React route pages (like /stats, /write) to navigation via hardcodedNavItems

  • Configure navigation order, title, and visibility per route

  • Navigation combines Blog link, hardcoded nav items, and markdown pages

  • All nav items sorted by order field (lower = first)

Deployment Steps

  1. Run npx convex dev to initialize Convex
  2. Set CONVEX_DEPLOY_KEY in Netlify environment variables
  3. Connect repo to Netlify and deploy
  4. Edge functions automatically handle RSS, sitemap, and API routes

Someday Features TBD

  • Newsletter signup
  • Comments system
  • Draft preview mode