Skip to content

EliuX/doodlify

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

39 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Doodlify 🎨

CD Release License Python

Automated Event-Based Frontend Customization Tool - Transform your website for special events using AI.

Doodlify is a Python CLI tool that automatically adapts frontend projects for special events like Halloween, Christmas, or custom celebrations. It uses AI agents to intelligently modify images, text, and other visual elements to match your event's theme.

✨ Features

  • πŸ€– AI-Powered Transformations: Uses OpenAI's GPT and image editing models to intelligently adapt content
  • 🎯 Smart Analysis: Automatically identifies files and elements to customize using AI-powered code analysis
  • 🧠 Improvement Suggestions: During analyze, detects repo improvements that boost event quality and auto-creates GitHub issues (deduplicated)
  • 🌳 Git Integration: Creates separate branches for each event with proper version control
  • πŸ”„ GitHub Actions Ready: Easily automate with CI/CD pipelines
  • πŸ“ i18n Support: Adapts internationalization files to match event themes
  • πŸ–ΌοΈ Image Transformation: Automatically generates event-themed variations of images
  • πŸ”’ Safe Backups: Creates backup copies of original files before modifications
  • πŸ“Š State Tracking: Maintains processing state to avoid duplicate work
  • 🎭 Two Execution Modes: Choose between Assistant mode (predictable) or Agentic mode (autonomous)

🎭 Assistant vs Agentic Modes

Doodlify offers two distinct execution modes to suit different needs:

βš™οΈ Assistant Mode (Default - Classic/Imperative)

AI as a tool - You control the workflow, AI helps at each step.

How it works:

  • Follows a predetermined sequence of operations
  • Calls AI for specific tasks (analyze, transform, adapt)
  • Deterministic execution: Same steps every time
  • Uses direct GitHub REST API calls
  • AI is stateless - no memory between operations

Think of it as: Calling an API repeatedly - you decide what happens next.

Best for:

  • Production deployments requiring predictability
  • Debugging and understanding exact execution flow
  • Environments without Docker
  • When you need full control over the process

Example workflow:

# Your code controls the flow:
result1 = ai.analyze(repo)           # Step 1: Analyze
result2 = ai.transform(images)       # Step 2: Transform
result3 = ai.commit(changes)         # Step 3: Commit

πŸ€– Agentic Mode (Autonomous with Haystack + MCP)

AI as an autonomous decision-maker - The agent decides what to do, when, and whether it's done.

How it works:

  • Agent receives a high-level mission ("Transform this repo for Halloween")
  • Autonomously decides which tools to use and in what order
  • Can adapt strategy based on results and errors
  • Uses Model Context Protocol (MCP) for GitHub operations
  • Agent has memory and context across tool invocations
  • Decides when the task is complete

Think of it as: Delegating to a smart teammate who figures out the steps themselves.

Best for:

  • Complex workflows requiring dynamic decisions
  • Experimental/exploratory transformations
  • When you want the AI to handle edge cases autonomously
  • Learning how AI agents approach problems

Example workflow:

# Agent controls the flow:
agent.run("Transform this repo for Halloween")
# Agent internally:
# - Should I analyze first? Yes
# - What images need work? Let me check
# - This transformation failed, let me retry differently
# - Am I done? Let me assess progress

Key Differences Summary

Aspect Assistant Mode Agentic Mode
Control You decide steps AI decides steps
Execution Predetermined sequence Dynamic adaptation
GitHub API Direct REST calls MCP protocol
AI State Stateless per call Maintains context
Error Handling Predefined logic Autonomous retry/adapt
Completion Fixed workflow end Agent decides when done
Dependencies Python + requests Python + Haystack + Docker (for MCP)
Predictability High Medium
Flexibility Medium High

Usage

Add the --agentic flag to any command:

# Assistant mode (default)
doodlify analyze
doodlify process --event-id halloween-2024

# Agentic mode
doodlify analyze --agentic
doodlify process --event-id halloween-2024 --agentic
doodlify push --agentic

πŸš€ Quick Start

Prerequisites

  • Python 3.8+
  • Git
  • GitHub Personal Access Token
  • OpenAI API Key
  • Docker (optional, for GitHub MCP server)

Installation

  1. Clone the repository:
