Skill: new-odoo-project
TRIGGER: User invokes /new-odoo-project to scaffold a new Odoo website builder project.
Objective
Scaffold a new Odoo website builder project directory, copy all bundled tools and workflows from the skill's templates/ directory, create a configured .env template, and orient the user for their first session.
Prerequisites
Before running this skill, ensure the following are in place:
- Python 3.8+ installed and available as
python3 - Python packages — install from the bundled requirements file:
This installspip install -r {skill_dir}/templates/requirements.txtrequestsandpython-dotenv, the only third-party dependencies. - An Odoo instance with admin or API access (URL, database name, and login email)
- Claude Code — this skill is designed for Claude Code's skill system
Step 1 — Gather technical information (ask all at once)
Ask the user for the following in a single message. Do not proceed until you have answers:
- Project parent directory — the folder where the project subdirectory should be created (e.g.
~/projectsor~/Odoo) - Client / project name — used for folder naming and memory. The project will be created at
{parent_dir}/{slugified-client-name}/(e.g.~/Odoo/client-acme/) - Odoo URL — e.g.
https://mysite.odoo.com - Odoo DB name — e.g.
mysite-main-12345 - Odoo login email
- Is this a production-only server, or is there a separate staging instance?
- If staging + production: collect both URLs and DB names (but NOT passwords)
- If production only: note that changes go live immediately — extra caution required
- GitHub repo linked to the Odoo.sh project — e.g.
https://github.com/org/repo. This is the repository Odoo.sh watches for deployments. Custom modules are added here as submodules. If the project is not hosted on Odoo.sh, answer "N/A".
Do NOT ask for any passwords. Tell the user: "I'll leave the password fields blank in .env — fill those in yourself before running any tools."
Do NOT ask about brand, fonts, or design yet — those come after the project is set up.
Step 2 — Create the project directory
Derive {project_dir} by slugifying the client name (lowercase, replace spaces with hyphens) and appending it to the parent directory: {parent_dir}/{slugified-client-name}.
For example, if parent is ~/Odoo and client name is "Demo Video", then {project_dir} = ~/Odoo/demo-video.
mkdir -p {project_dir}/tools
mkdir -p {project_dir}/workflows
mkdir -p {project_dir}/.tmp
Step 3 — Copy tools from skill templates
Copy all .py files from the skill's bundled templates. The skill's base directory is provided when invoked — use it to locate templates/tools/:
cp {skill_dir}/templates/tools/*.py {project_dir}/tools/
The migrate_to_production.py template ships pre-cleaned with empty META_UPDATES, CSS_VIEW_KEYS, and PAGE_URLS lists, and a clean main() with commented examples. No post-copy cleanup is needed.
Step 4 — Copy workflows from skill templates
cp {skill_dir}/templates/workflows/*.md {project_dir}/workflows/
Workflows are generic and apply to any Odoo project without modification.
Step 4b — Create .gitignore
Write .gitignore to the project root to prevent committing secrets and temporary files:
# Credentials
.env
# Temporary files
.tmp/
# Python
__pycache__/
*.pyc
*.pyo
# OS files
.DS_Store
Thumbs.db
# IDE
.vscode/
.idea/
Step 5 — Create .env
Write .env to the project root. Leave all password fields blank.
For a staging + production setup:
# Staging
ODOO_URL={staging_url}
ODOO_DB={staging_db}
ODOO_USER={login_email}
ODOO_PASSWORD=
# Production (fill in when ready to migrate)
# PROD_ODOO_URL={prod_url}
# PROD_ODOO_DB={prod_db}
# PROD_ODOO_USER=
# PROD_ODOO_PASSWORD=
For a production-only setup:
# Production (working directly on production — no staging)
ODOO_URL={odoo_url}
ODOO_DB={odoo_db}
ODOO_USER={login_email}
ODOO_PASSWORD=
Step 6 — Create CLAUDE.md
Write CLAUDE.md to the project root using this template:
# Agent Instructions
You're working inside the **WAT framework** (Workflows, Agents, Tools).
## The WAT Architecture
**Layer 1: Workflows** — Markdown SOPs in `workflows/`
**Layer 2: Agents** — Your role: read workflows, run tools, handle failures
**Layer 3: Tools** — Python scripts in `tools/` for deterministic execution
## How to Operate
1. Look for existing tools before building new ones
2. Learn and adapt when things fail — update workflows with findings
3. Keep workflows current as the project evolves
## File Structure
\`\`\`
.tmp/ # Temporary files — regenerated as needed
tools/ # Python scripts
workflows/ # Markdown SOPs
.env # Credentials — NEVER commit this
\`\`\`
## Project: {client_name}
- **Server:** {odoo_url}
- **DB:** {odoo_db}
- **GitHub repo:** {github_repo_url}
- **Brand colors:** TBD
- **Brand fonts:** TBD
- **Design direction:** TBD
- **Logo:** TBD
> ⚠️ [Production-only note if applicable: This project works directly on production. There is no separate staging server. Always use `--dry-run` before any migration. Be extra careful — changes go live immediately.]
## Key Workflows
- `workflows/design_page.md` — designing and building pages
- `workflows/push_to_odoo.md` — pushing content to Odoo
- `workflows/create_mailing.md` — formatting and pushing email mailings
- `workflows/design_survey.md` — designing and creating Odoo surveys
- `workflows/css_theming.md` — CSS injection pattern
- `workflows/migrate_staging_to_prod.md` — staging → production migration
## Rules
- Always read a workflow before starting a task that matches it
- Never store secrets anywhere except `.env`
- Validate HTML before pushing: `python3 tools/validate_html.py --input .tmp/draft.html`
- Always dry-run before migrating to production
Step 7 — Verify setup
Run a connection test:
cd {project_dir} && python3 -c "
import sys; sys.path.insert(0, 'tools')
from odoo_client import OdooClient
c = OdooClient()
uid = c.authenticate()
print('Connected — uid:', uid)
pages = c.search_read('website.page', [('active','=',True)], ['url','name','is_published'])
print(f'{len(pages)} pages found:')
for p in sorted(pages, key=lambda x: x['url']):
pub = 'published' if p['is_published'] else 'draft'
print(f' {p[\"url\"]:<35} {pub}')
"
If authentication error: remind the user to fill in ODOO_PASSWORD in .env.
If connection error: ask the user to double-check ODOO_URL and ODOO_DB.
Step 8 — Verify the WYSIWYG editor and snippet blocks
This step must be done by the user in a browser. Instruct them to:
- Log into the Odoo backend and open the website editor on any page (click Edit in the top bar)
- Look at the right-hand Blocks panel — confirm snippet thumbnails load with no orange ! warning icons
- Drag any block (e.g. a Text block) onto the page — confirm it drops and renders without errors
- Click an existing text element — confirm the formatting toolbar appears
- Click an existing image — confirm the image toolbar appears
If snippet blocks show orange ! icons (all or most of them):
Root cause: No theme is linked to the website (theme_id = False). This causes Odoo's snippet rendering to fail.
Fix — install and link theme_clean:
python3 - <<'EOF'
import sys
sys.path.insert(0, 'tools')
from odoo_client import OdooClient
c = OdooClient()
c.authenticate()
# Find theme_clean module
modules = c.search_read("ir.module.module", [["name", "=", "theme_clean"]], ["id", "name", "state"])
print("theme_clean:", modules)
# If state is 'uninstalled', install it
if modules and modules[0]["state"] == "uninstalled":
module_id = modules[0]["id"]
c._execute_kw("ir.module.module", "button_immediate_instal