diff --git a/.gitignore b/.gitignore index a34ec91..36bf50d 100644 --- a/.gitignore +++ b/.gitignore @@ -98,11 +98,7 @@ client-dist/ output/ # Generated demo sites (auto-generated by CLI) -test-sites/**/*-demo/ -test-sites/**/*-enhanced/ -test-sites/**/*-auto/ -test-sites/**/*-temp/ -test-sites/**/*-full/ +test-sites/**/*_enhanced/ # Air temporary files tmp/ diff --git a/cmd/auto_enhance.go b/cmd/auto_enhance.go deleted file mode 100644 index a085d64..0000000 --- a/cmd/auto_enhance.go +++ /dev/null @@ -1,91 +0,0 @@ -package cmd - -import ( - "fmt" - "os" - - "github.com/insertr/insertr/internal/content" - "github.com/spf13/cobra" -) - -var ( - autoEnhanceOutput string - autoEnhanceAggressive bool -) - -var autoEnhanceCmd = &cobra.Command{ - Use: "auto-enhance [input-dir]", - Short: "Automatically detect and add insertr classes to HTML elements", - Long: `Auto-enhance scans HTML files and automatically adds insertr classes to viable content elements. - -This command uses intelligent heuristics to detect editable content: -- Text-only elements (headers, paragraphs, simple links) -- Elements with safe inline formatting (strong, em, span, etc.) -- Container elements that benefit from expansion -- Buttons and other interactive content elements - -Examples: - insertr auto-enhance ./site --output ./enhanced - insertr auto-enhance ./blog --output ./blog-enhanced --aggressive - insertr auto-enhance /path/to/site --output /path/to/enhanced`, - Args: cobra.ExactArgs(1), - RunE: runAutoEnhance, -} - -func runAutoEnhance(cmd *cobra.Command, args []string) error { - inputDir := args[0] - - // Validate input directory - if _, err := os.Stat(inputDir); os.IsNotExist(err) { - return fmt.Errorf("input directory does not exist: %s", inputDir) - } - - // Default output directory if not specified - if autoEnhanceOutput == "" { - autoEnhanceOutput = inputDir + "-enhanced" - } - - fmt.Printf("🔍 Auto-enhancing HTML files...\n") - fmt.Printf("📁 Input: %s\n", inputDir) - fmt.Printf("📁 Output: %s\n", autoEnhanceOutput) - if autoEnhanceAggressive { - fmt.Printf("⚡ Aggressive mode: enabled\n") - } - fmt.Printf("\n") - - // Create discoverer - discoverer := content.NewDiscoverer() - - // Run element discovery - result, err := discoverer.DiscoverDirectory(inputDir, autoEnhanceOutput, autoEnhanceAggressive) - if err != nil { - return fmt.Errorf("auto-enhancement failed: %w", err) - } - - // Print results - fmt.Printf("✅ Auto-enhancement complete!\n\n") - fmt.Printf("📊 Results:\n") - fmt.Printf(" Files processed: %d\n", result.FilesProcessed) - fmt.Printf(" Elements enhanced: %d\n", result.ElementsEnhanced) - fmt.Printf(" Containers added: %d\n", result.ContainersAdded) - fmt.Printf(" Individual elements: %d\n", result.IndividualsAdded) - - if len(result.SkippedFiles) > 0 { - fmt.Printf("\n⚠️ Skipped files (%d):\n", len(result.SkippedFiles)) - for _, file := range result.SkippedFiles { - fmt.Printf(" - %s\n", file) - } - } - - fmt.Printf("\n🎯 Enhanced files ready in: %s\n", autoEnhanceOutput) - fmt.Printf("📝 Use 'insertr enhance %s' to inject content from database\n", autoEnhanceOutput) - - return nil -} - -func init() { - autoEnhanceCmd.Flags().StringVarP(&autoEnhanceOutput, "output", "o", "", "output directory for enhanced files") - autoEnhanceCmd.Flags().BoolVar(&autoEnhanceAggressive, "aggressive", false, "aggressive mode: enhance single-child containers") - - rootCmd.AddCommand(autoEnhanceCmd) -} diff --git a/insertr.yaml b/insertr.yaml index 0984c80..356386f 100644 --- a/insertr.yaml +++ b/insertr.yaml @@ -13,13 +13,18 @@ server: port: 8080 # HTTP API server port sites: # Registered sites for file-based enhancement - site_id: "demo" - path: "./test-sites/demo-site" + path: "./test-sites/demo-site_enhanced" domain: "localhost:3000" auto_enhance: true backup_originals: true - - site_id: "dan-eden-test" - path: "./test-sites/simple/dan-eden-portfolio" - domain: "localhost:3001" + - site_id: "simple" + path: "./test-sites/simple/test-simple_enhanced" + domain: "localhost:3000" + auto_enhance: true + backup_originals: true + - site_id: "dan-eden" + path: "./test-sites/simple/dan-eden-portfolio_enhanced" + domain: "localhost:3000" auto_enhance: true backup_originals: true # Example additional site configuration: diff --git a/internal/api/handlers.go b/internal/api/handlers.go index 7992cee..bed2f3f 100644 --- a/internal/api/handlers.go +++ b/internal/api/handlers.go @@ -342,8 +342,15 @@ func (h *ContentHandler) CreateContent(w http.ResponseWriter, r *http.Request) { item := h.convertToAPIContent(content) // Trigger file enhancement if site is registered for auto-enhancement - if h.siteManager != nil && h.siteManager.IsAutoEnhanceEnabled(siteID) { + log.Printf("🔍 Checking auto-enhancement for site: %s", siteID) + if h.siteManager == nil { + log.Printf("❌ No site manager configured") + } else if !h.siteManager.IsAutoEnhanceEnabled(siteID) { + log.Printf("❌ Auto-enhancement not enabled for site: %s", siteID) + } else { + log.Printf("✅ Triggering auto-enhancement for site: %s", siteID) go func() { + log.Printf("🔄 Starting enhancement for site: %s", siteID) if err := h.siteManager.EnhanceSite(siteID); err != nil { log.Printf("⚠️ Failed to enhance site %s: %v", siteID, err) } else { diff --git a/internal/content/discoverer.go b/internal/content/discoverer.go index d0dbed6..64928d5 100644 --- a/internal/content/discoverer.go +++ b/internal/content/discoverer.go @@ -133,12 +133,17 @@ func (disc *Discoverer) discoverNode(node *html.Node, result *FileDiscoveryResul if disc.isGoodContainer(node) { viableChildren := engine.FindViableChildren(node) if len(viableChildren) >= 2 || (aggressive && len(viableChildren) >= 1) { - // Add insertr class to container for expansion - disc.addInsertrClass(node) + // Container expansion: add insertr class to each viable child, not the container + for _, child := range viableChildren { + if !disc.hasInsertrClass(child) { + disc.addInsertrClass(child) + result.IndividualsAdded++ + result.ElementsEnhanced++ + } + } result.ContainersAdded++ - result.ElementsEnhanced += len(viableChildren) - // Don't process children since container expansion handles them + // Don't process children since we just processed them return } } diff --git a/internal/content/enhancer.go b/internal/content/enhancer.go index 64ad0e7..d040db9 100644 --- a/internal/content/enhancer.go +++ b/internal/content/enhancer.go @@ -194,9 +194,11 @@ func (e *Enhancer) enhanceWithEngine(htmlContent []byte, filePath string) ([]byt // EnhanceInPlace performs in-place enhancement of static site files func (e *Enhancer) EnhanceInPlace(sitePath string, siteID string) error { - // TODO: Implement in-place enhancement using the unified pipeline - fmt.Printf("📄 Enhancement requested for site %s at %s (unified pipeline implementation needed)\n", siteID, sitePath) - return nil + // Update the enhancer's site ID for this operation + e.siteID = siteID + + // Use EnhanceDirectory with same input and output (in-place) + return e.EnhanceDirectory(sitePath, sitePath) } // copyFile copies a file from src to dst diff --git a/internal/content/site_manager.go b/internal/content/site_manager.go index 772acd7..f7467e9 100644 --- a/internal/content/site_manager.go +++ b/internal/content/site_manager.go @@ -108,11 +108,6 @@ func (sm *SiteManager) GetAllSites() map[string]*SiteConfig { // IsAutoEnhanceEnabled checks if a site has auto-enhancement enabled func (sm *SiteManager) IsAutoEnhanceEnabled(siteID string) bool { - // Never auto-enhance in development mode - use manual enhance button instead - if sm.devMode { - return false - } - sm.mutex.RLock() defer sm.mutex.RUnlock() diff --git a/internal/engine/engine.go b/internal/engine/engine.go index 4a79ed2..a9d1ff9 100644 --- a/internal/engine/engine.go +++ b/internal/engine/engine.go @@ -75,6 +75,12 @@ func (e *ContentEngine) ProcessContent(input ContentInput) (*ContentResult, erro } } + // 5. Inject editor assets for enhancement mode (development) + if input.Mode == Enhancement { + injector := NewInjector(e.client, input.SiteID) + injector.InjectEditorAssets(doc, true, "") + } + return &ContentResult{ Document: doc, Elements: processedElements, diff --git a/justfile b/justfile index 8559b4f..beb36ee 100644 --- a/justfile +++ b/justfile @@ -15,6 +15,15 @@ dev: build-lib build #!/usr/bin/env bash echo "🚀 Starting Full-Stack Insertr Development..." echo "================================================" + echo "" + + # Enhance demo site if needed + if [ ! -d "./test-sites/demo-site_enhanced" ]; then + echo "🔧 Demo site not ready - enhancing now..." + ./insertr enhance test-sites/demo-site --output test-sites/demo-site_enhanced --config test-sites/demo-site/insertr.yaml + echo "✅ Demo site enhanced!" + fi + echo "" echo "📝 Unified logs below (API server + Demo site):" echo "🔌 [SERVER] = API server logs" @@ -34,7 +43,7 @@ dev: build-lib build # Start API server with prefixed output echo "🔌 Starting API server (localhost:8080)..." - INSERTR_DATABASE_PATH=./dev.db ./insertr serve --dev-mode 2>&1 | sed 's/^/🔌 [SERVER] /' & + INSERTR_DATABASE_PATH=./insertr.db ./insertr serve --dev-mode 2>&1 | sed 's/^/🔌 [SERVER] /' & SERVER_PID=$! # Wait for server startup @@ -53,8 +62,8 @@ dev: build-lib build echo "📝 Full-stack ready - edit content with real-time persistence!" echo "" - # Start demo site with prefixed output (this will block) - use local installation - cd {{justfile_directory()}} && npx --prefer-offline live-server test-sites/demo-site --port=3000 --host=localhost --open=/index.html 2>&1 | sed 's/^/🌐 [DEMO] /' & + # Start enhanced demo site with prefixed output (this will block) - use local installation + cd {{justfile_directory()}} && npx --prefer-offline live-server test-sites/demo-site_enhanced --port=3000 --host=localhost --open=/index.html 2>&1 | sed 's/^/🌐 [DEMO] /' & DEMO_PID=$! # Wait for both processes @@ -67,7 +76,7 @@ dev: build-lib build dev-about: build-lib build #!/usr/bin/env bash echo "🚀 Starting full-stack development (about page)..." - INSERTR_DATABASE_PATH=./dev.db ./insertr serve --dev-mode & + INSERTR_DATABASE_PATH=./insertr.db ./insertr serve --dev-mode & SERVER_PID=$! sleep 3 npx --prefer-offline live-server test-sites/demo-site --port=3000 --host=localhost --open=/about.html @@ -98,24 +107,29 @@ demo site="": echo "" echo "💡 Note: Sites are auto-enhanced on first run" elif [ "{{site}}" = "default" ] || [ "{{site}}" = "demo" ]; then + if [ ! -d "./test-sites/demo-site_enhanced" ]; then + echo "🔧 Default demo not ready - enhancing now..." + just build + ./insertr enhance test-sites/demo-site --output test-sites/demo-site_enhanced --config test-sites/demo-site/insertr.yaml + fi echo "🚀 Starting default demo site..." - just dev + just demo-site "demo" "./test-sites/demo-site_enhanced" "3000" elif [ "{{site}}" = "dan-eden" ]; then - if [ ! -d "./test-sites/simple/dan-eden-portfolio-demo" ]; then + if [ ! -d "./test-sites/simple/dan-eden-portfolio_enhanced" ]; then echo "🔧 Dan Eden demo not ready - enhancing now..." just build - ./insertr enhance test-sites/simple/dan-eden-portfolio --output test-sites/simple/dan-eden-portfolio-demo --config test-sites/simple/dan-eden-portfolio/insertr.yaml + ./insertr enhance test-sites/simple/dan-eden-portfolio --output test-sites/simple/dan-eden-portfolio_enhanced --config test-sites/simple/dan-eden-portfolio/insertr.yaml fi echo "🚀 Starting Dan Eden portfolio demo..." - just demo-site "dan-eden" "./test-sites/simple/dan-eden-portfolio-demo" "3000" + just demo-site "dan-eden" "./test-sites/simple/dan-eden-portfolio_enhanced" "3000" elif [ "{{site}}" = "simple" ]; then - if [ ! -d "./test-sites/simple/test-simple-demo" ]; then + if [ ! -d "./test-sites/simple/test-simple_enhanced" ]; then echo "🔧 Simple demo not ready - enhancing now..." just build - ./insertr enhance test-sites/simple/test-simple --output test-sites/simple/test-simple-demo --config test-sites/simple/test-simple/insertr.yaml + ./insertr enhance test-sites/simple/test-simple --output test-sites/simple/test-simple_enhanced --config test-sites/simple/test-simple/insertr.yaml fi echo "🚀 Starting simple test site demo..." - just demo-site "simple" "./test-sites/simple/test-simple-demo" "3000" + just demo-site "simple" "./test-sites/simple/test-simple_enhanced" "3000" else echo "❌ Unknown demo site: {{site}}" echo "" @@ -151,7 +165,7 @@ demo-site site_id path port="3000": build # Start API server echo "🔌 Starting API server (localhost:8080)..." - INSERTR_DATABASE_PATH=./dev.db ./insertr serve --dev-mode 2>&1 | sed 's/^/🔌 [{{site_id}}] /' & + INSERTR_DATABASE_PATH=./insertr.db ./insertr serve --dev-mode 2>&1 | sed 's/^/🔌 [{{site_id}}] /' & SERVER_PID=$! # Wait for server startup @@ -211,7 +225,7 @@ enhance input="test-sites/demo-site" output="dist": # Start content API server (default port 8080) serve port="8080": - INSERTR_DATABASE_PATH=./dev.db ./insertr serve --port {{port}} --dev-mode + INSERTR_DATABASE_PATH=./insertr.db ./insertr serve --port {{port}} --dev-mode # Start API server in production mode serve-prod port="8080" db="./insertr.db": @@ -292,14 +306,19 @@ clean-demos: echo "=========================================" # Demo directories - if [ -d "./test-sites/simple/dan-eden-portfolio-demo" ]; then - rm -rf "./test-sites/simple/dan-eden-portfolio-demo" - echo "🗑️ Removed: dan-eden-portfolio-demo" + if [ -d "./test-sites/demo-site_enhanced" ]; then + rm -rf "./test-sites/demo-site_enhanced" + echo "🗑️ Removed: demo-site_enhanced" fi - if [ -d "./test-sites/simple/test-simple-demo" ]; then - rm -rf "./test-sites/simple/test-simple-demo" - echo "🗑️ Removed: test-simple-demo" + if [ -d "./test-sites/simple/dan-eden-portfolio_enhanced" ]; then + rm -rf "./test-sites/simple/dan-eden-portfolio_enhanced" + echo "🗑️ Removed: dan-eden-portfolio_enhanced" + fi + + if [ -d "./test-sites/simple/test-simple_enhanced" ]; then + rm -rf "./test-sites/simple/test-simple_enhanced" + echo "🗑️ Removed: test-simple_enhanced" fi # Clean up any temporary directories diff --git a/test-sites/demo-site/insertr.yaml b/test-sites/demo-site/insertr.yaml new file mode 100644 index 0000000..17584fb --- /dev/null +++ b/test-sites/demo-site/insertr.yaml @@ -0,0 +1,27 @@ +# Insertr Configuration for Default Demo Site +# Main configuration for the default demo site + +# Global settings +dev_mode: true # Development mode for demos + +# Database configuration +database: + path: "./insertr.db" # Shared database with main config + +# Demo-specific configuration +demo: + site_id: "demo" # Unique site ID for default demo + inject_demo_gate: true # Auto-inject demo gate if no gates exist + mock_auth: true # Use mock authentication for demos + api_endpoint: "http://localhost:8080/api/content" + demo_port: 3000 # Port for live-server + +# CLI enhancement configuration +cli: + site_id: "demo" # Site ID for this demo + output: "./demo_enhanced" # Output directory for enhanced files + inject_demo_gate: true # Inject demo gate in development mode + +# Authentication configuration (for demo) +auth: + provider: "mock" # Mock auth for demos \ No newline at end of file diff --git a/test-sites/simple/dan-eden-portfolio-demo/index.html b/test-sites/simple/dan-eden-portfolio-demo/index.html deleted file mode 100644 index cad1398..0000000 --- a/test-sites/simple/dan-eden-portfolio-demo/index.html +++ /dev/null @@ -1 +0,0 @@ -Daniel Eden, Designer