git clone https://github.com/yourusername/doodlify.git
cd doodlify
  1. Install dependencies:
pip install -e .
  1. Set up environment variables:
cp .env.example .env
# Edit .env and add your credentials
  1. Create your configuration:
cp config.example.json config.json
# Edit config.json to match your project

Basic Usage

# Analyze your project
doodlify analyze

# Process active events
doodlify process

# Push changes and create PRs
doodlify push

# Or run all phases at once
doodlify run

# Check status
doodlify status

# Clear lock data
doodlify clear --event-id halloween-2024

πŸ“‹ Configuration

Environment Variables (.env)

# Required
GITHUB_PERSONAL_ACCESS_TOKEN=ghp_your_token_here
GITHUB_REPO_NAME=username/repository-name
OPENAI_API_KEY=sk-your_openai_key_here

# Optional
GIT_BRANCH_CHANGES_TARGET=main  # Target branch for PRs

Project Configuration (config.json)

{
  "project": {
    "name": "My Project",
    "description": "Description for AI agents",
    "sources": ["src/", "public/"],
    "targetBranch": "main"
  },
  "defaults": {
    "selector": "img.hero, .banner-image",
    "branchPrefix": "event/"
  },
  "events": [
    {
      "id": "halloween-2024",
      "name": "Halloween 2024",
      "description": "Spooky Halloween theme with pumpkins and autumn colors",
      "startDate": "2024-10-15",
      "endDate": "2024-11-01",
      "branch": "halloween-2024"
    }
  ]
}

Configuration Schema

project

  • name: Project name
  • description: Context for AI agents about your project structure
  • sources: Array of paths to analyze (leave empty for entire repo)
  • targetBranch: Target branch for pull requests (optional)

defaults

  • selector: CSS selector to match elements (e.g., "img.hero, main > img")
  • branchPrefix: Prefix for event branches (e.g., "event/" β†’ "event/halloween-2024")
  • reportSuggestions: Boolean map controlling which suggestions are auto-filed as GitHub issues. Use keys below. Default enables core items and disables optional ones.

Example:

{
  "defaults": {
    "reportSuggestions": {
      "i18n": false,
      "css_variables": true,
      "data_attrs": true,
      "svg_usage": true,
      "global_css": true,
      "marker_styles": true,
      "favicon_variants": true,
      "favicon_establish": true,
      "og_variants": true,
      "og_add": true,
      "selectors_guidance": true,
      "ai_considerations": true
    }
  }
}

events[]

  • id: Unique identifier (used for branch names)
  • name: Display name
  • description: Event context for AI agents
  • startDate/endDate: Date range (YYYY-MM-DD format)
  • branch: Branch name suffix

πŸ”„ Workflow

Doodlify operates in three phases:

1. Analyze Phase

doodlify analyze
  • Validates configuration
  • Clones/updates target repository
  • Performs AI-powered codebase analysis
  • Identifies files of interest for modification
  • Caches analysis results
  • Creates GitHub issues with improvement suggestions (only once per suggestion; tracked in config-lock.json)

Improvement suggestions

  • Source: Heuristics (missing i18n files, missing image assets, missing selectors) and AI considerations
  • Tracking: Stored in config-lock.json under reported_suggestions with a fingerprint to avoid duplicates
  • Permissions: Requires Personal Access Token with Issues: Read and write
Suggestion keys and defaults

The analyzer attaches a stable key to each suggestion. The orchestrator consults defaults.reportSuggestions[key] to decide if it should be filed.

  • Optional by default (false):

    • i18n β†’ "Optional: Centralize user-facing copy in i18n files"
  • Core by default (true):

    • css_variables β†’ Add CSS variables for theme tokens (colors, spacing)
    • data_attrs β†’ Add data attributes to mark adaptable elements
    • svg_usage β†’ Prefer SVG for logos/illustrations to enable recoloring
    • global_css β†’ Ensure a global stylesheet or theme entrypoint exists
    • marker_styles β†’ Style list markers (e.g., vignettes) to allow event variations
    • favicon_variants β†’ Provide event-ready favicon/touch icon variants (if favicon assets exist)
    • favicon_establish β†’ Establish predictable favicon/touch icon assets (if none exist)
    • og_variants β†’ Provide seasonal Open Graph social preview variants (if og:image exists)
    • og_add β†’ Add Open Graph image meta for social sharing (if og:image missing)
    • selectors_guidance β†’ Add CSS selectors or data-attributes to mark event-adaptable elements (if no selector in config)
    • ai_considerations β†’ Apply analyzer considerations to improve event readiness

