diff --git a/.claude/commands/plan.md b/.claude/commands/plan.md index 6cd1b04..1dda2c5 100644 --- a/.claude/commands/plan.md +++ b/.claude/commands/plan.md @@ -11,7 +11,7 @@ Given the implementation details provided as an argument, do this: - Success criteria and acceptance criteria - Any technical constraints or dependencies mentioned -3. Read the constitution at `/memory/constitution.md` to understand constitutional requirements. +3. Read the constitution at `.claude/constitution.md` to understand constitutional requirements. 4. Execute the implementation plan template: - Load `/templates/implementation-plan-template.md` (already copied to IMPL_PLAN path) diff --git a/.claude/features/analytics-events-tracking/tasks.md b/.claude/features/analytics-events-tracking/tasks.md deleted file mode 100644 index 4488ea6..0000000 --- a/.claude/features/analytics-events-tracking/tasks.md +++ /dev/null @@ -1,464 +0,0 @@ -# Analytics Events Tracking - Implementation Tasks - -**Feature**: Analytics Events Tracking for nodejsdesignpatterns.com -**Branch**: `feat/analytics-events-tracking` -**Goal**: Implement comprehensive GA4 event tracking to measure user engagement and conversions - ---- - -## Overview - -The site currently has basic GA4 setup (property G-NFE37ZH2W3) via Partytown but lacks custom event tracking. Based on analytics analysis, we need to track: - -- Book purchase intent (buy button views + clicks → CTR) -- Free chapter downloads (form views + submissions → conversion rate) -- Blog CTA performance (views + clicks → CTR) -- Outbound link clicks (Amazon, Packt, etc.) -- Blog engagement (scroll depth, read completion) -- Internal navigation patterns - -### Tracking Philosophy - -For all CTAs, we track both **impressions** (view events via Intersection Observer) and **actions** (click/submit events). This enables calculating click-through rates and conversion rates, not just absolute numbers. - ---- - -## Tasks - -### Phase 1: Setup & Infrastructure - -#### T001 - Create Analytics Utility Module [P] -**File**: `src/lib/analytics.ts` -**Description**: Create a TypeScript module with type-safe helper functions for sending GA4 events via gtag. Must handle Partytown's async nature. - -**Requirements**: -- Export typed `trackEvent()` function that wraps `gtag('event', ...)` -- Handle window.gtag potentially being undefined (Partytown delay) -- Define TypeScript interfaces for all event parameters -- Include event name constants to prevent typos - -**Events to support**: -```typescript -type AnalyticsEvent = - // Conversion events - | 'view_buy_buttons' - | 'click_buy_button' - | 'view_free_chapter_form' - | 'submit_free_chapter_form' - // Engagement events - | 'click_outbound_link' - | 'scroll_depth' - | 'blog_read_complete' - // CTA events (view + click for CTR calculation) - | 'view_blog_cta' - | 'click_blog_cta' -``` - ---- - -#### T002 - Define Event Schema Documentation [P] -**File**: `src/lib/analytics.ts` (inline JSDoc) or `.claude/features/analytics-events-tracking/events-schema.md` -**Description**: Document all custom events with their parameters for future reference. - -**Requirements**: -- Event name -- When it fires -- Parameters and their types -- Expected values - ---- - -### Phase 2: Core Conversion Events - -#### T003 - Track Buy Button Views and Clicks -**Files**: -- `src/components/pages/Home/components/BuyButtons.astro` -- `src/components/blog/BookPromo.astro` - -**Description**: Track when buy buttons become visible (impression) and when clicked. This enables CTR calculation. - -**Event Schema**: -```javascript -// Fired when buttons enter viewport (once per page load) -gtag('event', 'view_buy_buttons', { - source_page: '/blog/some-article' | '/', - button_location: 'hero' | 'sidebar' | 'footer' | 'blog_promo' -}) - -// Fired on click -gtag('event', 'click_buy_button', { - book_format: 'print' | 'ebook', - source_page: '/blog/some-article' | '/', - button_location: 'hero' | 'sidebar' | 'footer' | 'blog_promo' -}) -``` - -**Implementation**: -- Use Intersection Observer to track when buttons enter viewport -- Fire `view_buy_buttons` once per page load when visible -- Add `onclick` handlers for click tracking -- Pass format ('print' or 'ebook') based on button clicked -- Include page path for attribution - -**Metrics enabled**: -- Buy button CTR = `click_buy_button` / `view_buy_buttons` -- Format preference = print clicks vs ebook clicks - ---- - -#### T004 - Track Free Chapter Form Views and Submissions -**File**: `src/components/pages/Home/FreeChapter.astro` - -**Description**: Track when the free chapter form becomes visible (impression) and when submitted. This enables conversion rate calculation. - -**Event Schema**: -```javascript -// Fired when form section enters viewport (once per page load) -gtag('event', 'view_free_chapter_form', { - form_location: 'homepage_free_chapter_section' -}) - -// Fired on form submission -gtag('event', 'submit_free_chapter_form', { - form_location: 'homepage_free_chapter_section' -}) -``` - -**Implementation**: -- Use Intersection Observer to track when form enters viewport -- Fire `view_free_chapter_form` once per page load when visible -- Add `onsubmit` handler to the form -- Fire `submit_free_chapter_form` before form submission (form posts to external Kit.com) -- Consider also tracking form field focus as a micro-conversion - -**Metrics enabled**: -- Form conversion rate = `submit_free_chapter_form` / `view_free_chapter_form` - ---- - -#### T005 - Track Outbound Link Clicks -**Files**: -- `src/components/pages/Home/components/BuyButtons.astro` -- `src/components/blog/BookPromo.astro` -- `src/components/Footer.astro` - -**Description**: Track clicks on links that leave the site (Amazon, Packt, social profiles, etc.) - -**Event Schema**: -```javascript -gtag('event', 'click_outbound_link', { - link_url: 'https://amazon.com/...', - link_domain: 'amazon.com', - link_text: 'Buy print', - source_page: window.location.pathname -}) -``` - -**Implementation**: -- Can use event delegation at document level -- Filter for links with `href` starting with `http` but not matching site domain -- Extract domain from URL for grouping in reports - ---- - -### Phase 3: Engagement Events - -#### T006 - Track Scroll Depth on Blog Posts [P] -**File**: `src/components/blog/BlogLayout.astro` (new script) - -**Description**: Track how far users scroll on blog articles (25%, 50%, 75%, 100%) - -**Event Schema**: -```javascript -gtag('event', 'scroll_depth', { - percent_scrolled: 25 | 50 | 75 | 100, - page_path: '/blog/reading-writing-files-nodejs', - content_type: 'blog_post' -}) -``` - -**Implementation**: -- Use Intersection Observer for performance -- Only fire each threshold once per page load -- Only implement on blog pages (check route) - ---- - -#### T007 - Track Blog Read Completion [P] -**File**: `src/components/blog/BlogLayout.astro` - -**Description**: Fire event when user reaches the end of a blog post (indicates genuine read) - -**Event Schema**: -```javascript -gtag('event', 'blog_read_complete', { - page_path: '/blog/reading-writing-files-nodejs', - estimated_read_time: 8, // minutes - time_on_page: 240 // seconds actually spent -}) -``` - -**Implementation**: -- Trigger when user scrolls to article footer or "related posts" section -- Track time spent on page for validation -- Helps identify content quality vs. bounce rate - ---- - -#### T008 - Track Blog CTA Views and Clicks (with Variant Tracking) -**File**: `src/components/blog/BookPromo.astro` - -**Description**: Track when the book promo card becomes visible (impression) and when clicked. The component has **10 different variants** (promo01-promo10) with unique images and messages that are randomly selected. We need to track which variant performs best. - -**Current variants** (from `BookPromo.astro`): -- `promo01` - "Get the Node.js Design Patterns book. Your playbook to senior-level Node.js." -- `promo02` - "Buy Node.js Design Patterns and master async, streams, and scaling Node.js." -- `promo03` - "Upgrade your Node.js skills: get the book professional developers trust." -- `promo04` - "Join 30,000+ developers. Get the book they use to level up..." -- `promo05` - "The Node.js book with 4.6★ from 780+ reviews. Get your copy." -- `promo06` - "732 pages. 170 examples. 54 exercises..." -- `promo07` - "Stop stitching together half-baked tutorials..." -- `promo08` - "Master all there is to know about Node.js..." -- `promo09` - "Build production-grade Node.js with confidence..." -- `promo10` - "Serious about Node.js? This is the book..." - -**Event Schema**: -```javascript -// Fired when promo card enters viewport (once per page load) -gtag('event', 'view_blog_cta', { - cta_type: 'book_promo_card', - cta_position: 'sidebar', - cta_variant: 'promo05', // variant ID for A/B analysis - page_path: window.location.pathname -}) - -// Fired on click -gtag('event', 'click_blog_cta', { - cta_type: 'book_promo_card', - cta_position: 'sidebar', - cta_variant: 'promo05', // same variant ID - page_path: window.location.pathname -}) -``` - -**Implementation**: -- Extract variant ID from the selected promo key (e.g., `promo05` from `/src/images/promo/promo05.png`) -- Pass variant ID to the client via `data-variant` attribute on the promo card -- Use Intersection Observer to track when promo card enters viewport -- Fire `view_blog_cta` once per page load when visible -- Add click handler to track `click_blog_cta` -- Both events must include the same `cta_variant` for accurate CTR calculation - -**Metrics enabled**: -- Blog CTA CTR by variant = `click_blog_cta (variant X)` / `view_blog_cta (variant X)` -- Best performing variant identification -- Variant performance by blog post (some messages may resonate better with certain content) - -**Future optimization**: -Once we have enough data, we can adjust the random selection to favor higher-performing variants (weighted random selection). - ---- - -### Phase 4: Navigation & Discovery Events - -#### T009 - Track Internal Navigation Patterns [P] -**File**: `src/Layout.astro` or new `src/scripts/analytics-navigation.ts` - -**Description**: Track navigation between key sections (blog, homepage, chapters) - -**Event Schema**: -```javascript -gtag('event', 'internal_navigation', { - from_page: '/', - to_page: '/blog', - navigation_type: 'header_link' | 'footer_link' | 'inline_link' -}) -``` - -**Implementation**: -- Use click event delegation -- Only track internal links (same domain) -- Categorize by navigation location - ---- - -#### T010 - Track Chapter Section Engagement -**File**: `src/components/pages/Home/Chapters.astro` - -**Description**: Track when users interact with the chapters accordion/section - -**Event Schema**: -```javascript -gtag('event', 'view_chapter_details', { - chapter_number: 6, - chapter_title: 'Coding with Streams' -}) -``` - ---- - -### Phase 5: Testing & Validation - -#### T011 - Add GA4 Debug Mode Helper -**File**: `src/lib/analytics.ts` - -**Description**: Add development helper to enable GA4 debug mode and log events to console - -**Requirements**: -- Check for `?debug_analytics=true` URL param or dev environment -- Log all events to console with formatted output -- Enable GA4 debug mode for DebugView in GA4 interface - ---- - -#### T012 - Create Analytics Test Page (Dev Only) -**File**: `src/pages/dev/analytics-test.astro` (add to .gitignore or protect) - -**Description**: Create a test page that triggers all events for validation - -**Requirements**: -- Buttons to trigger each event type -- Display console output -- Only accessible in development - ---- - -#### T013 - Validate Events in GA4 DebugView -**Description**: Manual testing task - verify all events appear correctly in GA4 - -**Checklist**: -- [ ] `view_buy_buttons` fires when buttons enter viewport -- [ ] `click_buy_button` fires with correct format parameter -- [ ] `view_free_chapter_form` fires when form enters viewport -- [ ] `submit_free_chapter_form` fires on form submission -- [ ] `click_outbound_link` captures external links -- [ ] `scroll_depth` fires at correct thresholds (25/50/75/100%) -- [ ] `blog_read_complete` fires at article end -- [ ] `view_blog_cta` fires when promo card enters viewport with correct `cta_variant` -- [ ] `click_blog_cta` fires on promo card click with matching `cta_variant` -- [ ] Variant ID matches between view and click events for the same page load -- [ ] All events have correct page attribution -- [ ] View events only fire once per page load - ---- - -### Phase 6: Documentation & Cleanup - -#### T014 - Update README with Analytics Documentation [P] -**File**: `README.md` or `.claude/features/analytics-events-tracking/README.md` - -**Description**: Document the analytics implementation for future maintainers - -**Include**: -- List of all custom events -- How to add new events -- How to test events -- GA4 property ID and access info - ---- - -#### T015 - Create GA4 Custom Dimensions (Manual) -**Description**: Configure custom dimensions in GA4 admin for richer reporting - -**Dimensions to create**: -- `book_format` (event-scoped) - "print" or "ebook" -- `button_location` (event-scoped) - "hero", "sidebar", "footer", "blog_promo" -- `content_type` (event-scoped) - "blog_post", "homepage", etc. -- `cta_variant` (event-scoped) - "promo01" through "promo10" for A/B analysis -- `cta_position` (event-scoped) - "sidebar", "inline", etc. - ---- - -## Parallel Execution Guide - -The following tasks can be executed in parallel as they modify different files: - -### Parallel Group 1 (Infrastructure) -``` -T001 - Analytics Utility Module -T002 - Event Schema Documentation -``` - -### Parallel Group 2 (Conversion Events) -``` -T003 - Buy Button Clicks -T004 - Free Chapter Form -T005 - Outbound Links -``` - -### Parallel Group 3 (Engagement) -``` -T006 - Scroll Depth (blog) -T007 - Read Completion (blog) -T008 - Blog CTA Clicks -``` - -### Parallel Group 4 (Final) -``` -T011 - Debug Mode Helper -T014 - Documentation -``` - ---- - -## Dependencies - -``` -T001 (Analytics Module) - └── T003, T004, T005, T006, T007, T008, T009, T010 (all event implementations) - └── T011 (Debug Helper) - └── T012, T013 (Testing) - └── T014, T015 (Documentation) -``` - ---- - -## Files Modified Summary - -| File | Tasks | -|------|-------| -| `src/lib/analytics.ts` (NEW) | T001, T002, T011 | -| `src/components/pages/Home/components/BuyButtons.astro` | T003, T005 | -| `src/components/blog/BookPromo.astro` | T003, T005, T008 | -| `src/components/pages/Home/FreeChapter.astro` | T004 | -| `src/components/Footer.astro` | T005 | -| `src/components/blog/BlogLayout.astro` | T006, T007 | -| `src/components/pages/Home/Chapters.astro` | T010 | -| `src/Layout.astro` | T009 | - ---- - -## Success Metrics - -After implementation, we should be able to answer: - -1. **What's the buy button CTR?** (`click_buy_button` / `view_buy_buttons`) and which format is preferred -2. **What's the free chapter form conversion rate?** (`submit_free_chapter_form` / `view_free_chapter_form`) -3. **What's the blog CTA CTR?** (`click_blog_cta` / `view_blog_cta`) and which promo messages perform best -4. **Which blog posts drive the most purchase intent?** (clicks by page_path) -5. **How engaged are blog readers?** (scroll depth distribution, completion rate) -6. **What's the user journey?** (navigation patterns to purchase) - -### Example Calculated Metrics - -| Metric | Formula | -|--------|---------| -| Buy Button CTR | `click_buy_button` ÷ `view_buy_buttons` | -| Free Chapter Conversion | `submit_free_chapter_form` ÷ `view_free_chapter_form` | -| Blog CTA CTR | `click_blog_cta` ÷ `view_blog_cta` | -| **Blog CTA CTR by Variant** | `click_blog_cta (variant X)` ÷ `view_blog_cta (variant X)` | -| Blog Completion Rate | `blog_read_complete` ÷ `page_view (blog)` | -| Print vs Ebook Preference | `click_buy_button (print)` ÷ `click_buy_button (total)` | - -### Variant Performance Analysis - -With 10 promo variants tracked, you can build a report like: - -| Variant | Views | Clicks | CTR | -|---------|-------|--------|-----| -| promo05 (ratings) | 1,200 | 48 | 4.0% | -| promo04 (social proof) | 1,150 | 41 | 3.6% | -| promo06 (stats) | 980 | 29 | 3.0% | -| ... | ... | ... | ... | - -This data can later inform weighted random selection to show higher-performing variants more frequently. diff --git a/scripts/check-task-prerequisites.sh b/scripts/check-task-prerequisites.sh new file mode 100755 index 0000000..bf800f3 --- /dev/null +++ b/scripts/check-task-prerequisites.sh @@ -0,0 +1,130 @@ +#!/usr/bin/env bash +set -euo pipefail + +# check-task-prerequisites.sh +# Checks available design documents for /tasks command. +# +# Usage: ./scripts/check-task-prerequisites.sh [--json] +# +# Exit codes: +# 0 - Success +# 1 - Not in git repository root +# 2 - Not on a feature branch (feat/*) +# 3 - Feature directory not found +# 4 - plan.md not found (required prerequisite) + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" + +# Parse arguments +JSON_OUTPUT=false + +while [[ $# -gt 0 ]]; do + case "$1" in + --json) + JSON_OUTPUT=true + shift + ;; + *) + shift + ;; + esac +done + +# Helper function to output messages +output() { + if [[ "$JSON_OUTPUT" == true ]]; then + return + fi + echo "$1" >&2 +} + +# Helper function to output error and exit +error_exit() { + local code=$1 + local message=$2 + if [[ "$JSON_OUTPUT" == true ]]; then + echo "{\"error\": \"$message\", \"code\": $code}" + else + echo "Error: $message" >&2 + fi + exit "$code" +} + +# Validate repo root (check for .git directory) +if [[ ! -d "$REPO_ROOT/.git" ]]; then + error_exit 1 "Not in a git repository root. Run from repository root." +fi + +# Get current branch name +CURRENT_BRANCH=$(git -C "$REPO_ROOT" rev-parse --abbrev-ref HEAD) + +# Validate on feature branch (feat/*) +if [[ ! "$CURRENT_BRANCH" =~ ^feat/ ]]; then + error_exit 2 "Not on a feature branch. Current branch: $CURRENT_BRANCH. Expected: feat/*" +fi + +# Extract feature slug from branch name +SLUG="${CURRENT_BRANCH#feat/}" +FEATURE_DIR="$REPO_ROOT/.claude/features/$SLUG" + +output "Feature slug: $SLUG" +output "Feature directory: $FEATURE_DIR" + +# Verify feature directory exists +if [[ ! -d "$FEATURE_DIR" ]]; then + error_exit 3 "Feature directory not found: $FEATURE_DIR" +fi + +# Verify plan.md exists (required prerequisite) +PLAN_FILE="$FEATURE_DIR/plan.md" +if [[ ! -f "$PLAN_FILE" ]]; then + error_exit 4 "Implementation plan not found: $PLAN_FILE. Run /plan first." +fi + +# Scan for available docs +AVAILABLE_DOCS=() + +# Check for standard documents +[[ -f "$FEATURE_DIR/spec.md" ]] && AVAILABLE_DOCS+=("$FEATURE_DIR/spec.md") +[[ -f "$FEATURE_DIR/plan.md" ]] && AVAILABLE_DOCS+=("$FEATURE_DIR/plan.md") +[[ -f "$FEATURE_DIR/research.md" ]] && AVAILABLE_DOCS+=("$FEATURE_DIR/research.md") +[[ -f "$FEATURE_DIR/data-model.md" ]] && AVAILABLE_DOCS+=("$FEATURE_DIR/data-model.md") +[[ -f "$FEATURE_DIR/quickstart.md" ]] && AVAILABLE_DOCS+=("$FEATURE_DIR/quickstart.md") + +# Check for contracts directory and files +if [[ -d "$FEATURE_DIR/contracts" ]]; then + while IFS= read -r -d '' contract_file; do + AVAILABLE_DOCS+=("$contract_file") + done < <(find "$FEATURE_DIR/contracts" -type f -name "*.md" -print0 2>/dev/null || true) +fi + +# Output JSON result +if [[ "$JSON_OUTPUT" == true ]]; then + # Build JSON array of available docs + JSON_DOCS="[" + first=true + for doc in "${AVAILABLE_DOCS[@]}"; do + if [[ "$first" == true ]]; then + first=false + else + JSON_DOCS+=", " + fi + JSON_DOCS+="\"$doc\"" + done + JSON_DOCS+="]" + + echo "{\"FEATURE_DIR\": \"$FEATURE_DIR\", \"AVAILABLE_DOCS\": $JSON_DOCS, \"BRANCH\": \"$CURRENT_BRANCH\", \"SLUG\": \"$SLUG\"}" +else + echo "" + echo "Task prerequisites check passed." + echo " Branch: $CURRENT_BRANCH" + echo " Feature directory: $FEATURE_DIR" + echo "" + echo "Available documents:" + for doc in "${AVAILABLE_DOCS[@]}"; do + echo " - $(basename "$doc")" + done + echo "" + echo "Ready to generate tasks from these documents." +fi diff --git a/scripts/create-new-feature.sh b/scripts/create-new-feature.sh new file mode 100755 index 0000000..ab8d77c --- /dev/null +++ b/scripts/create-new-feature.sh @@ -0,0 +1,138 @@ +#!/usr/bin/env bash +set -euo pipefail + +# create-new-feature.sh +# Creates a new feature branch and specification directory for SDD workflow. +# +# Usage: ./scripts/create-new-feature.sh [--json] "Feature Description" +# +# Exit codes: +# 0 - Success +# 1 - Missing arguments +# 2 - Not in git repository root +# 3 - Git working directory not clean +# 4 - Branch already exists +# 5 - Feature directory already exists + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" + +# Parse arguments +JSON_OUTPUT=false +FEATURE_DESC="" + +while [[ $# -gt 0 ]]; do + case "$1" in + --json) + JSON_OUTPUT=true + shift + ;; + *) + FEATURE_DESC="$1" + shift + ;; + esac +done + +# Helper function to output messages +output() { + if [[ "$JSON_OUTPUT" == true ]]; then + return + fi + echo "$1" >&2 +} + +# Helper function to output error and exit +error_exit() { + local code=$1 + local message=$2 + if [[ "$JSON_OUTPUT" == true ]]; then + echo "{\"error\": \"$message\", \"code\": $code}" + else + echo "Error: $message" >&2 + fi + exit "$code" +} + +# Validate arguments +if [[ -z "$FEATURE_DESC" ]]; then + error_exit 1 "Missing feature description. Usage: $0 [--json] \"Feature Description\"" +fi + +# Validate repo root (check for .git directory) +if [[ ! -d "$REPO_ROOT/.git" ]]; then + error_exit 2 "Not in a git repository root. Run from repository root." +fi + +# Check git working directory is clean +if [[ -n "$(git -C "$REPO_ROOT" status --porcelain)" ]]; then + error_exit 3 "Git working directory is not clean. Commit or stash changes first." +fi + +# Generate kebab-case slug from feature description +generate_slug() { + local desc="$1" + echo "$desc" | \ + tr '[:upper:]' '[:lower:]' | \ + sed 's/[^a-z0-9 ]//g' | \ + sed 's/ */ /g' | \ + sed 's/^ *//;s/ *$//' | \ + tr ' ' '-' +} + +SLUG=$(generate_slug "$FEATURE_DESC") +BRANCH_NAME="feat/$SLUG" +FEATURE_DIR="$REPO_ROOT/.claude/features/$SLUG" +SPEC_FILE="$FEATURE_DIR/spec.md" +TEMPLATE_FILE="$REPO_ROOT/templates/spec-template.md" + +output "Feature slug: $SLUG" +output "Branch name: $BRANCH_NAME" + +# Verify branch doesn't exist (local or remote) +if git -C "$REPO_ROOT" show-ref --verify --quiet "refs/heads/$BRANCH_NAME" 2>/dev/null; then + error_exit 4 "Local branch '$BRANCH_NAME' already exists." +fi + +if git -C "$REPO_ROOT" show-ref --verify --quiet "refs/remotes/origin/$BRANCH_NAME" 2>/dev/null; then + error_exit 4 "Remote branch 'origin/$BRANCH_NAME' already exists." +fi + +# Verify feature directory doesn't exist +if [[ -d "$FEATURE_DIR" ]]; then + error_exit 5 "Feature directory '$FEATURE_DIR' already exists." +fi + +# Create feature directory +output "Creating feature directory: $FEATURE_DIR" +mkdir -p "$FEATURE_DIR" + +# Copy spec template if it exists, otherwise create a placeholder +if [[ -f "$TEMPLATE_FILE" ]]; then + cp "$TEMPLATE_FILE" "$SPEC_FILE" + output "Copied spec template to: $SPEC_FILE" +else + # Create a minimal placeholder if template doesn't exist + echo "# Feature Specification: $FEATURE_DESC" > "$SPEC_FILE" + echo "" >> "$SPEC_FILE" + echo "" >> "$SPEC_FILE" + output "Warning: Template not found, created placeholder spec file" +fi + +# Create and checkout feature branch +output "Creating and checking out branch: $BRANCH_NAME" +git -C "$REPO_ROOT" checkout -b "$BRANCH_NAME" + +# Output JSON result +if [[ "$JSON_OUTPUT" == true ]]; then + echo "{\"BRANCH_NAME\": \"$BRANCH_NAME\", \"SPEC_FILE\": \"$SPEC_FILE\", \"FEATURE_DIR\": \"$FEATURE_DIR\", \"SLUG\": \"$SLUG\"}" +else + echo "" + echo "Success! Created feature branch and specification." + echo " Branch: $BRANCH_NAME" + echo " Spec file: $SPEC_FILE" + echo "" + echo "Next steps:" + echo " 1. Edit the specification file" + echo " 2. Run /plan to create an implementation plan" +fi diff --git a/scripts/setup-plan.sh b/scripts/setup-plan.sh new file mode 100755 index 0000000..3250bea --- /dev/null +++ b/scripts/setup-plan.sh @@ -0,0 +1,116 @@ +#!/usr/bin/env bash +set -euo pipefail + +# setup-plan.sh +# Locates current feature context and sets up implementation plan file for /plan command. +# +# Usage: ./scripts/setup-plan.sh [--json] +# +# Exit codes: +# 0 - Success +# 1 - Not in git repository root +# 2 - Not on a feature branch (feat/*) +# 3 - Feature directory not found +# 4 - spec.md not found + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" + +# Parse arguments +JSON_OUTPUT=false + +while [[ $# -gt 0 ]]; do + case "$1" in + --json) + JSON_OUTPUT=true + shift + ;; + *) + shift + ;; + esac +done + +# Helper function to output messages +output() { + if [[ "$JSON_OUTPUT" == true ]]; then + return + fi + echo "$1" >&2 +} + +# Helper function to output error and exit +error_exit() { + local code=$1 + local message=$2 + if [[ "$JSON_OUTPUT" == true ]]; then + echo "{\"error\": \"$message\", \"code\": $code}" + else + echo "Error: $message" >&2 + fi + exit "$code" +} + +# Validate repo root (check for .git directory) +if [[ ! -d "$REPO_ROOT/.git" ]]; then + error_exit 1 "Not in a git repository root. Run from repository root." +fi + +# Get current branch name +CURRENT_BRANCH=$(git -C "$REPO_ROOT" rev-parse --abbrev-ref HEAD) + +# Validate on feature branch (feat/*) +if [[ ! "$CURRENT_BRANCH" =~ ^feat/ ]]; then + error_exit 2 "Not on a feature branch. Current branch: $CURRENT_BRANCH. Expected: feat/*" +fi + +# Extract feature slug from branch name +SLUG="${CURRENT_BRANCH#feat/}" +FEATURE_DIR="$REPO_ROOT/.claude/features/$SLUG" +SPEC_FILE="$FEATURE_DIR/spec.md" +PLAN_FILE="$FEATURE_DIR/plan.md" +TEMPLATE_FILE="$REPO_ROOT/templates/implementation-plan-template.md" + +output "Feature slug: $SLUG" +output "Feature directory: $FEATURE_DIR" + +# Verify feature directory exists +if [[ ! -d "$FEATURE_DIR" ]]; then + error_exit 3 "Feature directory not found: $FEATURE_DIR" +fi + +# Verify spec.md exists +if [[ ! -f "$SPEC_FILE" ]]; then + error_exit 4 "Specification file not found: $SPEC_FILE" +fi + +# Copy implementation plan template if plan.md doesn't exist +if [[ ! -f "$PLAN_FILE" ]]; then + if [[ -f "$TEMPLATE_FILE" ]]; then + cp "$TEMPLATE_FILE" "$PLAN_FILE" + output "Copied implementation plan template to: $PLAN_FILE" + else + # Create a minimal placeholder if template doesn't exist + echo "# Implementation Plan" > "$PLAN_FILE" + echo "" >> "$PLAN_FILE" + echo "" >> "$PLAN_FILE" + output "Warning: Template not found, created placeholder plan file" + fi +else + output "Plan file already exists: $PLAN_FILE" +fi + +# Output JSON result +if [[ "$JSON_OUTPUT" == true ]]; then + echo "{\"FEATURE_SPEC\": \"$SPEC_FILE\", \"IMPL_PLAN\": \"$PLAN_FILE\", \"SPECS_DIR\": \"$FEATURE_DIR\", \"BRANCH\": \"$CURRENT_BRANCH\", \"SLUG\": \"$SLUG\"}" +else + echo "" + echo "Feature context located successfully." + echo " Branch: $CURRENT_BRANCH" + echo " Spec file: $SPEC_FILE" + echo " Plan file: $PLAN_FILE" + echo "" + echo "Next steps:" + echo " 1. Read the spec file and create the implementation plan" + echo " 2. Run /tasks to break down the plan into tasks" +fi diff --git a/templates/implementation-plan-template.md b/templates/implementation-plan-template.md new file mode 100644 index 0000000..406b5b4 --- /dev/null +++ b/templates/implementation-plan-template.md @@ -0,0 +1,222 @@ +# Implementation Plan: [Feature Name] + +**Feature Branch**: `feat/[slug]` +**Spec File**: `.claude/features/[slug]/spec.md` +**Created**: [Date] +**Status**: Draft + +--- + +## Technical Context + +### Stack + +- **Framework**: Astro +- **Styling**: Tailwind CSS +- **Language**: TypeScript +- **Package Manager**: pnpm +- **Deployment**: GitHub Pages via GitHub Actions + +### Existing Patterns + +- [Relevant existing pattern in the codebase] +- [Component or module to reference] +- [Coding convention to follow] + +### User-Provided Context + +[Any specific technical direction or constraints from the user's request] + +--- + +## Research Summary + +### Codebase Analysis + +- [Key finding from codebase exploration] +- [Relevant existing implementation to reference] +- [Pattern or approach already used in the project] + +### Files to Modify + +| File | Change Type | Purpose | +| ----------------------------- | ----------- | -------------- | +| `src/path/to/file.ts` | Modify | [What changes] | +| `src/path/to/new-file.ts` | Create | [What it does] | +| `src/path/to/component.astro` | Modify | [What changes] | + +### Files to Reference + +- `src/path/to/example.ts` - Example of [pattern] +- `src/path/to/similar.astro` - Similar component implementation + +--- + +## Data Model + +### Entities + +#### [Entity Name] + +```typescript +interface EntityName { + id: string + // ... fields +} +``` + +### Content Collections + +[If using Astro content collections, define the schema here] + +```typescript +// src/content.config.ts addition +const collectionName = defineCollection({ + type: 'content', + schema: z.object({ + // ... schema definition + }), +}) +``` + +--- + +## API Contracts + +### Events/Hooks + +[Define any custom events, hooks, or callbacks] + +```typescript +// Event definitions +type FeatureEvent = { + name: string + payload: { + // ... payload structure + } +} +``` + +### External Integrations + +[If integrating with external services, define contracts here] + +--- + +## Quickstart Guide + +### Prerequisites + +- Node.js v18+ +- pnpm installed +- Repository cloned + +### Dev Setup + +```bash +# Install dependencies +pnpm install + +# Start development server +pnpm dev + +# Run type checking +pnpm check +``` + +### Testing + +```bash +# Run tests (if applicable) +pnpm test + +# Build for production +pnpm build + +# Preview production build +pnpm preview +``` + +### Verification Steps + +1. [Step to verify feature works] +2. [Step to verify edge cases] +3. [Step to verify accessibility] + +--- + +## Implementation Phases + +### Phase 0: Research + +- [ ] Analyze existing codebase patterns +- [ ] Identify files to modify +- [ ] Document technical decisions +- **Output**: `research.md` + +### Phase 1: Setup + +- [ ] Create necessary directories/files +- [ ] Set up type definitions +- [ ] Configure any new dependencies +- **Output**: `data-model.md`, `contracts/`, `quickstart.md` + +### Phase 2: Core Implementation + +- [ ] Implement core functionality +- [ ] Add necessary components +- [ ] Integrate with existing code +- **Output**: Working feature + +### Phase 3: Integration + +- [ ] Connect to existing systems +- [ ] Add error handling +- [ ] Implement logging/analytics (if needed) + +### Phase 4: Polish + +- [ ] Add tests (if applicable) +- [ ] Optimize performance +- [ ] Update documentation +- [ ] Code review preparation +- **Output**: `tasks.md` + +--- + +## Risk Assessment + +| Risk | Likelihood | Impact | Mitigation | +| ------------------ | ------------ | ------------ | --------------------- | +| [Risk description] | Low/Med/High | Low/Med/High | [Mitigation strategy] | +| [Risk description] | Low/Med/High | Low/Med/High | [Mitigation strategy] | + +--- + +## Progress Tracking + +| Phase | Status | Notes | +| -------------------- | ----------- | ----- | +| Phase 0: Research | Not Started | | +| Phase 1: Setup | Not Started | | +| Phase 2: Core | Not Started | | +| Phase 3: Integration | Not Started | | +| Phase 4: Polish | Not Started | | + +--- + +## Generated Artifacts + +Checklist of artifacts to generate: + +- [ ] `research.md` - Codebase analysis and technical decisions +- [ ] `data-model.md` - Entity definitions and schemas +- [ ] `contracts/` - API contracts and event definitions (if needed) +- [ ] `quickstart.md` - Development setup and verification steps +- [ ] `tasks.md` - Detailed task breakdown for implementation + +--- + +## Notes + +[Additional notes, decisions, or context that doesn't fit elsewhere] diff --git a/templates/spec-template.md b/templates/spec-template.md new file mode 100644 index 0000000..0776c02 --- /dev/null +++ b/templates/spec-template.md @@ -0,0 +1,144 @@ +# Feature Specification: [Feature Name] + +**Version**: 1.0.0 +**Created**: [Date] +**Status**: Draft + +--- + +## Overview + +[Brief description of the feature, its purpose, and the problem it solves. 2-3 sentences maximum.] + +--- + +## User Stories + +### Primary User Story + +> As a [user type], +> I want to [action/capability], +> so that [benefit/value]. + +### Additional User Stories + +- As a [user type], I want to [action] so that [benefit]. +- As a [user type], I want to [action] so that [benefit]. + +--- + +## Functional Requirements + +| ID | Requirement | Priority | Notes | +| ------ | ------------------------- | ------------ | ----- | +| FR-001 | [Requirement description] | Must Have | | +| FR-002 | [Requirement description] | Must Have | | +| FR-003 | [Requirement description] | Should Have | | +| FR-004 | [Requirement description] | Nice to Have | | + +**Priority Key:** + +- **Must Have**: Critical for MVP, feature is incomplete without it +- **Should Have**: Important but not blocking +- **Nice to Have**: Enhances UX but can be deferred + +--- + +## Acceptance Criteria + +The feature is complete when: + +- [ ] [Specific, testable criterion] +- [ ] [Specific, testable criterion] +- [ ] [Specific, testable criterion] +- [ ] All tests pass +- [ ] Code reviewed and approved +- [ ] Documentation updated + +--- + +## Non-Functional Requirements + +### Performance + +- [Page load impact, if any] +- [Bundle size considerations] +- [Runtime performance requirements] + +### Accessibility + +- [WCAG compliance requirements] +- [Keyboard navigation requirements] +- [Screen reader considerations] + +### SEO + +- [SEO impact, if any] +- [Structured data requirements] +- [Meta tag requirements] + +### Mobile + +- [Responsive design requirements] +- [Touch interaction requirements] +- [Mobile-specific behavior] + +--- + +## Success Criteria + +### Quantitative + +- [Measurable metric, e.g., "Page load time < 2s"] +- [Measurable metric, e.g., "Form conversion rate > 5%"] + +### Qualitative + +- [Qualitative goal, e.g., "Users can complete task without confusion"] +- [Qualitative goal, e.g., "Consistent with existing design language"] + +--- + +## Technical Constraints + +### Must Use + +- [Required technology/pattern] +- [Existing component to leverage] + +### Must Avoid + +- [Anti-pattern or approach to avoid] +- [Technology constraint] + +### Dependencies + +- [External service dependency] +- [Internal module dependency] + +--- + +## Out of Scope + +The following are explicitly NOT part of this feature: + +- [Item that might be confused as in-scope] +- [Future enhancement to defer] +- [Related but separate feature] + +--- + +## Open Questions + +| # | Question | Status | Resolution | +| --- | ----------------------------------- | -------- | ---------- | +| 1 | [Question that needs clarification] | Open | | +| 2 | [Question that needs clarification] | Resolved | [Answer] | + +--- + +## References + +- [Link to related documentation] +- [Link to design mockups] +- [Link to related issues/PRs] diff --git a/templates/tasks-template.md b/templates/tasks-template.md new file mode 100644 index 0000000..c01e913 --- /dev/null +++ b/templates/tasks-template.md @@ -0,0 +1,213 @@ +# [Feature Name] - Implementation Tasks + +**Feature**: [Feature description] +**Branch**: `feat/[slug]` +**Goal**: [One-line goal statement] + +--- + +## Overview + +[2-3 sentence description of what this feature implements and the approach taken.] + +### Key Decisions + +- [Important technical decision made during planning] +- [Architecture or pattern choice] +- [Trade-off or constraint acknowledged] + +--- + +## Tasks + +### Phase 1: Setup & Infrastructure + +#### T001 - [Task Title] [P] + +**File**: `src/path/to/file.ts` +**Description**: [What this task accomplishes] + +**Requirements**: + +- [Specific requirement] +- [Specific requirement] + +**Implementation Notes**: + +- [Helpful implementation detail] +- [Reference to existing pattern] + +--- + +#### T002 - [Task Title] [P] + +**File**: `src/path/to/another-file.ts` +**Description**: [What this task accomplishes] + +**Requirements**: + +- [Specific requirement] + +--- + +### Phase 2: Core Implementation + +#### T003 - [Task Title] + +**Files**: + +- `src/path/to/file.astro` +- `src/path/to/related.ts` + +**Description**: [What this task accomplishes] + +**Requirements**: + +- [Specific requirement] +- [Specific requirement] + +**Implementation Notes**: + +```typescript +// Example code or interface if helpful +interface Example { + field: string +} +``` + +--- + +#### T004 - [Task Title] + +**File**: `src/path/to/component.astro` +**Description**: [What this task accomplishes] + +**Requirements**: + +- [Specific requirement] + +--- + +### Phase 3: Integration + +#### T005 - [Task Title] + +**File**: `src/path/to/integration.ts` +**Description**: [What this task accomplishes] + +**Requirements**: + +- [Specific requirement] + +--- + +### Phase 4: Testing & Validation + +#### T006 - [Task Title] [P] + +**File**: `src/path/to/test.ts` (if applicable) +**Description**: [Testing task description] + +**Checklist**: + +- [ ] [Test scenario 1] +- [ ] [Test scenario 2] +- [ ] [Edge case verification] + +--- + +### Phase 5: Documentation & Cleanup + +#### T007 - [Task Title] [P] + +**File**: `README.md` or relevant documentation +**Description**: [Documentation task description] + +**Include**: + +- [Documentation item] +- [Documentation item] + +--- + +## Parallel Execution Guide + +The following tasks can be executed in parallel as they modify different files: + +### Parallel Group 1 (Infrastructure) + +``` +T001 - [Task Title] +T002 - [Task Title] +``` + +### Parallel Group 2 (Core) + +``` +T003 - [Task Title] +T004 - [Task Title] +``` + +### Parallel Group 3 (Polish) + +``` +T006 - [Task Title] +T007 - [Task Title] +``` + +--- + +## Dependencies + +``` +T001 (Setup) + └── T003, T004 (Core Implementation) + └── T005 (Integration) + └── T006, T007 (Testing & Documentation) +``` + +--- + +## Files Modified Summary + +| File | Tasks | +| ----------------------------- | ---------- | +| `src/path/to/file.ts` (NEW) | T001 | +| `src/path/to/component.astro` | T003, T004 | +| `src/path/to/integration.ts` | T005 | + +--- + +## Success Metrics + +After implementation, we should be able to: + +1. **[Metric category]**: [What can be measured or verified] +2. **[Metric category]**: [What can be measured or verified] +3. **[Metric category]**: [What can be measured or verified] + +### Verification Commands + +```bash +# Build the project +pnpm build + +# Run type checking +pnpm check + +# Preview the site +pnpm preview +``` + +--- + +## Notes + +[Any additional notes, caveats, or future considerations] + +--- + +**Task Legend:** + +- `[P]` = Parallelizable - can run concurrently with other `[P]` tasks in the same phase +- Tasks without `[P]` must run sequentially or have dependencies on previous tasks