Daniel Eden is a Product Designer at Meta Reality Labs, working on Avatars & Identity, helping people express their full selves in the Metaverse. He spends his time writing, thinking, posting, and talking about Design Systems: how they scale, how they break, and the people that maintain them.

Ora

An app about time for iPhone, iPad, and Apple Watch.

Learn more →

Solstice

An app about daylight for iPhone, iPad, Mac, Apple Watch, and Apple Vision Pro.

Learn more →

Where We Can Go

A conference talk and essay about design systems and design tools.

Zeitgeist

An app for Vercel developers for iPhone, iPad, and Mac.

Learn more →
2025Ora

iOS App

2021Solstice

iOS App

Broadcast

iOS App

2020Eventually

iOS App

Zeitgeist

iOS App

2019Clarity 2019

“Where We Can Go”

2018Lovers Magazine

Interview

2016Design Details

Podcast

One Day Out 2016

“System Failure”

2015dotCSS 2015

“Move Slow and Fix Things”

\ No newline at end of file diff --git a/test-sites/simple/test-simple-demo/index.html b/test-sites/simple/test-simple-demo/index.html new file mode 100644 index 0000000..d6668dc --- /dev/null +++ b/test-sites/simple/test-simple-demo/index.html @@ -0,0 +1,14 @@ + + Simple Test + + +