You can override any of these in your config.json under defaults.reportSuggestions.

CLI override:

  • Pass --report-all to doodlify analyze or doodlify run to report everything (including those set to false). These will be logged as OPTIONAL when filed due to the flag.

2. Process Phase

doodlify process
  • Processes all active unprocessed events
  • Creates event-specific branches
  • Transforms images using OpenAI
  • Adapts text/i18n content
  • Creates backup files
  • Commits changes locally

Advanced flags:

# Process a specific event (bypasses active/unprocessed filters)
doodlify process --event-id halloween-2025

# Process only certain files for an event
doodlify process --event-id halloween-2025 \
  --only frontend/web-ui/src/images/hero-ecommerce-construction.png,frontend/web-ui/src/images/hero-telephony.png

# Force reprocess even if `.original` backups exist
doodlify process --event-id halloween-2025 \
  --only frontend/web-ui/src/images/hero-ecommerce-construction.png \
  --force

3. Push Phase

doodlify push
  • Pushes branches to GitHub
  • Creates pull requests
  • Updates lock file with PR URLs

Notes:

  • PR creation now uses the direct GitHub REST API via requests (no MCP). Ensure your GITHUB_PERSONAL_ACCESS_TOKEN has repo permissions.

Push and PR workflow when you have local tweaks

If you made additional edits inside the workspace repo (e.g., fixed CSS or HTML) after processing, commit them first and then run doodlify push:

# The workspace repository lives here
cd .doodlify-workspace/<your-repo-name>

# Commit your changes on the event branch (created during process)
git status
git add -A
git commit -m "chore: manual fixes before PR"

# Return to your doodlify project root and push/PR
cd -
doodlify push

Notes:

  • The push step looks at processed events that haven’t been pushed yet and creates PRs automatically.
  • The event branch naming is <branchPrefix><event.branch> (e.g., feature/event/halloween-2025).

Workflow for another event

Sometimes you’ll want to run a new cycle for a different event (or re-run with different settings).

  • Activate or target the event explicitly:
# Re-run analysis (refreshes cache if needed)
doodlify analyze

# Process a specific event directly (bypasses date-based filtering)
doodlify process --event-id <event-id>

# Then push and open PRs
doodlify push
  • If you want to reprocess previously modified files for the same event, use either:

    • doodlify restore --event-id <event-id> --files <comma-separated files> to restore originals and process again, or
    • doodlify process --event-id <event-id> --only <files> --force to reprocess even if backups exist.
  • If you need a clean slate for an event (clears its state in the lock file):

doodlify clear --event-id <event-id>

Transition guidance:

  • Each event is processed on its own branch. Creating a new event branch is handled by process; it also auto-stashes any local, uncommitted changes in the workspace repo to avoid conflicts.
  • Best practice:
    • Finish and push the current event’s branch (doodlify push).
    • Commit any extra manual tweaks inside .doodlify-workspace/<repo> before switching.
    • Run doodlify analyze (optional but recommended) and doodlify process --event-id <next-event> for the new event.

🎨 AI-Powered Color Detection

When useEventColorPalette is enabled (either in defaults or per-event), Doodlify uses AI to intelligently detect and transform colors in your stylesheets.

Configuration

Enable in config.json:

{
  "defaults": {
    "useEventColorPalette": true
  },
  "events": [
    {
      "id": "halloween-2024",
      "name": "Halloween 2024",
      "description": "Spooky Halloween theme with pumpkins and orange/black colors",
      "useEventColorPalette": true  // Override per event
    }
  ]
}

How it works

  1. AI Analysis: For each CSS/SCSS/SASS/LESS file, the AI:

    • Identifies color variables (CSS custom properties, SCSS/SASS variables, LESS variables)
    • Detects direct color values in properties (background-color, color, border-color, etc.)
    • Determines which colors should change based on the event theme
  2. Smart Replacement: The AI suggests specific replacements from your event's color palette

  3. Automatic Backup: Original files are backed up as <name>.original.<ext> before changes

