@codedrobe/core
v0.6.0
Published
Cross-platform CodeDrobe runtime, CLI, app adapters, and .codedrobe-theme tooling.
Readme
CodeDrobe
Multi-app theming CLI and runtime for supported Chromium/Electron desktop applications. CodeDrobe injects reversible .codedrobe-theme packages over a loopback Chromium DevTools Protocol connection without modifying application bundles or app.asar.
npx --yes --package=@codedrobe/[email protected] codedrobe apps
npx --yes --package=@codedrobe/[email protected] codedrobe detect
npx --yes --package=@codedrobe/[email protected] codedrobe apply --app workbuddy --theme /absolute/theme.codedrobe-themeBun is supported as a CLI runtime:
bunx --package @codedrobe/[email protected] codedrobe appsCheck for or install the latest global CLI version:
codedrobe update --check
codedrobe update
codedrobe update --check --jsonInteractive global installations check at most once every 24 hours and print an update hint only when a newer version is available. JSON output, CI, non-interactive runs, and pinned npx/bunx invocations stay silent. Set NO_UPDATE_NOTIFIER=1 or CODEDROBE_DISABLE_UPDATE_CHECK=1 to disable automatic checks.
Applications can consume the same package as an ES module:
npm install @codedrobe/coreimport { applySkin, getAdapter, readThemePackage, resolveThemeTarget, restoreSkin } from "@codedrobe/core";
const adapter = getAdapter("codex");
const theme = await readThemePackage("/absolute/theme.codedrobe-theme");
const targetTheme = resolveThemeTarget(theme, adapter.id);
await applySkin({ adapter, targetTheme, port: 9335 });
await restoreSkin({ adapter, port: 9335 });Applications should normally use the high-level applySkin() and restoreSkin() APIs. They coordinate host settings, launch, DOM preflight, renderer injection, verification, and rollback. watchTheme() accepts an AbortSignal, so an Electron main process can own its lifecycle without relying on process signals.
The package ships TypeScript declarations for the root API and the @codedrobe/core/adapters and @codedrobe/core/theme subpath exports.
Built-in adapters currently include codex, workbuddy, qoderwork (QoderWork CN and global editions, macOS and Windows), and traework (TRAE SOLO global and CN editions, macOS and Windows). Existing applications are never restarted unless --restart-existing is explicitly provided.
Codex hot-reloads the managed appearance settings, so switching between Codex themes never requires a restart on its own. A restart is only required when the application is already running without the CDP debugging flag: Core returns CODEDROBE_RESTART_REQUIRED and leaves the app untouched unless --restart-existing is explicit. Manually restarting the app never enables theming — the debugging flag can only be set by a CodeDrobe-driven launch.
On Windows, applications installed outside the adapter's default paths (for example on a secondary drive) are also discovered through the installer's registry uninstall entries. If discovery still fails, pass the app bundle, installation directory, or executable file explicitly:
codedrobe detect --app workbuddy --app-path "/custom/WorkBuddy.app"
codedrobe apply --app workbuddy --app-path "/custom/WorkBuddy.app" --theme /absolute/theme.codedrobe-themeThe same appPath override is available to applications using the exported launchApp() API.
Capture a read-only DOM and computed-style snapshot for AI-assisted theme authoring:
codedrobe dom snapshot --app codex --output /absolute/codex-dom.json
codedrobe dom snapshot --app workbuddy --port 9440 --max-nodes 1500 --output /absolute/workbuddy-dom.jsonThe snapshot records the active CodeDrobe theme, element relationships, semantic classes, selected safe attributes, stable selector candidates with match counts, bounding boxes, adapter landmark matches, and theme-relevant computed styles. It deliberately excludes text content, form values, accessible names, query/hash data, links, and media sources. Only visible elements are included by default; use --include-hidden when a hidden route or dialog must be styled. The command never launches, restarts, or mutates the application.
Applications can call the same read-only API:
import { getAdapter, snapshotDom } from "@codedrobe/core";
const targets = await snapshotDom({
adapter: getAdapter("workbuddy"),
port: 9336,
maxNodes: 1500,
});Probe an application's current DOM without injecting or removing a theme:
codedrobe probe --app codex
codedrobe probe --app codex --theme /absolute/theme.codedrobe-theme --json
codedrobe probe --app workbuddy --timeout-ms 10000probe never launches or restarts an application. It prints the target address immediately, waits 5 seconds by default, and suggests the matching codedrobe launch command when no CDP renderer is available. Use --timeout-ms to change the wait from 250ms up to 5 minutes.
CodeDrobe probes each adapter's stable cross-route renderer landmarks before injecting CSS. A theme may add required landmarks, advisory landmarks, and route-specific contexts without adding runtime JavaScript:
{
"targets": {
"workbuddy": {
"css": "workbuddy.css",
"verification": {
"required": [
{ "name": "chat-surface", "any": [".chat-container", ".wb-cb-chat"] }
],
"recommended": [
{ "name": "conversation-list", "any": [".conversation-list"] }
],
"contexts": [
{
"name": "active-chat",
"when": { "any": [".chat-route"] },
"required": [
{ "name": "message-list", "any": [".message-list"] }
]
}
]
}
}
}
}Compatibility is judged per renderer window: windows missing required landmarks are skipped and reported, and the apply fails only when no window qualifies. Errors name the failing window and report the scope, active context, name, attempted selectors, selector parse errors, and the adapter's last-verified versions. Missing recommended landmarks are returned as warnings without blocking injection. Context checks run only while one of their when.any landmarks is visible. Pages that have not rendered their root landmark yet (splash and loading screens) are treated as booting and re-probed for the full apply budget instead of failing fast.
The built-in adapters only treat the root landmark as blocking; their sidebar, workspace, and composer probes are warning-level because applications hide those panels in popped-out windows, collapsed layouts, and secondary routes. Theme authors should follow the same principle: prefer recommended and reserve required for landmarks without which the theme genuinely malfunctions, since a required entry blocks applies whenever that panel is hidden.
A source manifest can declare up to 32 named PNG, JPEG, WebP, or GIF images. Packing embeds them under assets.images; the renderer creates scoped Blob URLs and exposes one CSS variable per image:
{
"images": {
"hero": "assets/hero.webp",
"background": "assets/background.jpg",
"logo": "assets/logo.png",
"texture": "assets/texture.png"
}
}.home-hero { background-image: var(--codedrobe-image-hero); }
.app-shell { background-image: var(--codedrobe-image-background); }
.brand::before { background-image: var(--codedrobe-image-logo); }
.panel { background-image: var(--codedrobe-image-texture); }Image IDs map directly to --codedrobe-image-<id>. The hero image also aliases to --codedrobe-art and, for converted Codex themes, --dream-art. Legacy assets.art packages still resolve as assets.images.hero, while new packing and conversion output assets.images.
codedrobe theme pack and codedrobe theme inspect also report non-blocking selector lint warnings for positional selectors, deep direct-child chains, localized text attributes, generated classes, and unusually long selectors. Keep adapter files limited to stable cross-route landmarks; put feature- and theme-specific DOM dependencies in the theme target.
Convert a legacy Codex-only package without copying JavaScript into a skill:
codedrobe theme convert ./legacy.codex-theme \
--output ./legacy.codedrobe-themeThe converter validates the old package, preserves its CSS, metadata, copy, artwork, and base-theme options, and creates a declaration-only package with a single targets.codex entry. Existing output files require --force before they can be replaced.
Converted Codex themes select a trusted renderer profile supplied by Core. It restores the legacy DOM classes, decorative layer, copy, and artwork variables expected by existing CSS while stopping any observer, timer, or style node left by the old Skill runtime. Theme packages remain declaration-only and cannot provide JavaScript.
For Codex themes with baseTheme, applySkin() changes only the three managed appearance keys under [desktop] in ~/.codex/config.toml. Restore merges those keys from config.before-codedrobe.toml and preserves unrelated edits. The default backup path remains compatible with the old Skill (~/Library/Application Support/CodeDrobe/ on macOS and %LOCALAPPDATA%\CodeDrobe\ on Windows), and restoreSkin() can recover host settings even while Codex/CDP is offline.
The Codex adapter was last verified against macOS app version 26.707.72221 (build 5307) on 2026-07-16, and the WorkBuddy adapter against 5.2.6 on macOS (2026-07-16) and Windows (2026-07-18). WorkBuddy passed the full launch/probe/apply/verify/screenshot/restore flow on both platforms; the Microsoft Store build of Codex passed the apply/restart flow on Windows. The QoderWork adapter was verified against the CN edition, macOS app version 0.9.12, on 2026-07-19 through the probe/apply/verify/screenshot/replace/restore flow on the home, conversation, and settings routes. Support for the global macOS edition and both Windows editions is based on static extraction of the official 0.9.12 installers (byte-identical renderer stylesheets and identical landmark class inventories) and has not yet passed a real-app run. Use codedrobe apps --json to read this metadata.
QoderWork forces remote-debugging-port=0 in its main process in every edition, so a caller-chosen port never binds. Core reads the live port from the per-edition DevToolsActivePort files automatically whenever --port is omitted; an explicit --port always wins.
The TRAE SOLO adapter was verified against the global edition, macOS app version 0.1.36 (Code-OSS commit ce5758dc), on 2026-07-19 through the probe/apply/verify/screenshot/replace/restore flow across the Work, Code, and Design home routes and a task conversation. Support for the CN edition (TRAE SOLO CN.app, cn.trae.solo.app) and both Windows editions is based on static extraction of the official 0.1.36 installers — same Code-OSS commit and a byte-identical solo-lite UI stylesheet — and has not yet passed a real-app run. TRAE SOLO is a VS Code derivative, but its main window is the custom solo-lite shell rather than the Monaco workbench; it accepts a standard --remote-debugging-port launch. On Windows it installs via Inno Setup, so discovery probes the product AppId uninstall keys ({GUID}_is1).