Welcome

+

This is a test paragraph with a link.

+
+

Section Title

+

Another paragraph here.

+ +
+ + + \ No newline at end of file diff --git a/test-sites/simple/test-simple-demo/insertr.yaml b/test-sites/simple/test-simple-demo/insertr.yaml new file mode 100644 index 0000000..85c15b9 --- /dev/null +++ b/test-sites/simple/test-simple-demo/insertr.yaml @@ -0,0 +1,27 @@ +# Insertr Configuration for Simple Demo Site +# Specific configuration for the simple test site demo + +# Global settings +dev_mode: true # Development mode for demos + +# Database configuration +database: + path: "./insertr.db" # Shared database with main config + +# Demo-specific configuration +demo: + site_id: "simple" # Unique site ID for simple demo + inject_demo_gate: true # Auto-inject demo gate if no gates exist + mock_auth: true # Use mock authentication for demos + api_endpoint: "http://localhost:8080/api/content" + demo_port: 3000 # Port for live-server + +# CLI enhancement configuration +cli: + site_id: "simple" # Site ID for this demo + output: "./simple-demo" # Output directory for enhanced files + inject_demo_gate: true # Inject demo gate in development mode + +# Authentication configuration (for demo) +auth: + provider: "mock" # Mock auth for demos \ No newline at end of file diff --git a/test-sites/simple/test-simple/insertr.yaml b/test-sites/simple/test-simple/insertr.yaml index 85c15b9..2787cbf 100644 --- a/test-sites/simple/test-simple/insertr.yaml +++ b/test-sites/simple/test-simple/insertr.yaml @@ -19,7 +19,7 @@ demo: # CLI enhancement configuration cli: site_id: "simple" # Site ID for this demo - output: "./simple-demo" # Output directory for enhanced files + output: "./simple_enhanced" # Output directory for enhanced files inject_demo_gate: true # Inject demo gate in development mode # Authentication configuration (for demo)