Benefits over regex-based approach

  • Context-aware: Understands which colors are thematic vs. structural
  • Framework-agnostic: Works with any CSS preprocessor or custom naming conventions
  • Intelligent: Considers the event description to make appropriate color choices
  • Safe: Creates backups and can be reverted using doodlify restore

Example Output

🎨 Using AI-powered color detection for theme transformation...
  πŸ“ Found 3 style file(s)
  πŸ” styles/theme.scss: Found 5 color change(s)
    βœ“ Replace primary brand color with Halloween orange
    βœ“ Update secondary accent to dark purple
    βœ“ Change header background to spooky black
    πŸ’Ύ Saved changes to styles/theme.scss

πŸ“š Documentation

For focused, task-oriented guides, see the docs/ folder:

πŸ€– AI Agents

Analyzer Agent

Uses OpenAI to:

  • Identify frontend framework (React, Vue, static HTML, etc.)
  • Locate visual elements (images, banners, logos)
  • Find i18n/localization files
  • Extract CSS selectors
  • Provide intelligent recommendations
  • Produce improvement suggestions for event readiness (e.g., add i18n files, ensure hero images, add selectors)

Image Agent

Uses OpenAI's image editing API to:

  • Transform images to match event themes
  • Maintain original composition
  • Apply appropriate color schemes
  • Add thematic elements

Text Agent

Uses GPT-4 to:

  • Adapt i18n files for events
  • Maintain tone and language
  • Keep message clarity
  • Preserve technical keys

πŸ“ File Structure

doodlify/
β”œβ”€β”€ doodlify/
β”‚   β”œβ”€β”€ __init__.py
β”‚   β”œβ”€β”€ cli.py                 # CLI interface
β”‚   β”œβ”€β”€ models.py              # Data models
β”‚   β”œβ”€β”€ config_manager.py      # Configuration handling
β”‚   β”œβ”€β”€ orchestrator.py        # Main workflow orchestrator
β”‚   β”œβ”€β”€ git_agent.py          # Local git operations
β”‚   β”œβ”€β”€ github_client.py       # GitHub MCP client
β”‚   └── agents/
β”‚       β”œβ”€β”€ analyzer_agent.py  # Codebase analysis
β”‚       β”œβ”€β”€ image_agent.py     # Image transformations
β”‚       └── text_agent.py      # Text adaptations
β”œβ”€β”€ .github/
β”‚   └── workflows/
β”‚       └── doodlify.yml       # GitHub Actions workflow
β”œβ”€β”€ config.json                # Your configuration
β”œβ”€β”€ event.manifest.json        # Optional: repo-level overrides (lives in target repo)
β”œβ”€β”€ config-lock.json          # State tracking (auto-generated)
β”œβ”€β”€ .env                       # Environment variables
β”œβ”€β”€ requirements.txt
β”œβ”€β”€ setup.py
└── README.md

πŸ”§ CI/CD Integration

GitHub Actions

The included workflow file (.github/workflows/doodlify.yml) is disabled by default.

To enable:

  1. Remove the if: false line from the workflow
  2. Add secrets to your repository:
    • GITHUB_PERSONAL_ACCESS_TOKEN
    • OPENAI_API_KEY
  3. Ensure the token has repository permissions: Contents: Read/Write, Pull requests: Read/Write and Issues: Read/Write

The workflow:

  • Runs daily at 9 AM UTC
  • Can be triggered manually
  • Commits config-lock.json to track state
  • Prevents duplicate processing

πŸ“Š State Management

Doodlify uses config-lock.json to track:

  • Processing status of each event
  • Analysis results (cached)
  • Branch and PR information
  • Modified files
  • Commit SHAs
  • Errors and timestamps
  • Reported improvement suggestions (title, fingerprint, issue number)

Lock filename note:

  • The lock file name is derived from the config file name you pass to the CLI.
  • Examples:
    • --config config.json β†’ config-lock.json
    • --config event.manifest.json β†’ event.manifest-lock.json

This prevents duplicate work in CI/CD environments.

πŸ› οΈ Advanced Usage

Custom Selectors

Target specific elements:

{
  "defaults": {
    "selector": "img.hero, main > img, [data-theme-image]"
  }
}

