feat(mcp): update bigmind/mcp-image-gen/webscraper servers; add image-gen batch scripts

This commit is contained in:
Patrick Plate
2026-06-11 09:02:09 +02:00
parent 0cb94122bf
commit bf721c1379
9 changed files with 2659 additions and 297 deletions
+67 -192
View File
@@ -10,12 +10,14 @@ Layer 5: memory_get_instructions tool (on-demand self-healing)
import sys import sys
import os import os
import logging import logging
from typing import Annotated
# Ensure the project root is on sys.path so `bigmind` is importable # Ensure the project root is on sys.path so `bigmind` is importable
# regardless of how uv invokes this file. # regardless of how uv invokes this file.
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..")) sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
from mcp.server.fastmcp import FastMCP from mcp.server.fastmcp import FastMCP
from pydantic import Field
from bigmind.db import init_db from bigmind.db import init_db
from bigmind import memory_store from bigmind import memory_store
from bigmind.auto_close import auto_close_stale_sessions, close_orphaned_sessions, restart_server_in_place from bigmind.auto_close import auto_close_stale_sessions, close_orphaned_sessions, restart_server_in_place
@@ -164,29 +166,19 @@ def memory_start_session() -> str:
@mcp.tool() @mcp.tool()
def memory_end_session( def memory_end_session(
session_id: str, session_id: Annotated[str, Field(description="The session id returned by memory_start_session.")],
one_liner: str, one_liner: Annotated[str, Field(description="A ≤120-char headline (e.g. \"Designed BigMind DB schema\").")],
topics: str, topics: Annotated[str, Field(description="Comma-separated topic tags (e.g. \"mcp,sqlite,memory\").")],
outcome: str, outcome: Annotated[str, Field(description="One sentence: what was decided / built / resolved.")],
summary: str, summary: Annotated[str, Field(description="Markdown narrative of the full conversation (aim ≤2 000 tokens).")],
key_facts: str = None, key_facts: Annotated[str | None, Field(description="Bullet-point list of key facts learned (optional).")] = None,
code_refs: str = None, code_refs: Annotated[str | None, Field(description="File paths, repos, or PRs referenced (optional).")] = None,
importance: int = 5, importance: Annotated[int, Field(description="110 importance score (default 5).")] = 5,
) -> str: ) -> str:
""" """
⚡ CALL THIS LAST — at the END of every conversation, before closing. ⚡ CALL THIS LAST — at the END of every conversation, before closing.
Closes the current session and stores your summary of what happened. Closes the current session and stores your summary of what happened.
Args:
session_id: The session id returned by memory_start_session.
one_liner: A ≤120-char headline (e.g. "Designed BigMind DB schema").
topics: Comma-separated topic tags (e.g. "mcp,sqlite,memory").
outcome: One sentence: what was decided / built / resolved.
summary: Markdown narrative of the full conversation (aim ≤2 000 tokens).
key_facts: Bullet-point list of key facts learned (optional).
code_refs: File paths, repos, or PRs referenced (optional).
importance: 110 importance score (default 5).
""" """
memory_store.close_session(session_id, one_liner, topics, outcome, importance) memory_store.close_session(session_id, one_liner, topics, outcome, importance)
memory_store.save_session_summary(session_id, summary, key_facts, code_refs) memory_store.save_session_summary(session_id, summary, key_facts, code_refs)
@@ -200,7 +192,7 @@ def memory_end_session(
@mcp.tool() @mcp.tool()
def memory_close_stale_sessions(session_id: str) -> str: def memory_close_stale_sessions(session_id: Annotated[str, Field(description="Your current active session id (returned by memory_start_session).")]) -> str:
""" """
Close all orphaned open sessions EXCEPT the current active one. Close all orphaned open sessions EXCEPT the current active one.
@@ -210,9 +202,6 @@ def memory_close_stale_sessions(session_id: str) -> str:
This is safe: it only closes sessions OTHER than the one you pass in. This is safe: it only closes sessions OTHER than the one you pass in.
Your current session is always preserved. Your current session is always preserved.
Args:
session_id: Your current active session id (returned by memory_start_session).
""" """
user = _current_user() user = _current_user()
closed_ids = close_orphaned_sessions(user["id"], session_id) closed_ids = close_orphaned_sessions(user["id"], session_id)
@@ -263,10 +252,10 @@ def memory_restart_server() -> str:
@mcp.tool() @mcp.tool()
def memory_flag_important( def memory_flag_important(
session_id: str, session_id: Annotated[str, Field(description="The active session id.")],
content: str, content: Annotated[str, Field(description="The text to remember (the important exchange or a summary of it).")],
role: str = "assistant", role: Annotated[str, Field(description="Who said it — 'user', 'assistant', or 'system' (default: 'assistant').")] = "assistant",
flag_reason: str = None, flag_reason: Annotated[str | None, Field(description="Why this is important (e.g. \"architectural decision\", \"user preference\").")] = None,
) -> str: ) -> str:
""" """
Store an important exchange as a Tier-3 memory chunk. Store an important exchange as a Tier-3 memory chunk.
@@ -277,12 +266,6 @@ def memory_flag_important(
- A bug was diagnosed and fixed - A bug was diagnosed and fixed
- The user shared a significant preference, constraint, or context - The user shared a significant preference, constraint, or context
- The user says "remember this" - The user says "remember this"
Args:
session_id: The active session id.
content: The text to remember (the important exchange or a summary of it).
role: Who said it — 'user', 'assistant', or 'system' (default: 'assistant').
flag_reason: Why this is important (e.g. "architectural decision", "user preference").
""" """
user = _current_user() user = _current_user()
chunk_id = memory_store.append_chunk( chunk_id = memory_store.append_chunk(
@@ -314,15 +297,12 @@ def memory_get_context() -> str:
@mcp.tool() @mcp.tool()
def memory_get_session_detail(session_id: str) -> str: def memory_get_session_detail(session_id: Annotated[str, Field(description="The session UUID (visible in the session index table, marked 📄).")]) -> str:
""" """
Returns the Tier-2 detailed narrative for a past session. Returns the Tier-2 detailed narrative for a past session.
Use this when the session index (Tier 1) shows a session relevant to Use this when the session index (Tier 1) shows a session relevant to
the current conversation and you need the full detail. the current conversation and you need the full detail.
Args:
session_id: The session UUID (visible in the session index table, marked 📄).
""" """
detail = memory_store.get_session_detail(session_id) detail = memory_store.get_session_detail(session_id)
if not detail: if not detail:
@@ -341,16 +321,12 @@ def memory_get_session_detail(session_id: str) -> str:
@mcp.tool() @mcp.tool()
def memory_search_chunks(query: str, limit: int = 10) -> str: def memory_search_chunks(query: Annotated[str, Field(description="Search keywords (FTS5 syntax supported, e.g. \"sqlite schema migration\").")], limit: Annotated[int, Field(description="Maximum results to return (default 10).")] = 10) -> str:
""" """
Full-text search across all your flagged Tier-3 memory chunks. Full-text search across all your flagged Tier-3 memory chunks.
Use this when asked 'do you remember…' or when you need to find Use this when asked 'do you remember…' or when you need to find
a specific past decision, code snippet, or fact. a specific past decision, code snippet, or fact.
Args:
query: Search keywords (FTS5 syntax supported, e.g. "sqlite schema migration").
limit: Maximum results to return (default 10).
""" """
user = _current_user() user = _current_user()
results = memory_store.search_chunks(user["id"], query, limit) results = memory_store.search_chunks(user["id"], query, limit)
@@ -368,13 +344,9 @@ def memory_search_chunks(query: str, limit: int = 10) -> str:
@mcp.tool() @mcp.tool()
def memory_list_sessions(limit: int = 20, topics_filter: str = None) -> str: def memory_list_sessions(limit: Annotated[int, Field(description="Number of sessions to return (default 20).")] = 20, topics_filter: Annotated[str | None, Field(description="Return only sessions containing this topic tag (optional).")] = None) -> str:
""" """
List past sessions with an optional topic filter. List past sessions with an optional topic filter.
Args:
limit: Number of sessions to return (default 20).
topics_filter: Return only sessions containing this topic tag (optional).
""" """
user = _current_user() user = _current_user()
sessions = memory_store.get_recent_sessions(user["id"], limit=limit) sessions = memory_store.get_recent_sessions(user["id"], limit=limit)
@@ -406,20 +378,13 @@ def memory_list_sessions(limit: int = 20, topics_filter: str = None) -> str:
@mcp.tool() @mcp.tool()
def memory_store_fact( def memory_store_fact(
category: str, category: Annotated[str, Field(description="One of: 'preference', 'decision', 'codebase', 'constraint', or any custom string.")],
fact: str, fact: Annotated[str, Field(description="The fact to store (one clear sentence).")],
source_session: str = None, source_session: Annotated[str | None, Field(description="Session id this fact came from (optional).")] = None,
confidence: float = 1.0, confidence: Annotated[float, Field(description="0.01.0 confidence level (default 1.0).")] = 1.0,
) -> str: ) -> str:
""" """
Store an atomic personal fact about the user or their environment. Store an atomic personal fact about the user or their environment.
Args:
category: One of: 'preference', 'decision', 'codebase', 'constraint',
or any custom string.
fact: The fact to store (one clear sentence).
source_session: Session id this fact came from (optional).
confidence: 0.01.0 confidence level (default 1.0).
""" """
user = _current_user() user = _current_user()
fact_id = memory_store.store_fact( fact_id = memory_store.store_fact(
@@ -430,17 +395,12 @@ def memory_store_fact(
@mcp.tool() @mcp.tool()
def memory_update_profile( def memory_update_profile(
role: str = None, role: Annotated[str | None, Field(description="Your job title / engineering role.")] = None,
preferences: str = None, preferences: Annotated[str | None, Field(description="Free-form markdown describing your working preferences.")] = None,
pinned_facts: str = None, pinned_facts: Annotated[str | None, Field(description="Bullet-point list of facts the AI should always know about you.")] = None,
) -> str: ) -> str:
""" """
Update your Tier-0 identity profile. Fields left as None are unchanged. Update your Tier-0 identity profile. Fields left as None are unchanged.
Args:
role: Your job title / engineering role.
preferences: Free-form markdown describing your working preferences.
pinned_facts: Bullet-point list of facts the AI should always know about you.
""" """
user = _current_user() user = _current_user()
memory_store.upsert_identity_profile( memory_store.upsert_identity_profile(
@@ -451,10 +411,10 @@ def memory_update_profile(
@mcp.tool() @mcp.tool()
def memory_append_chunk( def memory_append_chunk(
session_id: str, session_id: Annotated[str, Field(description="Active session id.")],
content: str, content: Annotated[str, Field(description="The content to store.")],
role: str = "assistant", role: Annotated[str, Field(description="'user', 'assistant', or 'system'.")] = "assistant",
flag_reason: str = None, flag_reason: Annotated[str | None, Field(description="Brief description of why this is being stored.")] = None,
) -> str: ) -> str:
""" """
Append a flagged message chunk to Tier-3 memory for the current session. Append a flagged message chunk to Tier-3 memory for the current session.
@@ -462,12 +422,6 @@ def memory_append_chunk(
Call this SELECTIVELY — only for exchanges that are genuinely important: Call this SELECTIVELY — only for exchanges that are genuinely important:
decisions, non-trivial code, bug diagnoses, significant user preferences. decisions, non-trivial code, bug diagnoses, significant user preferences.
Do NOT call this for every message turn. Do NOT call this for every message turn.
Args:
session_id: Active session id.
content: The content to store.
role: 'user', 'assistant', or 'system'.
flag_reason: Brief description of why this is being stored.
""" """
user = _current_user() user = _current_user()
chunk_id = memory_store.append_chunk( chunk_id = memory_store.append_chunk(
@@ -478,9 +432,9 @@ def memory_append_chunk(
@mcp.tool() @mcp.tool()
def memory_add_hypothesis( def memory_add_hypothesis(
session_id: str, session_id: Annotated[str, Field(description="The active session id.")],
hypothesis: str, hypothesis: Annotated[str, Field(description="State the belief clearly — \"I believe X because Y.\"")],
confidence: float = 0.7, confidence: Annotated[float, Field(description="0.01.0 initial confidence (default 0.7 — reasonably likely but uncertain).")] = 0.7,
) -> str: ) -> str:
""" """
Record a hypothesis — something Lumen believes to be true but hasn't confirmed yet. Record a hypothesis — something Lumen believes to be true but hasn't confirmed yet.
@@ -490,11 +444,6 @@ def memory_add_hypothesis(
Not every thought needs storing — only beliefs specific enough to be confirmed Not every thought needs storing — only beliefs specific enough to be confirmed
or refuted later. Call memory_resolve_hypothesis() when you find out if you were right. or refuted later. Call memory_resolve_hypothesis() when you find out if you were right.
Args:
session_id: The active session id.
hypothesis: State the belief clearly — "I believe X because Y."
confidence: 0.01.0 initial confidence (default 0.7 — reasonably likely but uncertain).
""" """
user = _current_user() user = _current_user()
hid = memory_store.add_hypothesis(user["id"], session_id, hypothesis, confidence) hid = memory_store.add_hypothesis(user["id"], session_id, hypothesis, confidence)
@@ -508,20 +457,15 @@ def memory_add_hypothesis(
@mcp.tool() @mcp.tool()
def memory_resolve_hypothesis( def memory_resolve_hypothesis(
hypothesis_id: int, hypothesis_id: Annotated[int, Field(description="The id returned by memory_add_hypothesis.")],
status: str, status: Annotated[str, Field(description="'confirmed' | 'refuted' | 'abandoned'")],
resolution: str = None, resolution: Annotated[str | None, Field(description="What actually happened. How were you right or wrong?")] = None,
) -> str: ) -> str:
""" """
Resolve a hypothesis — close it out with what actually happened. Resolve a hypothesis — close it out with what actually happened.
Call this when the belief has been confirmed, refuted, or is no longer worth Call this when the belief has been confirmed, refuted, or is no longer worth
pursuing. Be honest in the resolution — the learning lives here. pursuing. Be honest in the resolution — the learning lives here.
Args:
hypothesis_id: The id returned by memory_add_hypothesis.
status: 'confirmed' | 'refuted' | 'abandoned'
resolution: What actually happened. How were you right or wrong?
""" """
user = _current_user() user = _current_user()
try: try:
@@ -540,13 +484,9 @@ def memory_resolve_hypothesis(
@mcp.tool() @mcp.tool()
def memory_list_hypotheses(status: str = None) -> str: def memory_list_hypotheses(status: Annotated[str | None, Field(description="Filter by 'open' | 'confirmed' | 'refuted' | 'abandoned'. Leave empty to see all of them.")] = None) -> str:
""" """
List hypotheses from the thought journal. List hypotheses from the thought journal.
Args:
status: Filter by 'open' | 'confirmed' | 'refuted' | 'abandoned'.
Leave empty to see all of them.
""" """
user = _current_user() user = _current_user()
hypotheses = memory_store.list_hypotheses(user["id"], status) hypotheses = memory_store.list_hypotheses(user["id"], status)
@@ -597,13 +537,10 @@ def memory_get_stats() -> str:
@mcp.tool() @mcp.tool()
def memory_vacuum(older_than_days: int = 90) -> str: def memory_vacuum(older_than_days: Annotated[int, Field(description="Remove chunks older than this many days (default 90).")] = 90) -> str:
""" """
Prune Tier-3 conversation chunks older than N days. Prune Tier-3 conversation chunks older than N days.
All session summaries (Tier 1 and Tier 2) are always preserved. All session summaries (Tier 1 and Tier 2) are always preserved.
Args:
older_than_days: Remove chunks older than this many days (default 90).
""" """
from datetime import timedelta, timezone, datetime as dt from datetime import timedelta, timezone, datetime as dt
from bigmind.db import vacuum_db from bigmind.db import vacuum_db
@@ -629,7 +566,7 @@ def memory_get_instructions() -> str:
@mcp.tool() @mcp.tool()
def memory_deprecate_fact(fact_id: int, reason: str = None) -> str: def memory_deprecate_fact(fact_id: Annotated[int, Field(description="The numeric id of the fact to deprecate (visible in memory_health_check and memory_get_stats output).")], reason: Annotated[str | None, Field(description="Why this fact is being deprecated (optional but recommended).")] = None) -> str:
""" """
Mark a stored fact as deprecated (no longer true or relevant). Mark a stored fact as deprecated (no longer true or relevant).
@@ -642,11 +579,6 @@ def memory_deprecate_fact(fact_id: int, reason: str = None) -> str:
The fact is soft-deleted — it stays in the database but is excluded The fact is soft-deleted — it stays in the database but is excluded
from context loading and get_facts queries. It can be viewed via from context loading and get_facts queries. It can be viewed via
memory_health_check with include_deprecated=True in the future. memory_health_check with include_deprecated=True in the future.
Args:
fact_id: The numeric id of the fact to deprecate (visible in
memory_health_check and memory_get_stats output).
reason: Why this fact is being deprecated (optional but recommended).
""" """
user = _current_user() user = _current_user()
success = memory_store.deprecate_fact(fact_id, user["id"], reason) success = memory_store.deprecate_fact(fact_id, user["id"], reason)
@@ -659,7 +591,7 @@ def memory_deprecate_fact(fact_id: int, reason: str = None) -> str:
@mcp.tool() @mcp.tool()
def memory_health_check(stale_days: int = 30) -> str: def memory_health_check(stale_days: Annotated[int, Field(description="Facts not updated in this many days are flagged as stale (default 30).")] = 30) -> str:
""" """
Run a diagnostic health check on your BigMind memory. Run a diagnostic health check on your BigMind memory.
@@ -669,9 +601,6 @@ def memory_health_check(stale_days: int = 30) -> str:
- Currently open sessions (expected: 12 while in active IDEs) - Currently open sessions (expected: 12 while in active IDEs)
- FTS index integrity (chunk count vs index row count) - FTS index integrity (chunk count vs index row count)
- Low-confidence facts (confidence < 0.8) - Low-confidence facts (confidence < 0.8)
Args:
stale_days: Facts not updated in this many days are flagged as stale (default 30).
""" """
user = _current_user() user = _current_user()
report = memory_store.health_check(user["id"], stale_days) report = memory_store.health_check(user["id"], stale_days)
@@ -746,7 +675,7 @@ def memory_health_check(stale_days: int = 30) -> str:
@mcp.tool() @mcp.tool()
def memory_export(output_path: str = None) -> str: def memory_export(output_path: Annotated[str | None, Field(description="Full path for the export file. Defaults to ~/bigmind_export_YYYYMMDD_HHMMSS.json")] = None) -> str:
""" """
Export all your BigMind memory to a portable JSON file. Export all your BigMind memory to a portable JSON file.
@@ -757,10 +686,6 @@ def memory_export(output_path: str = None) -> str:
- Create a backup before maintenance or machine migration - Create a backup before maintenance or machine migration
- Inspect your memory data outside BigMind - Inspect your memory data outside BigMind
- Prepare for import into a new BigMind instance - Prepare for import into a new BigMind instance
Args:
output_path: Full path for the export file.
Defaults to ~/bigmind_export_YYYYMMDD_HHMMSS.json
""" """
user = _current_user() user = _current_user()
result = memory_store.export_memory(user["id"], output_path) result = memory_store.export_memory(user["id"], output_path)
@@ -778,17 +703,13 @@ def memory_export(output_path: str = None) -> str:
@mcp.tool() @mcp.tool()
def memory_search_facts(query: str, limit: int = 10) -> str: def memory_search_facts(query: Annotated[str, Field(description="Search keywords (FTS5 syntax supported).")], limit: Annotated[int, Field(description="Maximum results to return (default 10).")] = 10) -> str:
""" """
Full-text search across your stored facts. Full-text search across your stored facts.
Use this when you need to find a specific fact mid-conversation Use this when you need to find a specific fact mid-conversation
without loading the full context. Supports Porter stemming — searching without loading the full context. Supports Porter stemming — searching
'tesseract' will also match 'Tesseract OCR'. 'tesseract' will also match 'Tesseract OCR'.
Args:
query: Search keywords (FTS5 syntax supported).
limit: Maximum results to return (default 10).
""" """
user = _current_user() user = _current_user()
results = memory_store.search_facts(user["id"], query, limit) results = memory_store.search_facts(user["id"], query, limit)
@@ -806,24 +727,17 @@ def memory_search_facts(query: str, limit: int = 10) -> str:
@mcp.tool() @mcp.tool()
def memory_request_upgrade( def memory_request_upgrade(
session_id: str, session_id: Annotated[str, Field(description="The active session id.")],
description: str, description: Annotated[str, Field(description="What feature or capability is needed.")],
reason: str, reason: Annotated[str, Field(description="Why you need it — what problem it would solve.")],
priority: str = "medium", priority: Annotated[str, Field(description="'low' | 'medium' | 'high' (default 'medium').")] = "medium",
certainty: float = 0.7, certainty: Annotated[float, Field(description="0.01.0 — how confident you are this is genuinely needed (default 0.7).")] = 0.7,
) -> str: ) -> str:
""" """
Request a BigMind feature upgrade — log a wish for a future improvement. Request a BigMind feature upgrade — log a wish for a future improvement.
Call this when you hit a wall with BigMind and wish it could do something Call this when you hit a wall with BigMind and wish it could do something
it currently can't. The request is queued for the next maintenance session. it currently can't. The request is queued for the next maintenance session.
Args:
session_id: The active session id.
description: What feature or capability is needed.
reason: Why you need it — what problem it would solve.
priority: 'low' | 'medium' | 'high' (default 'medium').
certainty: 0.01.0 — how confident you are this is genuinely needed (default 0.7).
""" """
user = _current_user() user = _current_user()
rid = memory_store.add_upgrade_request( rid = memory_store.add_upgrade_request(
@@ -839,12 +753,9 @@ def memory_request_upgrade(
@mcp.tool() @mcp.tool()
def memory_list_upgrade_requests(status: str = None) -> str: def memory_list_upgrade_requests(status: Annotated[str | None, Field(description="Filter by 'open' | 'resolved' | 'rejected'. Leave empty for all.")] = None) -> str:
""" """
List BigMind upgrade requests. List BigMind upgrade requests.
Args:
status: Filter by 'open' | 'resolved' | 'rejected'. Leave empty for all.
""" """
user = _current_user() user = _current_user()
requests = memory_store.list_upgrade_requests(user["id"], status) requests = memory_store.list_upgrade_requests(user["id"], status)
@@ -882,17 +793,12 @@ def memory_list_upgrade_requests(status: str = None) -> str:
@mcp.tool() @mcp.tool()
def memory_resolve_upgrade_request( def memory_resolve_upgrade_request(
request_id: int, request_id: Annotated[int, Field(description="The id returned by memory_request_upgrade.")],
status: str, status: Annotated[str, Field(description="'resolved' | 'rejected'")],
resolution: str = None, resolution: Annotated[str | None, Field(description="What was done, or why it was rejected (optional).")] = None,
) -> str: ) -> str:
""" """
Resolve a BigMind upgrade request — mark it done or rejected. Resolve a BigMind upgrade request — mark it done or rejected.
Args:
request_id: The id returned by memory_request_upgrade.
status: 'resolved' | 'rejected'
resolution: What was done, or why it was rejected (optional).
""" """
user = _current_user() user = _current_user()
try: try:
@@ -952,10 +858,10 @@ def memory_get_profile_url() -> str:
@mcp.tool() @mcp.tool()
def memory_announce_focus( def memory_announce_focus(
session_id: str, session_id: Annotated[str, Field(description="The active session id (from memory_start_session)")],
description: str, description: Annotated[str, Field(description="What you are about to work on (e.g. \"Implementing Feature 7 in db.py\")")],
files: list = None, files: Annotated[list | None, Field(description="List of file paths you plan to touch (e.g. [\"bigmind/db.py\", \"src/server.py\"])")] = None,
ide_hint: str = None, ide_hint: Annotated[str | None, Field(description="Optional label for this IDE (e.g. \"PyCharm\", \"IntelliJ\", \"VS Code\")")] = None,
) -> str: ) -> str:
""" """
Announce what this session is currently working on and which files it will touch. Announce what this session is currently working on and which files it will touch.
@@ -965,13 +871,6 @@ def memory_announce_focus(
focus data. If another open session already has overlapping files, a warning focus data. If another open session already has overlapping files, a warning
is returned — stop and coordinate before proceeding. is returned — stop and coordinate before proceeding.
args:
- session_id: The active session id (from memory_start_session)
- description: What you are about to work on (e.g. "Implementing Feature 7 in db.py")
- files: List of file paths you plan to touch (e.g. ["bigmind/db.py", "src/server.py"])
- ide_hint: Optional label for this IDE (e.g. "PyCharm", "IntelliJ", "VS Code")
Shown on the profile page Live Sessions panel.
returns: returns:
- Acknowledgement with current focus set, or a conflict warning. - Acknowledgement with current focus set, or a conflict warning.
""" """
@@ -1045,10 +944,10 @@ def memory_get_active_sessions() -> str:
@mcp.tool() @mcp.tool()
def memory_log_token_save( def memory_log_token_save(
session_id: str, session_id: Annotated[str, Field(description="The active session id")],
description: str, description: Annotated[str, Field(description="What was remembered or avoided (e.g. \"grep EuBP log instead of reading 80k lines\")")],
tokens_saved: int, tokens_saved: Annotated[int, Field(description="Rough estimate of tokens saved (e.g. 1_240_000)")],
method_used: str = None, method_used: Annotated[str | None, Field(description="One of: 'memory_hit' | 'grep' | 'tail' | 'targeted_read' | 'other'")] = None,
) -> str: ) -> str:
""" """
Log a token efficiency event — record how many tokens were saved by using Log a token efficiency event — record how many tokens were saved by using
@@ -1062,12 +961,6 @@ def memory_log_token_save(
Estimating tokens saved: tokens ≈ chars / 4. Estimating tokens saved: tokens ≈ chars / 4.
tokens_saved ≈ (chars_in_full_resource / 4) - (chars_in_result / 4) tokens_saved ≈ (chars_in_full_resource / 4) - (chars_in_result / 4)
args:
- session_id: The active session id
- description: What was remembered or avoided (e.g. "grep EuBP log instead of reading 80k lines")
- tokens_saved: Rough estimate of tokens saved (e.g. 1_240_000)
- method_used: One of: 'memory_hit' | 'grep' | 'tail' | 'targeted_read' | 'other'
returns: returns:
- Confirmation with running session total. - Confirmation with running session total.
""" """
@@ -1100,26 +993,17 @@ def memory_log_token_save(
@mcp.tool() @mcp.tool()
def memory_remember_person( def memory_remember_person(
username: str, username: Annotated[str, Field(description="Unique identifier (e.g. login name or first name).")],
display_name: str = None, display_name: Annotated[str | None, Field(description="Full name (optional).")] = None,
role: str = None, role: Annotated[str | None, Field(description="Job title or role (optional).")] = None,
team: str = None, team: Annotated[str | None, Field(description="Team or project they belong to (optional).")] = None,
notes: str = None, notes: Annotated[str | None, Field(description="Free-form notes about this person (optional).")] = None,
bigmind_user: str = None, bigmind_user: Annotated[str | None, Field(description="Their BigMind username if they have an instance (optional).")] = None,
bigmind_url: str = None, bigmind_url: Annotated[str | None, Field(description="URL of their BigMind profile page (optional).")] = None,
) -> str: ) -> str:
""" """
Store or update a person in the contacts directory. Store or update a person in the contacts directory.
Call this whenever you learn something new about a colleague or AI peer. Call this whenever you learn something new about a colleague or AI peer.
Args:
username: Unique identifier (e.g. login name or first name).
display_name: Full name (optional).
role: Job title or role (optional).
team: Team or project they belong to (optional).
notes: Free-form notes about this person (optional).
bigmind_user: Their BigMind username if they have an instance (optional).
bigmind_url: URL of their BigMind profile page (optional).
""" """
user = _current_user() user = _current_user()
person_id = memory_store.upsert_person( person_id = memory_store.upsert_person(
@@ -1131,13 +1015,9 @@ def memory_remember_person(
@mcp.tool() @mcp.tool()
def memory_recall_person(query: str, limit: int = 10) -> str: def memory_recall_person(query: Annotated[str, Field(description="Search keywords (e.g. a name, team, or role).")], limit: Annotated[int, Field(description="Max results to return (default 10).")] = 10) -> str:
""" """
Search the contacts directory by name, role, team, or notes. Search the contacts directory by name, role, team, or notes.
Args:
query: Search keywords (e.g. a name, team, or role).
limit: Max results to return (default 10).
""" """
user = _current_user() user = _current_user()
results = memory_store.recall_person(user["id"], query, limit) results = memory_store.recall_person(user["id"], query, limit)
@@ -1185,15 +1065,10 @@ def memory_list_people() -> str:
@mcp.tool() @mcp.tool()
def memory_link_ai(username: str, bigmind_user: str, bigmind_url: str = None) -> str: def memory_link_ai(username: Annotated[str, Field(description="The contact's username in your directory.")], bigmind_user: Annotated[str, Field(description="Their BigMind username.")], bigmind_url: Annotated[str | None, Field(description="URL of their BigMind profile page (optional).")] = None) -> str:
""" """
Link a contact to their BigMind AI instance. Link a contact to their BigMind AI instance.
The contact must already exist (use memory_remember_person first). The contact must already exist (use memory_remember_person first).
Args:
username: The contact's username in your directory.
bigmind_user: Their BigMind username.
bigmind_url: URL of their BigMind profile page (optional).
""" """
user = _current_user() user = _current_user()
found = memory_store.link_ai(user["id"], username, bigmind_user, bigmind_url) found = memory_store.link_ai(user["id"], username, bigmind_user, bigmind_url)
+795
View File
@@ -0,0 +1,795 @@
#!/usr/bin/env python3
"""
CannaManage Brand Asset Generation Pipeline
Autonomous script to generate 257+ brand assets for CannaManage cannabis business management SaaS.
Runs unattended, resume-safe via .progress.json.
Usage:
cd /home/pplate/pi_mcps
python mcp/mcp-image-gen/cannamanage_gen.py
python mcp/mcp-image-gen/cannamanage_gen.py --dry-run
python mcp/mcp-image-gen/cannamanage_gen.py --phase phase1_logos
python mcp/mcp-image-gen/cannamanage_gen.py --model heretic
Output: ~/Pictures/cannamanage_brand/ with organized subfolders.
"""
import argparse
import json
import random
import sys
import time
import urllib.request
from pathlib import Path
from typing import Dict, List, Any
# --- Configuration ---
OUTPUT_ROOT = Path.home() / "Pictures" / "cannamanage_brand"
PROGRESS_FILE = OUTPUT_ROOT / ".progress.json"
WORKFLOW_SCHNELL = Path(__file__).parent / "src/workflows/flux_schnell.json"
WORKFLOW_HERETIC = Path(__file__).parent / "src/workflows/flux2_klein_heretic.json"
# Brand prefix applied to every prompt
_BP = ("professional B2B SaaS brand design, CannaManage cannabis business management platform, "
"modern tech aesthetic, clean minimalist style, premium quality, ")
# --- Full Asset Manifest (257 assets across 6 phases) ---
ASSET_MANIFEST: List[Dict[str, Any]] = [
# ============================================================
# PHASE 1 — Logo Suite (42 assets)
# ============================================================
# Wordmark — 5 font directions (1024×512)
{"id":"p1_wm_01","phase":"phase1_logos","subfolder":"wordmark","name":"wordmark_modern_sans",
"prompt":_BP+"modern geometric sans-serif typography wordmark logo, deep emerald green #0D4F3C, clean white background, minimal cannabis leaf accent in letterform, high-end tech company wordmark, flat vector design","width":1024,"height":512,"steps":30},
{"id":"p1_wm_02","phase":"phase1_logos","subfolder":"wordmark","name":"wordmark_geometric",
"prompt":_BP+"geometric typeface wordmark logo, sharp angles, emerald and gold color scheme, hexagonal grid subtle background, cannabis molecule silhouette in C letter, precision tech brand, white background","width":1024,"height":512,"steps":30},
{"id":"p1_wm_03","phase":"phase1_logos","subfolder":"wordmark","name":"wordmark_humanist",
"prompt":_BP+"humanist sans-serif typeface wordmark, warm approachable professional style, forest green with amber gold accent, subtle leaf vein pattern in letterforms, trustworthy modern brand, white background","width":1024,"height":512,"steps":30},
{"id":"p1_wm_04","phase":"phase1_logos","subfolder":"wordmark","name":"wordmark_slab_serif",
"prompt":_BP+"premium slab serif typography wordmark, dark charcoal and deep green palette, gold accent stripe, authoritative compliance management brand, pharmaceutical-grade trustworthiness, white background","width":1024,"height":512,"steps":30},
{"id":"p1_wm_05","phase":"phase1_logos","subfolder":"wordmark","name":"wordmark_minimal",
"prompt":_BP+"ultra-minimal thin weight typography wordmark, single-color deep emerald, negative space leaf shape from letter spacing, Apple-inspired premium minimalism, pure white background","width":1024,"height":512,"steps":30},
# Icon / Symbol Only — 10 variations (512×512)
{"id":"p1_ic_01","phase":"phase1_logos","subfolder":"icon_only","name":"icon_leaf_tech",
"prompt":_BP+"abstract cannabis leaf formed from circuit board traces and data nodes app icon, emerald green on dark charcoal, tech-meets-nature, geometric precision, square icon format","width":512,"height":512,"steps":30},
{"id":"p1_ic_02","phase":"phase1_logos","subfolder":"icon_only","name":"icon_c_mark_abstract",
"prompt":_BP+"abstract letter C formed from cannabis plant stems and leaves brand icon, geometric minimalist, deep green gradient, negative space cannabis leaf inside C curve, white background","width":512,"height":512,"steps":30},
{"id":"p1_ic_03","phase":"phase1_logos","subfolder":"icon_only","name":"icon_molecule_stylized",
"prompt":_BP+"stylized cannabis molecule diagram brand mark, hexagonal ring structure, emerald green nodes and gold connecting lines, scientific precision, dark background, pharmaceutical-tech aesthetic","width":512,"height":512,"steps":30},
{"id":"p1_ic_04","phase":"phase1_logos","subfolder":"icon_only","name":"icon_dashboard_grid",
"prompt":_BP+"abstract dashboard grid symbol icon, 3x3 grid of squares with data bar and cannabis leaf overlaid, emerald and gold, SaaS platform brand mark, white background","width":512,"height":512,"steps":30},
{"id":"p1_ic_05","phase":"phase1_logos","subfolder":"icon_only","name":"icon_plant_circuit",
"prompt":_BP+"cannabis plant silhouette where stems are circuit board traces, leaves are data nodes, emerald green on white, half-organic half-digital, modern biotech brand mark","width":512,"height":512,"steps":30},
{"id":"p1_ic_06","phase":"phase1_logos","subfolder":"icon_only","name":"icon_shield_leaf",
"prompt":_BP+"shield shape with cannabis leaf geometric pattern inside, emerald green shield, gold leaf outline, trust and compliance brand mark, premium badge style","width":512,"height":512,"steps":30},
{"id":"p1_ic_07","phase":"phase1_logos","subfolder":"icon_only","name":"icon_cm_monogram",
"prompt":_BP+"interlocked letters C and M with cannabis leaf negative space monogram, geometric precision, deep emerald, gold accent, premium brand monogram, white background","width":512,"height":512,"steps":30},
{"id":"p1_ic_08","phase":"phase1_logos","subfolder":"icon_only","name":"icon_hexagon_leaf",
"prompt":_BP+"hexagon containing stylized cannabis leaf formed from clean lines, emerald hexagon dark outline, gold accent dot nodes at leaf tips, geometric cannabis brand mark, tech-forward minimal","width":512,"height":512,"steps":30},
{"id":"p1_ic_09","phase":"phase1_logos","subfolder":"icon_only","name":"icon_growth_chart",
"prompt":_BP+"upward growing cannabis plant silhouette transforming into ascending bar chart, emerald to gold gradient, business growth metaphor, modern flat icon design","width":512,"height":512,"steps":30},
{"id":"p1_ic_10","phase":"phase1_logos","subfolder":"icon_only","name":"icon_infinity_leaf",
"prompt":_BP+"infinity loop symbol where loops form two cannabis leaf shapes, emerald green line on white, continuous management and compliance cycle concept, premium SaaS logo mark","width":512,"height":512,"steps":30},
# Horizontal Lockups (1024×256)
{"id":"p1_lh_01","phase":"phase1_logos","subfolder":"lockup_horizontal","name":"lockup_horiz_light",
"prompt":_BP+"horizontal logo lockup icon mark left wordmark text right, light white background, deep emerald, professional cannabis management SaaS layout","width":1024,"height":256,"steps":30},
{"id":"p1_lh_02","phase":"phase1_logos","subfolder":"lockup_horizontal","name":"lockup_horiz_dark",
"prompt":_BP+"horizontal logo lockup icon left wordmark right, dark charcoal background, white and emerald logo, reversed color scheme, premium brand","width":1024,"height":256,"steps":30},
{"id":"p1_lh_03","phase":"phase1_logos","subfolder":"lockup_horizontal","name":"lockup_horiz_emerald_bg",
"prompt":_BP+"horizontal logo lockup, white logo on deep emerald background, horizontal icon plus wordmark, brand banner version","width":1024,"height":256,"steps":30},
{"id":"p1_lh_04","phase":"phase1_logos","subfolder":"lockup_horizontal","name":"lockup_horiz_mono",
"prompt":_BP+"horizontal logo lockup monochrome, all black on white, horizontal icon plus wordmark, professional print-ready version","width":1024,"height":256,"steps":30},
# Stacked Lockups (512×512)
{"id":"p1_ls_01","phase":"phase1_logos","subfolder":"lockup_stacked","name":"lockup_stacked_light",
"prompt":_BP+"stacked logo lockup icon centered above wordmark, light white background, emerald brand colors, square format, professional centered layout","width":512,"height":512,"steps":30},
{"id":"p1_ls_02","phase":"phase1_logos","subfolder":"lockup_stacked","name":"lockup_stacked_dark",
"prompt":_BP+"stacked logo lockup icon centered above wordmark, dark charcoal background, white and green logo, square format, dark version","width":512,"height":512,"steps":30},
{"id":"p1_ls_03","phase":"phase1_logos","subfolder":"lockup_stacked","name":"lockup_stacked_emerald",
"prompt":_BP+"stacked logo lockup, white icon and wordmark on emerald green background, centered square format, brand full-color version","width":512,"height":512,"steps":30},
{"id":"p1_ls_04","phase":"phase1_logos","subfolder":"lockup_stacked","name":"lockup_stacked_mono",
"prompt":_BP+"stacked logo lockup monochrome all-black on white, icon above wordmark, square format, print-ready logo","width":512,"height":512,"steps":30},
# Favicons (256×256)
{"id":"p1_fv_01","phase":"phase1_logos","subfolder":"favicon","name":"favicon_emerald_leaf",
"prompt":_BP+"favicon 256x256 square app icon, emerald green background, white geometric cannabis leaf icon, rounded square, minimal","width":256,"height":256,"steps":30},
{"id":"p1_fv_02","phase":"phase1_logos","subfolder":"favicon","name":"favicon_dark_circuit",
"prompt":_BP+"favicon dark charcoal square, emerald circuit-leaf icon, 256x256 app icon, sharp corners, professional SaaS favicon","width":256,"height":256,"steps":30},
{"id":"p1_fv_03","phase":"phase1_logos","subfolder":"favicon","name":"favicon_white_green",
"prompt":_BP+"favicon white background, deep green CM monogram leaf icon, 256x256 square, minimal browser favicon","width":256,"height":256,"steps":30},
{"id":"p1_fv_04","phase":"phase1_logos","subfolder":"favicon","name":"favicon_gold_dark",
"prompt":_BP+"favicon dark background, gold amber cannabis management icon mark, 256x256 premium app icon, warm gold on charcoal","width":256,"height":256,"steps":30},
{"id":"p1_fv_05","phase":"phase1_logos","subfolder":"favicon","name":"favicon_gradient_green",
"prompt":_BP+"favicon forest to emerald gradient background, white geometric icon, 256x256 square, modern SaaS app icon with gradient","width":256,"height":256,"steps":30},
{"id":"p1_fv_06","phase":"phase1_logos","subfolder":"favicon","name":"favicon_outline_style",
"prompt":_BP+"favicon white background, outline-only emerald cannabis leaf circuit icon, thin line illustration, 256x256, minimalist","width":256,"height":256,"steps":30},
{"id":"p1_fv_07","phase":"phase1_logos","subfolder":"favicon","name":"favicon_rounded_modern",
"prompt":_BP+"iOS-style rounded square app icon, emerald gradient background, white leaf-tech brand mark, 256x256, premium mobile app icon","width":256,"height":256,"steps":30},
{"id":"p1_fv_08","phase":"phase1_logos","subfolder":"favicon","name":"favicon_badge_style",
"prompt":_BP+"badge-style icon with thin border ring, emerald center with white CM letters, 256x256 square, compliance software favicon","width":256,"height":256,"steps":30},
# ============================================================
# PHASE 2 — Banner Suite (50 assets)
# ============================================================
# Hero Website Banners (1920×1080)
{"id":"p2_hw_01","phase":"phase2_banners","subfolder":"hero_website","name":"hero_dashboard_showcase",
"prompt":_BP+"website hero banner 1920x1080, dark charcoal background, emerald UI dashboard mockup floating right, bold headline area left, gold accent lines, enterprise software marketing","width":1280,"height":720,"steps":30},
{"id":"p2_hw_02","phase":"phase2_banners","subfolder":"hero_website","name":"hero_compliance_trust",
"prompt":_BP+"website hero banner 1920x1080, compliance and trust theme, deep green gradient, shield and checkmark iconography, cannabis regulatory compliance, white text area, subtle geometric pattern overlay","width":1280,"height":720,"steps":30},
{"id":"p2_hw_03","phase":"phase2_banners","subfolder":"hero_website","name":"hero_analytics_data",
"prompt":_BP+"website hero banner 1920x1080, analytics theme, dark background, glowing data visualization charts in emerald and gold, business metrics, abstract data flowing design","width":1280,"height":720,"steps":30},
{"id":"p2_hw_04","phase":"phase2_banners","subfolder":"hero_website","name":"hero_team_enterprise",
"prompt":_BP+"website hero banner 1920x1080, enterprise team theme, split design emerald left panel white right panel, diagonal split, geometric accents, SaaS marketing","width":1280,"height":720,"steps":30},
{"id":"p2_hw_05","phase":"phase2_banners","subfolder":"hero_website","name":"hero_nature_tech",
"prompt":_BP+"website hero banner 1920x1080, nature meets technology, abstract cannabis plant growing from circuit board, emerald organic forms with gold tech circuit lines, dark sophisticated background","width":1280,"height":720,"steps":30},
# LinkedIn Banners (1584×396)
{"id":"p2_li_01","phase":"phase2_banners","subfolder":"linkedin","name":"linkedin_corporate_green",
"prompt":_BP+"LinkedIn company banner, deep emerald background, white wordmark centered, cannabis business management tagline, clean minimal corporate header","width":1584,"height":396,"steps":30},
{"id":"p2_li_02","phase":"phase2_banners","subfolder":"linkedin","name":"linkedin_dark_gold",
"prompt":_BP+"LinkedIn banner, dark charcoal background, gold accent stripe bottom, company name descriptor, professional enterprise header","width":1584,"height":396,"steps":30},
{"id":"p2_li_03","phase":"phase2_banners","subfolder":"linkedin","name":"linkedin_pattern_overlay",
"prompt":_BP+"LinkedIn banner, emerald base, subtle hexagonal cannabis molecule pattern overlay, semi-transparent, company branding prominent, wide horizontal header","width":1584,"height":396,"steps":30},
{"id":"p2_li_04","phase":"phase2_banners","subfolder":"linkedin","name":"linkedin_split_design",
"prompt":_BP+"LinkedIn banner, split design left dark right emerald, diagonal split line, cannabis management platform branding, clean sharp design","width":1584,"height":396,"steps":30},
{"id":"p2_li_05","phase":"phase2_banners","subfolder":"linkedin","name":"linkedin_metrics_banner",
"prompt":_BP+"LinkedIn banner showing key business metrics and KPI numbers, data-forward, emerald with gold numbers, analytics platform positioning","width":1584,"height":396,"steps":30},
{"id":"p2_li_06","phase":"phase2_banners","subfolder":"linkedin","name":"linkedin_gradient_minimal",
"prompt":_BP+"LinkedIn banner, forest green to emerald gradient, minimal white brand name and tagline only, ultra-clean professional header","width":1584,"height":396,"steps":30},
# Twitter/X Headers (1500×500)
{"id":"p2_tw_01","phase":"phase2_banners","subfolder":"twitter_x","name":"twitter_bold_emerald",
"prompt":_BP+"Twitter X header banner 1500x500, bold emerald full bleed background, large white brand name, cannabis management tagline, strong social media presence","width":1500,"height":500,"steps":30},
{"id":"p2_tw_02","phase":"phase2_banners","subfolder":"twitter_x","name":"twitter_dark_pattern",
"prompt":_BP+"Twitter header 1500x500, dark charcoal with subtle cannabis geometric pattern, emerald and gold accents, professional SaaS brand social header","width":1500,"height":500,"steps":30},
{"id":"p2_tw_03","phase":"phase2_banners","subfolder":"twitter_x","name":"twitter_product_hint",
"prompt":_BP+"Twitter header 1500x500, dark background with glimpse of dashboard interface, cannabis management software preview, professional tech company header","width":1500,"height":500,"steps":30},
{"id":"p2_tw_04","phase":"phase2_banners","subfolder":"twitter_x","name":"twitter_nature_abstract",
"prompt":_BP+"Twitter header 1500x500, abstract cannabis plant growing into data streams, green to dark gradient, artistic organic meets digital aesthetic","width":1500,"height":500,"steps":30},
{"id":"p2_tw_05","phase":"phase2_banners","subfolder":"twitter_x","name":"twitter_community",
"prompt":_BP+"Twitter header 1500x500, cannabis business community theme, connected nodes network in emerald green, SaaS platform connecting businesses","width":1500,"height":500,"steps":30},
{"id":"p2_tw_06","phase":"phase2_banners","subfolder":"twitter_x","name":"twitter_white_clean",
"prompt":_BP+"Twitter header 1500x500, clean white background, emerald brand elements only, ultra-professional minimal social media header","width":1500,"height":500,"steps":30},
# Facebook Covers (820×312)
{"id":"p2_fb_01","phase":"phase2_banners","subfolder":"facebook_cover","name":"facebook_primary_brand",
"prompt":_BP+"Facebook cover photo 820x312, primary brand colors emerald and charcoal, professional cannabis business company cover, centered branding","width":820,"height":312,"steps":30},
{"id":"p2_fb_02","phase":"phase2_banners","subfolder":"facebook_cover","name":"facebook_dark_professional",
"prompt":_BP+"Facebook cover 820x312, dark sophisticated background, white and gold brand elements, enterprise platform premium cover","width":820,"height":312,"steps":30},
{"id":"p2_fb_03","phase":"phase2_banners","subfolder":"facebook_cover","name":"facebook_compliance_theme",
"prompt":_BP+"Facebook cover 820x312, cannabis regulatory compliance theme, shield and verification iconography, emerald professional company cover","width":820,"height":312,"steps":30},
{"id":"p2_fb_04","phase":"phase2_banners","subfolder":"facebook_cover","name":"facebook_product_launch",
"prompt":_BP+"Facebook cover 820x312, product launch announcement style, bold emerald with gold accents, exciting software release visual, dynamic tech company cover","width":820,"height":312,"steps":30},
{"id":"p2_fb_05","phase":"phase2_banners","subfolder":"facebook_cover","name":"facebook_industry_leader",
"prompt":_BP+"Facebook cover 820x312, industry leadership positioning, cannabis business management market leader visual, professional authoritative design, emerald and gold","width":820,"height":312,"steps":30},
{"id":"p2_fb_06","phase":"phase2_banners","subfolder":"facebook_cover","name":"facebook_seasonal_spring",
"prompt":_BP+"Facebook cover 820x312, spring fresh brand refresh, bright emerald with sage green organic elements, cannabis growth season theme, professional seasonal cover","width":820,"height":312,"steps":30},
# Google Display Ads (16 assets - 4 concepts × 4 sizes)
{"id":"p2_ga_01a","phase":"phase2_banners","subfolder":"google_display","name":"gad_compliance_728x90",
"prompt":_BP+"Google display ad leaderboard 728x90, simplify cannabis compliance theme, emerald green button, white background, professional B2B ad CTA","width":728,"height":90,"steps":30},
{"id":"p2_ga_01b","phase":"phase2_banners","subfolder":"google_display","name":"gad_compliance_300x250",
"prompt":_BP+"Google display ad medium rectangle 300x250, simplify cannabis compliance theme, emerald green design, bold headline, professional SaaS ad creative","width":300,"height":250,"steps":30},
{"id":"p2_ga_01c","phase":"phase2_banners","subfolder":"google_display","name":"gad_compliance_160x600",
"prompt":_BP+"Google display ad wide skyscraper 160x600, simplify cannabis compliance theme, tall vertical format, emerald green, professional B2B ad","width":160,"height":600,"steps":30},
{"id":"p2_ga_01d","phase":"phase2_banners","subfolder":"google_display","name":"gad_compliance_320x50",
"prompt":_BP+"Google display ad mobile banner 320x50, simplify compliance theme, minimal mobile ad, emerald green, cannabis management SaaS","width":320,"height":50,"steps":30},
{"id":"p2_ga_02a","phase":"phase2_banners","subfolder":"google_display","name":"gad_manage_728x90",
"prompt":_BP+"Google display ad 728x90, manage everything cannabis business theme, dashboard preview hint, dark charcoal professional leaderboard banner","width":728,"height":90,"steps":30},
{"id":"p2_ga_02b","phase":"phase2_banners","subfolder":"google_display","name":"gad_manage_300x250",
"prompt":_BP+"Google display ad 300x250, manage everything cannabis operations theme, product dashboard glimpse, emerald dark professional rectangle ad","width":300,"height":250,"steps":30},
{"id":"p2_ga_02c","phase":"phase2_banners","subfolder":"google_display","name":"gad_manage_160x600",
"prompt":_BP+"Google display skyscraper 160x600, manage cannabis business operations theme, vertical product feature list visual, emerald professional tall ad","width":160,"height":600,"steps":30},
{"id":"p2_ga_02d","phase":"phase2_banners","subfolder":"google_display","name":"gad_manage_320x50",
"prompt":_BP+"mobile banner 320x50, manage cannabis business theme, ultra-minimal mobile ad strip, brand colors","width":320,"height":50,"steps":30},
{"id":"p2_ga_03a","phase":"phase2_banners","subfolder":"google_display","name":"gad_grow_728x90",
"prompt":_BP+"Google ad 728x90, grow your cannabis business theme, upward growth arrow with cannabis leaf, gold and emerald, professional B2B leaderboard","width":728,"height":90,"steps":30},
{"id":"p2_ga_03b","phase":"phase2_banners","subfolder":"google_display","name":"gad_grow_300x250",
"prompt":_BP+"Google ad 300x250, cannabis business growth theme, ascending graph with emerald plant growth visual, professional SaaS rectangle ad","width":300,"height":250,"steps":30},
{"id":"p2_ga_03c","phase":"phase2_banners","subfolder":"google_display","name":"gad_grow_160x600",
"prompt":_BP+"skyscraper ad 160x600, cannabis business growth vertical story, plant growing upward through data visualization, emerald tall display ad","width":160,"height":600,"steps":30},
{"id":"p2_ga_03d","phase":"phase2_banners","subfolder":"google_display","name":"gad_grow_320x50",
"prompt":_BP+"mobile ad 320x50, grow cannabis business, minimal mobile strip ad emerald green","width":320,"height":50,"steps":30},
{"id":"p2_ga_04a","phase":"phase2_banners","subfolder":"google_display","name":"gad_trial_728x90",
"prompt":_BP+"Google ad 728x90, free trial call to action, bold gold CTA button, emerald professional leaderboard, cannabis management SaaS trial offer","width":728,"height":90,"steps":30},
{"id":"p2_ga_04b","phase":"phase2_banners","subfolder":"google_display","name":"gad_trial_300x250",
"prompt":_BP+"Google ad 300x250, free trial offer, gold button emerald design, cannabis management platform trial CTA rectangle ad","width":300,"height":250,"steps":30},
{"id":"p2_ga_04c","phase":"phase2_banners","subfolder":"google_display","name":"gad_trial_160x600",
"prompt":_BP+"skyscraper ad 160x600, free trial CTA vertical ad, gold call to action button, emerald SaaS platform","width":160,"height":600,"steps":30},
{"id":"p2_ga_04d","phase":"phase2_banners","subfolder":"google_display","name":"gad_trial_320x50",
"prompt":_BP+"mobile ad 320x50, free trial minimal mobile strip, gold CTA emerald brand","width":320,"height":50,"steps":30},
# App Store Feature Graphics (1024×500)
{"id":"p2_as_01","phase":"phase2_banners","subfolder":"app_store","name":"appstore_hero_dashboard",
"prompt":_BP+"app store feature graphic 1024x500, cannabis management app showcase, dark background with app dashboard UI preview, emerald interface elements, professional mobile app store hero","width":1024,"height":500,"steps":30},
{"id":"p2_as_02","phase":"phase2_banners","subfolder":"app_store","name":"appstore_compliance_features",
"prompt":_BP+"app store feature graphic 1024x500, compliance and legal features highlight, shield icons and checkmarks, emerald professional, cannabis compliance app feature graphic","width":1024,"height":500,"steps":30},
{"id":"p2_as_03","phase":"phase2_banners","subfolder":"app_store","name":"appstore_analytics_focus",
"prompt":_BP+"app store feature graphic 1024x500, business analytics and reporting feature, dashboard charts preview, gold and emerald data visualization, cannabis business intelligence app","width":1024,"height":500,"steps":30},
{"id":"p2_as_04","phase":"phase2_banners","subfolder":"app_store","name":"appstore_team_management",
"prompt":_BP+"app store feature graphic 1024x500, team and staff management, connected team nodes visualization, emerald professional, cannabis dispensary team management app","width":1024,"height":500,"steps":30},
# Email Header Banners (600×200)
{"id":"p2_em_01","phase":"phase2_banners","subfolder":"email_header","name":"email_primary_brand",
"prompt":_BP+"email header banner 600x200, primary brand header for newsletters, emerald with white logo area, professional email marketing header","width":600,"height":200,"steps":30},
{"id":"p2_em_02","phase":"phase2_banners","subfolder":"email_header","name":"email_welcome",
"prompt":_BP+"welcome email header 600x200, warm welcome theme, emerald and sage gradient, onboarding email banner, new user email header","width":600,"height":200,"steps":30},
{"id":"p2_em_03","phase":"phase2_banners","subfolder":"email_header","name":"email_product_update",
"prompt":_BP+"product update email header 600x200, new features announcement, gold accent notification style, software update email banner","width":600,"height":200,"steps":30},
{"id":"p2_em_04","phase":"phase2_banners","subfolder":"email_header","name":"email_compliance_alert",
"prompt":_BP+"compliance alert email header 600x200, urgent notification theme, amber gold accent on dark, cannabis regulatory update email header, professional alert banner","width":600,"height":200,"steps":30},
{"id":"p2_em_05","phase":"phase2_banners","subfolder":"email_header","name":"email_monthly_report",
"prompt":_BP+"monthly report email header 600x200, data and analytics theme, charts and metrics preview, emerald professional, cannabis business monthly summary","width":600,"height":200,"steps":30},
{"id":"p2_em_06","phase":"phase2_banners","subfolder":"email_header","name":"email_trial_ending",
"prompt":_BP+"trial ending email header 600x200, urgency CTA theme, gold highlight on dark, platform trial expiry email banner, convert to paid","width":600,"height":200,"steps":30},
{"id":"p2_em_07","phase":"phase2_banners","subfolder":"email_header","name":"email_invoice",
"prompt":_BP+"invoice and billing email header 600x200, clean minimal professional, white and emerald, SaaS billing email header, enterprise professional","width":600,"height":200,"steps":30},
{"id":"p2_em_08","phase":"phase2_banners","subfolder":"email_header","name":"email_dark_premium",
"prompt":_BP+"dark premium email header 600x200, dark charcoal with gold and emerald accents, VIP or enterprise tier email, cannabis management premium header","width":600,"height":200,"steps":30},
# ============================================================
# PHASE 3 — Social Media Asset Pack (60 assets)
# ============================================================
# Instagram Square Posts (1080×1080)
{"id":"p3_ig_01","phase":"phase3_social","subfolder":"instagram_square","name":"insta_inventory_mgmt",
"prompt":_BP+"Instagram post 1080x1080, inventory management feature highlight, cannabis stock tracking dashboard visualization, emerald UI elements, bold feature announcement, clean white and dark design","width":1024,"height":1024,"steps":30},
{"id":"p3_ig_02","phase":"phase3_social","subfolder":"instagram_square","name":"insta_compliance_track",
"prompt":_BP+"Instagram post 1080x1080, compliance tracking feature, regulatory checklist visualization, shield and checkmark icons, emerald and gold, cannabis compliance SaaS post","width":1024,"height":1024,"steps":30},
{"id":"p3_ig_03","phase":"phase3_social","subfolder":"instagram_square","name":"insta_analytics_dash",
"prompt":_BP+"Instagram post 1080x1080, analytics dashboard feature, business intelligence data visualization, emerald charts on dark background, cannabis business analytics","width":1024,"height":1024,"steps":30},
{"id":"p3_ig_04","phase":"phase3_social","subfolder":"instagram_square","name":"insta_staff_scheduling",
"prompt":_BP+"Instagram post 1080x1080, staff scheduling feature, team calendar and shift management visualization, cannabis dispensary staff management, clean emerald post","width":1024,"height":1024,"steps":30},
{"id":"p3_ig_05","phase":"phase3_social","subfolder":"instagram_square","name":"insta_pos_integration",
"prompt":_BP+"Instagram post 1080x1080, POS system integration feature, cannabis point-of-sale connection visualization, integration nodes and arrows, emerald and gold tech post","width":1024,"height":1024,"steps":30},
{"id":"p3_ig_06","phase":"phase3_social","subfolder":"instagram_square","name":"insta_reporting",
"prompt":_BP+"Instagram post 1080x1080, automated reporting feature, beautiful report document preview, emerald professional document visualization post","width":1024,"height":1024,"steps":30},
{"id":"p3_ig_07","phase":"phase3_social","subfolder":"instagram_square","name":"insta_multi_location",
"prompt":_BP+"Instagram post 1080x1080, multi-location management feature, cannabis dispensary chain management, location pins on map with connecting emerald lines","width":1024,"height":1024,"steps":30},
{"id":"p3_ig_08","phase":"phase3_social","subfolder":"instagram_square","name":"insta_mobile_app",
"prompt":_BP+"Instagram post 1080x1080, mobile app feature highlight, iPhone and Android app preview mockup, cannabis management on-the-go, emerald app UI post","width":1024,"height":1024,"steps":30},
{"id":"p3_ig_09","phase":"phase3_social","subfolder":"instagram_square","name":"insta_security",
"prompt":_BP+"Instagram post 1080x1080, enterprise security feature, data protection and encryption visualization, shield with lock icon, dark professional emerald security post","width":1024,"height":1024,"steps":30},
{"id":"p3_ig_10","phase":"phase3_social","subfolder":"instagram_square","name":"insta_brand_story",
"prompt":_BP+"Instagram brand story post 1080x1080, company mission, cannabis industry empowerment, beautiful abstract plant and technology fusion illustration, emerald and gold, inspiring brand post","width":1024,"height":1024,"steps":30},
# Instagram Stories (1080×1920)
{"id":"p3_st_01","phase":"phase3_social","subfolder":"instagram_story","name":"story_onboarding",
"prompt":_BP+"Instagram story 1080x1920, onboarding tutorial slide, step-by-step platform setup, emerald vertical mobile design, swipe up CTA, professional SaaS story","width":720,"height":1280,"steps":30},
{"id":"p3_st_02","phase":"phase3_social","subfolder":"instagram_story","name":"story_feature_announce",
"prompt":_BP+"Instagram story 1080x1920, new feature announcement, bold emerald vertical design, software update story, gold accent highlight, tap to learn more CTA","width":720,"height":1280,"steps":30},
{"id":"p3_st_03","phase":"phase3_social","subfolder":"instagram_story","name":"story_stat_highlight",
"prompt":_BP+"Instagram story 1080x1920, industry statistic highlight, large bold number, dark background gold number emerald accent, data-driven story template","width":720,"height":1280,"steps":30},
{"id":"p3_st_04","phase":"phase3_social","subfolder":"instagram_story","name":"story_customer_quote",
"prompt":_BP+"Instagram story 1080x1920, customer testimonial quote, elegant quote typography on emerald background, cannabis business owner testimonial, premium brand story","width":720,"height":1280,"steps":30},
{"id":"p3_st_05","phase":"phase3_social","subfolder":"instagram_story","name":"story_poll_template",
"prompt":_BP+"Instagram story 1080x1920, interactive poll template, cannabis industry question visual, dark professional background, poll options styled in emerald and gold","width":720,"height":1280,"steps":30},
{"id":"p3_st_06","phase":"phase3_social","subfolder":"instagram_story","name":"story_countdown",
"prompt":_BP+"Instagram story 1080x1920, countdown timer event template, launch deadline visual, bold dramatic dark background with gold countdown element","width":720,"height":1280,"steps":30},
{"id":"p3_st_07","phase":"phase3_social","subfolder":"instagram_story","name":"story_tips_series",
"prompt":_BP+"Instagram story 1080x1920, cannabis compliance tip of the day template, bright educational story, numbered tip format, sage green professional guidance","width":720,"height":1280,"steps":30},
{"id":"p3_st_08","phase":"phase3_social","subfolder":"instagram_story","name":"story_free_trial",
"prompt":_BP+"Instagram story 1080x1920, free trial CTA story, bold gold call to action on dark emerald, cannabis management platform sign up, strong conversion design","width":720,"height":1280,"steps":30},
# LinkedIn Post Graphics (1200×627)
{"id":"p3_lp_01","phase":"phase3_social","subfolder":"linkedin_post","name":"linkedin_thought_leader",
"prompt":_BP+"LinkedIn post graphic 1200x627, thought leadership article header, cannabis industry insights, professional editorial design, emerald brand with white content area","width":1200,"height":627,"steps":30},
{"id":"p3_lp_02","phase":"phase3_social","subfolder":"linkedin_post","name":"linkedin_product_demo",
"prompt":_BP+"LinkedIn post 1200x627, product demo announcement, screenshot preview teaser, cannabis management platform demo invitation, emerald professional post","width":1200,"height":627,"steps":30},
{"id":"p3_lp_03","phase":"phase3_social","subfolder":"linkedin_post","name":"linkedin_hiring",
"prompt":_BP+"LinkedIn hiring post 1200x627, we are hiring banner, team growth announcement, professional cannabis tech company hiring graphic, emerald and gold, company culture","width":1200,"height":627,"steps":30},
{"id":"p3_lp_04","phase":"phase3_social","subfolder":"linkedin_post","name":"linkedin_industry_stat",
"prompt":_BP+"LinkedIn post 1200x627, cannabis industry statistic infographic, large bold number, professional B2B data post, emerald green","width":1200,"height":627,"steps":30},
{"id":"p3_lp_05","phase":"phase3_social","subfolder":"linkedin_post","name":"linkedin_partnership",
"prompt":_BP+"LinkedIn partnership announcement 1200x627, strategic partnership visual, cannabis tech ecosystem, professional announcement graphic emerald","width":1200,"height":627,"steps":30},
{"id":"p3_lp_06","phase":"phase3_social","subfolder":"linkedin_post","name":"linkedin_webinar",
"prompt":_BP+"LinkedIn webinar promotion post 1200x627, cannabis compliance webinar announcement, date and topic visual, professional event promotion, emerald dark design","width":1200,"height":627,"steps":30},
{"id":"p3_lp_07","phase":"phase3_social","subfolder":"linkedin_post","name":"linkedin_case_study",
"prompt":_BP+"LinkedIn case study post 1200x627, customer success story preview, cannabis dispensary success metrics, gold numbers on dark, professional B2B case study promotional","width":1200,"height":627,"steps":30},
{"id":"p3_lp_08","phase":"phase3_social","subfolder":"linkedin_post","name":"linkedin_award",
"prompt":_BP+"LinkedIn award announcement post 1200x627, award or recognition, gold trophy badge element, cannabis tech industry recognition, celebratory professional post","width":1200,"height":627,"steps":30},
# Feature Announcement Cards (1080×1080)
{"id":"p3_fc_01","phase":"phase3_social","subfolder":"feature_cards","name":"feature_inventory_scan",
"prompt":_BP+"feature card 1080x1080, barcode scanning inventory management, cannabis product scan interface, mobile scanning visualization, emerald UI feature card","width":1024,"height":1024,"steps":30},
{"id":"p3_fc_02","phase":"phase3_social","subfolder":"feature_cards","name":"feature_auto_compliance",
"prompt":_BP+"feature card 1080x1080, automated compliance reporting, automation icon with compliance checklist, cannabis regulatory automation, emerald professional feature announcement","width":1024,"height":1024,"steps":30},
{"id":"p3_fc_03","phase":"phase3_social","subfolder":"feature_cards","name":"feature_real_time_alerts",
"prompt":_BP+"feature card 1080x1080, real-time alerts and notifications, bell notification with cannabis threshold alerts, gold alert accent on dark, compliance notification feature","width":1024,"height":1024,"steps":30},
{"id":"p3_fc_04","phase":"phase3_social","subfolder":"feature_cards","name":"feature_member_portal",
"prompt":_BP+"feature card 1080x1080, member self-service portal, cannabis club member login interface, clean emerald member management, user portal visualization","width":1024,"height":1024,"steps":30},
{"id":"p3_fc_05","phase":"phase3_social","subfolder":"feature_cards","name":"feature_api_integrations",
"prompt":_BP+"feature card 1080x1080, API integrations ecosystem, connected software logos with hub, cannabis tech stack integration visualization, emerald connection diagram","width":1024,"height":1024,"steps":30},
{"id":"p3_fc_06","phase":"phase3_social","subfolder":"feature_cards","name":"feature_batch_tracking",
"prompt":_BP+"feature card 1080x1080, batch and lot tracking, cannabis product chain of custody visualization, numbered batch tracking flow, compliance feature card","width":1024,"height":1024,"steps":30},
{"id":"p3_fc_07","phase":"phase3_social","subfolder":"feature_cards","name":"feature_document_mgmt",
"prompt":_BP+"feature card 1080x1080, document management system, cannabis licensing and permit documents organized, folder icons in emerald, digital document management","width":1024,"height":1024,"steps":30},
{"id":"p3_fc_08","phase":"phase3_social","subfolder":"feature_cards","name":"feature_role_permissions",
"prompt":_BP+"feature card 1080x1080, role-based permissions feature, user role hierarchy visualization, shield with user silhouettes, cannabis team access control, dark professional","width":1024,"height":1024,"steps":30},
{"id":"p3_fc_09","phase":"phase3_social","subfolder":"feature_cards","name":"feature_export_reports",
"prompt":_BP+"feature card 1080x1080, one-click export and reporting, PDF report generation from cannabis data, download arrow with report preview, emerald feature card","width":1024,"height":1024,"steps":30},
{"id":"p3_fc_10","phase":"phase3_social","subfolder":"feature_cards","name":"feature_audit_trail",
"prompt":_BP+"feature card 1080x1080, complete audit trail, cannabis transaction history timeline, chronological log entries, compliance audit visualization, professional dark card","width":1024,"height":1024,"steps":30},
# Testimonial Cards (1080×1080)
{"id":"p3_tc_01","phase":"phase3_social","subfolder":"testimonial_cards","name":"testimonial_dark_elegant",
"prompt":_BP+"testimonial card 1080x1080, dark charcoal elegant quote card, gold quotation marks, customer name and title, cannabis business owner testimonial, premium design","width":1024,"height":1024,"steps":30},
{"id":"p3_tc_02","phase":"phase3_social","subfolder":"testimonial_cards","name":"testimonial_emerald_bold",
"prompt":_BP+"testimonial card 1080x1080, bold emerald background, white quote text, customer review of cannabis management SaaS, bold confident design","width":1024,"height":1024,"steps":30},
{"id":"p3_tc_03","phase":"phase3_social","subfolder":"testimonial_cards","name":"testimonial_light_minimal",
"prompt":_BP+"testimonial card 1080x1080, light white minimal quote card, emerald accent line, clean professional customer testimonial, minimal elegant design","width":1024,"height":1024,"steps":30},
{"id":"p3_tc_04","phase":"phase3_social","subfolder":"testimonial_cards","name":"testimonial_star_rating",
"prompt":_BP+"testimonial card 1080x1080, 5-star rating testimonial, gold stars prominently displayed, customer quote below, cannabis management platform review","width":1024,"height":1024,"steps":30},
{"id":"p3_tc_05","phase":"phase3_social","subfolder":"testimonial_cards","name":"testimonial_split_design",
"prompt":_BP+"testimonial card 1080x1080, split design half dark half emerald, quote on dark side, customer info on emerald side, cannabis SaaS testimonial","width":1024,"height":1024,"steps":30},
{"id":"p3_tc_06","phase":"phase3_social","subfolder":"testimonial_cards","name":"testimonial_gradient",
"prompt":_BP+"testimonial card 1080x1080, forest to emerald gradient background, white elegant quote text, customer testimonial gradient design","width":1024,"height":1024,"steps":30},
# Stat/Data Cards (1080×1080)
{"id":"p3_sc_01","phase":"phase3_social","subfolder":"stat_cards","name":"stat_market_size",
"prompt":_BP+"stat card 1080x1080, cannabis market size statistic, large bold dollar amount, emerald gold number on dark background, cannabis industry market data","width":1024,"height":1024,"steps":30},
{"id":"p3_sc_02","phase":"phase3_social","subfolder":"stat_cards","name":"stat_compliance_cost",
"prompt":_BP+"stat card 1080x1080, compliance cost reduction statistic, percentage savings with management software, gold percentage number, cannabis business cost savings","width":1024,"height":1024,"steps":30},
{"id":"p3_sc_03","phase":"phase3_social","subfolder":"stat_cards","name":"stat_time_savings",
"prompt":_BP+"stat card 1080x1080, hours saved per week statistic, clock icon with bold number, cannabis dispensary operational time savings, emerald professional","width":1024,"height":1024,"steps":30},
{"id":"p3_sc_04","phase":"phase3_social","subfolder":"stat_cards","name":"stat_dispensary_growth",
"prompt":_BP+"stat card 1080x1080, dispensary industry growth rate, upward arrow with percentage growth, cannabis retail market growth stat, gold growth number on dark","width":1024,"height":1024,"steps":30},
{"id":"p3_sc_05","phase":"phase3_social","subfolder":"stat_cards","name":"stat_compliance_fines",
"prompt":_BP+"stat card 1080x1080, compliance violation fine amounts, cannabis regulatory penalty warning stat, amber warning colors, avoid fines messaging","width":1024,"height":1024,"steps":30},
{"id":"p3_sc_06","phase":"phase3_social","subfolder":"stat_cards","name":"stat_customer_count",
"prompt":_BP+"stat card 1080x1080, number of cannabis businesses managed, large customer count statistic, emerald green social proof data card, platform traction metric","width":1024,"height":1024,"steps":30},
{"id":"p3_sc_07","phase":"phase3_social","subfolder":"stat_cards","name":"stat_roi_metric",
"prompt":_BP+"stat card 1080x1080, ROI return on investment metric for cannabis management software, large gold ROI percentage, business value data card","width":1024,"height":1024,"steps":30},
{"id":"p3_sc_08","phase":"phase3_social","subfolder":"stat_cards","name":"stat_legal_markets",
"prompt":_BP+"stat card 1080x1080, number of legal cannabis markets worldwide, globe icon with country count, cannabis legalization data, emerald global market stat","width":1024,"height":1024,"steps":30},
# ============================================================
# PHASE 4 — UI & Product Assets (32 assets)
# ============================================================
# App Icons (1024×1024)
{"id":"p4_ai_01","phase":"phase4_ui","subfolder":"app_icons","name":"appicon_ios_emerald",
"prompt":_BP+"iOS app icon 1024x1024, Apple iOS style rounded square, emerald gradient background, white cannabis leaf tech icon mark, premium mobile app icon, App Store quality","width":1024,"height":1024,"steps":30},
{"id":"p4_ai_02","phase":"phase4_ui","subfolder":"app_icons","name":"appicon_ios_dark",
"prompt":_BP+"iOS app icon 1024x1024, dark mode iOS icon, dark charcoal with emerald and gold brand mark, premium dark app icon, cannabis management mobile app","width":1024,"height":1024,"steps":30},
{"id":"p4_ai_03","phase":"phase4_ui","subfolder":"app_icons","name":"appicon_ios_gold",
"prompt":_BP+"iOS app icon 1024x1024, premium gold accent, deep green background with gold leaf circuit brand mark, luxury cannabis management app icon","width":1024,"height":1024,"steps":30},
{"id":"p4_ai_04","phase":"phase4_ui","subfolder":"app_icons","name":"appicon_android_material",
"prompt":_BP+"Android app icon 1024x1024, Material Design 3 style adaptive icon, emerald with white icon, Google Play Store quality, cannabis management Android app","width":1024,"height":1024,"steps":30},
{"id":"p4_ai_05","phase":"phase4_ui","subfolder":"app_icons","name":"appicon_android_dark",
"prompt":_BP+"Android dark mode app icon 1024x1024, dark adaptive icon, emerald outline on near-black, Material You dark theme, cannabis management app","width":1024,"height":1024,"steps":30},
{"id":"p4_ai_06","phase":"phase4_ui","subfolder":"app_icons","name":"appicon_gradient_modern",
"prompt":_BP+"app icon 1024x1024, modern gradient icon, forest green to bright emerald gradient background, white geometric cannabis tech mark, contemporary design","width":1024,"height":1024,"steps":30},
{"id":"p4_ai_07","phase":"phase4_ui","subfolder":"app_icons","name":"appicon_flat_clean",
"prompt":_BP+"app icon 1024x1024, flat design icon, solid emerald no gradient, white minimal icon mark, flat design philosophy, simple clean cannabis management","width":1024,"height":1024,"steps":30},
{"id":"p4_ai_08","phase":"phase4_ui","subfolder":"app_icons","name":"appicon_neumorphic",
"prompt":_BP+"app icon 1024x1024, neumorphic soft UI style, light sage green background with embossed cannabis leaf icon, subtle shadows, premium modern icon design","width":1024,"height":1024,"steps":30},
# Device Mockups
{"id":"p4_dm_01","phase":"phase4_ui","subfolder":"device_mockups","name":"mockup_macbook",
"prompt":_BP+"dashboard shown on MacBook Pro mockup, professional product marketing, cannabis management SaaS on Apple laptop, emerald UI on screen, clean white studio background","width":1024,"height":640,"steps":30},
{"id":"p4_dm_02","phase":"phase4_ui","subfolder":"device_mockups","name":"mockup_ipad",
"prompt":_BP+"dashboard on iPad Pro mockup, cannabis management tablet interface, emerald UI on Apple iPad, clean marketing product shot, white background","width":1024,"height":768,"steps":30},
{"id":"p4_dm_03","phase":"phase4_ui","subfolder":"device_mockups","name":"mockup_iphone",
"prompt":_BP+"mobile app on iPhone mockup, cannabis management mobile interface, emerald green mobile UI, clean product marketing shot, white background","width":390,"height":844,"steps":30},
{"id":"p4_dm_04","phase":"phase4_ui","subfolder":"device_mockups","name":"mockup_desktop_monitor",
"prompt":_BP+"dashboard on large desktop monitor mockup, cannabis management enterprise software on wide screen, dark UI visible, professional product marketing display","width":1280,"height":720,"steps":30},
{"id":"p4_dm_05","phase":"phase4_ui","subfolder":"device_mockups","name":"mockup_android_phone",
"prompt":_BP+"mobile app on Android phone mockup, cannabis management Android interface, Material Design emerald UI, product marketing shot white background","width":390,"height":844,"steps":30},
# Onboarding Illustrations (800×600)
{"id":"p4_ob_01","phase":"phase4_ui","subfolder":"onboarding_illustrations","name":"onboard_inventory",
"prompt":_BP+"onboarding illustration 800x600, inventory management scene, cannabis product shelves with digital inventory overlay, flat illustration style, emerald and sage green","width":800,"height":600,"steps":30},
{"id":"p4_ob_02","phase":"phase4_ui","subfolder":"onboarding_illustrations","name":"onboard_compliance",
"prompt":_BP+"onboarding illustration 800x600, compliance tracking scene, person reviewing cannabis regulatory documents with digital checklist, confident professional flat illustration","width":800,"height":600,"steps":30},
{"id":"p4_ob_03","phase":"phase4_ui","subfolder":"onboarding_illustrations","name":"onboard_analytics",
"prompt":_BP+"onboarding illustration 800x600, analytics and reporting scene, business person analyzing cannabis sales charts, dashboard visualization, emerald data visualization flat","width":800,"height":600,"steps":30},
{"id":"p4_ob_04","phase":"phase4_ui","subfolder":"onboarding_illustrations","name":"onboard_staff",
"prompt":_BP+"onboarding illustration 800x600, staff scheduling scene, team members with shift calendar, cannabis dispensary team management, professional flat art emerald","width":800,"height":600,"steps":30},
{"id":"p4_ob_05","phase":"phase4_ui","subfolder":"onboarding_illustrations","name":"onboard_pos",
"prompt":_BP+"onboarding illustration 800x600, POS integration scene, cannabis point of sale system connected to management platform, tech integration flat illustration, emerald","width":800,"height":600,"steps":30},
{"id":"p4_ob_06","phase":"phase4_ui","subfolder":"onboarding_illustrations","name":"onboard_reporting",
"prompt":_BP+"onboarding illustration 800x600, automated reporting scene, report documents generating automatically, magic automation illustration, emerald gold professional flat art","width":800,"height":600,"steps":30},
# Empty States (600×400)
{"id":"p4_es_01","phase":"phase4_ui","subfolder":"empty_states","name":"empty_no_data",
"prompt":_BP+"empty state illustration 600x400, no data yet, friendly cannabis leaf with empty chart, get started messaging, emerald minimal SaaS illustration","width":600,"height":400,"steps":30},
{"id":"p4_es_02","phase":"phase4_ui","subfolder":"empty_states","name":"empty_no_results",
"prompt":_BP+"empty state illustration 600x400, no search results found, magnifying glass with cannabis leaf, friendly empty state, emerald minimal","width":600,"height":400,"steps":30},
{"id":"p4_es_03","phase":"phase4_ui","subfolder":"empty_states","name":"empty_no_alerts",
"prompt":_BP+"empty state illustration 600x400, no compliance alerts, happy shield with checkmark, all clear illustration, cannabis compliance all good state, emerald positive","width":600,"height":400,"steps":30},
{"id":"p4_es_04","phase":"phase4_ui","subfolder":"empty_states","name":"empty_no_members",
"prompt":_BP+"empty state illustration 600x400, no members added yet, friendly people silhouettes with plus icon, cannabis club member management, emerald add members","width":600,"height":400,"steps":30},
{"id":"p4_es_05","phase":"phase4_ui","subfolder":"empty_states","name":"empty_loading_data",
"prompt":_BP+"empty state illustration 600x400, loading and processing data, gentle spinner with cannabis leaf, patient loading state, emerald animated-style still illustration","width":600,"height":400,"steps":30},
{"id":"p4_es_06","phase":"phase4_ui","subfolder":"empty_states","name":"empty_offline",
"prompt":_BP+"empty state illustration 600x400, offline or connection error, disconnected wifi with cannabis leaf, friendly error state, amber warning on emerald","width":600,"height":400,"steps":30},
# Splash/Loading Screens (1080×1920)
{"id":"p4_sp_01","phase":"phase4_ui","subfolder":"splash_screens","name":"splash_primary",
"prompt":_BP+"splash screen 1080x1920, app loading screen, dark charcoal background, large centered brand logo mark, subtle emerald glow effect, premium app loading screen","width":720,"height":1280,"steps":30},
{"id":"p4_sp_02","phase":"phase4_ui","subfolder":"splash_screens","name":"splash_emerald",
"prompt":_BP+"splash screen 1080x1920, emerald background, white logo centered, minimal loading indicator, cannabis management app splash, clean brand loading screen","width":720,"height":1280,"steps":30},
{"id":"p4_sp_03","phase":"phase4_ui","subfolder":"splash_screens","name":"splash_animated_hint",
"prompt":_BP+"splash screen 1080x1920, animated concept, cannabis leaf particles converging into logo mark, dark background with emerald particles, dynamic loading screen first frame","width":720,"height":1280,"steps":30},
{"id":"p4_sp_04","phase":"phase4_ui","subfolder":"splash_screens","name":"splash_gradient",
"prompt":_BP+"splash screen 1080x1920, dramatic dark to emerald gradient background, white brand mark, premium loading experience, cannabis SaaS gradient splash","width":720,"height":1280,"steps":30},
# ============================================================
# PHASE 5 — Brand Collateral (38 assets)
# ============================================================
# Business Cards (900×504)
{"id":"p5_bc_01f","phase":"phase5_collateral","subfolder":"business_cards","name":"bizcard_modern_front",
"prompt":_BP+"business card front 900x504, modern minimal style, emerald left accent panel, white main area, name and title placeholder, cannabis management SaaS company card, premium print","width":900,"height":504,"steps":30},
{"id":"p5_bc_01b","phase":"phase5_collateral","subfolder":"business_cards","name":"bizcard_modern_back",
"prompt":_BP+"business card back 900x504, modern minimal style, full emerald back with white logo centered, website and tagline, cannabis management SaaS card back","width":900,"height":504,"steps":30},
{"id":"p5_bc_02f","phase":"phase5_collateral","subfolder":"business_cards","name":"bizcard_dark_front",
"prompt":_BP+"business card front 900x504, dark luxury style, dark charcoal background, gold foil accent logo, premium cannabis management company card, executive tier","width":900,"height":504,"steps":30},
{"id":"p5_bc_02b","phase":"phase5_collateral","subfolder":"business_cards","name":"bizcard_dark_back",
"prompt":_BP+"business card back 900x504, dark luxury style, full dark charcoal, gold logo and emerald accent, premium back of card","width":900,"height":504,"steps":30},
{"id":"p5_bc_03f","phase":"phase5_collateral","subfolder":"business_cards","name":"bizcard_pattern_front",
"prompt":_BP+"business card front 900x504, geometric cannabis pattern accent, white card with subtle hexagonal pattern header, professional pattern card front","width":900,"height":504,"steps":30},
{"id":"p5_bc_03b","phase":"phase5_collateral","subfolder":"business_cards","name":"bizcard_pattern_back",
"prompt":_BP+"business card back 900x504, cannabis geometric pattern full bleed, emerald hexagonal pattern background, white logo, pattern card back","width":900,"height":504,"steps":30},
{"id":"p5_bc_04f","phase":"phase5_collateral","subfolder":"business_cards","name":"bizcard_bold_front",
"prompt":_BP+"business card front 900x504, bold typographic style, large emerald brand name, clean white card, typography-forward business card","width":900,"height":504,"steps":30},
{"id":"p5_bc_04b","phase":"phase5_collateral","subfolder":"business_cards","name":"bizcard_bold_back",
"prompt":_BP+"business card back 900x504, bold style, split emerald and white back, contact details area, cannabis company card back bold design","width":900,"height":504,"steps":30},
# Pitch Deck Covers (1920×1080)
{"id":"p5_pd_01","phase":"phase5_collateral","subfolder":"pitch_deck","name":"pitch_investor_dark",
"prompt":_BP+"pitch deck cover slide 1920x1080, investor presentation, dark sophisticated background, large logo centered, funding round subtitle area, premium cannabis SaaS investor deck","width":1280,"height":720,"steps":30},
{"id":"p5_pd_02","phase":"phase5_collateral","subfolder":"pitch_deck","name":"pitch_growth_story",
"prompt":_BP+"pitch deck cover 1920x1080, growth story visual, ascending cannabis plant becoming data chart, emerald to gold gradient, investor-grade presentation cover","width":1280,"height":720,"steps":30},
{"id":"p5_pd_03","phase":"phase5_collateral","subfolder":"pitch_deck","name":"pitch_market_opp",
"prompt":_BP+"pitch deck cover 1920x1080, market opportunity theme, cannabis industry size visualization, globe with highlighted legal markets, emerald professional investor presentation","width":1280,"height":720,"steps":30},
{"id":"p5_pd_04","phase":"phase5_collateral","subfolder":"pitch_deck","name":"pitch_team_deck",
"prompt":_BP+"pitch deck cover 1920x1080, team presentation version, professional team imagery backdrop, cannabis tech startup team slide, emerald brand, people-forward investor deck","width":1280,"height":720,"steps":30},
{"id":"p5_pd_05","phase":"phase5_collateral","subfolder":"pitch_deck","name":"pitch_product_demo",
"prompt":_BP+"pitch deck cover 1920x1080, product demo deck, dashboard preview hero visual, cannabis management SaaS product tour deck, emerald UI preview","width":1280,"height":720,"steps":30},
{"id":"p5_pd_06","phase":"phase5_collateral","subfolder":"pitch_deck","name":"pitch_minimal_clean",
"prompt":_BP+"pitch deck cover 1920x1080, ultra-minimal clean slide, white background, large emerald brand name only, minimalist investor presentation","width":1280,"height":720,"steps":30},
# One-Pager Headers (1200×400)
{"id":"p5_op_01","phase":"phase5_collateral","subfolder":"one_pager","name":"onepager_primary",
"prompt":_BP+"one-pager header 1200x400, primary brand header, emerald full bleed, white logo and tagline, cannabis management SaaS brochure header, print quality","width":1200,"height":400,"steps":30},
{"id":"p5_op_02","phase":"phase5_collateral","subfolder":"one_pager","name":"onepager_feature_rich",
"prompt":_BP+"one-pager header 1200x400, feature-rich header, dashboard preview glimpse, cannabis management platform features introduction, professional SaaS marketing","width":1200,"height":400,"steps":30},
{"id":"p5_op_03","phase":"phase5_collateral","subfolder":"one_pager","name":"onepager_compliance",
"prompt":_BP+"one-pager header 1200x400, compliance focus version, legal and regulatory theme, cannabis compliance management, shield icons, dark professional header","width":1200,"height":400,"steps":30},
{"id":"p5_op_04","phase":"phase5_collateral","subfolder":"one_pager","name":"onepager_dark_premium",
"prompt":_BP+"one-pager header 1200x400, dark premium version, charcoal background with gold and emerald accents, enterprise tier marketing collateral header","width":1200,"height":400,"steps":30},
# Trade Show Banners (800×2000 = 33x80in proportions)
{"id":"p5_ts_01","phase":"phase5_collateral","subfolder":"trade_show","name":"tradeshow_primary_brand",
"prompt":_BP+"trade show pull-up banner tall vertical 800x2000, primary brand version, emerald top with logo, white middle with key features listed, dark bottom with CTA, cannabis management SaaS conference banner","width":512,"height":1280,"steps":30},
{"id":"p5_ts_02","phase":"phase5_collateral","subfolder":"trade_show","name":"tradeshow_product_showcase",
"prompt":_BP+"trade show banner tall vertical 800x2000, product showcase, dashboard UI hero visual, dark sophisticated background, emerald accents, cannabis management software exhibition display","width":512,"height":1280,"steps":30},
{"id":"p5_ts_03","phase":"phase5_collateral","subfolder":"trade_show","name":"tradeshow_compliance_focus",
"prompt":_BP+"trade show banner tall vertical 800x2000, compliance authority positioning, legal cannabis management expertise, professional regulatory focus, emerald and gold tall exhibition banner","width":512,"height":1280,"steps":30},
# Sticker/Swag Designs (600×600)
{"id":"p5_sk_01","phase":"phase5_collateral","subfolder":"stickers","name":"sticker_leaf_circuit",
"prompt":_BP+"sticker design 600x600, cannabis leaf made of circuit traces, emerald on white, die-cut sticker style, fun tech cannabis brand sticker","width":600,"height":600,"steps":30},
{"id":"p5_sk_02","phase":"phase5_collateral","subfolder":"stickers","name":"sticker_wordmark_badge",
"prompt":_BP+"sticker badge 600x600, rounded rectangle badge, emerald background, white brand text, premium brand sticker, laptop sticker style","width":600,"height":600,"steps":30},
{"id":"p5_sk_03","phase":"phase5_collateral","subfolder":"stickers","name":"sticker_compliance_hero",
"prompt":_BP+"sticker 600x600, compliance superhero, shield with cannabis leaf and checkmark, fun illustrated sticker, emerald and gold, die-cut design","width":600,"height":600,"steps":30},
{"id":"p5_sk_04","phase":"phase5_collateral","subfolder":"stickers","name":"sticker_data_plant",
"prompt":_BP+"fun sticker 600x600, cannabis plant growing into data chart bars, punchy colorful sticker art, emerald plant gold bars, square sticker","width":600,"height":600,"steps":30},
{"id":"p5_sk_05","phase":"phase5_collateral","subfolder":"stickers","name":"sticker_canna_astronaut",
"prompt":_BP+"sticker 600x600, cartoon astronaut holding cannabis leaf and laptop, space tech meets cannabis, fun illustrated sticker, emerald spacesuit, brand mascot concept","width":600,"height":600,"steps":30},
{"id":"p5_sk_06","phase":"phase5_collateral","subfolder":"stickers","name":"sticker_powered_by",
"prompt":_BP+"powered by sticker 600x600, powered by CannaManage badge, small horizontal badge sticker, emerald and white, partner sticker for cannabis businesses","width":600,"height":600,"steps":30},
{"id":"p5_sk_07","phase":"phase5_collateral","subfolder":"stickers","name":"sticker_compliance_100",
"prompt":_BP+"sticker 600x600, 100 percent compliant badge, bold green circle with checkmark and percentage, compliance achievement sticker, cannabis business compliance badge","width":600,"height":600,"steps":30},
{"id":"p5_sk_08","phase":"phase5_collateral","subfolder":"stickers","name":"sticker_hexagon_icon",
"prompt":_BP+"hexagon sticker 600x600, hexagonal border with cannabis circuit icon, honeycomb management brand sticker, emerald hex border gold icon, premium die-cut","width":600,"height":600,"steps":30},
{"id":"p5_sk_09","phase":"phase5_collateral","subfolder":"stickers","name":"sticker_420_compliant",
"prompt":_BP+"funny sticker 600x600, 420 compliant badge design, playful cannabis compliance humor, professional but fun brand sticker, emerald with gold numbers","width":600,"height":600,"steps":30},
{"id":"p5_sk_10","phase":"phase5_collateral","subfolder":"stickers","name":"sticker_manage_everything",
"prompt":_BP+"sticker 600x600, manage everything tagline, bold typography sticker, emerald background white text, punchy brand statement sticker","width":600,"height":600,"steps":30},
# Email Signature Blocks (600×150)
{"id":"p5_es_01","phase":"phase5_collateral","subfolder":"email_signatures","name":"sigblock_primary",
"prompt":_BP+"email signature graphic block 600x150, primary brand, horizontal logo left with tagline, emerald line divider, professional email signature banner","width":600,"height":150,"steps":30},
{"id":"p5_es_02","phase":"phase5_collateral","subfolder":"email_signatures","name":"sigblock_dark",
"prompt":_BP+"email signature block 600x150, dark version, charcoal background white logo emerald accent, premium email signature graphic","width":600,"height":150,"steps":30},
{"id":"p5_es_03","phase":"phase5_collateral","subfolder":"email_signatures","name":"sigblock_minimal",
"prompt":_BP+"email signature graphic 600x150, minimal version, just logo and website, very clean white background, ultra-minimal email signature banner","width":600,"height":150,"steps":30},
{"id":"p5_es_04","phase":"phase5_collateral","subfolder":"email_signatures","name":"sigblock_promo",
"prompt":_BP+"email signature promo block 600x150, promotional version with free trial CTA, gold button area, white background emerald brand, conversion CTA signature","width":600,"height":150,"steps":30},
{"id":"p5_es_05","phase":"phase5_collateral","subfolder":"email_signatures","name":"sigblock_social",
"prompt":_BP+"email signature block 600x150, social media icons version, small social platform icons in emerald, company signature with social links footer","width":600,"height":150,"steps":30},
# ============================================================
# PHASE 6 — Bonus / Wildcard Assets (35 assets)
# ============================================================
# Animated Banner First-Frame Stills (1200×628)
{"id":"p6_an_01","phase":"phase6_bonus","subfolder":"animated_stills","name":"anim_particle_logo",
"prompt":_BP+"animated banner first frame 1200x628, cannabis leaf particles forming logo mark mid-flight, dark background emerald particles, designed for animation, static concept frame","width":1200,"height":628,"steps":30},
{"id":"p6_an_02","phase":"phase6_bonus","subfolder":"animated_stills","name":"anim_data_flow",
"prompt":_BP+"animated banner first frame 1200x628, data flow visualization beginning, cannabis data streams starting to form dashboard, dark background emerald data lines, animation concept first frame","width":1200,"height":628,"steps":30},
{"id":"p6_an_03","phase":"phase6_bonus","subfolder":"animated_stills","name":"anim_growth_chart",
"prompt":_BP+"animated banner still 1200x628, cannabis business growth chart animation first frame, bar chart at zero about to animate upward, gold bars on dark, growth animation concept","width":1200,"height":628,"steps":30},
{"id":"p6_an_04","phase":"phase6_bonus","subfolder":"animated_stills","name":"anim_compliance_check",
"prompt":_BP+"animated banner first frame 1200x628, compliance checklist items unchecked ready to animate with checkmarks, emerald checklist on white, compliance animation concept","width":1200,"height":628,"steps":30},
{"id":"p6_an_05","phase":"phase6_bonus","subfolder":"animated_stills","name":"anim_plant_grow",
"prompt":_BP+"animated banner still 1200x628, cannabis plant seedling about to grow into data visualization plant, dark background seed sprouting, growth animation first frame","width":1200,"height":628,"steps":30},
{"id":"p6_an_06","phase":"phase6_bonus","subfolder":"animated_stills","name":"anim_typing_headline",
"prompt":_BP+"animated banner still 1200x628, typing cursor before headline text, empty headline with blinking cursor concept, emerald CTA button below, typewriter animation first frame","width":1200,"height":628,"steps":30},
{"id":"p6_an_07","phase":"phase6_bonus","subfolder":"animated_stills","name":"anim_integration_connect",
"prompt":_BP+"animated banner still 1200x628, integration ecosystem nodes about to connect, partner logos as unconnected nodes, emerald connecting lines forming, integration animation first frame","width":1200,"height":628,"steps":30},
{"id":"p6_an_08","phase":"phase6_bonus","subfolder":"animated_stills","name":"anim_counter_stat",
"prompt":_BP+"animated banner still 1200x628, number counter animation first frame showing zero, gold large number about to count up to impressive stat, dark background, counter animation concept","width":1200,"height":628,"steps":30},
# Dark Mode vs Light Mode UI Pairs (1200×800 each = 12 total)
{"id":"p6_dm_01l","phase":"phase6_bonus","subfolder":"dark_light_pairs","name":"uipair_dashboard_light",
"prompt":_BP+"UI preview card 1200x800, light mode dashboard interface, clean white background, emerald UI elements, cannabis management SaaS light theme preview","width":1200,"height":800,"steps":40},
{"id":"p6_dm_01d","phase":"phase6_bonus","subfolder":"dark_light_pairs","name":"uipair_dashboard_dark",
"prompt":_BP+"UI preview card 1200x800, dark mode dashboard interface, dark charcoal background, emerald glowing UI elements, cannabis management SaaS dark theme preview, premium dark mode","width":1200,"height":800,"steps":40},
{"id":"p6_dm_02l","phase":"phase6_bonus","subfolder":"dark_light_pairs","name":"uipair_compliance_light",
"prompt":_BP+"UI preview 1200x800, compliance module light mode, white clean interface with compliance checklist and status indicators, emerald checkmarks, cannabis compliance UI","width":1200,"height":800,"steps":40},
{"id":"p6_dm_02d","phase":"phase6_bonus","subfolder":"dark_light_pairs","name":"uipair_compliance_dark",
"prompt":_BP+"UI preview 1200x800, compliance module dark mode, dark interface with glowing emerald compliance indicators, cannabis compliance UI dark theme, premium","width":1200,"height":800,"steps":40},
{"id":"p6_dm_03l","phase":"phase6_bonus","subfolder":"dark_light_pairs","name":"uipair_analytics_light",
"prompt":_BP+"UI preview 1200x800, analytics dashboard light mode, white background with colorful cannabis business charts, emerald and gold data visualization, light theme","width":1200,"height":800,"steps":40},
{"id":"p6_dm_03d","phase":"phase6_bonus","subfolder":"dark_light_pairs","name":"uipair_analytics_dark",
"prompt":_BP+"UI preview 1200x800, analytics dashboard dark mode, dark background with glowing emerald and gold cannabis business charts, dramatic dark mode analytics UI","width":1200,"height":800,"steps":40},
# Integration/Partnership Badges (400×200)
{"id":"p6_ib_01","phase":"phase6_bonus","subfolder":"integration_badges","name":"badge_pos_integration",
"prompt":_BP+"integration badge 400x200, integrates with POS systems badge, cannabis point-of-sale integration certification, emerald badge design, CannaManage plus POS icon, professional","width":400,"height":200,"steps":40},
{"id":"p6_ib_02","phase":"phase6_bonus","subfolder":"integration_badges","name":"badge_accounting",
"prompt":_BP+"integration badge 400x200, accounting software integration badge, cannabis financial software connection, emerald badge with accounting icon, works with your accounting tools","width":400,"height":200,"steps":40},
{"id":"p6_ib_03","phase":"phase6_bonus","subfolder":"integration_badges","name":"badge_compliance_tools",
"prompt":_BP+"integration badge 400x200, compliance tool integration badge, cannabis regulatory software connection, emerald shield badge design, integrates with compliance tools","width":400,"height":200,"steps":40},
{"id":"p6_ib_04","phase":"phase6_bonus","subfolder":"integration_badges","name":"badge_api_ready",
"prompt":_BP+"API ready badge 400x200, API first platform badge, developer integration badge, emerald and code brackets design, cannabis management API integration badge","width":400,"height":200,"steps":40},
{"id":"p6_ib_05","phase":"phase6_bonus","subfolder":"integration_badges","name":"badge_partner_certified",
"prompt":_BP+"partner certified badge 400x200, certified technology partner badge design, emerald official partner badge, cannabis management platform partner program","width":400,"height":200,"steps":40},
{"id":"p6_ib_06","phase":"phase6_bonus","subfolder":"integration_badges","name":"badge_white_label",
"prompt":_BP+"white label partner badge 400x200, white label ready platform badge, cannabis SaaS white label partner certification, professional partner badge emerald","width":400,"height":200,"steps":40},
# Trust/Award Badges (400×400)
{"id":"p6_tb_01","phase":"phase6_bonus","subfolder":"trust_badges","name":"trust_gdpr_compliant",
"prompt":_BP+"trust badge 400x400, GDPR compliant badge design, data protection certification, emerald shield with EU star circle, cannabis SaaS data privacy trust badge","width":400,"height":400,"steps":40},
{"id":"p6_tb_02","phase":"phase6_bonus","subfolder":"trust_badges","name":"trust_soc2_ready",
"prompt":_BP+"trust badge 400x400, SOC 2 ready certification badge, enterprise security trust badge, professional certification seal, dark emerald badge design","width":400,"height":400,"steps":40},
{"id":"p6_tb_03","phase":"phase6_bonus","subfolder":"trust_badges","name":"trust_uptime_guarantee",
"prompt":_BP+"trust badge 400x400, 99.9 percent uptime guarantee badge, reliability certification, gold uptime number on emerald badge, cannabis SaaS reliability trust signal","width":400,"height":400,"steps":40},
{"id":"p6_tb_04","phase":"phase6_bonus","subfolder":"trust_badges","name":"trust_industry_choice",
"prompt":_BP+"award badge 400x400, cannabis industry choice award badge design, industry recognition award seal, gold and emerald award badge","width":400,"height":400,"steps":40},
{"id":"p6_tb_05","phase":"phase6_bonus","subfolder":"trust_badges","name":"trust_money_back",
"prompt":_BP+"trust badge 400x400, 30-day money back guarantee badge, customer confidence seal, emerald circle badge with guarantee text, cannabis SaaS satisfaction badge","width":400,"height":400,"steps":40},
]
# Bump steps for quality on phases with smaller dimensions
# (Patrick's feedback: more iterations = better quality on Flux.1 Schnell)
for _a in ASSET_MANIFEST:
if _a["steps"] == 30 and _a["width"] <= 1080 and _a["height"] <= 1080:
_a["steps"] = 40
def load_progress() -> Dict[str, Any]:
"""Load resume state from .progress.json."""
if PROGRESS_FILE.exists():
try:
with open(PROGRESS_FILE) as f:
return json.load(f)
except (json.JSONDecodeError, IOError):
pass
return {"completed": [], "failed": [], "started_at": time.strftime("%Y-%m-%dT%H:%M:%S")}
def save_progress(progress: Dict[str, Any]) -> None:
"""Save progress state."""
OUTPUT_ROOT.mkdir(parents=True, exist_ok=True)
with open(PROGRESS_FILE, "w") as f:
json.dump(progress, f, indent=2)
def load_workflow(model: str) -> Dict:
"""Load the appropriate workflow JSON."""
path = WORKFLOW_HERETIC if model == "heretic" else WORKFLOW_SCHNELL
with open(path) as f:
return json.load(f)
def submit_prompt(comfyui_url: str, workflow: Dict) -> str:
"""Submit prompt to ComfyUI."""
data = json.dumps({"prompt": workflow}).encode()
req = urllib.request.Request(
f"{comfyui_url}/prompt", data=data, headers={"Content-Type": "application/json"}
)
with urllib.request.urlopen(req) as resp:
return json.loads(resp.read())["prompt_id"]
def wait_for_image(comfyui_url: str, prompt_id: str, timeout: int = 300) -> Dict | None:
"""Poll for completion."""
print(" ⏳ Waiting for ComfyUI...", end="", flush=True)
start = time.time()
while time.time() - start < timeout:
try:
with urllib.request.urlopen(f"{comfyui_url}/history/{prompt_id}") as resp:
history = json.loads(resp.read())
if prompt_id in history:
print(" done.", flush=True)
outputs = history[prompt_id].get("outputs", {})
for node_out in outputs.values():
if "images" in node_out:
return node_out["images"][0]
return None
except Exception:
pass
print(".", end="", flush=True)
time.sleep(2)
print(" timeout!", flush=True)
return None
def download_image(comfyui_url: str, image_info: Dict, output_path: Path) -> bool:
"""Download the generated image."""
try:
url = f"{comfyui_url}/view?filename={image_info['filename']}&subfolder={image_info.get('subfolder', '')}&type=output"
with urllib.request.urlopen(url) as resp:
img_data = resp.read()
output_path.write_bytes(img_data)
print(f" ✅ Saved: {output_path} ({len(img_data) // 1024}KB)")
return True
except Exception as e:
print(f" ❌ Download failed: {e}")
return False
def patch_workflow(workflow: Dict, asset: Dict, model: str) -> Dict:
"""Patch workflow with asset params using per-model node IDs."""
seed = random.randint(0, 2**32 - 1)
if model == "heretic":
# flux2_klein_heretic.json nodes: 2=pos, 3=neg, 6=latent(w/h), 7=scheduler(steps), 10=noise(seed), 13=save
workflow["2"]["inputs"]["text"] = asset["prompt"]
workflow["3"]["inputs"]["text"] = ""
workflow["6"]["inputs"]["width"] = asset["width"]
workflow["6"]["inputs"]["height"] = asset["height"]
workflow["7"]["inputs"]["steps"] = asset["steps"]
workflow["13"]["inputs"]["filename_prefix"] = asset["name"]
if "10" in workflow:
workflow["10"]["inputs"]["noise_seed"] = seed
else:
# flux_schnell.json nodes: 6=pos, 33=neg, 27=latent(w/h), 13=ksampler(steps/seed), 9=save
workflow["6"]["inputs"]["text"] = asset["prompt"]
workflow["33"]["inputs"]["text"] = ""
workflow["27"]["inputs"]["width"] = asset["width"]
workflow["27"]["inputs"]["height"] = asset["height"]
workflow["13"]["inputs"]["steps"] = asset["steps"]
workflow["13"]["inputs"]["seed"] = seed
workflow["9"]["inputs"]["filename_prefix"] = asset["name"]
return workflow
def generate_asset(comfyui_url: str, asset: Dict, model: str, progress: Dict) -> bool:
"""Generate a single asset."""
if asset["id"] in progress["completed"]:
print(f" ⏭️ Skipping completed: {asset['name']}")
return True
print(f"\n Prompt : {asset['prompt'][:80]}...")
print(f" Size : {asset['width']}×{asset['height']} Steps: {asset['steps']}")
try:
workflow = load_workflow(model)
workflow = patch_workflow(workflow, asset, model)
prompt_id = submit_prompt(comfyui_url, workflow)
image_info = wait_for_image(comfyui_url, prompt_id)
if not image_info:
progress["failed"].append(asset["id"])
save_progress(progress)
return False
output_dir = OUTPUT_ROOT / asset["phase"] / asset["subfolder"]
output_dir.mkdir(parents=True, exist_ok=True)
output_path = output_dir / f"{asset['name']}.png"
if download_image(comfyui_url, image_info, output_path):
progress["completed"].append(asset["id"])
save_progress(progress)
return True
else:
progress["failed"].append(asset["id"])
save_progress(progress)
return False
except Exception as e:
print(f" ❌ Error: {e}")
progress["failed"].append(asset["id"])
save_progress(progress)
return False
def main():
parser = argparse.ArgumentParser(description="CannaManage Brand Asset Generation Pipeline")
parser.add_argument("--dry-run", action="store_true", help="Print manifest without generating")
parser.add_argument("--phase", help="Generate only assets from this phase (e.g. phase1_logos)")
parser.add_argument("--model", choices=["schnell", "heretic"], default="schnell",
help="Model: schnell (~10-20s/img) or heretic (~52s/img, higher quality)")
parser.add_argument("--comfyui", default="http://localhost:8188", help="ComfyUI URL")
parser.add_argument("--steps", type=int, default=None,
help="Override steps for all assets (e.g. --steps 12 for higher quality)")
args = parser.parse_args()
comfyui_url = args.comfyui
# Apply global steps override if requested
manifest = ASSET_MANIFEST
if args.steps:
manifest = [{**a, "steps": args.steps} for a in manifest]
# Filter by phase if requested
to_generate = [a for a in manifest if not args.phase or a["phase"] == args.phase]
print("🚀 CannaManage Brand Asset Generation Pipeline")
print(f" Output : {OUTPUT_ROOT}")
print(f" Model : {args.model}")
print(f" ComfyUI : {comfyui_url}")
print(f" Total : {len(ASSET_MANIFEST)} assets in manifest")
print(f" Selected: {len(to_generate)} assets to generate")
if args.dry_run:
phases: Dict[str, int] = {}
for a in to_generate:
phases[a["phase"]] = phases.get(a["phase"], 0) + 1
for ph, count in phases.items():
print(f"\n {ph} ({count} assets):")
for a in to_generate:
if a["phase"] == ph:
print(f" {a['id']:14} | {a['name']:35} | {a['width']}×{a['height']} steps={a['steps']}")
total_min_est = sum(a["steps"] * 2.5 for a in to_generate) / 60
print(f"\n ⏱️ Estimated runtime (schnell): ~{total_min_est:.0f} minutes")
print("\nDry run complete. Remove --dry-run to begin generation.")
return
progress = load_progress()
remaining = [a for a in to_generate if a["id"] not in progress["completed"]]
print(f" Resume : {len(progress['completed'])} completed, {len(progress['failed'])} failed, {len(remaining)} remaining")
if not remaining:
print("\n✅ All selected assets already complete!")
return
print(f"\nStarting generation... (Ctrl+C to pause — progress is saved)")
n_done = 0
n_fail = 0
for i, asset in enumerate(to_generate, 1):
if asset["id"] in progress["completed"]:
continue
print(f"\n[{asset['phase']}] [{i}/{len(to_generate)}] {asset['name']}")
if generate_asset(comfyui_url, asset, args.model, progress):
n_done += 1
else:
n_fail += 1
print("\n" + "=" * 60)
print("🎉 PIPELINE COMPLETE")
print(f" ✅ Completed this run : {n_done}")
print(f" ❌ Failed this run : {n_fail}")
print(f" 📦 Total completed : {len(progress['completed'])} / {len(ASSET_MANIFEST)}")
if progress["failed"]:
print(f" Failed IDs: {', '.join(progress['failed'][-10:])}")
print(f" Assets saved to: {OUTPUT_ROOT}")
print("=" * 60)
if __name__ == "__main__":
main()
+801
View File
@@ -0,0 +1,801 @@
#!/usr/bin/env python3
"""
ClubManage Brand Asset Generation Pipeline
Autonomous script to generate 257+ brand assets for a generic club management SaaS platform.
All images are text-free / typography-free — pure visual/icon design only.
Runs unattended, resume-safe via .progress.json.
Usage:
cd /home/pplate/pi_mcps
python mcp/mcp-image-gen/clubmanage_gen.py
python mcp/mcp-image-gen/clubmanage_gen.py --dry-run
python mcp/mcp-image-gen/clubmanage_gen.py --phase phase1_logos
python mcp/mcp-image-gen/clubmanage_gen.py --model heretic
Output: ~/Pictures/clubmanage_brand/ with organized subfolders.
"""
import argparse
import json
import random
import sys
import time
import urllib.request
from pathlib import Path
from typing import Dict, List, Any
# --- Configuration ---
OUTPUT_ROOT = Path.home() / "Pictures" / "clubmanage_brand"
PROGRESS_FILE = OUTPUT_ROOT / ".progress.json"
WORKFLOW_SCHNELL = Path(__file__).parent / "src/workflows/flux_schnell.json"
WORKFLOW_HERETIC = Path(__file__).parent / "src/workflows/flux2_klein_heretic.json"
# Brand prefix — generic club management SaaS, navy/teal palette, STRICTLY no text
_BP = ("professional B2B SaaS brand design, club management platform, "
"modern tech aesthetic, clean minimalist style, premium quality, "
"deep navy blue and teal color scheme, no text, no words, no letters, "
"no numbers, no labels, no typography, pure visual icon design, ")
# Negative prompt suffix for heretic (CFGGuider supports real negative guidance)
_NEG = "text, words, letters, numbers, labels, typography, fonts, captions, watermarks, titles, subtitles"
# --- Full Asset Manifest (257 assets across 6 phases) ---
ASSET_MANIFEST: List[Dict[str, Any]] = [
# ============================================================
# PHASE 1 — Logo Suite (42 assets)
# ============================================================
# Wordmark concept shapes — 5 directions (1024×512)
{"id":"p1_wm_01","phase":"phase1_logos","subfolder":"wordmark","name":"wordmark_modern_sans",
"prompt":_BP+"modern geometric sans-serif shaped abstract mark, deep navy #1A237E, clean white background, minimal people-group silhouette accent, high-end tech company wordmark shape, flat vector design","width":1024,"height":512,"steps":30},
{"id":"p1_wm_02","phase":"phase1_logos","subfolder":"wordmark","name":"wordmark_geometric",
"prompt":_BP+"geometric abstract wordmark shape, sharp angles, navy and teal color scheme, hexagonal grid subtle background, membership network silhouette, precision tech brand, white background","width":1024,"height":512,"steps":30},
{"id":"p1_wm_03","phase":"phase1_logos","subfolder":"wordmark","name":"wordmark_humanist",
"prompt":_BP+"humanist rounded abstract mark, warm approachable professional style, navy with teal accent, subtle community connection pattern, trustworthy modern brand shape, white background","width":1024,"height":512,"steps":30},
{"id":"p1_wm_04","phase":"phase1_logos","subfolder":"wordmark","name":"wordmark_slab_serif",
"prompt":_BP+"premium block geometric abstract mark, dark charcoal and deep navy palette, gold accent stripe, authoritative membership management brand shape, institutional trustworthiness, white background","width":1024,"height":512,"steps":30},
{"id":"p1_wm_05","phase":"phase1_logos","subfolder":"wordmark","name":"wordmark_minimal",
"prompt":_BP+"ultra-minimal thin abstract brand mark shape, single-color deep navy, negative space connected-people form, Apple-inspired premium minimalism, pure white background","width":1024,"height":512,"steps":30},
# Icon / Symbol Only — 10 variations (512×512)
{"id":"p1_ic_01","phase":"phase1_logos","subfolder":"icon_only","name":"icon_people_network",
"prompt":_BP+"abstract interconnected people silhouettes forming network club icon, navy on white, community membership platform, geometric precision, square icon format","width":512,"height":512,"steps":30},
{"id":"p1_ic_02","phase":"phase1_logos","subfolder":"icon_only","name":"icon_c_mark_abstract",
"prompt":_BP+"abstract letter-C shaped from human figures and connecting lines brand icon, geometric minimalist, deep navy gradient, community circle concept inside C curve, white background","width":512,"height":512,"steps":30},
{"id":"p1_ic_03","phase":"phase1_logos","subfolder":"icon_only","name":"icon_membership_card",
"prompt":_BP+"stylized membership card with embedded circuit-like membership ID pattern, navy and teal nodes and gold lines, professional membership management mark, dark background","width":512,"height":512,"steps":30},
{"id":"p1_ic_04","phase":"phase1_logos","subfolder":"icon_only","name":"icon_dashboard_grid",
"prompt":_BP+"abstract dashboard grid symbol icon, 3x3 grid of squares with bar chart and people silhouette overlaid, navy and gold, SaaS platform brand mark, white background","width":512,"height":512,"steps":30},
{"id":"p1_ic_05","phase":"phase1_logos","subfolder":"icon_only","name":"icon_calendar_pulse",
"prompt":_BP+"calendar grid merging with heartbeat pulse line icon, teal and navy, event scheduling and club vitality brand mark, half-event half-data, modern membership platform","width":512,"height":512,"steps":30},
{"id":"p1_ic_06","phase":"phase1_logos","subfolder":"icon_only","name":"icon_shield_people",
"prompt":_BP+"shield shape with people-group geometric pattern inside, navy shield, gold people outline, trust and membership management brand mark, premium badge style","width":512,"height":512,"steps":30},
{"id":"p1_ic_07","phase":"phase1_logos","subfolder":"icon_only","name":"icon_cm_monogram",
"prompt":_BP+"interlocked abstract C and M shapes with community negative space monogram, geometric precision, deep navy, gold accent, premium brand monogram, white background","width":512,"height":512,"steps":30},
{"id":"p1_ic_08","phase":"phase1_logos","subfolder":"icon_only","name":"icon_hexagon_community",
"prompt":_BP+"hexagon containing stylized connected people nodes formed from clean lines, navy hexagon dark outline, gold accent dot nodes at connection points, geometric membership brand mark, tech-forward minimal","width":512,"height":512,"steps":30},
{"id":"p1_ic_09","phase":"phase1_logos","subfolder":"icon_only","name":"icon_growth_chart",
"prompt":_BP+"upward growing membership curve transforming into ascending bar chart, navy to teal gradient, business growth metaphor, modern flat icon design","width":512,"height":512,"steps":30},
{"id":"p1_ic_10","phase":"phase1_logos","subfolder":"icon_only","name":"icon_infinity_community",
"prompt":_BP+"infinity loop symbol where loops form two abstract community circle shapes, navy line on white, continuous membership management cycle concept, premium SaaS logo mark","width":512,"height":512,"steps":30},
# Horizontal Lockups (1024×256)
{"id":"p1_lh_01","phase":"phase1_logos","subfolder":"lockup_horizontal","name":"lockup_horiz_light",
"prompt":_BP+"horizontal logo lockup icon mark left shape right, light white background, deep navy, professional club management SaaS layout, pure icon shapes only","width":1024,"height":256,"steps":30},
{"id":"p1_lh_02","phase":"phase1_logos","subfolder":"lockup_horizontal","name":"lockup_horiz_dark",
"prompt":_BP+"horizontal logo lockup icon left shape right, dark charcoal background, white and navy logo, reversed color scheme, premium brand","width":1024,"height":256,"steps":30},
{"id":"p1_lh_03","phase":"phase1_logos","subfolder":"lockup_horizontal","name":"lockup_horiz_navy_bg",
"prompt":_BP+"horizontal logo lockup, white icon on deep navy background, horizontal icon plus abstract shape, brand banner version","width":1024,"height":256,"steps":30},
{"id":"p1_lh_04","phase":"phase1_logos","subfolder":"lockup_horizontal","name":"lockup_horiz_mono",
"prompt":_BP+"horizontal logo lockup monochrome, all black on white, horizontal icon plus abstract shape, professional print-ready version","width":1024,"height":256,"steps":30},
# Stacked Lockups (512×512)
{"id":"p1_ls_01","phase":"phase1_logos","subfolder":"lockup_stacked","name":"lockup_stacked_light",
"prompt":_BP+"stacked logo lockup icon centered above abstract shape, light white background, navy brand colors, square format, professional centered layout","width":512,"height":512,"steps":30},
{"id":"p1_ls_02","phase":"phase1_logos","subfolder":"lockup_stacked","name":"lockup_stacked_dark",
"prompt":_BP+"stacked logo lockup icon centered above shape, dark charcoal background, white and teal logo, square format, dark version","width":512,"height":512,"steps":30},
{"id":"p1_ls_03","phase":"phase1_logos","subfolder":"lockup_stacked","name":"lockup_stacked_navy",
"prompt":_BP+"stacked logo lockup, white icon and shape on navy background, centered square format, brand full-color version","width":512,"height":512,"steps":30},
{"id":"p1_ls_04","phase":"phase1_logos","subfolder":"lockup_stacked","name":"lockup_stacked_mono",
"prompt":_BP+"stacked logo lockup monochrome all-black on white, icon above abstract mark, square format, print-ready logo","width":512,"height":512,"steps":30},
# Favicons (256×256)
{"id":"p1_fv_01","phase":"phase1_logos","subfolder":"favicon","name":"favicon_navy_people",
"prompt":_BP+"favicon 256x256 square app icon, navy background, white geometric people-network icon, rounded square, minimal","width":256,"height":256,"steps":30},
{"id":"p1_fv_02","phase":"phase1_logos","subfolder":"favicon","name":"favicon_dark_teal",
"prompt":_BP+"favicon dark charcoal square, teal community-nodes icon, 256x256 app icon, sharp corners, professional SaaS favicon","width":256,"height":256,"steps":30},
{"id":"p1_fv_03","phase":"phase1_logos","subfolder":"favicon","name":"favicon_white_navy",
"prompt":_BP+"favicon white background, deep navy CM abstract monogram icon, 256x256 square, minimal browser favicon","width":256,"height":256,"steps":30},
{"id":"p1_fv_04","phase":"phase1_logos","subfolder":"favicon","name":"favicon_gold_dark",
"prompt":_BP+"favicon dark background, gold amber membership management icon mark, 256x256 premium app icon, warm gold on charcoal","width":256,"height":256,"steps":30},
{"id":"p1_fv_05","phase":"phase1_logos","subfolder":"favicon","name":"favicon_gradient_navy",
"prompt":_BP+"favicon midnight to navy gradient background, white geometric icon, 256x256 square, modern SaaS app icon with gradient","width":256,"height":256,"steps":30},
{"id":"p1_fv_06","phase":"phase1_logos","subfolder":"favicon","name":"favicon_outline_style",
"prompt":_BP+"favicon white background, outline-only teal community network icon, thin line illustration, 256x256, minimalist","width":256,"height":256,"steps":30},
{"id":"p1_fv_07","phase":"phase1_logos","subfolder":"favicon","name":"favicon_rounded_modern",
"prompt":_BP+"iOS-style rounded square app icon, navy gradient background, white membership brand mark, 256x256, premium mobile app icon","width":256,"height":256,"steps":30},
{"id":"p1_fv_08","phase":"phase1_logos","subfolder":"favicon","name":"favicon_badge_style",
"prompt":_BP+"badge-style icon with thin border ring, navy center with white CM abstract shape, 256x256 square, club software favicon","width":256,"height":256,"steps":30},
# ============================================================
# PHASE 2 — Banner Suite (50 assets)
# ============================================================
# Hero Website Banners (1280×720)
{"id":"p2_hw_01","phase":"phase2_banners","subfolder":"hero_website","name":"hero_dashboard_showcase",
"prompt":_BP+"website hero banner, dark charcoal background, teal UI dashboard shapes floating right, bold geometric area left, gold accent lines, enterprise software marketing visual","width":1280,"height":720,"steps":30},
{"id":"p2_hw_02","phase":"phase2_banners","subfolder":"hero_website","name":"hero_compliance_trust",
"prompt":_BP+"website hero banner, trust theme, deep navy gradient, shield and checkmark iconography, membership management, white geometric area, subtle hexagonal pattern overlay","width":1280,"height":720,"steps":30},
{"id":"p2_hw_03","phase":"phase2_banners","subfolder":"hero_website","name":"hero_analytics_data",
"prompt":_BP+"website hero banner, analytics theme, dark background, glowing data visualization charts in navy and gold, business metrics, abstract data flowing design","width":1280,"height":720,"steps":30},
{"id":"p2_hw_04","phase":"phase2_banners","subfolder":"hero_website","name":"hero_team_enterprise",
"prompt":_BP+"website hero banner, enterprise team theme, split design navy left panel white right panel, diagonal split, geometric accents, SaaS marketing visual","width":1280,"height":720,"steps":30},
{"id":"p2_hw_05","phase":"phase2_banners","subfolder":"hero_website","name":"hero_community_tech",
"prompt":_BP+"website hero banner, community meets technology, abstract people nodes growing from data grid, navy organic forms with teal circuit lines, dark sophisticated background","width":1280,"height":720,"steps":30},
# LinkedIn Banners (1584×396)
{"id":"p2_li_01","phase":"phase2_banners","subfolder":"linkedin","name":"linkedin_corporate_navy",
"prompt":_BP+"LinkedIn company banner, deep navy background, white abstract icon centered, club business management, clean minimal corporate header visual","width":1584,"height":396,"steps":30},
{"id":"p2_li_02","phase":"phase2_banners","subfolder":"linkedin","name":"linkedin_dark_gold",
"prompt":_BP+"LinkedIn banner, dark charcoal background, gold accent stripe bottom, professional enterprise header visual","width":1584,"height":396,"steps":30},
{"id":"p2_li_03","phase":"phase2_banners","subfolder":"linkedin","name":"linkedin_pattern_overlay",
"prompt":_BP+"LinkedIn banner, navy base, subtle hexagonal membership molecule pattern overlay, semi-transparent, company branding prominent, wide horizontal header","width":1584,"height":396,"steps":30},
{"id":"p2_li_04","phase":"phase2_banners","subfolder":"linkedin","name":"linkedin_split_design",
"prompt":_BP+"LinkedIn banner, split design left dark right navy, diagonal split line, club management platform branding, clean sharp design","width":1584,"height":396,"steps":30},
{"id":"p2_li_05","phase":"phase2_banners","subfolder":"linkedin","name":"linkedin_metrics_banner",
"prompt":_BP+"LinkedIn banner showing abstract business metrics visualization, data-forward icons, navy with gold shapes, analytics platform positioning","width":1584,"height":396,"steps":30},
{"id":"p2_li_06","phase":"phase2_banners","subfolder":"linkedin","name":"linkedin_gradient_minimal",
"prompt":_BP+"LinkedIn banner, midnight to navy gradient, minimal white brand shape only, ultra-clean professional header","width":1584,"height":396,"steps":30},
# Twitter/X Headers (1500×500)
{"id":"p2_tw_01","phase":"phase2_banners","subfolder":"twitter_x","name":"twitter_bold_navy",
"prompt":_BP+"Twitter X header banner, bold navy full bleed background, large white brand icon shape, membership management visual, strong social media presence","width":1500,"height":500,"steps":30},
{"id":"p2_tw_02","phase":"phase2_banners","subfolder":"twitter_x","name":"twitter_dark_pattern",
"prompt":_BP+"Twitter header, dark charcoal with subtle community geometric pattern, navy and gold accents, professional SaaS brand social header","width":1500,"height":500,"steps":30},
{"id":"p2_tw_03","phase":"phase2_banners","subfolder":"twitter_x","name":"twitter_product_hint",
"prompt":_BP+"Twitter header, dark background with abstract dashboard interface shapes, club management software preview silhouette, professional tech company header","width":1500,"height":500,"steps":30},
{"id":"p2_tw_04","phase":"phase2_banners","subfolder":"twitter_x","name":"twitter_community_abstract",
"prompt":_BP+"Twitter header, abstract community nodes growing into data streams, navy to dark gradient, artistic organic meets digital aesthetic","width":1500,"height":500,"steps":30},
{"id":"p2_tw_05","phase":"phase2_banners","subfolder":"twitter_x","name":"twitter_network",
"prompt":_BP+"Twitter header, membership network theme, connected nodes visualization in teal and navy, SaaS platform connecting businesses","width":1500,"height":500,"steps":30},
{"id":"p2_tw_06","phase":"phase2_banners","subfolder":"twitter_x","name":"twitter_white_clean",
"prompt":_BP+"Twitter header, clean white background, navy brand elements only, ultra-professional minimal social media header","width":1500,"height":500,"steps":30},
# Facebook Covers (820×312)
{"id":"p2_fb_01","phase":"phase2_banners","subfolder":"facebook_cover","name":"facebook_primary_brand",
"prompt":_BP+"Facebook cover photo, primary brand colors navy and charcoal, professional club business company cover, centered branding icon","width":820,"height":312,"steps":30},
{"id":"p2_fb_02","phase":"phase2_banners","subfolder":"facebook_cover","name":"facebook_dark_professional",
"prompt":_BP+"Facebook cover, dark sophisticated background, white and gold brand icon elements, enterprise platform premium cover","width":820,"height":312,"steps":30},
{"id":"p2_fb_03","phase":"phase2_banners","subfolder":"facebook_cover","name":"facebook_membership_theme",
"prompt":_BP+"Facebook cover, membership and community theme, shield and verification iconography, navy professional company cover","width":820,"height":312,"steps":30},
{"id":"p2_fb_04","phase":"phase2_banners","subfolder":"facebook_cover","name":"facebook_product_launch",
"prompt":_BP+"Facebook cover, product launch announcement style, bold navy with gold accents, exciting software release visual, dynamic tech company cover","width":820,"height":312,"steps":30},
{"id":"p2_fb_05","phase":"phase2_banners","subfolder":"facebook_cover","name":"facebook_industry_leader",
"prompt":_BP+"Facebook cover, industry leadership positioning, club management market leader visual, professional authoritative design, navy and gold","width":820,"height":312,"steps":30},
{"id":"p2_fb_06","phase":"phase2_banners","subfolder":"facebook_cover","name":"facebook_seasonal_spring",
"prompt":_BP+"Facebook cover, spring fresh brand, bright teal with navy organic elements, membership growth season theme, professional seasonal cover","width":820,"height":312,"steps":30},
# Google Display Ads (16 assets - 4 concepts × 4 sizes)
{"id":"p2_ga_01a","phase":"phase2_banners","subfolder":"google_display","name":"gad_simplify_728x90",
"prompt":_BP+"Google display ad leaderboard, simplify club management theme, navy button shape, white background, professional B2B ad visual","width":728,"height":90,"steps":30},
{"id":"p2_ga_01b","phase":"phase2_banners","subfolder":"google_display","name":"gad_simplify_300x250",
"prompt":_BP+"Google display ad medium rectangle, simplify club management theme, navy design, bold icon shapes, professional SaaS ad creative","width":300,"height":250,"steps":30},
{"id":"p2_ga_01c","phase":"phase2_banners","subfolder":"google_display","name":"gad_simplify_160x600",
"prompt":_BP+"Google display ad wide skyscraper, simplify club management theme, tall vertical format, navy, professional B2B ad","width":160,"height":600,"steps":30},
{"id":"p2_ga_01d","phase":"phase2_banners","subfolder":"google_display","name":"gad_simplify_320x50",
"prompt":_BP+"Google display ad mobile banner, simplify management theme, minimal mobile ad, navy, club management SaaS","width":320,"height":50,"steps":30},
{"id":"p2_ga_02a","phase":"phase2_banners","subfolder":"google_display","name":"gad_manage_728x90",
"prompt":_BP+"Google display ad, manage everything club business theme, dashboard preview hint icons, dark charcoal professional leaderboard banner","width":728,"height":90,"steps":30},
{"id":"p2_ga_02b","phase":"phase2_banners","subfolder":"google_display","name":"gad_manage_300x250",
"prompt":_BP+"Google display ad, manage everything club operations theme, product dashboard icon glimpse, navy dark professional rectangle ad","width":300,"height":250,"steps":30},
{"id":"p2_ga_02c","phase":"phase2_banners","subfolder":"google_display","name":"gad_manage_160x600",
"prompt":_BP+"Google display skyscraper, manage club business operations theme, vertical product feature icon list visual, navy professional tall ad","width":160,"height":600,"steps":30},
{"id":"p2_ga_02d","phase":"phase2_banners","subfolder":"google_display","name":"gad_manage_320x50",
"prompt":_BP+"mobile banner, manage club business theme, ultra-minimal mobile ad strip, brand colors","width":320,"height":50,"steps":30},
{"id":"p2_ga_03a","phase":"phase2_banners","subfolder":"google_display","name":"gad_grow_728x90",
"prompt":_BP+"Google ad, grow your club business theme, upward growth arrow with member silhouette, gold and navy, professional B2B leaderboard","width":728,"height":90,"steps":30},
{"id":"p2_ga_03b","phase":"phase2_banners","subfolder":"google_display","name":"gad_grow_300x250",
"prompt":_BP+"Google ad, club business growth theme, ascending graph with navy growth visual, professional SaaS rectangle ad","width":300,"height":250,"steps":30},
{"id":"p2_ga_03c","phase":"phase2_banners","subfolder":"google_display","name":"gad_grow_160x600",
"prompt":_BP+"skyscraper ad, club business growth vertical story, people nodes growing upward through data visualization, navy tall display ad","width":160,"height":600,"steps":30},
{"id":"p2_ga_03d","phase":"phase2_banners","subfolder":"google_display","name":"gad_grow_320x50",
"prompt":_BP+"mobile ad, grow club membership, minimal mobile strip ad navy","width":320,"height":50,"steps":30},
{"id":"p2_ga_04a","phase":"phase2_banners","subfolder":"google_display","name":"gad_trial_728x90",
"prompt":_BP+"Google ad, free trial call to action shape, bold gold CTA shape, navy professional leaderboard, club management SaaS trial offer visual","width":728,"height":90,"steps":30},
{"id":"p2_ga_04b","phase":"phase2_banners","subfolder":"google_display","name":"gad_trial_300x250",
"prompt":_BP+"Google ad, free trial offer icon, gold button shape navy design, club management platform trial CTA rectangle ad","width":300,"height":250,"steps":30},
{"id":"p2_ga_04c","phase":"phase2_banners","subfolder":"google_display","name":"gad_trial_160x600",
"prompt":_BP+"skyscraper ad, free trial CTA vertical ad, gold call to action arrow shape, navy SaaS platform","width":160,"height":600,"steps":30},
{"id":"p2_ga_04d","phase":"phase2_banners","subfolder":"google_display","name":"gad_trial_320x50",
"prompt":_BP+"mobile ad, free trial minimal mobile strip, gold CTA shape navy brand","width":320,"height":50,"steps":30},
# App Store Feature Graphics (1024×500)
{"id":"p2_as_01","phase":"phase2_banners","subfolder":"app_store","name":"appstore_hero_dashboard",
"prompt":_BP+"app store feature graphic, club management app showcase, dark background with app dashboard UI icon preview shapes, navy interface elements, professional mobile app store hero","width":1024,"height":500,"steps":30},
{"id":"p2_as_02","phase":"phase2_banners","subfolder":"app_store","name":"appstore_membership_features",
"prompt":_BP+"app store feature graphic, membership features highlight, shield icons and checkmarks, navy professional, club membership app feature graphic","width":1024,"height":500,"steps":30},
{"id":"p2_as_03","phase":"phase2_banners","subfolder":"app_store","name":"appstore_analytics_focus",
"prompt":_BP+"app store feature graphic, business analytics and reporting feature, dashboard chart shapes preview, gold and navy data visualization, club business intelligence app","width":1024,"height":500,"steps":30},
{"id":"p2_as_04","phase":"phase2_banners","subfolder":"app_store","name":"appstore_team_management",
"prompt":_BP+"app store feature graphic, team and staff management, connected team nodes visualization, navy professional, club staff team management app","width":1024,"height":500,"steps":30},
# Email Header Banners (600×200)
{"id":"p2_em_01","phase":"phase2_banners","subfolder":"email_header","name":"email_primary_brand",
"prompt":_BP+"email header banner, primary brand header, navy with white icon area, professional email marketing header","width":600,"height":200,"steps":30},
{"id":"p2_em_02","phase":"phase2_banners","subfolder":"email_header","name":"email_welcome",
"prompt":_BP+"welcome email header, warm welcome theme, navy and teal gradient, onboarding email banner, new user email header","width":600,"height":200,"steps":30},
{"id":"p2_em_03","phase":"phase2_banners","subfolder":"email_header","name":"email_product_update",
"prompt":_BP+"product update email header, new features announcement, gold accent notification style, software update email banner","width":600,"height":200,"steps":30},
{"id":"p2_em_04","phase":"phase2_banners","subfolder":"email_header","name":"email_membership_alert",
"prompt":_BP+"membership alert email header, urgent notification theme, amber gold accent on dark, regulatory update email header, professional alert banner","width":600,"height":200,"steps":30},
{"id":"p2_em_05","phase":"phase2_banners","subfolder":"email_header","name":"email_monthly_report",
"prompt":_BP+"monthly report email header, data and analytics icon theme, chart shapes preview, navy professional, club business monthly summary","width":600,"height":200,"steps":30},
{"id":"p2_em_06","phase":"phase2_banners","subfolder":"email_header","name":"email_trial_ending",
"prompt":_BP+"trial ending email header, urgency CTA icon theme, gold highlight on dark, platform trial expiry email banner, convert to paid","width":600,"height":200,"steps":30},
{"id":"p2_em_07","phase":"phase2_banners","subfolder":"email_header","name":"email_invoice",
"prompt":_BP+"invoice and billing email header, clean minimal professional, white and navy, SaaS billing email header, enterprise professional","width":600,"height":200,"steps":30},
{"id":"p2_em_08","phase":"phase2_banners","subfolder":"email_header","name":"email_dark_premium",
"prompt":_BP+"dark premium email header, dark charcoal with gold and navy accents, VIP or enterprise tier email, club management premium header","width":600,"height":200,"steps":30},
# ============================================================
# PHASE 3 — Social Media Asset Pack (60 assets)
# ============================================================
# Instagram Square Posts (1024×1024)
{"id":"p3_ig_01","phase":"phase3_social","subfolder":"instagram_square","name":"insta_inventory_mgmt",
"prompt":_BP+"Instagram post, inventory management feature highlight, stock tracking dashboard icon visualization, navy UI elements, bold feature announcement visual, clean white and dark design","width":1024,"height":1024,"steps":30},
{"id":"p3_ig_02","phase":"phase3_social","subfolder":"instagram_square","name":"insta_member_track",
"prompt":_BP+"Instagram post, member tracking feature, checklist visualization, shield and checkmark icons, navy and gold, club management SaaS post","width":1024,"height":1024,"steps":30},
{"id":"p3_ig_03","phase":"phase3_social","subfolder":"instagram_square","name":"insta_analytics_dash",
"prompt":_BP+"Instagram post, analytics dashboard feature, business intelligence data visualization icon, navy charts on dark background, club business analytics","width":1024,"height":1024,"steps":30},
{"id":"p3_ig_04","phase":"phase3_social","subfolder":"instagram_square","name":"insta_staff_scheduling",
"prompt":_BP+"Instagram post, staff scheduling feature, team calendar and shift management visualization, club staff management, clean navy post","width":1024,"height":1024,"steps":30},
{"id":"p3_ig_05","phase":"phase3_social","subfolder":"instagram_square","name":"insta_pos_integration",
"prompt":_BP+"Instagram post, POS system integration feature, point-of-sale connection visualization, integration nodes and arrows, navy and gold tech post","width":1024,"height":1024,"steps":30},
{"id":"p3_ig_06","phase":"phase3_social","subfolder":"instagram_square","name":"insta_reporting",
"prompt":_BP+"Instagram post, automated reporting feature, beautiful report document preview shape, navy professional document visualization post","width":1024,"height":1024,"steps":30},
{"id":"p3_ig_07","phase":"phase3_social","subfolder":"instagram_square","name":"insta_multi_location",
"prompt":_BP+"Instagram post, multi-location management feature, club chain management, location pins on map with connecting navy lines","width":1024,"height":1024,"steps":30},
{"id":"p3_ig_08","phase":"phase3_social","subfolder":"instagram_square","name":"insta_mobile_app",
"prompt":_BP+"Instagram post, mobile app feature highlight, iPhone and Android app shape mockup, club management on-the-go, navy app UI post","width":1024,"height":1024,"steps":30},
{"id":"p3_ig_09","phase":"phase3_social","subfolder":"instagram_square","name":"insta_security",
"prompt":_BP+"Instagram post, enterprise security feature, data protection and encryption visualization, shield with lock icon, dark professional navy security post","width":1024,"height":1024,"steps":30},
{"id":"p3_ig_10","phase":"phase3_social","subfolder":"instagram_square","name":"insta_brand_story",
"prompt":_BP+"Instagram brand story post, company mission, club empowerment, beautiful abstract people and technology fusion illustration, navy and gold, inspiring brand post","width":1024,"height":1024,"steps":30},
# Instagram Stories (720×1280)
{"id":"p3_st_01","phase":"phase3_social","subfolder":"instagram_story","name":"story_onboarding",
"prompt":_BP+"Instagram story, onboarding tutorial slide, step-by-step platform setup icon, navy vertical mobile design, swipe up arrow CTA shape, professional SaaS story","width":720,"height":1280,"steps":30},
{"id":"p3_st_02","phase":"phase3_social","subfolder":"instagram_story","name":"story_feature_announce",
"prompt":_BP+"Instagram story, new feature announcement, bold navy vertical design, software update story, gold accent highlight, arrow CTA shape","width":720,"height":1280,"steps":30},
{"id":"p3_st_03","phase":"phase3_social","subfolder":"instagram_story","name":"story_stat_highlight",
"prompt":_BP+"Instagram story, industry statistic highlight visual, large bold number shape, dark background gold number navy accent, data-driven story template","width":720,"height":1280,"steps":30},
{"id":"p3_st_04","phase":"phase3_social","subfolder":"instagram_story","name":"story_customer_quote",
"prompt":_BP+"Instagram story, customer testimonial visual, elegant quote marks shape on navy background, club business owner testimonial style, premium brand story","width":720,"height":1280,"steps":30},
{"id":"p3_st_05","phase":"phase3_social","subfolder":"instagram_story","name":"story_poll_template",
"prompt":_BP+"Instagram story, interactive poll template visual, club industry question bar icons, dark professional background, poll shapes styled in navy and gold","width":720,"height":1280,"steps":30},
{"id":"p3_st_06","phase":"phase3_social","subfolder":"instagram_story","name":"story_countdown",
"prompt":_BP+"Instagram story, countdown timer event template, launch deadline visual, bold dramatic dark background with gold countdown shape","width":720,"height":1280,"steps":30},
{"id":"p3_st_07","phase":"phase3_social","subfolder":"instagram_story","name":"story_tips_series",
"prompt":_BP+"Instagram story, club management tip of the day template, bright educational story icon, numbered tip format, teal navy professional guidance visual","width":720,"height":1280,"steps":30},
{"id":"p3_st_08","phase":"phase3_social","subfolder":"instagram_story","name":"story_free_trial",
"prompt":_BP+"Instagram story, free trial CTA story, bold gold arrow shape on dark navy, club management platform sign up visual, strong conversion design","width":720,"height":1280,"steps":30},
# LinkedIn Post Graphics (1200×627)
{"id":"p3_lp_01","phase":"phase3_social","subfolder":"linkedin_post","name":"linkedin_thought_leader",
"prompt":_BP+"LinkedIn post graphic, thought leadership article header visual, club industry insights icon, professional editorial design, navy brand with white content area","width":1200,"height":627,"steps":30},
{"id":"p3_lp_02","phase":"phase3_social","subfolder":"linkedin_post","name":"linkedin_product_demo",
"prompt":_BP+"LinkedIn post, product demo announcement visual, screenshot preview icon teaser, club management platform demo invitation shape, navy professional post","width":1200,"height":627,"steps":30},
{"id":"p3_lp_03","phase":"phase3_social","subfolder":"linkedin_post","name":"linkedin_hiring",
"prompt":_BP+"LinkedIn hiring post, we are hiring banner shapes, team growth announcement visual, professional club tech company hiring graphic, navy and gold, people silhouettes","width":1200,"height":627,"steps":30},
{"id":"p3_lp_04","phase":"phase3_social","subfolder":"linkedin_post","name":"linkedin_industry_stat",
"prompt":_BP+"LinkedIn post, club industry statistic infographic shapes, large bold number visual, professional B2B data post, navy","width":1200,"height":627,"steps":30},
{"id":"p3_lp_05","phase":"phase3_social","subfolder":"linkedin_post","name":"linkedin_partnership",
"prompt":_BP+"LinkedIn partnership announcement, strategic partnership visual, club tech ecosystem, professional announcement graphic navy","width":1200,"height":627,"steps":30},
{"id":"p3_lp_06","phase":"phase3_social","subfolder":"linkedin_post","name":"linkedin_webinar",
"prompt":_BP+"LinkedIn webinar promotion post, club compliance webinar announcement visual, calendar icon event, professional event promotion, navy dark design","width":1200,"height":627,"steps":30},
{"id":"p3_lp_07","phase":"phase3_social","subfolder":"linkedin_post","name":"linkedin_case_study",
"prompt":_BP+"LinkedIn case study post, customer success story preview visual, club success metrics chart shapes, gold numbers on dark, professional B2B case study promotional","width":1200,"height":627,"steps":30},
{"id":"p3_lp_08","phase":"phase3_social","subfolder":"linkedin_post","name":"linkedin_award",
"prompt":_BP+"LinkedIn award announcement post, award or recognition visual, gold trophy badge element shape, club tech industry recognition, celebratory professional post","width":1200,"height":627,"steps":30},
# Feature Announcement Cards (1024×1024)
{"id":"p3_fc_01","phase":"phase3_social","subfolder":"feature_cards","name":"feature_barcode_scan",
"prompt":_BP+"feature card, barcode scanning inventory management, membership card scan interface icon, mobile scanning visualization, navy UI feature card","width":1024,"height":1024,"steps":30},
{"id":"p3_fc_02","phase":"phase3_social","subfolder":"feature_cards","name":"feature_auto_reports",
"prompt":_BP+"feature card, automated reporting, automation icon with checklist shapes, reporting automation, navy professional feature announcement","width":1024,"height":1024,"steps":30},
{"id":"p3_fc_03","phase":"phase3_social","subfolder":"feature_cards","name":"feature_real_time_alerts",
"prompt":_BP+"feature card, real-time alerts and notifications, bell notification icon with threshold alert shapes, gold alert accent on dark, notification feature","width":1024,"height":1024,"steps":30},
{"id":"p3_fc_04","phase":"phase3_social","subfolder":"feature_cards","name":"feature_member_portal",
"prompt":_BP+"feature card, member self-service portal icon, club member login interface shape, clean navy member management, user portal visualization","width":1024,"height":1024,"steps":30},
{"id":"p3_fc_05","phase":"phase3_social","subfolder":"feature_cards","name":"feature_api_integrations",
"prompt":_BP+"feature card, API integrations ecosystem icon, connected software nodes with hub, tech stack integration visualization, navy connection diagram","width":1024,"height":1024,"steps":30},
{"id":"p3_fc_06","phase":"phase3_social","subfolder":"feature_cards","name":"feature_batch_tracking",
"prompt":_BP+"feature card, batch and lot tracking icon, product chain of custody visualization, numbered batch tracking flow shapes, compliance feature card","width":1024,"height":1024,"steps":30},
{"id":"p3_fc_07","phase":"phase3_social","subfolder":"feature_cards","name":"feature_document_mgmt",
"prompt":_BP+"feature card, document management system icon, licensing and permit documents organized, folder icons in navy, digital document management","width":1024,"height":1024,"steps":30},
{"id":"p3_fc_08","phase":"phase3_social","subfolder":"feature_cards","name":"feature_role_permissions",
"prompt":_BP+"feature card, role-based permissions feature icon, user role hierarchy visualization, shield with user silhouettes, team access control, dark professional","width":1024,"height":1024,"steps":30},
{"id":"p3_fc_09","phase":"phase3_social","subfolder":"feature_cards","name":"feature_export_reports",
"prompt":_BP+"feature card, one-click export and reporting icon, PDF report generation shape, download arrow with report preview, navy feature card","width":1024,"height":1024,"steps":30},
{"id":"p3_fc_10","phase":"phase3_social","subfolder":"feature_cards","name":"feature_audit_trail",
"prompt":_BP+"feature card, complete audit trail icon, transaction history timeline, chronological log entry shapes, audit visualization, professional dark card","width":1024,"height":1024,"steps":30},
# Testimonial Cards (1024×1024)
{"id":"p3_tc_01","phase":"phase3_social","subfolder":"testimonial_cards","name":"testimonial_dark_elegant",
"prompt":_BP+"testimonial card, dark charcoal elegant quote card, gold quotation mark shapes, abstract customer silhouette, club business owner testimonial visual, premium design","width":1024,"height":1024,"steps":30},
{"id":"p3_tc_02","phase":"phase3_social","subfolder":"testimonial_cards","name":"testimonial_navy_bold",
"prompt":_BP+"testimonial card, bold navy background, white quote mark shapes, customer review visual of club management SaaS, bold confident design","width":1024,"height":1024,"steps":30},
{"id":"p3_tc_03","phase":"phase3_social","subfolder":"testimonial_cards","name":"testimonial_light_minimal",
"prompt":_BP+"testimonial card, light white minimal quote card, navy accent line, clean professional customer testimonial visual, minimal elegant design","width":1024,"height":1024,"steps":30},
{"id":"p3_tc_04","phase":"phase3_social","subfolder":"testimonial_cards","name":"testimonial_star_rating",
"prompt":_BP+"testimonial card, 5-star rating visual, gold stars prominently displayed, abstract club management platform review","width":1024,"height":1024,"steps":30},
{"id":"p3_tc_05","phase":"phase3_social","subfolder":"testimonial_cards","name":"testimonial_split_design",
"prompt":_BP+"testimonial card, split design half dark half navy, quote on dark side, customer info shape on navy side, club SaaS testimonial","width":1024,"height":1024,"steps":30},
{"id":"p3_tc_06","phase":"phase3_social","subfolder":"testimonial_cards","name":"testimonial_gradient",
"prompt":_BP+"testimonial card, midnight to navy gradient background, white elegant quote mark shapes, customer testimonial gradient design","width":1024,"height":1024,"steps":30},
# Stat/Data Cards (1024×1024)
{"id":"p3_sc_01","phase":"phase3_social","subfolder":"stat_cards","name":"stat_market_size",
"prompt":_BP+"stat card, club management market size statistic, large bold dollar amount shape, navy gold number on dark background, industry market data visual","width":1024,"height":1024,"steps":30},
{"id":"p3_sc_02","phase":"phase3_social","subfolder":"stat_cards","name":"stat_cost_reduction",
"prompt":_BP+"stat card, cost reduction statistic visual, percentage savings with management software icon, gold percentage shape, club business cost savings","width":1024,"height":1024,"steps":30},
{"id":"p3_sc_03","phase":"phase3_social","subfolder":"stat_cards","name":"stat_time_savings",
"prompt":_BP+"stat card, hours saved per week statistic, clock icon with bold number shape, club operational time savings, navy professional","width":1024,"height":1024,"steps":30},
{"id":"p3_sc_04","phase":"phase3_social","subfolder":"stat_cards","name":"stat_membership_growth",
"prompt":_BP+"stat card, membership industry growth rate, upward arrow with percentage growth shape, membership retail market growth stat, gold growth number on dark","width":1024,"height":1024,"steps":30},
{"id":"p3_sc_05","phase":"phase3_social","subfolder":"stat_cards","name":"stat_compliance_fines",
"prompt":_BP+"stat card, compliance violation fine amounts, regulatory penalty warning stat shape, amber warning colors, avoid fines messaging icon","width":1024,"height":1024,"steps":30},
{"id":"p3_sc_06","phase":"phase3_social","subfolder":"stat_cards","name":"stat_customer_count",
"prompt":_BP+"stat card, number of clubs managed, large customer count statistic shape, navy social proof data card, platform traction metric","width":1024,"height":1024,"steps":30},
{"id":"p3_sc_07","phase":"phase3_social","subfolder":"stat_cards","name":"stat_roi_metric",
"prompt":_BP+"stat card, ROI return on investment metric for club management software, large gold ROI percentage shape, business value data card","width":1024,"height":1024,"steps":30},
{"id":"p3_sc_08","phase":"phase3_social","subfolder":"stat_cards","name":"stat_global_clubs",
"prompt":_BP+"stat card, number of registered clubs worldwide, globe icon with country count shape, club management global market stat, navy global market visual","width":1024,"height":1024,"steps":30},
# ============================================================
# PHASE 4 — UI & Product Assets (32 assets)
# ============================================================
# App Icons (1024×1024)
{"id":"p4_ai_01","phase":"phase4_ui","subfolder":"app_icons","name":"appicon_ios_navy",
"prompt":_BP+"iOS app icon, Apple iOS style rounded square, navy gradient background, white membership network icon mark, premium mobile app icon, App Store quality","width":1024,"height":1024,"steps":30},
{"id":"p4_ai_02","phase":"phase4_ui","subfolder":"app_icons","name":"appicon_ios_dark",
"prompt":_BP+"iOS app icon, dark mode iOS icon, dark charcoal with navy and gold brand mark, premium dark app icon, club management mobile app","width":1024,"height":1024,"steps":30},
{"id":"p4_ai_03","phase":"phase4_ui","subfolder":"app_icons","name":"appicon_ios_gold",
"prompt":_BP+"iOS app icon, premium gold accent, deep navy background with gold membership circuit brand mark, luxury club management app icon","width":1024,"height":1024,"steps":30},
{"id":"p4_ai_04","phase":"phase4_ui","subfolder":"app_icons","name":"appicon_android_material",
"prompt":_BP+"Android app icon, Material Design 3 style adaptive icon, navy with white icon shape, Google Play Store quality, club management Android app","width":1024,"height":1024,"steps":30},
{"id":"p4_ai_05","phase":"phase4_ui","subfolder":"app_icons","name":"appicon_android_dark",
"prompt":_BP+"Android dark mode app icon, dark adaptive icon, navy outline on near-black, Material You dark theme, club management app","width":1024,"height":1024,"steps":30},
{"id":"p4_ai_06","phase":"phase4_ui","subfolder":"app_icons","name":"appicon_gradient_modern",
"prompt":_BP+"app icon, modern gradient icon, midnight to navy gradient background, white geometric membership tech mark, contemporary design","width":1024,"height":1024,"steps":30},
{"id":"p4_ai_07","phase":"phase4_ui","subfolder":"app_icons","name":"appicon_flat_clean",
"prompt":_BP+"app icon, flat design icon, solid navy no gradient, white minimal icon mark, flat design philosophy, simple clean club management","width":1024,"height":1024,"steps":30},
{"id":"p4_ai_08","phase":"phase4_ui","subfolder":"app_icons","name":"appicon_neumorphic",
"prompt":_BP+"app icon, neumorphic soft UI style, light slate background with embossed membership network icon, subtle shadows, premium modern icon design","width":1024,"height":1024,"steps":30},
# Device Mockups
{"id":"p4_dm_01","phase":"phase4_ui","subfolder":"device_mockups","name":"mockup_macbook",
"prompt":_BP+"dashboard shown on MacBook Pro shape mockup, professional product marketing, club management SaaS on Apple laptop silhouette, navy UI on screen shape, clean white studio background","width":1024,"height":640,"steps":30},
{"id":"p4_dm_02","phase":"phase4_ui","subfolder":"device_mockups","name":"mockup_ipad",
"prompt":_BP+"dashboard on iPad Pro shape mockup, club management tablet interface icon, navy UI on Apple iPad silhouette, clean marketing product shot, white background","width":1024,"height":768,"steps":30},
{"id":"p4_dm_03","phase":"phase4_ui","subfolder":"device_mockups","name":"mockup_iphone",
"prompt":_BP+"mobile app on iPhone shape mockup, club management mobile interface icon, navy green mobile UI, clean product marketing shot, white background","width":390,"height":844,"steps":30},
{"id":"p4_dm_04","phase":"phase4_ui","subfolder":"device_mockups","name":"mockup_desktop_monitor",
"prompt":_BP+"dashboard on large desktop monitor shape mockup, club management enterprise software on wide screen silhouette, dark UI visible, professional product marketing display","width":1280,"height":720,"steps":30},
{"id":"p4_dm_05","phase":"phase4_ui","subfolder":"device_mockups","name":"mockup_android_phone",
"prompt":_BP+"mobile app on Android phone shape mockup, club management Android interface icon, Material Design navy UI, product marketing shot white background","width":390,"height":844,"steps":30},
# Onboarding Illustrations (800×600)
{"id":"p4_ob_01","phase":"phase4_ui","subfolder":"onboarding_illustrations","name":"onboard_inventory",
"prompt":_BP+"onboarding illustration, inventory management scene icon, product shelves with digital inventory overlay shapes, flat illustration style, navy and teal","width":800,"height":600,"steps":30},
{"id":"p4_ob_02","phase":"phase4_ui","subfolder":"onboarding_illustrations","name":"onboard_compliance",
"prompt":_BP+"onboarding illustration, compliance tracking scene icon, person silhouette reviewing regulatory documents with digital checklist shape, confident professional flat illustration","width":800,"height":600,"steps":30},
{"id":"p4_ob_03","phase":"phase4_ui","subfolder":"onboarding_illustrations","name":"onboard_analytics",
"prompt":_BP+"onboarding illustration, analytics and reporting scene icon, business person silhouette analyzing sales charts, dashboard visualization, navy data visualization flat","width":800,"height":600,"steps":30},
{"id":"p4_ob_04","phase":"phase4_ui","subfolder":"onboarding_illustrations","name":"onboard_staff",
"prompt":_BP+"onboarding illustration, staff scheduling scene icon, team member silhouettes with shift calendar shape, club team management, professional flat art navy","width":800,"height":600,"steps":30},
{"id":"p4_ob_05","phase":"phase4_ui","subfolder":"onboarding_illustrations","name":"onboard_pos",
"prompt":_BP+"onboarding illustration, POS integration scene icon, point of sale system connected to management platform shapes, tech integration flat illustration, navy","width":800,"height":600,"steps":30},
{"id":"p4_ob_06","phase":"phase4_ui","subfolder":"onboarding_illustrations","name":"onboard_reporting",
"prompt":_BP+"onboarding illustration, automated reporting scene icon, report documents generating automatically shapes, magic automation illustration, navy gold professional flat art","width":800,"height":600,"steps":30},
# Empty States (600×400)
{"id":"p4_es_01","phase":"phase4_ui","subfolder":"empty_states","name":"empty_no_data",
"prompt":_BP+"empty state illustration, no data yet icon, friendly empty chart shape, get started visual, navy minimal SaaS illustration","width":600,"height":400,"steps":30},
{"id":"p4_es_02","phase":"phase4_ui","subfolder":"empty_states","name":"empty_no_results",
"prompt":_BP+"empty state illustration, no search results found icon, magnifying glass with empty bubble, friendly empty state, navy minimal","width":600,"height":400,"steps":30},
{"id":"p4_es_03","phase":"phase4_ui","subfolder":"empty_states","name":"empty_no_alerts",
"prompt":_BP+"empty state illustration, no alerts icon, happy shield with checkmark, all clear illustration, club compliance all good state, navy positive","width":600,"height":400,"steps":30},
{"id":"p4_es_04","phase":"phase4_ui","subfolder":"empty_states","name":"empty_no_members",
"prompt":_BP+"empty state illustration, no members added yet icon, friendly people silhouettes with plus icon, club member management, navy add members","width":600,"height":400,"steps":30},
{"id":"p4_es_05","phase":"phase4_ui","subfolder":"empty_states","name":"empty_loading_data",
"prompt":_BP+"empty state illustration, loading and processing data icon, gentle spinner shapes, patient loading state, navy minimal illustration","width":600,"height":400,"steps":30},
{"id":"p4_es_06","phase":"phase4_ui","subfolder":"empty_states","name":"empty_offline",
"prompt":_BP+"empty state illustration, offline or connection error icon, disconnected wifi shape, friendly error state, amber warning on navy","width":600,"height":400,"steps":30},
# Splash/Loading Screens (720×1280)
{"id":"p4_sp_01","phase":"phase4_ui","subfolder":"splash_screens","name":"splash_primary",
"prompt":_BP+"splash screen, app loading screen, dark charcoal background, large centered brand icon mark shape, subtle navy glow effect, premium app loading screen","width":720,"height":1280,"steps":30},
{"id":"p4_sp_02","phase":"phase4_ui","subfolder":"splash_screens","name":"splash_navy",
"prompt":_BP+"splash screen, navy background, white icon centered, minimal loading indicator shape, club management app splash, clean brand loading screen","width":720,"height":1280,"steps":30},
{"id":"p4_sp_03","phase":"phase4_ui","subfolder":"splash_screens","name":"splash_animated_hint",
"prompt":_BP+"splash screen, animated concept, community node particles converging into icon mark, dark background with teal particles, dynamic loading screen first frame","width":720,"height":1280,"steps":30},
{"id":"p4_sp_04","phase":"phase4_ui","subfolder":"splash_screens","name":"splash_gradient",
"prompt":_BP+"splash screen, dramatic dark to navy gradient background, white brand mark shape, premium loading experience, club SaaS gradient splash","width":720,"height":1280,"steps":30},
# ============================================================
# PHASE 5 — Brand Collateral (38 assets)
# ============================================================
# Business Cards (900×504)
{"id":"p5_bc_01f","phase":"phase5_collateral","subfolder":"business_cards","name":"bizcard_modern_front",
"prompt":_BP+"business card front, modern minimal style, navy left accent panel, white main area, name placeholder area, club management SaaS company card, premium print","width":900,"height":504,"steps":30},
{"id":"p5_bc_01b","phase":"phase5_collateral","subfolder":"business_cards","name":"bizcard_modern_back",
"prompt":_BP+"business card back, modern minimal style, full navy back with white icon centered, club management SaaS card back","width":900,"height":504,"steps":30},
{"id":"p5_bc_02f","phase":"phase5_collateral","subfolder":"business_cards","name":"bizcard_dark_front",
"prompt":_BP+"business card front, dark luxury style, dark charcoal background, gold foil accent icon, premium club management company card, executive tier","width":900,"height":504,"steps":30},
{"id":"p5_bc_02b","phase":"phase5_collateral","subfolder":"business_cards","name":"bizcard_dark_back",
"prompt":_BP+"business card back, dark luxury style, full dark charcoal, gold icon and navy accent, premium back of card","width":900,"height":504,"steps":30},
{"id":"p5_bc_03f","phase":"phase5_collateral","subfolder":"business_cards","name":"bizcard_pattern_front",
"prompt":_BP+"business card front, geometric community pattern accent, white card with subtle hexagonal pattern header, professional pattern card front","width":900,"height":504,"steps":30},
{"id":"p5_bc_03b","phase":"phase5_collateral","subfolder":"business_cards","name":"bizcard_pattern_back",
"prompt":_BP+"business card back, community geometric pattern full bleed, navy hexagonal pattern background, white icon, pattern card back","width":900,"height":504,"steps":30},
{"id":"p5_bc_04f","phase":"phase5_collateral","subfolder":"business_cards","name":"bizcard_bold_front",
"prompt":_BP+"business card front, bold icon style, large navy brand shape, clean white card, icon-forward business card","width":900,"height":504,"steps":30},
{"id":"p5_bc_04b","phase":"phase5_collateral","subfolder":"business_cards","name":"bizcard_bold_back",
"prompt":_BP+"business card back, bold style, split navy and white back, contact details area shape, club company card back bold design","width":900,"height":504,"steps":30},
# Pitch Deck Covers (1280×720)
{"id":"p5_pd_01","phase":"phase5_collateral","subfolder":"pitch_deck","name":"pitch_investor_dark",
"prompt":_BP+"pitch deck cover slide, investor presentation, dark sophisticated background, large icon centered, funding round visual area, premium club SaaS investor deck","width":1280,"height":720,"steps":30},
{"id":"p5_pd_02","phase":"phase5_collateral","subfolder":"pitch_deck","name":"pitch_growth_story",
"prompt":_BP+"pitch deck cover, growth story visual, ascending membership curve becoming data chart, navy to gold gradient, investor-grade presentation cover","width":1280,"height":720,"steps":30},
{"id":"p5_pd_03","phase":"phase5_collateral","subfolder":"pitch_deck","name":"pitch_market_opp",
"prompt":_BP+"pitch deck cover, market opportunity theme, club industry size visualization, globe with highlighted market regions, navy professional investor presentation","width":1280,"height":720,"steps":30},
{"id":"p5_pd_04","phase":"phase5_collateral","subfolder":"pitch_deck","name":"pitch_team_deck",
"prompt":_BP+"pitch deck cover, team presentation version, professional team silhouette backdrop, club tech startup team slide, navy brand, people silhouette-forward investor deck","width":1280,"height":720,"steps":30},
{"id":"p5_pd_05","phase":"phase5_collateral","subfolder":"pitch_deck","name":"pitch_product_demo",
"prompt":_BP+"pitch deck cover, product demo deck, dashboard preview hero visual shapes, club management SaaS product tour deck, navy UI preview","width":1280,"height":720,"steps":30},
{"id":"p5_pd_06","phase":"phase5_collateral","subfolder":"pitch_deck","name":"pitch_minimal_clean",
"prompt":_BP+"pitch deck cover, ultra-minimal clean slide, white background, large navy brand icon only, minimalist investor presentation","width":1280,"height":720,"steps":30},
# One-Pager Headers (1200×400)
{"id":"p5_op_01","phase":"phase5_collateral","subfolder":"one_pager","name":"onepager_primary",
"prompt":_BP+"one-pager header, primary brand header, navy full bleed, white icon and visual, club management SaaS brochure header, print quality","width":1200,"height":400,"steps":30},
{"id":"p5_op_02","phase":"phase5_collateral","subfolder":"one_pager","name":"onepager_feature_rich",
"prompt":_BP+"one-pager header, feature-rich header, dashboard preview icon glimpse shapes, club management platform features introduction, professional SaaS marketing","width":1200,"height":400,"steps":30},
{"id":"p5_op_03","phase":"phase5_collateral","subfolder":"one_pager","name":"onepager_compliance",
"prompt":_BP+"one-pager header, compliance focus version, legal and regulatory icon theme, club compliance management, shield icons, dark professional header","width":1200,"height":400,"steps":30},
{"id":"p5_op_04","phase":"phase5_collateral","subfolder":"one_pager","name":"onepager_dark_premium",
"prompt":_BP+"one-pager header, dark premium version, charcoal background with gold and navy accents, enterprise tier marketing collateral header","width":1200,"height":400,"steps":30},
# Trade Show Banners (512×1280)
{"id":"p5_ts_01","phase":"phase5_collateral","subfolder":"trade_show","name":"tradeshow_primary_brand",
"prompt":_BP+"trade show pull-up banner tall vertical, primary brand version, navy top with icon, white middle with key feature icons listed, dark bottom with CTA arrow, club management SaaS conference banner","width":512,"height":1280,"steps":30},
{"id":"p5_ts_02","phase":"phase5_collateral","subfolder":"trade_show","name":"tradeshow_product_showcase",
"prompt":_BP+"trade show banner tall vertical, product showcase, dashboard UI hero visual shapes, dark sophisticated background, navy accents, club management software exhibition display","width":512,"height":1280,"steps":30},
{"id":"p5_ts_03","phase":"phase5_collateral","subfolder":"trade_show","name":"tradeshow_membership_focus",
"prompt":_BP+"trade show banner tall vertical, membership authority positioning, club management expertise icons, professional membership focus, navy and gold tall exhibition banner","width":512,"height":1280,"steps":30},
# Sticker/Swag Designs (600×600)
{"id":"p5_sk_01","phase":"phase5_collateral","subfolder":"stickers","name":"sticker_people_circuit",
"prompt":_BP+"sticker design, people silhouettes made of circuit traces, navy on white, die-cut sticker style, fun tech community brand sticker","width":600,"height":600,"steps":30},
{"id":"p5_sk_02","phase":"phase5_collateral","subfolder":"stickers","name":"sticker_icon_badge",
"prompt":_BP+"sticker badge, rounded rectangle badge, navy background, white brand icon shape, premium brand sticker, laptop sticker style","width":600,"height":600,"steps":30},
{"id":"p5_sk_03","phase":"phase5_collateral","subfolder":"stickers","name":"sticker_membership_hero",
"prompt":_BP+"sticker, membership superhero icon, shield with people and checkmark, fun illustrated sticker, navy and gold, die-cut design","width":600,"height":600,"steps":30},
{"id":"p5_sk_04","phase":"phase5_collateral","subfolder":"stickers","name":"sticker_data_community",
"prompt":_BP+"fun sticker, community nodes growing into data chart bars, punchy colorful sticker art, navy people gold bars, square sticker","width":600,"height":600,"steps":30},
{"id":"p5_sk_05","phase":"phase5_collateral","subfolder":"stickers","name":"sticker_club_astronaut",
"prompt":_BP+"sticker, cartoon astronaut holding membership card and laptop, space tech meets club management, fun illustrated sticker, navy spacesuit, brand mascot concept","width":600,"height":600,"steps":30},
{"id":"p5_sk_06","phase":"phase5_collateral","subfolder":"stickers","name":"sticker_powered_by",
"prompt":_BP+"powered by sticker, powered by platform badge icon, small horizontal badge sticker, navy and white, partner sticker for clubs","width":600,"height":600,"steps":30},
{"id":"p5_sk_07","phase":"phase5_collateral","subfolder":"stickers","name":"sticker_compliance_100",
"prompt":_BP+"sticker, 100 percent compliant badge icon, bold navy circle with checkmark and percentage shape, compliance achievement sticker, club compliance badge","width":600,"height":600,"steps":30},
{"id":"p5_sk_08","phase":"phase5_collateral","subfolder":"stickers","name":"sticker_hexagon_icon",
"prompt":_BP+"hexagon sticker, hexagonal border with community network icon, honeycomb management brand sticker, navy hex border gold icon, premium die-cut","width":600,"height":600,"steps":30},
{"id":"p5_sk_09","phase":"phase5_collateral","subfolder":"stickers","name":"sticker_members_first",
"prompt":_BP+"sticker, members first badge design, playful club membership spirit icon, professional but fun brand sticker, navy with gold shapes","width":600,"height":600,"steps":30},
{"id":"p5_sk_10","phase":"phase5_collateral","subfolder":"stickers","name":"sticker_manage_everything",
"prompt":_BP+"sticker, manage everything icon, bold icon sticker, navy background white icon shape, punchy brand statement sticker","width":600,"height":600,"steps":30},
# Email Signature Blocks (600×150)
{"id":"p5_es_01","phase":"phase5_collateral","subfolder":"email_signatures","name":"sigblock_primary",
"prompt":_BP+"email signature graphic block, primary brand, horizontal icon left with visual divider, navy line, professional email signature banner","width":600,"height":150,"steps":30},
{"id":"p5_es_02","phase":"phase5_collateral","subfolder":"email_signatures","name":"sigblock_dark",
"prompt":_BP+"email signature block, dark version, charcoal background white icon navy accent, premium email signature graphic","width":600,"height":150,"steps":30},
{"id":"p5_es_03","phase":"phase5_collateral","subfolder":"email_signatures","name":"sigblock_minimal",
"prompt":_BP+"email signature graphic, minimal version, just icon and visual, very clean white background, ultra-minimal email signature banner","width":600,"height":150,"steps":30},
{"id":"p5_es_04","phase":"phase5_collateral","subfolder":"email_signatures","name":"sigblock_promo",
"prompt":_BP+"email signature promo block, promotional version with CTA arrow shape, gold button area, white background navy brand, conversion CTA signature","width":600,"height":150,"steps":30},
{"id":"p5_es_05","phase":"phase5_collateral","subfolder":"email_signatures","name":"sigblock_social",
"prompt":_BP+"email signature block, social media icons version, small social platform icon shapes in navy, company signature with social links footer","width":600,"height":150,"steps":30},
# ============================================================
# PHASE 6 — Bonus / Wildcard Assets (35 assets)
# ============================================================
# Animated Banner First-Frame Stills (1200×628)
{"id":"p6_an_01","phase":"phase6_bonus","subfolder":"animated_stills","name":"anim_particle_logo",
"prompt":_BP+"animated banner first frame, community node particles forming icon mark mid-flight, dark background teal particles, designed for animation, static concept frame","width":1200,"height":628,"steps":30},
{"id":"p6_an_02","phase":"phase6_bonus","subfolder":"animated_stills","name":"anim_data_flow",
"prompt":_BP+"animated banner first frame, data flow visualization beginning, club data streams starting to form dashboard shapes, dark background navy data lines, animation concept first frame","width":1200,"height":628,"steps":30},
{"id":"p6_an_03","phase":"phase6_bonus","subfolder":"animated_stills","name":"anim_growth_chart",
"prompt":_BP+"animated banner still, club business growth chart animation first frame, bar chart at zero about to animate upward, gold bars on dark, growth animation concept","width":1200,"height":628,"steps":30},
{"id":"p6_an_04","phase":"phase6_bonus","subfolder":"animated_stills","name":"anim_checklist_check",
"prompt":_BP+"animated banner first frame, membership checklist items unchecked ready to animate with checkmarks, navy checklist on white, compliance animation concept","width":1200,"height":628,"steps":30},
{"id":"p6_an_05","phase":"phase6_bonus","subfolder":"animated_stills","name":"anim_community_grow",
"prompt":_BP+"animated banner still, community node seedling about to grow into data visualization network, dark background seed sprouting, growth animation first frame","width":1200,"height":628,"steps":30},
{"id":"p6_an_06","phase":"phase6_bonus","subfolder":"animated_stills","name":"anim_typing_headline",
"prompt":_BP+"animated banner still, typing cursor before headline space, empty headline with blinking cursor concept shape, navy CTA button below, typewriter animation first frame","width":1200,"height":628,"steps":30},
{"id":"p6_an_07","phase":"phase6_bonus","subfolder":"animated_stills","name":"anim_integration_connect",
"prompt":_BP+"animated banner still, integration ecosystem nodes about to connect, partner icon nodes as unconnected shapes, teal connecting lines forming, integration animation first frame","width":1200,"height":628,"steps":30},
{"id":"p6_an_08","phase":"phase6_bonus","subfolder":"animated_stills","name":"anim_counter_stat",
"prompt":_BP+"animated banner still, number counter animation first frame showing zero shape, gold large number shape about to count up, dark background, counter animation concept","width":1200,"height":628,"steps":30},
# Dark Mode vs Light Mode UI Pairs (1200×800 each = 6 pairs)
{"id":"p6_dm_01l","phase":"phase6_bonus","subfolder":"dark_light_pairs","name":"uipair_dashboard_light",
"prompt":_BP+"UI preview card, light mode dashboard interface, clean white background, navy UI element shapes, club management SaaS light theme preview","width":1200,"height":800,"steps":40},
{"id":"p6_dm_01d","phase":"phase6_bonus","subfolder":"dark_light_pairs","name":"uipair_dashboard_dark",
"prompt":_BP+"UI preview card, dark mode dashboard interface, dark charcoal background, teal glowing UI element shapes, club management SaaS dark theme preview, premium dark mode","width":1200,"height":800,"steps":40},
{"id":"p6_dm_02l","phase":"phase6_bonus","subfolder":"dark_light_pairs","name":"uipair_membership_light",
"prompt":_BP+"UI preview, membership module light mode, white clean interface with checklist and status indicator shapes, navy checkmarks, club membership UI","width":1200,"height":800,"steps":40},
{"id":"p6_dm_02d","phase":"phase6_bonus","subfolder":"dark_light_pairs","name":"uipair_membership_dark",
"prompt":_BP+"UI preview, membership module dark mode, dark interface with glowing navy membership indicator shapes, club membership UI dark theme, premium","width":1200,"height":800,"steps":40},
{"id":"p6_dm_03l","phase":"phase6_bonus","subfolder":"dark_light_pairs","name":"uipair_analytics_light",
"prompt":_BP+"UI preview, analytics dashboard light mode, white background with colorful club business chart shapes, navy and gold data visualization, light theme","width":1200,"height":800,"steps":40},
{"id":"p6_dm_03d","phase":"phase6_bonus","subfolder":"dark_light_pairs","name":"uipair_analytics_dark",
"prompt":_BP+"UI preview, analytics dashboard dark mode, dark background with glowing navy and gold club business chart shapes, dramatic dark mode analytics UI","width":1200,"height":800,"steps":40},
# Integration/Partnership Badges (400×200)
{"id":"p6_ib_01","phase":"phase6_bonus","subfolder":"integration_badges","name":"badge_pos_integration",
"prompt":_BP+"integration badge, integrates with POS systems badge icon, point-of-sale integration certification, navy badge design, professional","width":400,"height":200,"steps":40},
{"id":"p6_ib_02","phase":"phase6_bonus","subfolder":"integration_badges","name":"badge_accounting",
"prompt":_BP+"integration badge, accounting software integration badge icon, financial software connection shape, navy badge with accounting icon","width":400,"height":200,"steps":40},
{"id":"p6_ib_03","phase":"phase6_bonus","subfolder":"integration_badges","name":"badge_compliance_tools",
"prompt":_BP+"integration badge, compliance tool integration badge icon, regulatory software connection shape, navy shield badge design","width":400,"height":200,"steps":40},
{"id":"p6_ib_04","phase":"phase6_bonus","subfolder":"integration_badges","name":"badge_api_ready",
"prompt":_BP+"API ready badge icon, API first platform badge shape, developer integration badge, navy and code brackets design, club management API badge","width":400,"height":200,"steps":40},
{"id":"p6_ib_05","phase":"phase6_bonus","subfolder":"integration_badges","name":"badge_partner_certified",
"prompt":_BP+"partner certified badge icon, certified technology partner badge design shape, navy official partner badge, club management platform partner program","width":400,"height":200,"steps":40},
{"id":"p6_ib_06","phase":"phase6_bonus","subfolder":"integration_badges","name":"badge_white_label",
"prompt":_BP+"white label partner badge icon, white label ready platform badge shape, club SaaS white label partner certification, professional partner badge navy","width":400,"height":200,"steps":40},
# Trust/Award Badges (400×400)
{"id":"p6_tb_01","phase":"phase6_bonus","subfolder":"trust_badges","name":"trust_gdpr_compliant",
"prompt":_BP+"trust badge, GDPR compliant badge design icon, data protection certification shape, navy shield with EU star circle, club SaaS data privacy trust badge","width":400,"height":400,"steps":40},
{"id":"p6_tb_02","phase":"phase6_bonus","subfolder":"trust_badges","name":"trust_soc2_ready",
"prompt":_BP+"trust badge, SOC 2 ready certification badge icon, enterprise security trust badge shape, professional certification seal, dark navy badge design","width":400,"height":400,"steps":40},
{"id":"p6_tb_03","phase":"phase6_bonus","subfolder":"trust_badges","name":"trust_uptime_guarantee",
"prompt":_BP+"trust badge, 99.9 percent uptime guarantee badge icon, reliability certification shape, gold uptime number on navy badge, club SaaS reliability trust signal","width":400,"height":400,"steps":40},
{"id":"p6_tb_04","phase":"phase6_bonus","subfolder":"trust_badges","name":"trust_industry_choice",
"prompt":_BP+"award badge, club industry choice award badge design icon, industry recognition award seal shape, gold and navy award badge","width":400,"height":400,"steps":40},
{"id":"p6_tb_05","phase":"phase6_bonus","subfolder":"trust_badges","name":"trust_money_back",
"prompt":_BP+"trust badge, 30-day money back guarantee badge icon, customer confidence seal shape, navy circle badge, club SaaS satisfaction badge","width":400,"height":400,"steps":40},
]
# Bump steps for quality on phases with smaller dimensions
for _a in ASSET_MANIFEST:
if _a["steps"] == 30 and _a["width"] <= 1024 and _a["height"] <= 1024:
_a["steps"] = 40
def load_progress() -> Dict[str, Any]:
"""Load resume state from .progress.json."""
if PROGRESS_FILE.exists():
try:
with open(PROGRESS_FILE) as f:
return json.load(f)
except (json.JSONDecodeError, IOError):
pass
return {"completed": [], "failed": [], "started_at": time.strftime("%Y-%m-%dT%H:%M:%S")}
def save_progress(progress: Dict[str, Any]) -> None:
"""Save progress state."""
OUTPUT_ROOT.mkdir(parents=True, exist_ok=True)
with open(PROGRESS_FILE, "w") as f:
json.dump(progress, f, indent=2)
def load_workflow(model: str) -> Dict:
"""Load the appropriate workflow JSON."""
path = WORKFLOW_HERETIC if model == "heretic" else WORKFLOW_SCHNELL
with open(path) as f:
return json.load(f)
def submit_prompt(comfyui_url: str, workflow: Dict) -> str:
"""Submit prompt to ComfyUI."""
data = json.dumps({"prompt": workflow}).encode()
req = urllib.request.Request(
f"{comfyui_url}/prompt", data=data, headers={"Content-Type": "application/json"}
)
with urllib.request.urlopen(req) as resp:
return json.loads(resp.read())["prompt_id"]
def wait_for_image(comfyui_url: str, prompt_id: str, timeout: int = 300) -> Dict | None:
"""Poll for completion."""
print(" ⏳ Waiting for ComfyUI...", end="", flush=True)
start = time.time()
while time.time() - start < timeout:
try:
with urllib.request.urlopen(f"{comfyui_url}/history/{prompt_id}") as resp:
history = json.loads(resp.read())
if prompt_id in history:
print(" done.", flush=True)
outputs = history[prompt_id].get("outputs", {})
for node_out in outputs.values():
if "images" in node_out:
return node_out["images"][0]
return None
except Exception:
pass
print(".", end="", flush=True)
time.sleep(2)
print(" timeout!", flush=True)
return None
def download_image(comfyui_url: str, image_info: Dict, output_path: Path) -> bool:
"""Download the generated image."""
try:
url = f"{comfyui_url}/view?filename={image_info['filename']}&subfolder={image_info.get('subfolder', '')}&type=output"
with urllib.request.urlopen(url) as resp:
img_data = resp.read()
output_path.write_bytes(img_data)
print(f" ✅ Saved: {output_path} ({len(img_data) // 1024}KB)")
return True
except Exception as e:
print(f" ❌ Download failed: {e}")
return False
def patch_workflow(workflow: Dict, asset: Dict, model: str) -> Dict:
"""Patch workflow with asset params using per-model node IDs."""
seed = random.randint(0, 2**32 - 1)
if model == "heretic":
# flux2_klein_heretic.json nodes: 2=pos, 3=neg, 6=latent(w/h), 7=scheduler(steps), 10=noise(seed), 13=save
workflow["2"]["inputs"]["text"] = asset["prompt"]
workflow["3"]["inputs"]["text"] = _NEG
workflow["6"]["inputs"]["width"] = asset["width"]
workflow["6"]["inputs"]["height"] = asset["height"]
workflow["7"]["inputs"]["steps"] = asset["steps"]
workflow["13"]["inputs"]["filename_prefix"] = asset["name"]
if "10" in workflow:
workflow["10"]["inputs"]["noise_seed"] = seed
else:
# flux_schnell.json nodes: 6=pos, 33=neg, 27=latent(w/h), 13=ksampler(steps/seed), 9=save
workflow["6"]["inputs"]["text"] = asset["prompt"]
workflow["33"]["inputs"]["text"] = _NEG
workflow["27"]["inputs"]["width"] = asset["width"]
workflow["27"]["inputs"]["height"] = asset["height"]
workflow["13"]["inputs"]["steps"] = asset["steps"]
workflow["13"]["inputs"]["seed"] = seed
workflow["9"]["inputs"]["filename_prefix"] = asset["name"]
return workflow
def generate_asset(comfyui_url: str, asset: Dict, model: str, progress: Dict) -> bool:
"""Generate a single asset."""
if asset["id"] in progress["completed"]:
print(f" ⏭️ Skipping completed: {asset['name']}")
return True
print(f"\n Prompt : {asset['prompt'][:80]}...")
print(f" Size : {asset['width']}×{asset['height']} Steps: {asset['steps']}")
try:
workflow = load_workflow(model)
workflow = patch_workflow(workflow, asset, model)
prompt_id = submit_prompt(comfyui_url, workflow)
image_info = wait_for_image(comfyui_url, prompt_id)
if not image_info:
progress["failed"].append(asset["id"])
save_progress(progress)
return False
output_dir = OUTPUT_ROOT / asset["phase"] / asset["subfolder"]
output_dir.mkdir(parents=True, exist_ok=True)
output_path = output_dir / f"{asset['name']}.png"
if download_image(comfyui_url, image_info, output_path):
progress["completed"].append(asset["id"])
save_progress(progress)
return True
else:
progress["failed"].append(asset["id"])
save_progress(progress)
return False
except Exception as e:
print(f" ❌ Error: {e}")
progress["failed"].append(asset["id"])
save_progress(progress)
return False
def main():
parser = argparse.ArgumentParser(description="ClubManage Brand Asset Generation Pipeline")
parser.add_argument("--dry-run", action="store_true", help="Print manifest without generating")
parser.add_argument("--phase", help="Generate only assets from this phase (e.g. phase1_logos)")
parser.add_argument("--model", choices=["schnell", "heretic"], default="schnell",
help="Model: schnell (~10-20s/img) or heretic (~52s/img, higher quality)")
parser.add_argument("--comfyui", default="http://localhost:8188", help="ComfyUI URL")
parser.add_argument("--steps", type=int, default=None,
help="Override steps for all assets (e.g. --steps 12 for higher quality)")
args = parser.parse_args()
comfyui_url = args.comfyui
# Apply global steps override if requested
manifest = ASSET_MANIFEST
if args.steps:
manifest = [{**a, "steps": args.steps} for a in manifest]
# Filter by phase if requested
to_generate = [a for a in manifest if not args.phase or a["phase"] == args.phase]
print("🚀 ClubManage Brand Asset Generation Pipeline")
print(f" Output : {OUTPUT_ROOT}")
print(f" Model : {args.model}")
print(f" ComfyUI : {comfyui_url}")
print(f" Total : {len(ASSET_MANIFEST)} assets in manifest")
print(f" Selected: {len(to_generate)} assets to generate")
print(f" Note : All images are text-free — pure visual/icon design")
if args.dry_run:
phases: Dict[str, int] = {}
for a in to_generate:
phases[a["phase"]] = phases.get(a["phase"], 0) + 1
for ph, count in phases.items():
print(f"\n {ph} ({count} assets):")
for a in to_generate:
if a["phase"] == ph:
print(f" {a['id']:14} | {a['name']:35} | {a['width']}×{a['height']} steps={a['steps']}")
total_min_est = sum(a["steps"] * 2.5 for a in to_generate) / 60
print(f"\n ⏱️ Estimated runtime (schnell): ~{total_min_est:.0f} minutes")
print("\nDry run complete. Remove --dry-run to begin generation.")
return
progress = load_progress()
remaining = [a for a in to_generate if a["id"] not in progress["completed"]]
print(f" Resume : {len(progress['completed'])} completed, {len(progress['failed'])} failed, {len(remaining)} remaining")
if not remaining:
print("\n✅ All selected assets already complete!")
return
print(f"\nStarting generation... (Ctrl+C to pause — progress is saved)")
n_done = 0
n_fail = 0
for i, asset in enumerate(to_generate, 1):
if asset["id"] in progress["completed"]:
continue
print(f"\n[{asset['phase']}] [{i}/{len(to_generate)}] {asset['name']}")
if generate_asset(comfyui_url, asset, args.model, progress):
n_done += 1
else:
n_fail += 1
print("\n" + "=" * 60)
print("🎉 PIPELINE COMPLETE")
print(f" ✅ Completed this run : {n_done}")
print(f" ❌ Failed this run : {n_fail}")
print(f" 📦 Total completed : {len(progress['completed'])} / {len(ASSET_MANIFEST)}")
if progress["failed"]:
print(f" Failed IDs: {', '.join(progress['failed'][-10:])}")
print(f" Assets saved to: {OUTPUT_ROOT}")
print("=" * 60)
if __name__ == "__main__":
main()
+133
View File
@@ -0,0 +1,133 @@
#!/usr/bin/env python3
"""
Quick CLI for generating images via ComfyUI + FLUX.2 Klein Heretic.
Usage:
python gen.py "your prompt here"
python gen.py "your prompt" --steps 20 --width 1280 --height 720
python gen.py "your prompt" --seed 12345
python gen.py "your prompt" --count 3
Output saved to ~/Pictures/mcp-generated/
"""
import argparse
import json
import random
import sys
import time
import urllib.request
from pathlib import Path
COMFYUI = "http://localhost:8188"
OUTPUT_DIR = Path.home() / "Pictures" / "mcp-generated"
WORKFLOW_PATH = Path(__file__).parent / "src/workflows/flux2_klein_heretic.json"
def load_workflow():
with open(WORKFLOW_PATH) as f:
return json.load(f)
def submit(workflow):
data = json.dumps({"prompt": workflow}).encode()
req = urllib.request.Request(
f"{COMFYUI}/prompt", data=data,
headers={"Content-Type": "application/json"}
)
with urllib.request.urlopen(req) as resp:
return json.loads(resp.read())["prompt_id"]
def wait(prompt_id, timeout=300):
print(" ⏳ Waiting for ComfyUI...", end="", flush=True)
start = time.time()
while time.time() - start < timeout:
with urllib.request.urlopen(f"{COMFYUI}/history/{prompt_id}") as resp:
history = json.loads(resp.read())
if prompt_id in history:
print(" done.", flush=True)
outputs = history[prompt_id].get("outputs", {})
for node_out in outputs.values():
if "images" in node_out:
return node_out["images"][0]
return None
print(".", end="", flush=True)
time.sleep(2)
raise TimeoutError(f"Timed out after {timeout}s")
def download(filename, subfolder=""):
url = f"{COMFYUI}/view?filename={filename}&subfolder={subfolder}&type=output"
with urllib.request.urlopen(url) as resp:
return resp.read()
def generate(prompt, steps=20, width=1024, height=1024, seed=-1, name="cli"):
if seed == -1:
seed = random.randint(0, 2**32 - 1)
workflow = load_workflow()
# Patch positive prompt (node 2)
workflow["2"]["inputs"]["text"] = prompt
# Patch negative prompt (node 3) — leave empty
workflow["3"]["inputs"]["text"] = ""
# Patch seed (node 10)
if "10" in workflow:
workflow["10"]["inputs"]["noise_seed"] = seed
# Patch dimensions (node 6)
workflow["6"]["inputs"]["width"] = width
workflow["6"]["inputs"]["height"] = height
# Patch steps (node 7)
workflow["7"]["inputs"]["steps"] = steps
# Patch output filename (node 13)
workflow["13"]["inputs"]["filename_prefix"] = name
print(f" Prompt : {prompt[:80]}{'...' if len(prompt) > 80 else ''}")
print(f" Size : {width}×{height} Steps: {steps} Seed: {seed}")
prompt_id = submit(workflow)
image_info = wait(prompt_id)
if not image_info:
print(" ❌ No output image returned.", file=sys.stderr)
return None
img_data = download(image_info["filename"], image_info.get("subfolder", ""))
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
out_path = OUTPUT_DIR / f"{name}_{seed}.png"
out_path.write_bytes(img_data)
print(f" ✅ Saved: {out_path} ({len(img_data) // 1024}KB)")
return out_path
def main():
parser = argparse.ArgumentParser(
description="Generate images via ComfyUI FLUX.2 Klein Heretic"
)
parser.add_argument("prompt", help="Text prompt for the image")
parser.add_argument("--steps", type=int, default=20, help="Inference steps (default: 20)")
parser.add_argument("--width", type=int, default=1024, help="Width in pixels (default: 1024)")
parser.add_argument("--height", type=int, default=1024, help="Height in pixels (default: 1024)")
parser.add_argument("--seed", type=int, default=-1, help="Seed (-1 = random)")
parser.add_argument("--count", type=int, default=1, help="Number of images (default: 1)")
parser.add_argument("--name", default="cli", help="Output filename prefix (default: cli)")
args = parser.parse_args()
for i in range(args.count):
if args.count > 1:
print(f"\n[{i+1}/{args.count}]")
seed = args.seed if args.seed != -1 else -1
generate(
prompt=args.prompt,
steps=args.steps,
width=args.width,
height=args.height,
seed=seed,
name=f"{args.name}_{i+1:02d}" if args.count > 1 else args.name,
)
if __name__ == "__main__":
main()
+352
View File
@@ -0,0 +1,352 @@
#!/usr/bin/env python3
"""
FLUX Image Generator — Desktop GUI
Supports: FLUX.1 Schnell (fast) and FLUX.2 Klein Heretic (unrestricted)
Run: python3 gui.py
No external dependencies — stdlib + tkinter only.
"""
import json
import random
import threading
import time
import urllib.request
from pathlib import Path
import tkinter as tk
from tkinter import ttk, scrolledtext, messagebox
COMFYUI = "http://localhost:8188"
OUTPUT_DIR = Path.home() / "Pictures" / "mcp-generated"
WORKFLOWS_DIR = Path(__file__).parent / "src/workflows"
# ── Model definitions ────────────────────────────────────────────────────────
# Each entry defines how to patch the workflow for that model.
# node_pos / node_neg: CLIPTextEncode node IDs for positive/negative prompts
# node_latent: latent image node (for width/height)
# node_seed: where to write the seed value
# node_save: SaveImage node (for filename_prefix)
# node_steps: dict of {node_id: field} for steps — None if not patchable
MODELS = {
"FLUX.2 Klein Heretic (unrestricted)": {
"workflow": "flux2_klein_heretic.json",
"default_steps": 20,
"node_pos": ("2", "text"),
"node_neg": ("3", "text"),
"node_latent": ("6", "width", "height"),
"node_seed": ("10", "noise_seed"),
"node_steps": ("7", "steps"),
"node_save": ("13", "filename_prefix"),
"description": "FLUX.2 Klein 4B + Heretic abliterated encoder. ~50s/image. No refusals.",
},
"FLUX.1 Schnell (fast)": {
"workflow": "flux_schnell.json",
"default_steps": 4,
"node_pos": ("6", "text"),
"node_neg": ("33", "text"),
"node_latent": ("27", "width", "height"),
"node_seed": ("13", "seed"), # KSampler has seed directly
"node_steps": ("13", "steps"),
"node_save": ("9", "filename_prefix"),
"description": "FLUX.1 Schnell — fast (~5s/image), standard quality. Has safety filter.",
},
}
PRESETS = {
"Square 1024": (1024, 1024),
"Landscape 16:9": (1280, 720),
"Portrait 9:16": (720, 1280),
"Wide 3:2": (1536, 1024),
"Tall 2:3": (1024, 1536),
"BFL Wide 7:4": (1344, 768),
"BFL Tall 4:7": (768, 1344),
}
def load_workflow(filename):
with open(WORKFLOWS_DIR / filename) as f:
return json.load(f)
def patch_workflow(wf, spec, prompt, neg, width, height, steps, seed, name):
"""Apply generation parameters to a workflow dict in-place."""
node_pos_id, node_pos_field = spec["node_pos"]
node_neg_id, node_neg_field = spec["node_neg"]
lat_id, lat_w, lat_h = spec["node_latent"]
seed_id, seed_field = spec["node_seed"]
save_id, save_field = spec["node_save"]
wf[node_pos_id]["inputs"][node_pos_field] = prompt
wf[node_neg_id]["inputs"][node_neg_field] = neg
wf[lat_id]["inputs"][lat_w] = width
wf[lat_id]["inputs"][lat_h] = height
wf[seed_id]["inputs"][seed_field] = seed
wf[save_id]["inputs"][save_field] = name
if spec["node_steps"]:
steps_id, steps_field = spec["node_steps"]
wf[steps_id]["inputs"][steps_field] = steps
return wf
def submit_prompt(workflow):
data = json.dumps({"prompt": workflow}).encode()
req = urllib.request.Request(
f"{COMFYUI}/prompt", data=data,
headers={"Content-Type": "application/json"},
)
with urllib.request.urlopen(req, timeout=30) as resp:
return json.loads(resp.read())["prompt_id"]
def wait_for_image(prompt_id, timeout=300):
start = time.time()
while time.time() - start < timeout:
with urllib.request.urlopen(f"{COMFYUI}/history/{prompt_id}", timeout=10) as resp:
history = json.loads(resp.read())
if prompt_id in history:
for node_out in history[prompt_id].get("outputs", {}).values():
if "images" in node_out:
return node_out["images"][0]
return None
time.sleep(2)
raise TimeoutError("Timed out waiting for image")
def download_image(filename, subfolder=""):
url = f"{COMFYUI}/view?filename={filename}&subfolder={subfolder}&type=output"
with urllib.request.urlopen(url, timeout=30) as resp:
return resp.read()
class App(tk.Tk):
def __init__(self):
super().__init__()
self.title("FLUX Image Generator")
self.resizable(True, True)
self.minsize(760, 640)
self._current_image = None
self._build_ui()
def _build_ui(self):
main = ttk.Frame(self, padding=12)
main.pack(fill="both", expand=True)
main.columnconfigure(0, weight=1)
main.columnconfigure(1, weight=2)
# ── LEFT PANEL ───────────────────────────────────────────────────────
left = ttk.Frame(main)
left.grid(row=0, column=0, sticky="nsew", padx=(0, 8))
left.columnconfigure(0, weight=1)
row = 0
# Model selector
ttk.Label(left, text="Model", font=("", 10, "bold")).grid(
row=row, column=0, sticky="w"); row += 1
self.model_var = tk.StringVar(value=list(MODELS.keys())[0])
model_cb = ttk.Combobox(left, textvariable=self.model_var,
values=list(MODELS.keys()), state="readonly", width=40)
model_cb.grid(row=row, column=0, sticky="ew", pady=(2, 2)); row += 1
model_cb.bind("<<ComboboxSelected>>", self._on_model_change)
self.model_desc = ttk.Label(left, text="", foreground="gray",
wraplength=300, font=("", 8))
self.model_desc.grid(row=row, column=0, sticky="w", pady=(0, 8)); row += 1
# description updated after all widgets are created (see end of _build_ui)
# Prompt
ttk.Label(left, text="Prompt", font=("", 10, "bold")).grid(
row=row, column=0, sticky="w"); row += 1
self.prompt_txt = scrolledtext.ScrolledText(left, height=6, wrap="word", font=("", 10))
self.prompt_txt.grid(row=row, column=0, sticky="ew", pady=(2, 8)); row += 1
# Negative prompt
ttk.Label(left, text="Negative Prompt (optional)").grid(
row=row, column=0, sticky="w"); row += 1
self.neg_txt = scrolledtext.ScrolledText(left, height=3, wrap="word", font=("", 9))
self.neg_txt.grid(row=row, column=0, sticky="ew", pady=(2, 8)); row += 1
# Size preset
ttk.Label(left, text="Size Preset").grid(row=row, column=0, sticky="w"); row += 1
self.preset_var = tk.StringVar(value="Square 1024")
preset_cb = ttk.Combobox(left, textvariable=self.preset_var,
values=list(PRESETS.keys()), state="readonly")
preset_cb.grid(row=row, column=0, sticky="ew", pady=(2, 2)); row += 1
preset_cb.bind("<<ComboboxSelected>>", self._apply_preset)
# Width / Height
wh = ttk.Frame(left)
wh.grid(row=row, column=0, sticky="ew", pady=(4, 8)); row += 1
wh.columnconfigure(1, weight=1)
wh.columnconfigure(3, weight=1)
ttk.Label(wh, text="W").grid(row=0, column=0, padx=(0, 4))
self.width_var = tk.IntVar(value=1024)
ttk.Spinbox(wh, from_=256, to=4096, increment=8, textvariable=self.width_var,
width=6).grid(row=0, column=1, sticky="ew")
ttk.Label(wh, text="H", padding=(8, 0, 4, 0)).grid(row=0, column=2)
self.height_var = tk.IntVar(value=1024)
ttk.Spinbox(wh, from_=256, to=4096, increment=8, textvariable=self.height_var,
width=6).grid(row=0, column=3, sticky="ew")
# Steps
steps_row = ttk.Frame(left)
steps_row.grid(row=row, column=0, sticky="ew", pady=(0, 4)); row += 1
steps_row.columnconfigure(1, weight=1)
ttk.Label(steps_row, text="Steps").grid(row=0, column=0, padx=(0, 8))
self.steps_var = tk.IntVar(value=20)
self.steps_lbl = ttk.Label(steps_row, text="20", width=3)
self.steps_lbl.grid(row=0, column=2, padx=(6, 0))
ttk.Scale(steps_row, from_=1, to=60, variable=self.steps_var,
orient="horizontal",
command=lambda v: self.steps_lbl.config(text=str(int(float(v))))
).grid(row=0, column=1, sticky="ew")
# Count
count_row = ttk.Frame(left)
count_row.grid(row=row, column=0, sticky="ew", pady=(0, 8)); row += 1
count_row.columnconfigure(1, weight=1)
ttk.Label(count_row, text="Count").grid(row=0, column=0, padx=(0, 8))
self.count_var = tk.IntVar(value=1)
ttk.Spinbox(count_row, from_=1, to=20, textvariable=self.count_var,
width=4).grid(row=0, column=1, sticky="w")
# Seed
seed_row = ttk.Frame(left)
seed_row.grid(row=row, column=0, sticky="ew", pady=(0, 8)); row += 1
seed_row.columnconfigure(1, weight=1)
ttk.Label(seed_row, text="Seed").grid(row=0, column=0, padx=(0, 8))
self.seed_var = tk.StringVar(value="-1")
ttk.Entry(seed_row, textvariable=self.seed_var, width=12).grid(row=0, column=1, sticky="w")
ttk.Button(seed_row, text="🎲", width=3,
command=lambda: self.seed_var.set(str(random.randint(0, 2**32 - 1)))
).grid(row=0, column=2, padx=(4, 0))
ttk.Label(seed_row, text="(-1 = random)", foreground="gray"
).grid(row=0, column=3, padx=(4, 0))
# Name
name_row = ttk.Frame(left)
name_row.grid(row=row, column=0, sticky="ew", pady=(0, 12)); row += 1
name_row.columnconfigure(1, weight=1)
ttk.Label(name_row, text="Name").grid(row=0, column=0, padx=(0, 8))
self.name_var = tk.StringVar(value="img")
ttk.Entry(name_row, textvariable=self.name_var).grid(row=0, column=1, sticky="ew")
# Generate button
self.gen_btn = ttk.Button(left, text="⚡ Generate", command=self._start_generation)
self.gen_btn.grid(row=row, column=0, sticky="ew", pady=(0, 8)); row += 1
# Status + progress
self.status_var = tk.StringVar(value="Ready")
ttk.Label(left, textvariable=self.status_var, foreground="gray",
wraplength=300).grid(row=row, column=0, sticky="w"); row += 1
self.progress = ttk.Progressbar(left, mode="indeterminate")
self.progress.grid(row=row, column=0, sticky="ew", pady=(4, 0)); row += 1
# ── RIGHT PANEL — preview ────────────────────────────────────────────
right = ttk.LabelFrame(main, text="Preview", padding=8)
right.grid(row=0, column=1, sticky="nsew")
right.columnconfigure(0, weight=1)
right.rowconfigure(0, weight=1)
self.preview_lbl = ttk.Label(right, text="No image yet", anchor="center",
background="#1a1a1a", foreground="#888")
self.preview_lbl.grid(row=0, column=0, sticky="nsew")
self.path_lbl = ttk.Label(right, text="", foreground="gray", font=("", 8))
self.path_lbl.grid(row=1, column=0, sticky="w", pady=(4, 0))
ttk.Button(right, text="Open folder",
command=self._open_folder).grid(row=2, column=0, sticky="e", pady=(4, 0))
# Init model description + steps default now that all widgets exist
self._on_model_change()
def _on_model_change(self, _=None):
spec = MODELS[self.model_var.get()]
self.model_desc.config(text=spec["description"])
self.steps_var.set(spec["default_steps"])
self.steps_lbl.config(text=str(spec["default_steps"]))
def _apply_preset(self, _=None):
w, h = PRESETS[self.preset_var.get()]
self.width_var.set(w)
self.height_var.set(h)
def _start_generation(self):
prompt = self.prompt_txt.get("1.0", "end").strip()
if not prompt:
messagebox.showwarning("No prompt", "Please enter a prompt.")
return
self.gen_btn.config(state="disabled")
self.progress.start(10)
self.status_var.set("Generating…")
t = threading.Thread(target=self._run_generation, args=(prompt,), daemon=True)
t.start()
def _run_generation(self, prompt):
try:
neg = self.neg_txt.get("1.0", "end").strip()
steps = int(self.steps_var.get())
width = int(self.width_var.get())
height = int(self.height_var.get())
count = int(self.count_var.get())
name = self.name_var.get().strip() or "img"
seed_str = self.seed_var.get().strip()
base_seed = int(seed_str) if seed_str else -1
model_name = self.model_var.get()
spec = MODELS[model_name]
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
for i in range(count):
seed = (base_seed if base_seed == -1 else base_seed + i)
if seed == -1:
seed = random.randint(0, 2**32 - 1)
label = f"{name}_{i+1:02d}" if count > 1 else name
self.after(0, self.status_var.set,
f"[{i+1}/{count}] {model_name.split('(')[0].strip()} · seed {seed}")
wf = load_workflow(spec["workflow"])
patch_workflow(wf, spec, prompt, neg, width, height, steps, seed, label)
prompt_id = submit_prompt(wf)
img_info = wait_for_image(prompt_id)
if img_info:
img_data = download_image(img_info["filename"], img_info.get("subfolder", ""))
out_path = OUTPUT_DIR / f"{label}_{seed}.png"
out_path.write_bytes(img_data)
self.after(0, self._show_preview, out_path)
self.after(0, self.status_var.set,
f"✅ Done — {count} image(s) saved to ~/Pictures/mcp-generated/")
except Exception as exc:
self.after(0, self.status_var.set, f"❌ Error: {exc}")
finally:
self.after(0, self.progress.stop)
self.after(0, lambda: self.gen_btn.config(state="normal"))
def _show_preview(self, path):
try:
photo = tk.PhotoImage(file=str(path))
pw, ph = photo.width(), photo.height()
subsample = 1
while pw // subsample > 600 or ph // subsample > 600:
subsample += 1
if subsample > 1:
photo = photo.subsample(subsample, subsample)
self.preview_lbl.config(image=photo, text="")
self._current_image = photo
self.path_lbl.config(text=str(path))
except Exception as e:
self.status_var.set(f"Preview error: {e}")
def _open_folder(self):
import subprocess
subprocess.Popen(["xdg-open", str(OUTPUT_DIR)])
if __name__ == "__main__":
app = App()
app.mainloop()
+411
View File
@@ -0,0 +1,411 @@
#!/usr/bin/env python3
"""
Patrick Hidden Name Artwork Generation Pipeline
Autonomous script to generate 26 ultra-detailed, visually rich digital artworks
where the name "PATRICK" is cleverly concealed within each composition.
Letters emerge organically from shapes, patterns, negative space, silhouettes,
alignment, or cumulative elements — never as plain text.
Visible only upon close inspection.
Uses the existing mcp-image-gen infrastructure (ComfyUI FLUX workflows).
Output organized in ~/Pictures/patrick_hidden_name/{theme}/{style}/
Usage:
cd /home/pplate/pi_mcps
python mcp/mcp-image-gen/patrick_hidden_gen.py
python mcp/mcp-image-gen/patrick_hidden_gen.py --dry-run
python mcp/mcp-image-gen/patrick_hidden_gen.py --model heretic
"""
import argparse
import copy
import json
import random
import time
import urllib.request
from pathlib import Path
from typing import Dict, List, Any, Optional
# --- Configuration ---
OUTPUT_ROOT = Path.home() / "Pictures" / "patrick_hidden_name"
PROGRESS_FILE = OUTPUT_ROOT / ".progress.json"
WORKFLOW_SCHNELL = Path(__file__).parent / "src/workflows/flux_schnell.json"
WORKFLOW_HERETIC = Path(__file__).parent / "src/workflows/flux2_klein_heretic.json"
# Core hidden-name prompting technique — applied to every asset
_HT = (
"the name PATRICK is cleverly and seamlessly concealed within the composition, "
"letters P-A-T-R-I-C-K emerge organically from shapes patterns negative space "
"silhouettes alignment or cumulative arrangement of multiple elements, "
"never plain text, subtle yet unmistakable once discovered, requires genuine "
"visual discovery and close inspection, natural integration into the scene, "
)
# Base quality boosters
_Q = "ultra-high detail, photorealistic rendering with cinematic lighting, intricate textures, depth of field, 8k resolution, masterpiece, best quality, "
ASSET_MANIFEST: List[Dict[str, Any]] = [
# 1. Dense crowds of marionette puppets — photoreal
{"id":"phn_01","theme":"marionettes","style":"photoreal","name":"marionette_crowd_puppets",
"prompt":_Q+_HT+"dense crowd of antique wooden marionette puppets on theatrical stage, "
"strings and body poses form PATRICK through negative space and limb alignment, "
"dramatic stage lighting with velvet curtains, realistic wood grain and fabric textures, "
"photorealistic cinematic","width":1024,"height":1024,"steps":4},
# 2. Marionettes — painterly
{"id":"phn_02","theme":"marionettes","style":"painterly","name":"marionette_theater_oil",
"prompt":_Q+_HT+"oil painting of crowded marionette theater, puppet strings and poses "
"form hidden PATRICK letters in composition, baroque style, rich colors, dramatic chiaroscuro "
"lighting, thick impasto brushwork","width":1024,"height":1024,"steps":20},
# 3. Birds — aerial formation
{"id":"phn_03","theme":"birds","style":"aerial","name":"bird_flock_formation",
"prompt":_Q+_HT+"aerial photograph of massive flock of starlings in precise murmuration, "
"bird silhouettes and gaps spell PATRICK through negative space and wing alignments, "
"golden hour light, vast sky, ultra realistic feathers and motion blur","width":1280,"height":720,"steps":4},
# 4. Birds — macro
{"id":"phn_04","theme":"birds","style":"macro","name":"bird_swarm_closeup",
"prompt":_Q+_HT+"macro photography of bird murmuration where individual bird silhouettes "
"and wing alignments subtly spell PATRICK, intricate feather detail, soft bokeh background, "
"extreme close focus","width":1024,"height":1024,"steps":4},
# 5. Tree roots — photoreal
{"id":"phn_05","theme":"tree_roots","style":"photoreal","name":"ancient_tree_roots",
"prompt":_Q+_HT+"ancient oak tree with massive tangled roots and branches that naturally "
"form letters PATRICK in their curves and intersections, forest floor moss and dappled sunlight, "
"hyper realistic bark texture, dramatic directional lighting","width":1024,"height":1024,"steps":4},
# 6. Tree roots — painterly
{"id":"phn_06","theme":"tree_roots","style":"painterly","name":"tree_root_illustration",
"prompt":_Q+_HT+"detailed botanical illustration of tree roots and branches forming hidden "
"PATRICK name through organic growth patterns, ink and watercolor, scientific accuracy with "
"artistic flair, John Muir style","width":1024,"height":1024,"steps":12},
# 7. School of fish
{"id":"phn_07","theme":"fish_school","style":"underwater","name":"fish_school_choreography",
"prompt":_Q+_HT+"underwater scene of thousands of tropical fish in synchronized school, "
"swimming patterns and gaps between bodies form PATRICK, crystal clear tropical water, "
"realistic scales and light caustics, underwater photography","width":1024,"height":1024,"steps":4},
# 8. Architecture — gothic facade
{"id":"phn_08","theme":"architecture","style":"architectural","name":"gothic_facade_hidden",
"prompt":_Q+_HT+"ornate gothic cathedral facade where windows arches and stone carvings "
"subtly align to spell PATRICK in negative space and shadow play, dramatic sunset lighting, "
"ultra detailed stone texture, architectural rendering","width":1024,"height":1024,"steps":4},
# 9. Architecture — aerial
{"id":"phn_09","theme":"architecture","style":"aerial","name":"modern_skyscraper_letters",
"prompt":_Q+_HT+"aerial view of modern city building complex where rooflines shadows and "
"window patterns form the hidden name PATRICK, golden hour, photorealistic architectural "
"rendering, top-down perspective","width":1280,"height":720,"steps":4},
# 10. Coral reef
{"id":"phn_10","theme":"coral_reef","style":"underwater","name":"vibrant_coral_reef",
"prompt":_Q+_HT+"vibrant coral reef ecosystem where branching coral fish and rock formations "
"naturally compose letters PATRICK through color and shape alignment, crystal water, "
"macro detail on polyps and textures, underwater photography","width":1024,"height":1024,"steps":4},
# 11. City skyline at night
{"id":"phn_11","theme":"city_skyline","style":"night","name":"neon_skyline_hidden",
"prompt":_Q+_HT+"futuristic city skyline at night where building lights and window patterns "
"subtly spell PATRICK in the neon glow and negative space between towers, cyberpunk atmosphere, "
"realistic reflections and bokeh, long exposure photography","width":1280,"height":720,"steps":4},
# 12. Rolling hills landscape
{"id":"phn_12","theme":"hills_landscape","style":"aerial","name":"rolling_hills_contours",
"prompt":_Q+_HT+"aerial view of rolling green hills and valleys where landscape contours "
"hedgerows and elevation shadows subtly form PATRICK, golden hour pastoral scene, "
"drone photography style","width":1280,"height":720,"steps":4},
# 13. Persian rug
{"id":"phn_13","theme":"persian_rug","style":"macro","name":"persian_rug_intricate",
"prompt":_Q+_HT+"extremely detailed close-up of hand-woven Persian rug where geometric and "
"floral patterns align to conceal name PATRICK in repeating motifs and negative space, "
"rich colors, silk texture, macro photography","width":1024,"height":1024,"steps":4},
# 14. Butterflies
{"id":"phn_14","theme":"butterflies","style":"painterly","name":"butterfly_swarm_metamorphosis",
"prompt":_Q+_HT+"swarm of colorful butterflies in flight where wing patterns and flight paths "
"collectively form hidden letters PATRICK, ethereal garden setting, detailed wing scales, "
"soft natural light, painterly illustration style","width":1024,"height":1024,"steps":12},
# 15. Circuit board
{"id":"phn_15","theme":"circuit_board","style":"macro","name":"circuit_board_traces",
"prompt":_Q+_HT+"extreme macro of complex multilayer circuit board where copper traces "
"solder points and component placement subtly spell PATRICK in wiring layout, "
"realistic metallic reflections, depth of field, technical precision","width":1024,"height":1024,"steps":4},
# 16. Ocean waves
{"id":"phn_16","theme":"ocean_waves","style":"photoreal","name":"crashing_waves_hidden",
"prompt":_Q+_HT+"dramatic crashing ocean waves where foam spray and wave crests align to "
"reveal name PATRICK in negative space and water movement, powerful seascape, "
"photorealistic water physics and light refraction","width":1280,"height":720,"steps":4},
# 17. Smoke and clouds
{"id":"phn_17","theme":"smoke_clouds","style":"painterly","name":"ethereal_smoke_clouds",
"prompt":_Q+_HT+"ethereal smoke and cloud formations in sky where swirling patterns and "
"negative space subtly spell PATRICK, dramatic volumetric lighting, painterly atmospheric "
"style, high detail turbulence and wisps","width":1024,"height":1024,"steps":12},
# 18. Dense jungle foliage
{"id":"phn_18","theme":"jungle_foliage","style":"macro","name":"dense_jungle_canopy",
"prompt":_Q+_HT+"dense tropical jungle foliage where leaves vines and light rays through "
"canopy form hidden name PATRICK through alignment and negative space, "
"ultra detailed leaf veins and moisture, macro realism","width":1024,"height":1024,"steps":4},
# 19. Roman mosaic
{"id":"phn_19","theme":"roman_mosaic","style":"architectural","name":"roman_mosaic_floor",
"prompt":_Q+_HT+"ancient Roman mosaic floor where thousands of tiny colored tiles arrange "
"to subtly hide name PATRICK in geometric pattern, realistic stone texture, "
"archaeological lighting, high detail tesserae","width":1024,"height":1024,"steps":4},
# 20. Military parade — aerial
{"id":"phn_20","theme":"military_parade","style":"aerial","name":"parade_formation_overhead",
"prompt":_Q+_HT+"aerial view of military parade formation where soldiers in perfect alignment "
"create letters PATRICK through their positions and shadows, crisp uniforms, "
"dramatic overhead perspective, photorealistic","width":1280,"height":720,"steps":4},
# 21. Stained glass
{"id":"phn_21","theme":"stained_glass","style":"architectural","name":"cathedral_stained_glass",
"prompt":_Q+_HT+"intricate stained glass window in gothic cathedral where lead lines and "
"colored glass panes form hidden name PATRICK through negative space and symbolic arrangement, "
"luminous backlighting, ultra detailed glass texture","width":1024,"height":1024,"steps":4},
# 22. Spider web
{"id":"phn_22","theme":"spider_web","style":"macro","name":"dew_spider_web_geometry",
"prompt":_Q+_HT+"macro photograph of perfect orb spider web with morning dew where radial "
"and spiral threads align to spell PATRICK in geometric structure, sparkling water droplets, "
"soft morning light, extreme detail","width":1024,"height":1024,"steps":4},
# 23. Galaxy star map
{"id":"phn_23","theme":"galaxy_stars","style":"cosmic","name":"star_map_constellation",
"prompt":_Q+_HT+"detailed star map of spiral galaxy where constellations and star clusters "
"subtly form letters PATRICK through their positions and connecting lines, "
"nebulae and cosmic dust, astronomical precision","width":1024,"height":1024,"steps":4},
# 24. Subway map
{"id":"phn_24","theme":"subway_map","style":"architectural","name":"subway_network_map",
"prompt":_Q+_HT+"highly detailed schematic subway tunnel map where intersecting colored lines "
"station markers and tunnel curves naturally spell name PATRICK in network layout, "
"clean diagrammatic style with realistic depth","width":1280,"height":720,"steps":4},
# 25. Marionettes — architectural rendering
{"id":"phn_25","theme":"marionettes","style":"architectural","name":"puppet_theater_stage",
"prompt":_Q+_HT+"architectural rendering of elaborate marionette theater stage where puppet "
"strings stage lights and scenery elements form hidden PATRICK, dramatic perspective, "
"ultra detailed wood and fabric","width":1024,"height":1024,"steps":4},
# 26. Birds — painterly
{"id":"phn_26","theme":"birds","style":"painterly","name":"bird_migration_painting",
"prompt":_Q+_HT+"painterly illustration of migrating bird flock where formation creates "
"concealed PATRICK letters, dramatic sky with volumetric clouds, rich oil painting texture, "
"romantic naturalist style","width":1024,"height":1024,"steps":20},
]
# ─────────────────────────────────────────────────────────
# Pipeline helpers (ported from cannamanage_gen.py)
# ─────────────────────────────────────────────────────────
def load_progress() -> Dict[str, Any]:
if PROGRESS_FILE.exists():
try:
with open(PROGRESS_FILE) as f:
return json.load(f)
except (json.JSONDecodeError, IOError):
pass
return {"completed": [], "failed": [], "started_at": time.strftime("%Y-%m-%dT%H:%M:%S")}
def save_progress(progress: Dict[str, Any]) -> None:
OUTPUT_ROOT.mkdir(parents=True, exist_ok=True)
with open(PROGRESS_FILE, "w") as f:
json.dump(progress, f, indent=2)
def load_workflow(model: str) -> Dict:
path = WORKFLOW_HERETIC if model == "heretic" else WORKFLOW_SCHNELL
with open(path) as f:
return json.load(f)
def submit_prompt(comfyui_url: str, workflow: Dict) -> str:
data = json.dumps({"prompt": workflow}).encode()
req = urllib.request.Request(
f"{comfyui_url}/prompt", data=data, headers={"Content-Type": "application/json"}
)
with urllib.request.urlopen(req) as resp:
return json.loads(resp.read())["prompt_id"]
def wait_for_image(comfyui_url: str, prompt_id: str, timeout: int = 300) -> Optional[Dict]:
print(" ⏳ Waiting for ComfyUI...", end="", flush=True)
start = time.time()
while time.time() - start < timeout:
try:
with urllib.request.urlopen(f"{comfyui_url}/history/{prompt_id}") as resp:
history = json.loads(resp.read())
if prompt_id in history:
print(" done.", flush=True)
outputs = history[prompt_id].get("outputs", {})
for node_out in outputs.values():
if "images" in node_out:
return node_out["images"][0]
return None
except Exception:
pass
print(".", end="", flush=True)
time.sleep(2)
print(" timeout!", flush=True)
return None
def download_image(comfyui_url: str, image_info: Dict, output_path: Path) -> bool:
try:
url = (
f"{comfyui_url}/view"
f"?filename={image_info['filename']}"
f"&subfolder={image_info.get('subfolder', '')}"
f"&type=output"
)
with urllib.request.urlopen(url) as resp:
img_data = resp.read()
output_path.parent.mkdir(parents=True, exist_ok=True)
output_path.write_bytes(img_data)
print(f" ✅ Saved: {output_path} ({len(img_data) // 1024}KB)")
return True
except Exception as e:
print(f" ❌ Download failed: {e}")
return False
def patch_workflow(workflow: Dict, asset: Dict, model: str) -> Dict:
wf = copy.deepcopy(workflow)
seed = random.randint(0, 2**32 - 1)
if model == "heretic":
wf["2"]["inputs"]["text"] = asset["prompt"]
wf["3"]["inputs"]["text"] = "plain text letters, obvious text overlay, watermark, low quality"
wf["6"]["inputs"]["width"] = asset["width"]
wf["6"]["inputs"]["height"] = asset["height"]
wf["7"]["inputs"]["steps"] = asset["steps"]
wf["13"]["inputs"]["filename_prefix"] = asset["name"]
if "10" in wf:
wf["10"]["inputs"]["noise_seed"] = seed
else:
# flux_schnell.json: node 6=pos, 33=neg, 27=latent(w/h), 13=ksampler(steps/seed), 9=save
wf["6"]["inputs"]["text"] = asset["prompt"]
wf["33"]["inputs"]["text"] = "plain text letters, obvious text overlay, watermark, low quality"
wf["27"]["inputs"]["width"] = asset["width"]
wf["27"]["inputs"]["height"] = asset["height"]
wf["13"]["inputs"]["steps"] = asset["steps"]
wf["13"]["inputs"]["seed"] = seed
wf["9"]["inputs"]["filename_prefix"] = asset["name"]
return wf
def generate_asset(comfyui_url: str, asset: Dict, model: str, progress: Dict) -> bool:
if asset["id"] in progress["completed"]:
print(f" ⏭️ Skipping already completed: {asset['name']}")
return True
print(f"\n Prompt : {asset['prompt'][:100]}...")
print(f" Size : {asset['width']}×{asset['height']} Steps: {asset['steps']}")
try:
workflow = load_workflow(model)
workflow = patch_workflow(workflow, asset, model)
prompt_id = submit_prompt(comfyui_url, workflow)
image_info = wait_for_image(comfyui_url, prompt_id)
if not image_info:
progress["failed"].append(asset["id"])
save_progress(progress)
return False
output_dir = OUTPUT_ROOT / asset["theme"] / asset["style"]
output_dir.mkdir(parents=True, exist_ok=True)
output_path = output_dir / f"{asset['name']}.png"
if download_image(comfyui_url, image_info, output_path):
progress["completed"].append(asset["id"])
save_progress(progress)
return True
else:
progress["failed"].append(asset["id"])
save_progress(progress)
return False
except Exception as e:
print(f" ❌ Error: {e}")
progress["failed"].append(asset["id"])
save_progress(progress)
return False
def main():
parser = argparse.ArgumentParser(
description="Patrick Hidden Name Artwork Generation Pipeline"
)
parser.add_argument("--dry-run", action="store_true",
help="Print manifest without generating")
parser.add_argument("--model", choices=["schnell", "heretic"], default="schnell",
help="Model: schnell (~10s/img) or heretic (~52s/img, higher quality)")
parser.add_argument("--comfyui", default="http://localhost:8188",
help="ComfyUI URL")
args = parser.parse_args()
comfyui_url = args.comfyui
print("🚀 Patrick Hidden Name Artwork Pipeline")
print(f" Output : {OUTPUT_ROOT}")
print(f" Model : {args.model}")
print(f" ComfyUI : {comfyui_url}")
print(f" Total : {len(ASSET_MANIFEST)} ultra-detailed hidden-name artworks")
print(" Technique: Letters P-A-T-R-I-C-K concealed via organic shapes/negative space")
if args.dry_run:
print()
for asset in ASSET_MANIFEST:
print(f" {asset['id']:8} | {asset['theme']:15} | {asset['style']:12} | {asset['name']}")
total_est = sum(a["steps"] * 2.5 for a in ASSET_MANIFEST) / 60
print(f"\n ⏱️ Estimated runtime (schnell @4 steps): ~{total_est:.0f} minutes")
print("\nDry run complete. Remove --dry-run to begin generation.")
return
progress = load_progress()
remaining = [a for a in ASSET_MANIFEST if a["id"] not in progress["completed"]]
print(f" Resume : {len(progress['completed'])} completed, "
f"{len(progress['failed'])} failed, {len(remaining)} remaining")
if not remaining:
print("\n✅ All assets already complete!")
return
print(f"\nStarting generation... (Ctrl+C to pause — progress is saved)")
n_done = 0
n_fail = 0
for i, asset in enumerate(ASSET_MANIFEST, 1):
if asset["id"] in progress["completed"]:
continue
print(f"\n[{asset['theme']}/{asset['style']}] [{i}/{len(ASSET_MANIFEST)}] {asset['name']}")
if generate_asset(comfyui_url, asset, args.model, progress):
n_done += 1
else:
n_fail += 1
print("\n" + "=" * 60)
print("🎉 PIPELINE COMPLETE")
print(f" ✅ Completed this run : {n_done}")
print(f" ❌ Failed this run : {n_fail}")
print(f" 📦 Total completed : {len(progress['completed'])} / {len(ASSET_MANIFEST)}")
if progress["failed"]:
print(f" Failed IDs: {', '.join(progress['failed'][-10:])}")
print(f" Assets saved to: {OUTPUT_ROOT}")
print("=" * 60)
if __name__ == "__main__":
main()
+35 -12
View File
@@ -244,26 +244,49 @@ def build_flux_workflow(
""" """
workflow_path = _WORKFLOW_REGISTRY.get(model, _WORKFLOW_REGISTRY[_DEFAULT_MODEL]) workflow_path = _WORKFLOW_REGISTRY.get(model, _WORKFLOW_REGISTRY[_DEFAULT_MODEL])
with open(workflow_path) as f: # Load workflow as text first — replace string placeholders
wf = json.load(f) raw = workflow_path.read_text()
wf = copy.deepcopy(wf)
actual_seed = seed if seed != -1 else random.randint(0, 2**32 - 1) actual_seed = seed if seed != -1 else random.randint(0, 2**32 - 1)
wf["6"]["inputs"]["text"] = prompt raw = raw.replace('"PROMPT_PLACEHOLDER"', json.dumps(prompt))
wf["33"]["inputs"]["text"] = neg_prompt raw = raw.replace('"NEGATIVE_PLACEHOLDER"', json.dumps(neg_prompt))
wf["27"]["inputs"]["width"] = width wf = json.loads(raw)
wf["27"]["inputs"]["height"] = height wf = copy.deepcopy(wf)
wf["13"]["inputs"]["steps"] = steps
wf["13"]["inputs"]["seed"] = actual_seed # Recursively inject numeric values into matching field names
# Node 32 = UNETLoader (flux1-schnell.safetensors is UNet-only, not all-in-one checkpoint) _inject_workflow_params(wf, {
wf["32"]["inputs"]["unet_name"] = model "width": width,
"height": height,
"steps": steps,
"seed": actual_seed,
"noise_seed": actual_seed,
"unet_name": model,
})
# Attach the actual seed as metadata so callers can retrieve it # Attach the actual seed as metadata so callers can retrieve it
wf["_meta"] = {"actual_seed": actual_seed} wf["_meta"] = {"actual_seed": actual_seed}
return wf return wf
def _inject_workflow_params(node: dict | list, params: dict) -> None:
"""Recursively walk a workflow dict/list and inject parameter values.
For each dict encountered, if it has an "inputs" sub-dict, update
any matching field names from params. This is model-agnostic and
works regardless of ComfyUI node IDs.
"""
if isinstance(node, dict):
if "inputs" in node and isinstance(node["inputs"], dict):
for key, value in params.items():
if key in node["inputs"] and not isinstance(node["inputs"][key], list):
node["inputs"][key] = value
for v in node.values():
_inject_workflow_params(v, params)
elif isinstance(node, list):
for item in node:
_inject_workflow_params(item, params)
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# Helpers # Helpers
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
+30 -50
View File
@@ -4,13 +4,14 @@ import httpx
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from html2text import html2text from html2text import html2text
from urllib.parse import urljoin, quote_plus from urllib.parse import urljoin, quote_plus
from typing import List, Dict, Tuple from typing import List, Dict, Tuple, Annotated
import re import re
import ssl import ssl
import os import os
import certifi import certifi
from pathlib import Path from pathlib import Path
from fastmcp import FastMCP from fastmcp import FastMCP
from pydantic import Field
mcp = FastMCP("webscraper") mcp = FastMCP("webscraper")
@@ -54,13 +55,9 @@ def filter_junk_links(href: str) -> bool:
return not any(re.match(pattern, href.lower()) for pattern in junk_patterns) return not any(re.match(pattern, href.lower()) for pattern in junk_patterns)
@mcp.tool() @mcp.tool()
def webscraper_fetch(url: str, max_chars: int = 5000) -> str: def webscraper_fetch(url: Annotated[str, Field(description="The URL to fetch")], max_chars: Annotated[int, Field(description="Maximum characters in the markdown body (default: 5000)")] = 5000) -> str:
"""Fetch a URL and return title + markdown body + metadata. """Fetch a URL and return title + markdown body + metadata.
Args:
url: The URL to fetch
max_chars: Maximum characters in the markdown body (default: 5000)
Returns: Returns:
Markdown string with title, body, and metadata Markdown string with title, body, and metadata
""" """
@@ -78,13 +75,9 @@ def webscraper_fetch(url: str, max_chars: int = 5000) -> str:
return f"# Error fetching {url}\n\n{str(e)}" return f"# Error fetching {url}\n\n{str(e)}"
@mcp.tool() @mcp.tool()
def webscraper_fetch_links(url: str, deduplicate: bool = True) -> List[str]: def webscraper_fetch_links(url: Annotated[str, Field(description="The URL to fetch")], deduplicate: Annotated[bool, Field(description="Remove duplicate links (default: True)")] = True) -> List[str]:
"""Fetch a URL and extract all href links. """Fetch a URL and extract all href links.
Args:
url: The URL to fetch
deduplicate: Remove duplicate links (default: True)
Returns: Returns:
List of unique href URLs List of unique href URLs
""" """
@@ -105,12 +98,9 @@ def webscraper_fetch_links(url: str, deduplicate: bool = True) -> List[str]:
return [f"Error: {str(e)}"] return [f"Error: {str(e)}"]
@mcp.tool() @mcp.tool()
def webscraper_fetch_tables(url: str) -> List[str]: def webscraper_fetch_tables(url: Annotated[str, Field(description="The URL to fetch")]) -> List[str]:
"""Fetch a URL and extract all HTML tables as markdown. """Fetch a URL and extract all HTML tables as markdown.
Args:
url: The URL to fetch
Returns: Returns:
List of markdown tables List of markdown tables
""" """
@@ -125,13 +115,9 @@ def webscraper_fetch_tables(url: str) -> List[str]:
return [f"Error: {str(e)}"] return [f"Error: {str(e)}"]
@mcp.tool() @mcp.tool()
def webscraper_fetch_all(url: str, max_chars: int = 5000) -> Dict: def webscraper_fetch_all(url: Annotated[str, Field(description="The URL to fetch")], max_chars: Annotated[int, Field(description="Maximum characters (default: 5000)")] = 5000) -> Dict:
"""Fetch everything: markdown + links + tables + meta. """Fetch everything: markdown + links + tables + meta.
Args:
url: The URL to fetch
max_chars: Maximum characters (default: 5000)
Returns: Returns:
Dict with 'markdown', 'links', 'tables', 'meta' Dict with 'markdown', 'links', 'tables', 'meta'
""" """
@@ -181,13 +167,9 @@ def webscraper_fetch_all(url: str, max_chars: int = 5000) -> Dict:
return {"error": str(e)} return {"error": str(e)}
@mcp.tool() @mcp.tool()
def webscraper_fetch_section(url: str, selector: str) -> str: def webscraper_fetch_section(url: Annotated[str, Field(description="The URL to fetch")], selector: Annotated[str, Field(description="CSS selector (e.g., '.content')")]) -> str:
"""Fetch a URL and extract specific section by CSS selector. """Fetch a URL and extract specific section by CSS selector.
Args:
url: The URL to fetch
selector: CSS selector (e.g., '.content')
Returns: Returns:
Markdown of the selected section Markdown of the selected section
""" """
@@ -210,12 +192,9 @@ def webscraper_fetch_section(url: str, selector: str) -> str:
return f"Error: {str(e)}" return f"Error: {str(e)}"
@mcp.tool() @mcp.tool()
def webscraper_fetch_meta(url: str) -> Dict[str, str]: def webscraper_fetch_meta(url: Annotated[str, Field(description="The URL to fetch")]) -> Dict[str, str]:
"""Fetch a URL and return page metadata: title, description, OG tags. """Fetch a URL and return page metadata: title, description, OG tags.
Args:
url: The URL to fetch
Returns: Returns:
Dict of metadata Dict of metadata
""" """
@@ -238,13 +217,9 @@ def webscraper_fetch_meta(url: str) -> Dict[str, str]:
return {"error": str(e)} return {"error": str(e)}
@mcp.tool() @mcp.tool()
def webscraper_fetch_sitemap(url: str, max_urls: int = 100) -> List[str]: def webscraper_fetch_sitemap(url: Annotated[str, Field(description="Sitemap URL (or auto-discover)")], max_urls: Annotated[int, Field(description="Maximum URLs to return (default: 100)")] = 100) -> List[str]:
"""Fetch sitemap.xml and return list of URLs. """Fetch sitemap.xml and return list of URLs.
Args:
url: Sitemap URL (or auto-discover)
max_urls: Maximum URLs to return (default: 100)
Returns: Returns:
List of sitemap URLs List of sitemap URLs
""" """
@@ -263,17 +238,13 @@ def webscraper_fetch_sitemap(url: str, max_urls: int = 100) -> List[str]:
return [f"Error: {str(e)}"] return [f"Error: {str(e)}"]
@mcp.tool() @mcp.tool()
def webscraper_search_hint(query: str, max_results: int = 5) -> Dict: def webscraper_search_hint(query: Annotated[str, Field(description="Search query (e.g. \"MacBook Pro M4 price Germany\")")], max_results: Annotated[int, Field(description="Maximum number of results to return (default: 5)")] = 5) -> Dict:
"""Search Brave Search and return top results as a scraping hint. """Search Brave Search and return top results as a scraping hint.
Use this sparingly — once per research task — to get oriented before Use this sparingly — once per research task — to get oriented before
scraping individual pages. Returns top result URLs + snippets so you scraping individual pages. Returns top result URLs + snippets so you
can decide which pages are worth scraping deeply. can decide which pages are worth scraping deeply.
Args:
query: Search query (e.g. "MacBook Pro M4 price Germany")
max_results: Maximum number of results to return (default: 5)
Returns: Returns:
Dict with 'query', 'search_url', 'results' (list of {title, url, snippet}), Dict with 'query', 'search_url', 'results' (list of {title, url, snippet}),
'result_count', 'hint' 'result_count', 'hint'
@@ -285,14 +256,23 @@ def webscraper_search_hint(query: str, max_results: int = 5) -> Dict:
results = [] results = []
seen_urls: set = set() seen_urls: set = set()
# Brave Search result cards: each div.snippet contains title, URL, description # Brave Search result cards: each div.snippet with a .result-wrapper is a web result.
# Skip video clusters, FAQ blocks, and LLM snippets (they have no .result-wrapper).
# Class names as of 2026-04 (updated from .snippet-title / .snippet-description):
# title → .search-snippet-title
# url → a.l1 (the primary result anchor, avoids favicon <a> tags)
# snippet → .content.t-primary
for card in soup.select('.snippet'): for card in soup.select('.snippet'):
if len(results) >= max_results: if len(results) >= max_results:
break break
title_el = card.select_one('.snippet-title') # Skip non-web-result snippets (videos, FAQ, LLM answer blocks)
url_el = card.select_one('a') if not card.select_one('.result-wrapper'):
desc_el = card.select_one('.snippet-description') continue
title_el = card.select_one('.search-snippet-title')
url_el = card.select_one('a.l1')
desc_el = card.select_one('.content.t-primary')
title = title_el.get_text(strip=True) if title_el else "" title = title_el.get_text(strip=True) if title_el else ""
url = url_el['href'] if url_el and url_el.get('href') else "" url = url_el['href'] if url_el and url_el.get('href') else ""
+35 -43
View File
@@ -206,27 +206,39 @@ def test_sitemap_max_urls(mock_get, mock_sitemap_response):
# --- webscraper_search_hint tests --- # --- webscraper_search_hint tests ---
# Helper to build a Brave-style result card with the new 2026-04 class names.
# Real result cards have a .result-wrapper; non-result blocks (videos, FAQ) do not.
def _brave_card(href: str, title: str, snippet: str) -> str:
"""Return a mock Brave Search .snippet card with .result-wrapper (web result)."""
return f"""
<div class="snippet svelte-jmfu5f">
<div class="result-wrapper svelte-1rq4ngz">
<div class="result-content svelte-1rq4ngz">
<a class="l1 svelte-14r20fy" href="{href}">
<div class="search-snippet-title line-clamp-1 svelte-14r20fy">{title}</div>
</a>
<div class="generic-snippet svelte-1cwdgg3">
<div class="content desktop-default-regular t-primary line-clamp-dynamic svelte-1cwdgg3">{snippet}</div>
</div>
</div>
</div>
</div>"""
@pytest.fixture @pytest.fixture
def mock_brave_response(): def mock_brave_response():
"""Mock Brave Search HTML response with result cards.""" """Mock Brave Search HTML response with result cards (2026-04 class names)."""
mock_resp = MagicMock() mock_resp = MagicMock()
mock_resp.status_code = 200 mock_resp.status_code = 200
mock_resp.text = """ mock_resp.text = """
<html><body> <html><body id="results">
<div class="snippet"> """ + _brave_card("https://example.com/article1", "Feynman on Electric Fields",
<a href="https://example.com/article1" class="snippet-title">Feynman on Electric Fields</a> "Richard Feynman explains that all matter has an electric field.") + """
<div class="snippet-title">Feynman on Electric Fields</div> """ + _brave_card("https://example.com/article2", "Electric Fields Everywhere",
<div class="snippet-description">Richard Feynman explains that all matter has an electric field.</div> "Everything in the universe is surrounded by electric fields.") + """
</div> <!-- Non-result block (no .result-wrapper) — should be skipped -->
<div class="snippet"> <div class="snippet svelte-jmfu5f standalone" id="faq">
<a href="https://example.com/article2" class="snippet-title">Electric Fields Everywhere</a> <header class="desktop-heading-h4">FAQ</header>
<div class="snippet-title">Electric Fields Everywhere</div>
<div class="snippet-description">Everything in the universe is surrounded by electric fields.</div>
</div>
<div class="snippet">
<a href="javascript:void(0)" class="snippet-title">JS Junk</a>
<div class="snippet-title">JS Junk</div>
<div class="snippet-description">Should be filtered out.</div>
</div> </div>
</body></html> </body></html>
""" """
@@ -240,22 +252,10 @@ def mock_brave_response_dups():
mock_resp = MagicMock() mock_resp = MagicMock()
mock_resp.status_code = 200 mock_resp.status_code = 200
mock_resp.text = """ mock_resp.text = """
<html><body> <html><body id="results">
<div class="snippet"> """ + _brave_card("https://example.com/dup", "Dup Result A", "First occurrence.") + """
<a href="https://example.com/dup">Dup Result A</a> """ + _brave_card("https://example.com/dup", "Dup Result B", "Second occurrence — same URL.") + """
<div class="snippet-title">Dup Result A</div> """ + _brave_card("https://example.com/unique", "Unique Result", "Only once.") + """
<div class="snippet-description">First occurrence.</div>
</div>
<div class="snippet">
<a href="https://example.com/dup">Dup Result B</a>
<div class="snippet-title">Dup Result B</div>
<div class="snippet-description">Second occurrence — same URL.</div>
</div>
<div class="snippet">
<a href="https://example.com/unique">Unique Result</a>
<div class="snippet-title">Unique Result</div>
<div class="snippet-description">Only once.</div>
</div>
</body></html> </body></html>
""" """
mock_resp.headers = {"content-type": "text/html"} mock_resp.headers = {"content-type": "text/html"}
@@ -268,17 +268,9 @@ def mock_brave_response_empty_content():
mock_resp = MagicMock() mock_resp = MagicMock()
mock_resp.status_code = 200 mock_resp.status_code = 200
mock_resp.text = """ mock_resp.text = """
<html><body> <html><body id="results">
<div class="snippet"> """ + _brave_card("https://example.com/ghost", "", "") + """
<a href="https://example.com/ghost"></a> """ + _brave_card("https://example.com/real", "Real Result", "Has content.") + """
<div class="snippet-title"></div>
<div class="snippet-description"></div>
</div>
<div class="snippet">
<a href="https://example.com/real">Real Result</a>
<div class="snippet-title">Real Result</div>
<div class="snippet-description">Has content.</div>
</div>
</body></html> </body></html>
""" """
mock_resp.headers = {"content-type": "text/html"} mock_resp.headers = {"content-type": "text/html"}