Changelog
v3.7.0 — June 7, 2026
R&D workflow — switch foundation
Reworked how cc switch handles R&D workspaces (a single multi-repo Odoo checkout: odoo, enterprise, design-themes, upgrade, upgrade-util).
- All shared repos now follow the env's branch. On switch, each repo checks out the env branch wherever it already exists (local / fork / upstream), materializing a tracking branch from the fork when needed. If the branch doesn't exist in a repo, that repo is left untouched — no fallback checkout, no auto-created branch.
- Per-repo remotes resolved by URL, not by a single workspace-wide remote name.
odoo-dev/*→ fork,odoo/*→ upstream. This handles inconsistent remote names (originvsodoovsodoo-dev) and fork-less repos (e.g.upgrade, which only has the upstream) with zero per-workspace config. Both fork and upstream are fetched before rebase, fixing a stale-rebase bug where only the fork was fetched. - Every repo is optional. A workspace missing
enterprise/design-themes/upgrade/etc. just skips those repos; non-R&D projects are completely unaffected. --upgrade-pathnow spans both upgrade repos:upgrade-util/srcandupgrade/migrations. Previously onlyupgrade-util/srcwas emitted because theupgraderepo was invisible (theODOO_UPGRADEconstant pointed atupgrade-util). Split intoODOO_UPGRADE(upgrade) andODOO_UPGRADE_UTIL(upgrade-util).- R&D addons path no longer appends the workspace root. The project path equals the version root in R&D mode, so it was adding a junk trailing entry; the addons set is now exactly the shared repos.
R&D workflow — environment lifecycle (anti-bloat)
R&D maps one env per ticket, so the env list grows without bound. Environments now carry a lifecycle status so the picker stays short.
- New
statuson environments:active(default) /merged/archived. The column is added automatically by the ORM's schema sync — no migration; rows predating it read asactive. - Default switch picker filters to what's live.
cc switch <project>(and the no-arg recent picker) now show onlyactive, pinned, or recently-used (≤14 days) envs.archivedis always hidden;mergedlingers through the grace period (recent/pinned) then drops off.cc switch --all/-ashows everything. If every env is filtered out, switch transparently falls back to showing all rather than claiming the project is empty. - Manage status from the CLI:
cc env archive|activate|merged [project], plus a "Status" field in the interactivecc env editmenu. Status shows as a badge oncc env listcards and incc env list --json. - Auto-stale: two new settings (
env.auto_stale_days,env.auto_stale_status, incc config/cc setupunder Environments). Whendays > 0, each switch retires active envs unused for that long to merged/archived — pinned envs are never touched.0disables. - Reactivation prompt: switching onto a merged/archived env (via
--all,--env <name>, or a single-env project) asks whether to set it active again, so the lifecycle isn't a one-way trip. - New RPCs
env.set_statusandenv.sweep_stale;env.find_by_project_name/env.get_recent_envsgain aninclude_allparameter.
R&D workflow — creation UX
- Auto-detected workspace:
cc project add <name>run inside an R&D workspace now detects it from the current directory — no more-w. (Non-R&D dirs are unaffected.) - Home repo: R&D project creation asks which shared repo the module(s) live in (odoo/enterprise/upgrade, only those present are offered) and stores it as
Project.home_repo. It scopes creation; checkout still follows the branch across all repos. - Fork-scoped branch picker: the branch prompt now lists only the home repo's fork (odoo-dev) branches, newest first — your own dev branches, not the upstream's thousands. Fast and relevant; falls back to a manual entry when there's no fork.
- Dash-safe autocomplete: fixed the autocomplete breaking when you typed past a
-(e.g.master-l10n_…). prompt_toolkit was treating-as a word boundary; completion now matches the whole token. Applies to everyccautocomplete prompt (branches, databases, …).
R&D workflow — workspaces via git worktrees
Stop cloning Odoo once per version. New cc workspace actions (backed by the cc.workspace.worktree module):
cc workspace create [name]— build a new R&D workspace by addinggit worktrees of each shared repo from an existing version's clones. The worktrees share the source's object store, so a second working area for parallel ticket work costs ~nothing. Creates the new dir (detached at the base branch —cc switchmoves each repo onto the ticket branch), plus its ownversion+workspacerows.cc workspace consolidate— fold duplicate full clones of the same repo (the "I cloned odoo per version" situation) into worktrees of one canonical clone, reclaiming the wasted disk. Reversible and safe: only clean clones are touched; every branch is copied into the canonical first (divergent ones preserved under a__ccsuffix); the old clone is moved to<path>.cc-bak(instant, same-filesystem) and replaced by a worktree — nothing is deleted, and a failedworktree addrolls the move back. You reclaim disk by deleting the.cc-bakdirs once satisfied.
R&D workflow — forward-port discovery
A ticket is a project; each branch in its forward-port chain is an env (carrying its own version + branch). cc now builds that chain for you.
Project.main_branch— the ticket's starting branch (e.g.19.0-fix-issue), set when you create an R&D project.- Auto-discovery on
cc project add— after you pick the home repo and main branch, cc scans the fork for the chain (<target>-<main_branch>-fw, e.g.19.1-19.0-fix-issue-fw,master-19.0-fix-issue-fw), resolves each target token against your registered cc versions, and creates one env per (version, branch). Unregistered targets are skipped with a note. cc env add <ticket> --fw(alias--ports) — re-scan later when you push a new forward-port; idempotent, only adds what's missing.- Matching is by stripping the known
-<main>-fwsuffix and resolving the leading token against version names — sosaas-17.4and multi-hop ports work without a brittle regex. Newcc.workspace.forward_portsmodule.
Companion — control env states from the web
The env lifecycle (active / merged / archived) was CLI-only. The env detail page now has a segmented status control right in the header — click to set the state, with the live value reflected. New POST /api/env/[name]/status route (→ env.set_status); the env GET now returns status.
Active envs stop hanging
In multi-version mode each version keeps its own active env, and nothing ever expired it — so a saas slot you switched to once kept showing as "active" in cc status (cwd-resolved) and the dashboard forever. Now an active slot only counts as active if it was switched within the current session: after the most recent timesheet_eod that's passed, or "today" when no EOD is set. Cross EOD → it reads inactive (computed, so cc status self-heals immediately); switching re-activates. Dead AppState slots are also pruned lazily on the next switch (new env.deactivate_stale).
Fixes
cc pr createnow uses the repo's PR template. It was passing--body "", which overrides.github/PULL_REQUEST_TEMPLATE.md. cc now resolves the template (gh's standard locations) and prefills it via--body-file, falling back to an empty body only when there's no template.
v3.6.0 — June 5, 2026
GitHub integration overhaul
Replaced all raw GitHub API calls with the gh CLI. Authentication now comes from the OS keyring via gh auth login — no more storing a PAT in CC's database.
cc pr — full PR workflow
The cc pr command gains subcommands for the complete PR lifecycle:
cc pr— interactive TUI picker of your open PRs (unchanged)cc pr list— table of open PRscc pr create [base]— create a PR from the current branch (interactive title prompt,--draftflag)cc pr view <number>— show PR details, review status, and diff statscc pr merge <number>— merge with method picker (squash/merge/rebase)cc pr checkout <number>— checkout a PR branch locallycc pr checks <number>— show CI check statusescc pr --json— JSON output (unchanged)
Web companion
- Dashboard code reviews and env CI checks now use
gh— no PAT required - Settings page: GitHub section replaced with read-only
ghauth status - New
/api/github/statusendpoint for auth state
Removed
github_patandgithub_usernamesettings — deleted by migration v18- PAT input and classic PAT instructions from the Settings page
- All direct
urllib/fetchcalls toapi.github.com
New files
src/cc/utils/gh.py— PythonghCLI helper (search, view, create, merge, checkout, checks)web/lib/gh.ts— TypeScriptghCLI helper with type-safe remapping to existing contracts
v3.5.0 — May 30, 2026
Web companion redesign
The companion app is rewritten away from the generic shadcn-dashboard look toward a distinctive identity.
- Typography + layout — Rubik display font, no Card wrappers, hero-stats pattern (big tabular-nums with small labels), asymmetric compositions, section headers and rows separated by thin borders
- Shared primitives —
SectionHeader,StatDisplay,EnvTag,StatusIndicator,TimeGauge,ActivityStrip— every page composes from the same vocabulary - Shared hooks —
useAutoRefresh,useDebounce,useIdle,useEvents - All pages redesigned — Dashboard, Projects, Skills, Health, Timesheet, History, Logs, Databases, Env detail
- Sidebar — replaced shadcn
SidebarwithAppNav; collapsible (⌘B), state persisted tolocalStorage, icon-only mode for narrow displays - Themes work everywhere — recharts tooltips, sonner toasts, shadcn tooltip popovers all theme-aware via CSS variables +
color-mix(in oklch, ...). Coversdefault,purple,rose,green,blue,amber,chronocoder,light,stone,sky,sage. - Multi-active environments — Dashboard now lists every active env, not just the first one
- Light theme contrast pass — bumped opacity values that ghosted out on light backgrounds
- Bug fix — duplicate envs on Dashboard caused by SQL fanout in
/api/projects(LEFT JOINs that multiplied rows when a env had multipleapp_state/database/versionmatches). Fixed at the route level + defense-in-depth dedupe inDashboardClient.
Idle screen
A new ambient screen takes over after 10 minutes of inactivity.
- Big glowing cc wordmark with slow
text-shadowpulse, theme-aware glow viacolor-mix(in oklch, var(--cc-cyan-400) X%, transparent) - Bold tabular-nums clock (HH:MM with blinking colon, seconds in smaller superscript)
- Twinkling background stars + a single CRT scanline that sweeps top-to-bottom
- Rotating CLI command tips (23 entries) that fade in/out every 7 seconds
- DVD-screensaver easter egg (1-in-6 chance per activation, or force with
Shift+Dtwice) with corner-hit detection and a flash on every corner hit - Manual triggers for testing:
Shift+Itwice, orwindow.dispatchEvent(new Event("cc:idle")) - Wakes on any input
IDE writer plugin system
cc's editor integration is now pluggable instead of hardcoded.
- New
IdeWriterinterface incc.ide— four methods:name,detect,setup,apply - New
CcStatedataclass — stable contract passed to writers (workspace path, env, db, branch, version, odoo_bin, port, addons, modules, upgrade_path, python_path) - Built-in writers: VSCode + Cursor (out of the box). Anything else is a plugin.
- Setup vs apply split —
cc switchonly writessettings.json(database, addons, modules, ports, Python interpreter). Editor templates likelaunch.jsonare written once viacc ide setupand never touched again, so user customizations survive every switch. - New
cc idecommand —cc ide listshows registered writers + which are active;cc ide setupwrites templates for the active version cc workspace add— prompts to runcc ide setupwhen the new workspace is linked to a version with a path- Plugin discovery — entry-point group
cc.ide_writersforpip install …plugins, or drop a.pyfile in~/.cc-cli/ide_writers/ - Removed — the inline
_update_vscode_*methods fromswitch_command.py, the_update_configPyCharm/.odoorcpath (which never did real PyCharm integration anyway), and the now-unusedodoo_config_pathsetting + its detector. PyCharm is now a plugin opportunity.
See IDE Writers for the concept and cc ide for the new command.
Sync onboarding
Configuring a new device for sync used to be a manual, error-prone .env edit with no feedback until the first push failed.
- New
cc sync setup— interactive credential setup for a client device. Prompts for the server URL + API key (pre-filled from existing env/settings), verifies them against the server (reachability + a real authenticated probe), and only then writes~/.cc-cli/.envwith600permissions. Refuses to save a key the server rejects, and preserves any unrelated lines already in the file. - Clearer auth failures — a rejected API key on
push/pullnow prints an actionable message (the key isn't registered on the server; runcc sync setup) instead of dumping a urllib traceback through the transaction-rollback handler. cc sync registerwarning — now states explicitly that registering on a client only creates a local key; a remote server only accepts keys registered on the server itself, planted on the client viacc sync setup. This was the trap behind a confusing403 Invalid API keywhen a laptop with no.envsilently fell back to a stalesync.api_keysetting.- Fixed
synced_atnever being written — every syncable model had asynced_atcolumn that nothing ever set. Two consequences, both fixed:cc sync statusreported the entire stamped dataset as "pending" forever (regardless of what the server already had), andcc sync pull --since <T>returned zero rows always (synced_at > Tis false whensynced_atisNULL), silently breaking incremental sync. Now the receiving side stampssynced_aton every ingested row, and a successful push stamps the rows it sent (newsync.mark_syncedRPC). Status tells the truth and--sinceworks.
License
Changed from MIT to AGPL-3.0-only. If you fork cc and run a modified version as a network service, your changes must be made available to users under the same license.
Mac keyboard shortcuts
- Fixed: notes editor was wired to
Alt+N, which on Mac is a dead key (Option+N produces˜forñ, notn). Now⌘E(works on both platforms). - Added:
⌘Bto collapse the sidebar.
Misc
cc workspace addnow prompts to write IDE templates for the linked version's path- Env detail page: env name → semibold, CLOC rows have breathing room (ml/mr 3), tickets
+button visible cc ideavailable as a CLI command for IDE plugin management- Dashboard fixed: duplicate envs no longer rendered, project/env name dedup when they match (
almadeed / almadeed→ justalmadeed) - Project card branch names visible across all themes (was
text-muted-foreground/20, now full token) - AppNav version badge visible across all themes (was
/25, now full token) - Fixed: auto-update checker triggered a false-positive "Update available" notification on any branch whose
HEADdiffered fromorigin/main, including feature branches sitting ahead of main. Now flags only whenorigin/maincontains commits not reachable fromHEAD(the real "behind" case). - Fixed: shell integration called
cc daemon start --quietandcc daemon status --quietbut the flag didn't exist, causing argparse to exit 2 on every new shell session (visible as[N] + PID exit 2 …daemon start…).cc daemonnow accepts-q/--quiet. As a bonus,daemon status --quietnow exits non-zero when the daemon is stopped, so the shell integration'sstatus || startconditional actually works (previously status always exited 0, so the conditional never reachedstart).
v3.4.0 — May 28, 2026
Installer v2 + UX polish
New installer that works on any system with Python 3.10+ — no pyenv, no system pollution, no reinstalling per Python version.
Install
git clone https://github.com/chronofeldyx/cc.git && cd cc
./install.sh # base install
./install.sh --sync # with sync plugincc installs into its own venv at ~/.cc-cli/venv. A shell wrapper at ~/.cc-cli/bin/_cc_internal always points to it, regardless of which Python or pyenv version is active.
Highlights
- Isolated venv — no
pip installinto system Python, no--break-system-packages - Upgrade-safe — detects old pip installs, removes them, cleans stale
.zshrcentries, regenerates shell integration with correct paths - Bash support — shell integration now works with zsh, bash, and fish
- Symlink-safe — handles symlinked dotfiles (e.g.
~/.zshrc → ~/dotfiles/zsh/zshrc) ccwith no args — ASCII logo + getting started guide instead of raw argparse help- Spinners everywhere —
cc backupcreate/restore,cc syncpush/pull,cc cloc,cc webbuild all show progress - Clean TUI exits — Ctrl+C and selection no longer leave cut boxes on screen
- Narrow terminal support — env selector falls back to single-pane layout
- launch.json merge — cc appends its
CC: OdooandCC: Odoo [test]configs instead of replacing the file; existing user configs preserved cc env edit— now includes Branch, Version, GitHub URL, Notes, Project path- Error messages guide you — every error tells you what to do next
Setup wizard improvements
- Asks for your Odoo root directory instead of scanning from
$HOME - Auto-detects git branches and saves them per version
- Path and number prompts retry on invalid input instead of silently skipping
- Prints a summary of what was configured at the end
Removed
installer.sh— replaced byinstall.shcc upgradecommand — legacy v1 → v2 migration, no longer needed
v3.3.0 — May 26, 2026
Multi-device sync (plugin)
Sync cc data across multiple machines through a central server. Install with pip install cc-cli[sync] — the base package is unaffected.
- Encrypted transport — AES-256-GCM on all sync payloads, key derived from device API key
- Auto-sync — background push/pull every 5 minutes when configured
- FK resolution — foreign keys resolve by natural key (project name, version name), not raw IDs
cc sync resolve— remaps version references and project paths on new devices, auto-clones missing repos via SSH.envfile —~/.cc-cli/.envloaded on startup for secrets (CC_SERVER,CC_API_KEY)- Secret filtering —
github_patand sync credentials never leave the device - Intel sync — repository, skill_tag, knowledge_index tables included
Setup
- Install
pip install cc-cli[sync]on server and each client - Start the sync server:
python -m cc.sync.http_server --port 9100 - Register devices:
cc sync register --name laptop(run on the server) - Configure clients in
~/.cc-cli/.envwithCC_SERVERandCC_API_KEY - Restart daemon:
cc daemon restart— auto-sync starts immediately - First sync on a new device:
cc sync resolveto fix paths (once per device)
Synced tables
version, setting, database, project, environment, switch_log, backup, repository, skill_tag, knowledge_index
Systemd service files included in deploy/ for running the sync server and web companion on a Raspberry Pi.
v3.2.0 — May 24, 2026
Rich output migration
Every cc output surface migrated to a themed rich console. The legacy Colors class and halo dependency are removed.
- Themed console singleton with semantic styles (
primary,branch,db,success,warning,error,muted) - Shared builders —
themed_table()andenv_card()for consistent output - All commands themed —
cc stat,cc env list,cc project,cc time,cc cloc,cc switch,cc intel,cc config, and more - Rounded frames on all prompt_toolkit TUIs (selector, multiselect, confirm, theme picker)
- Logger rewritten — debug mode uses
RichHandler, normal mode uses a lightweight handler - Themes pruned 7 to 4 —
default,purple,chronocoder,custom - Config decomposed — 1200-line config command split into domain modules (shell installer, theme picker, workspace registration, venv linker, config schema)
- CI workflow — GitHub Actions for pytest + install + web build
v3.1.1 — May 24, 2026
- Removed TC001 device integration
- Fixed
launch.jsontemplate —-uarg now uses${config:cc.initMode}
v3.1.0 — May 18, 2026
Intel, workspaces, and CLI improvements
- Skill telemetry —
cc intel scan,cc reindex,/skillsweb page; scans git repos for skill patterns (models, wizards, controllers, etc.) and builds a knowledge index - Workspaces — group projects under an Odoo version; R&D mode auto-checkouts env branches in shared Odoo repos with fetch + rebase
- Virtual projects — time-tracking-only projects with no filesystem
cc venv— interactive TUI for pyenv virtualenv management- Database pools —
cc db --link/--unlinkto manage a pool of databases per environment --jsonflag oncc stat,cc time,cc env list,cc prcc switch --envautocomplete — tab completion for environment namescc branchauto-checkout — checks out branch when updating the active environmentcc cloc -a— CLOC only active modules, skip picker- ORM M2M support —
Property(many2many=...)with junction tables
v3.0.1 — May 6, 2026
- Pub/sub event bus for real-time web companion updates
- Pre/post switch hooks — scripts in
~/.cc-cli/hooks/, stdout eval'd in parent shell - Daemon auto-start with exponential backoff
cc module -imode toggle- O2M create command types 4 and 6
v3.0.0 — May 3, 2026
Daemon architecture
- Daemon process — long-running on Unix socket (
~/.cc-cli/cc.sock), JSON-RPC 2.0 - Single-writer guarantee — all writes go through the daemon; CLI, web, and extensions are clients
- Service layer — business logic in
src/cc/services/, each module maps to an RPC namespace @rpc_methoddecorator — type validation, introspection registrysystem.describe— full RPC schema with semantic hints- Real-time SSE — web companion subscribes to state changes
- Postgres service —
pg.list_databases,pg.get_db_stats,pg.drop_dbwith caching and parallel connections - RPC request log —
cc logsto view~/.cc-cli/logs/rpc.log - 77 tests covering services, router, DTOs, and RPC contracts
v2.4.0 — May 2, 2026
cc backup— named PostgreSQL snapshots with create, list, restore, deletecc tunnel— SSH tunnel to Odoo.sh PostgreSQL databases- CLI theming — 5 named color palettes via
cc theme - Notes editor — per-environment WYSIWYG (TipTap) with rich text
- Ticket IDs — multiple per environment, shown as pill badges
- Quick-switcher — Cmd+K / Ctrl+K fuzzy search across all environments
- Pin/star — favourite environments pinned to top of selectors
- Collapsible sidebar — icon-only mode with persisted state
- Web theming — 10 themes with full light mode support
v2.3.0 — April 3, 2026
- shadcn/ui migration — all companion components migrated
- Suspense streaming — slow sections (GitHub API, health checks) stream independently
- History pagination — 10 days per page with URL navigation
cc initdboverhaul — recursive file picker with date sorting- Shared formatting —
lib/fmt.tsconsolidatestimeAgo,fmtDuration, etc.
v2.2.0 — March 28, 2026
CC Companion
- Next.js web dashboard — reads directly from
~/.cc-cli/cc_cli.db - Dashboard — active environments, GitHub code reviews
- Projects page — environment grid with search, copy
cc switch, GitHub/SH links - Environment detail — version/branch/database pills, CI checks, CLOC, modules, notes
- Timesheet page — grouped bar chart, pie chart, ranked totals, date range selector
- History page — switch log grouped by day with delete and undo
- Health page — data quality checks with hints to run
cc doctor - Settings page — GitHub PAT, Odoo SH session sync
cc doctor— 9 data-quality checks with interactive auto-fix- Postgres health — untracked DBs, missing DBs, idle DBs with inline drop
v2.1.0 — March 26, 2026
- Single-repo mode — one Odoo directory with branch checkouts per version
- Auto-fetch — background
git fetchon switch when interval elapsed - pyenv integration — auto-link virtualenvs per Odoo version via
cc venv - Multi-version mode — one active project per Odoo version
- Timesheet (
cc time) — automatic session tracking with flag system cc cloc— lines of code per module- Update notifier — background version check on switch
v2.0.0 — February 8, 2026
The rewrite
- Pip-installable package
- SQLite replaces
storage.json - Custom prompt_toolkit prompter (rounded frames, themed selectors)
- Data moved to
~/.cc-cli/ - Daddy shell removed
- Questionary dependency removed
- ORM with one-to-many relations
v1.0.0 — March 16, 2025
First release
cc switch— project/environment switching with fuzzy directory searchcc config— Odoo version configurationcc initdb— database initialization from dump filescc module— install/upgrade Odoo modulescc fetch— update all Odoo version reposcc cd— navigate to project directorycc db— database switchingcc copy/cc restore— database dump and restorecc cloc— lines of code countercc project— project managementcc ticket/cc github/cc sh— quick-open external tools- VSCode extension integration
- Argcomplete tab completion
Pre-release — Sep 2024 to Feb 2025
Initial development under the chronofeldyx org. Parser skeleton, command inheritance system, unified fuzzy directory search, the "daddy shell" experiment, and iterative feature building that led to v1.0.
See History for the full story.