Event-Specific Analysis

Each event can have dedicated analysis results:

doodlify analyze
# Analysis is cached in config-lock.json

Clear and Reprocess

# Clear specific event
doodlify clear --event-id halloween-2024

# Clear all
doodlify clear

Reprocessing a single file

There are two supported workflows to re-run an individual file without clearing everything:

  1. Restore from backup, then process (safe, resets the file to its exact original)
# Restore the current file from its `.original` backup and remove the backup
doodlify restore \
  --event-id halloween-2025 \
  --files frontend/web-ui/src/images/hero-ecommerce-construction.png

# Re-run processing for just that file
doodlify process \
  --event-id halloween-2025 \
  --only frontend/web-ui/src/images/hero-ecommerce-construction.png
  1. Force process (skip the backup check and re-transform in place)
doodlify process \
  --event-id halloween-2025 \
  --only frontend/web-ui/src/images/hero-ecommerce-construction.png \
  --force

Notes:

  • Backups: When a file is first transformed, Doodlify creates a .original.{ext} sibling (e.g., image.original.png).
  • Default skip: Subsequent runs skip files with existing .original.{ext} to avoid duplicate work.
  • Restore: doodlify restore puts the original bytes back into the current file and removes the .original.{ext}, making it eligible for normal processing again.
  • Force: --force tells the processor to ignore .original.{ext} and reprocess anyway.

🧩 Optional Repo Manifest (event.manifest.json)

You can place an event.manifest.json file in the target repository (at the repo root) to override parts of your configuration after cloning. This is useful when the target repo wants to customize selectors, defaults, or events without editing the automation project.

Precedence (highest last):

  • config.json (passed to the CLI)
  • event.manifest.json (in the target repo) overrides project, defaults, and events

Example event.manifest.json in the target repo:

{
  "defaults": {
    "selector": "img.hero, [data-event-adaptable]",
    "branchPrefix": "feature/event/"
  },
  "project": {
    "targetBranch": "main"
  }
}

Notes:

  • Manifest is optional. If present, it is applied after cloning and before analysis.
  • Only the top-level keys project, defaults, and events are considered.
  • The manifest is intended as a consumer-owned override; your automation repo still keeps a boilerplate config.example.json.

πŸ› Troubleshooting

"No changes to commit"

  • Check if event dates are active
  • Verify selector matches elements in your code
  • Ensure images are in supported formats (PNG, JPG, WebP)

"Repository not found"

  • Verify GITHUB_REPO_NAME format: owner/repo
  • Check GitHub token has repo access

"OpenAI API Error"

  • Verify API key is valid
  • Check API quota/billing
  • Ensure image format is supported

MCP Server Issues

If Docker is unavailable, install Node.js and the tool will use npx:

npm install -g @modelcontextprotocol/server-github

⚠️ Known Issues

Agentic Mode (Experimental)

Status: Work in Progress - Not recommended for production use

The agentic mode is currently experimental and has the following known issues:

  • Multi-turn conversations: Agent conversation flow with Haystack has edge cases where tool results aren't properly chained between turns
  • File persistence: Transformed images may not be saved to disk in all scenarios
  • Limited tool coverage: Only image transformation is implemented; CSS color changes and text adaptation need agent tools
  • Debugging complexity: Autonomous decision-making makes it harder to trace what went wrong

Recommendation: Use Assistant Mode (default) for production workflows. It provides:

  • Deterministic, repeatable results
  • Better error messages and debugging
  • Full feature coverage (images, CSS, text, i18n)
  • Proven reliability in CI/CD environments

Agentic mode development continues as an experimental feature for exploring autonomous AI workflows.

🀝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

πŸ“„ License

MIT License - see LICENSE file for details

πŸ™ Acknowledgments

  • OpenAI for GPT and image editing APIs
  • GitHub MCP for repository operations
  • The open-source community for the amazing tools and libraries

πŸ“ž Support

For issues and questions:

  • Open an issue on GitHub
  • Check existing issues for solutions
  • Review the troubleshooting section

Made with ❀️ by [EliuX][mailto: eliecerhdz@gmail.com]

About

Automated Event-Based Frontend Customization Tool - Transform your website for special events using AI.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages