Skip to content
Development
Skill

/odoo-workflow

Mandatory pre-code gate and definition-of-done for ANY Odoo change (add field, override method, inherit view/xpath, OWL/JS patch, wizard, cron, controller, report, security, migration, bug fix, refactor, "optimize", "clean code", "stick to base"), Odoo 16-19. Also when the user

BOOST
From plugin
unclecatvn-agent-skills
1507 skills2 agents
Install
$ npx -y skills add unclecatvn/agent-skills --skill odoo-workflow --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/odoo-workflow

Context preview

The summary Claude sees to decide when to auto-load this skill.

Mandatory pre-code gate and definition-of-done for ANY Odoo change (add field, override method, inherit view/xpath, OWL/JS patch, wizard, cron, controller, report, security, migration, bug fix, refactor, "optimize", "clean code", "stick to base"), Odoo 16-19. Also when the user

SKILL.md

odoo-workflow.SKILL.md
name: odoo-workflow
description: >
  Mandatory pre-code gate and definition-of-done for ANY Odoo change (add field, override method,
  inherit view/xpath, OWL/JS patch, wizard, cron, controller, report, security, migration, bug fix,
  refactor, "optimize", "clean code", "stick to base"), Odoo 16-19. Also when the user pastes an
  Odoo traceback or install/upgrade error (ParseError "cannot be located in parent view", "Field
  ... does not exist", missing xmlid) or asks where an Odoo model, field, method, view or xmlid is
  defined. Run BEFORE brainstorming or planning: Odoo design questions are answered by tracing the
  real source into a Context Brief (file:line), not by open-ended Q&A or memory. Resolves the Odoo
  runtime and version, loads the matching odoo-<major> pack, and closes with install, test,
  upgrade, i18n, security and hygiene checks before commit.

Odoo Workflow - trace first, then code

Procedure for every Odoo change. The expensive failures are always the same: a field or method that does not exist, an xpath anchor that was never there, an override hooked on the wrong method, a stored field renamed without a migration, a `sudo()` nobody can audit, a test run that ran no tests. The fix is mechanical: **no citation, no code**.

When this applies

  • **Full path** - anything that ends in Odoo Python, XML, JS or data: new field, override,

inherited view, OWL patch, wizard, cron, controller, report, security, migration, bug fix, refactor, "optimize", "clean up". A pasted traceback starts here: its innermost frame in a workspace module is the first citation.

  • **Brief only** - questions about Odoo symbols ("where is X defined", "does `sale.order` have

F", "which model gets this field on 19"): run Steps 0-2 and answer with the Brief, no code.

  • **Fast path** - the change names no symbol outside the module being edited and adds no field,

override, xmlid, xpath, group or `depends`: a label, help text or typo in the module's own code, a manifest version bump, a test-only change. The Brief is one row citing the edited line; skip Steps 1, 3 and 6; Step 5 still applies (i18n when a string changed). Any doubt: full path.

  • Skip for documentation-only and git-only tasks (use `odoo-commit`).
  • Brainstorming and planning skills come *after* Step 2, and only if the business intent is still

unclear - the Context Brief is their input.

Step 0 - Runtime, version, pack

The bundled helper `scripts/odoo_trace.py` (stdlib Python 3.8+, read-only) resolves the runtime and answers the Python-side trace questions. Call it with the skill's base directory written out in full every time - shell variables do not survive between tool calls. Below, `odoo_trace` stands for `python3 <skill_dir>/scripts/odoo_trace.py`.

odoo_trace env

First hit wins: flags, `.claude/odoo.json`, an `odoo-bin` configuration in `.claude/launch.json` whose addons cover the cwd (both files in the cwd or nearest parent), then the one `*.conf` whose `addons_path` covers the cwd, searched from the parent directory upwards (each level and its subdirectories). It prints `version` (from `odoo/release.py`), `odoo_root`, `conf`, `python`, `dev_db`, and the addons roots in the order Odoo uses them (the first root holding a module name wins). An `odoo_version` in `.claude/odoo.json` or a `.odoo-version` file must match `release.py`.

  • Exit 2 prints `SETUP ERROR:` and the cause. Runtime not located: ask once for the core

checkout and conf, pass them as `odoo_trace --odoo-root <core> --conf <conf> <command>` on every call (`roots` included), and offer to write a gitignored `.claude/odoo.json` with `odoo_version`, `odoo_root`, `conf`, `python`, `dev_db` (machine-local paths). Version sources that disagree, or several confs covering the cwd: ask which one is right. Never trace against custom roots alone.

  • An explicit statement from the user or the project `CLAUDE.md` / `AGENTS.md` outranks the

helper. If they disagree, stop and ask. Do not silently assume a version.

  • Load the Odoo reference pack for that major: `odoo-<major>` with the skills CLI,

`<plugin>:odoo-<major>-0` in the Claude Code plugin (for example `agent-skills:odoo-18-0`). Read its `references/api-highlights.md` (APIs removed or renamed in this version) and only the guide section the task needs (`grep -n '^## ' <guide>`, then a range). Pack missing: say so and continue - the real source is the authority, never memory.

Step 1 - Trace the chain

**Python symbols: the helper.** It parses classes with `ast`, applies the version's `_name` rules, follows `_inherit` parents (mixins such as `mail.thread`, `portal.mixin`), `_inherits` delegation, `base` extensions and the core `BaseModel`, marks classes in files the module never imports (`UNIMPORTED`), and prints absolute `file:line`.

| Question | Command | |----------|---------| | Classes defining / extending MODEL, its mixins, type, `_auto`, `_log_access` | `odoo_trace model MODEL` | | Does FIELD exist on MODEL (own, parent, `_inherits`, magic), every definition, comodel; a dotted path is checked hop by hop | `odoo_trace field MODEL FIELD[.FIELD...]` | | Every definition of METHOD in `super()` order (#1 runs first), `super()` calls, hooks, AMBIGUOUS pairs | `odoo_trace method MODEL METHOD --module MODULE` | | Transitive `depends` of MODULE in load order | `odoo_trace depends MODULE` | | Does an xmlid exist (loaded XML record or CSV row, or generated at install) | `odoo_trace xmlid module.name` | | Files of MODULE that never load (not in `data`/`assets`, not imported) | `odoo_trace unlisted MODULE` |

The last line is the `VERDICT`. Exit 0 = found, 1 = NOT FOUND (the verdict names the closest real symbols), 2 = setup error or answer unknown. Only exit 1 supports a NOT FOUND cell. Lists on hub models (`sale.order`, `mail.thread`) are capped; `--all` after `model`, `method` or `unlisted` prints them whole.

**XML, JS, controllers, uses: grep over the same roots.**

Read more
Ships withunclecatvn-agent-skills

Reference packs, a trace-first development workflow, and specialized reviewers that make AI coding assistants work from your real Odoo source instead of from memory. Odoo 16–19.

Get the whole plugin

Other skills on unclecatvn-agent-skills.