Light theme — the dashboard and login page gain a light theme alongside the dark "Engineer's Console" field. It follows the OS (prefers-color-scheme) by default; a header toggle cycles System → Light → Dark and persists the choice to localStorage, applied before first paint so there is no flash. It is built by re-pointing the existing :root color tokens — signal colors switch to AA-verified darkened variants on the light field, while the embedded terminal stays dark — and the logo is now transparent so it reads cleanly on either field.
Larger dashboard type scale — 68 hardcoded px font sizes were replaced with six semantic rem tokens (--text-2xs…--text-xl), raising every tier ~+2px (body 13→15px, titles 15→17px, header 20→23px) for readability at density. (#63)
Note dialog Delete button — the environment note editor now has an explicit Delete action. (#63)
MCP bootstrap instructions — the MCP initialize response now tells agents to load get_agent_instructions first and then call get_odoo_development_guide(version=...) before writing Odoo module code.
Git-independent live-mount apply flow — local_path environments now use an Oduflow-owned per-environment file snapshot instead of Git status to detect local changes. Git commits are optional in live-mount mode, non-git folders are supported as-is, and already-applied dirty/untracked files are no longer reported repeatedly.
Config-gated live-mounts — added [server].allow_local_path (default: true) to enable the single-developer live-mount workflow by default while still allowing operators to disable local bind mounts explicitly.
Mode-aware agent instructions — get_agent_instructions now starts with a dynamic code-delivery-mode preface. When a live-mounted environment is active, agents see the local workflow first, including the explicit install/upgrade/restart rules that apply to snapshot-based detection.
Live-mount templates in Web UI — environments created from templates that record local_path can now be recreated as live-mounts when allow_local_path is enabled, instead of always being rejected as HTTP-only.
Local pull_and_apply repeat detection — snapshots advance only after successful apply operations, and stay unchanged when strict guardrails block or install/upgrade fails.
License config path — license activation now stores license.key in the resolved Oduflow config directory instead of hard-coding /etc/oduflow; when /etc/oduflow is not writable it follows the same ~/.oduflow/conf fallback as the rest of the config. The dashboard license API now uses the running server settings, so the unlicensed badge still appears when no key is installed. (fe142ec)
CLI startup warning — suppress the noisy Authlib deprecation warning emitted by FastMCP on startup. (44872e8)
rebuild_environment renamed to update_environment — the tool (and its REST route /api/environments/{branch}/update) now also accepts odoo_image and env_vars to switch the image and replace container environment variables. Called with no arguments it behaves exactly like the old rebuild_environment (re-create the container, preserving DB and filestore). (a13c73a)
Stdio live-mount + explicit pull_and_apply guardrail — create_environment(local_path=...) bind-mounts the agent's own checkout live into the container (stdio transport only), so edits apply instantly with no git push/pull; pull_and_apply is transport-agnostic and takes explicit install/upgrade/restart actions, with a guardrail that cross-checks the requested action against the detected diff and surfaces non-blocking warnings (aca9445)
Environment lifecycle automation — idle environments auto-stop and long-stopped environments auto-delete after configurable hours (protected environments are exempt); container-level tools auto-wake a stopped environment and prepend a note; activity is tracked per team in activity.json (e992971)
Environment variables for environments — create_environment accepts env_vars (comma-separated KEY=VALUE) injected on top of the database connection variables; update_environment can replace them later. Env vars are persisted on the container, reported by get_environment_info, and editable from the web dashboard create form (a13c73a)
Self-hosted OAuth Authorization Server for MCP clients (5f32f58)
GitHub OAuth support for MCP HTTP transport (97c3fc8)
auto_install_modules parameter for environments and templates (e868d90)
Docker volume management — manage persistent service data via Docker volumes, mount external Docker volumes to services, and browse/manage files inside volumes (6b05f8a, a396583, 5cabc2c)
Engineer's Console redesign — visual system aligned with oduflow.dev (OKLCH tokens, Outfit + Geist Mono, signal palette); all assets vendored (xterm.js and fonts, no CDN, works air-gapped); state-driven Start/Stop toggle; in-system dialogs replace native confirm()/prompt(); accessibility (focus traps, ARIA roles, keyboard navigation, ≥44px touch targets); responsive down to 390px; single polling interval; real RAM/CPU metrics on macOS (e992971)
Session-cookie auth with login form and logout — replaces the HTTP Basic browser dialog; signed itsdangerous session cookies (7-day expiry, persistent server-side secret); Basic auth retained for API/CLI clients (9e24ab2)
Show git branch in env list when it differs from the environment name (ae5441d)
host_mode checkbox on service creation and restore forms (73fbee7)
PR and commits icon-links next to the repo URL (25017cd)
WebSocket terminal auth — Console/SQL terminals failed because browsers can't send a Basic auth header on a WS handshake; added a signed cookie auth fallback for HTTP and WebSocket scopes (9e24ab2)
Greenfield DB init race — for template_name=none, initialize the empty DB in an isolated short-lived container before the serving container starts, avoiding a concurrent orm_signaling_registry collision that left base uninstalled (aca9445)
Orphan PG role on template restore — restore env-derived templates with --no-owner so deleting the source environment can drop its per-environment role (aca9445)
Test port flag by Odoo version — pick --longpolling-port vs --gevent-port based on the environment's Odoo major version (79b1c35)
run_odoo_tests port & execution — pass --no-http --workers 0 to avoid an 8069 conflict; override test ports and use -u so tests actually run (6311dc4, 738263e)
Post-clone DB fixup — transfer object ownership and drop signaling sequences (205e79f)
Filter containers by prefix to isolate test/production environments (4a50e1c)
Skip submodule recursion on git fetch to tolerate inaccessible submodules (5a1a476)
Raise NotFoundError when deleting a non-existent environment (0a1d875)
update_service URL KeyError; fresh pull on create (27ec4c9)
Propagate cap_add/privileged in restore_service and surface them in list_service_presets (6bca16c)
Strip docker volume name prefix in resolve_volume_binds (2573b17)
Exclude checkboxes from full-width input styling in forms (7f685c9)
Pass missing team arg to _get_used_ports in template_up (fbfc85e)
Recreate live-mount environments as live-mounts — record local_path in template metadata and restore it on create (9e24ab2)
Stdio transport is now the default — oduflow starts in stdio mode by default (previously HTTP). Use oduflow --transport http for HTTP mode. (34e42fa, f33dfe6)
Move repo-level odoo.conf to .oduflow/odoo.conf — per-repo Odoo config is now read from <repo>/.oduflow/odoo.conf instead of the repo root
Auto-initialize on startup — oduflow automatically runs initialization (system setup, Docker check) on first start, removing the need for a separate oduflow init step (34e42fa, f33dfe6)
MCP tools refinement — output cache for long-running tool results, 7 new MCP tools, 3 enhanced tools; renamed exec_in_odoo to run_odoo_command (44810aa)
Include odoo.conf in upgrade — module upgrades now apply odoo.conf changes, skipping files that haven't changed (f69bc2f)
Show template database name in list-templates output (c816229)
Default odoo.conf values — added workers=0 and db_maxconn=4 to the odoo.conf template for single-process development (f16ab37)
Team-based multi-tenancy replaces instance-based isolation — configuration migrated from .env / ODUFLOW_INSTANCE_ID to TOML-based oduflow.toml with per-team settings (workspaces, templates, credentials, port ranges, hostnames). The .env.example file has been removed. (ad3b382, 14503a0)
Team-based multi-tenancy — per-team isolation with dedicated hostnames, git credentials, port ranges, and MCP token auth; auto-generated Traefik dynamic config for per-team routing; team resolution from Host header or bearer token (ad3b382, 14503a0)
CLI: run-instance command, --version and --instance flags — run a named instance directly from CLI with version info support (0094369)
CLI: systemd-install / systemd-uninstall commands — install/remove Oduflow as a systemd service (d266ca9)
Per-environment PostgreSQL credentials — each environment gets its own isolated database role and password (e4949b0)
Two-tier database sanitization — system-wide sanitization scripts plus per-repo .odoo_sanitize/ folder support (cd0b9ec)
MCP tool: read_file_in_odoo — read files and list directories inside Odoo containers without shell commands (abcc525)
MCP tool: reset_admin_password — reset the admin user password in any environment's database (608b476)
Extra repos: fetch summary and propagation — update_extra_repo returns a summary of fetched branches and propagates updates to running environments (a80ba53)
Per-branch locking module — new LockManager replaces the single global mutex with per-branch and per-team locks (ad3b382)
Docker publishing support — added .dockerignore and Docker publishing instructions (24f653a)
MCP concurrency — pass stateless_http=True to unblock concurrent MCP requests; run sync MCP tools in thread pool to prevent event loop blocking during long operations (81457b1, ed4a265)
TLS certresolver name — match Docker label to Traefik's ACME provider name ("letsencrypt" not "le") (727448b)
HOME fallback for systemd — add HOME=/root to GIT_ENV so git operations work under systemd (a982b9d)
Reject SSH repo URLs — SSH URLs caused hangs due to interactive host-key prompts; now rejected early with a clear error (ad3b382)
Database ownership on template clone — fixed ownership reassignment for tables, sequences, views, and materialized views; switched to GRANT role approach (31df320, afb66d0, 5c7b737)
Environment deletion — drop database before role to avoid dependency errors (4b28e9e)
Strip db_password from odoo.conf — ensures the Docker entrypoint uses environment variables instead (f9f89d5)
Template publish — prevent self-copy in reload_template, scope publish to environments matching the template (b92631a)
Git sync — replace git pull --rebase with fetch + reset --hard for reliable sync; use explicit refspec in pull_repo (d57ee7e, 74ef53d)
Load extra_addons from template metadata in create_environment (3d629e6)