Skip to content
testy-coolPublic

About

Enable, disable, and reload Chrome extensions from Vicinae or the terminal.

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

crxctl 🔌 — Chrome extensions, one command away

Enable, disable, and reload Chrome extensions from the terminal or Vicinae.

crxctl list
crxctl disable "Dark Reader"
crxctl enable "Dark Reader"
crxctl reload RepoAura

crxctl turns the controls hidden in chrome://extensions into a small typed interface that works for people, scripts, and coding agents. Its Vicinae command is a searchable keyboard-first view over the same control code and activity history.

What you get

  • list, enable, disable, reload, and doctor commands.
  • Stable JSON output for scripts and agents.
  • Exact extension-ID targeting and convenient, ambiguity-safe name targeting.
  • A searchable Vicinae list with real extension icons and enabled/disabled filters.
  • Frequently managed extensions ranked first across both the CLI and Vicinae.
  • A protected bridge that cannot disable or reload itself.
  • No uninstall operation, webpage access, analytics, account, or cloud service.
Dark Reader              3×  v4.9.129  Enabled ●   → disable, reload
React Developer Tools        v7.0.1    Enabled ●   → disable, reload
SingleFile                    v1.23.1   Disabled ○  → enable

The rows above come from the included Vicinae fixture. Fixture actions remain in memory and never contact Chrome or alter the real activity log.

Requirements

  • Linux with Google Chrome or Chromium.
  • Python 3 for the native-messaging host.
  • Bun to build and install the single-file CLI and Vicinae bundle.
  • Vicinae is optional and required only for the launcher interface. Version 0.24.0 is the currently tested runtime.
  • Node.js 22 is used by the development test suite.

Install

git clone https://github.com/testy-cool/crxctl.git
cd crxctl
./install.sh --browser chrome

Use --browser chromium for Chromium. The installer:

  1. registers the narrow native-messaging host for the current user;
  2. compiles and installs crxctl under $XDG_BIN_HOME or ~/.local/bin;
  3. installs the Vicinae package under $XDG_DATA_HOME/vicinae/extensions/crxctl or ~/.local/share/vicinae/extensions/crxctl;
  4. preserves replaced files under $XDG_STATE_HOME/crxctl/backups;
  5. prints the remaining manual Chrome step.

Inspect the exact paths without changing anything:

./install.sh --browser chrome --dry-run

Now open chrome://extensions, enable Developer mode, choose Load unpacked, and select this repository's chrome-bridge/ directory. Its ID must be:

kmkokakhnlegbconjfepgdbomaakfacc

The ID is derived from the public key committed in manifest.json; it is not a credential. If Chrome was running while the host was registered, restart Chrome once. Then verify the complete local path:

crxctl doctor

If ~/.local/bin is not on PATH, invoke ~/.local/bin/crxctl or add that directory to your shell configuration.

CLI

crxctl list [--json]
crxctl enable <id-or-name> [--json]
crxctl disable <id-or-name> [--json]
crxctl reload <id-or-name> [--json]
crxctl doctor [--json]

Names match exactly and case-insensitively. If two installed extensions share a name, crxctl refuses to guess and asks for the stable Chrome extension ID. Enabling an enabled extension and disabling a disabled extension are successful no-ops. Reload is available only for enabled extensions and is truthfully implemented as disable followed by enable because chrome.management exposes no direct reload method.

The CLI never prompts. stdout contains only the requested result; warnings and errors use stderr. Exit 0 means success, 1 an operational failure, and 2 invalid usage. See the frozen CLI contract for JSON schemas, error identifiers, state semantics, and compatibility guarantees.

Agent skill

The repository includes a portable crxctl agent skill that teaches coding agents to reload the extension they just built, verify the JSON result, avoid touching unrelated extensions, and handle bridge failures without repeatedly interrupting the user.

Install it for Codex from a working clone so updates to the clone remain live:

skill_root="${CODEX_HOME:-$HOME/.codex}/skills"
mkdir -p "$skill_root"
ln -s "$(pwd)/skills/crxctl" "$skill_root/crxctl"

Other agents that support SKILL.md packages can load the same directory. The skill contains no extension inventory, credentials, or machine-specific paths.

Vicinae

Search for Manage Chrome Extensions.

  • Enter: enable or disable the selected extension.
  • Vicinae's refresh shortcut: reload an enabled extension.
  • Vicinae's copy shortcut: copy the extension ID.
  • Ctrl+Shift+R: refetch the extension list.
  • Ctrl+P on Vicinae 0.24.0: open the All / Enabled / Disabled filter.

Policy-installed extensions that Chrome will not allow users to disable expose no mutation actions. Enable Use fixture data in the command preferences to judge the interface without installing the Chrome bridge.

How it works

Only a Chrome extension with the management permission can control other extensions. crxctl keeps that privileged boundary small:

terminal CLI ─┐
              ├─ shared typed control ─ user-only socket ─ native host ─ Chrome bridge
Vicinae UI ───┘
  • shared/ owns the socket contract, target resolution, mutation rules, ranking model, and local activity log.
  • cli/ is the scriptable interface and compiles to one local executable.
  • vicinae/ is the searchable human interface over the shared control code.
  • host/ is a dependency-free Python native host accepting only list, setEnabled, reload, and icon.
  • chrome-bridge/ is a Manifest V3 extension using chrome.management, nativeMessaging, and offscreen.

The internal native-host name and socket filename retain their original Vicinae-era identifiers so upgrades do not break already-installed bridges. They are compatibility details, not separate products.

Permissions, data, and safety

The Chrome bridge requests:

  • management: list and enable or disable extensions;
  • nativeMessaging: connect to the local native host;
  • offscreen: render Chrome-internal extension icons.

It requests no host permissions and cannot read webpages. The native host has no shell, arbitrary argv, file, URL, network, or generic-command operation. Requests are schema-checked before Chrome sees them, and the socket is accessible only to the current user.

Successful actions append extension ID, action kind, and timestamp to $XDG_STATE_HOME/crxctl/activity.jsonl or ~/.local/state/crxctl/activity.jsonl. Existing Vicinae-only action counts are still included in ranking after an upgrade. Icon PNGs are cached by extension ID and version under $XDG_CACHE_HOME/crxctl/icons or ~/.cache/crxctl/icons. These files remain local and nothing is transmitted to this project or its maintainers.

See SECURITY.md for the full boundary and private reporting path.

Uninstall

First remove crxctl Bridge from chrome://extensions. Then remove the installed files for Chrome:

rm "${XDG_BIN_HOME:-$HOME/.local/bin}/crxctl"
rm -rf "${XDG_DATA_HOME:-$HOME/.local/share}/vicinae/extensions/crxctl"
rm "${XDG_CONFIG_HOME:-$HOME/.config}/google-chrome/NativeMessagingHosts/io.github.testy_cool.vicinae_chrome_extensions.json"

For Chromium, replace google-chrome with chromium. Optional local ranking, cache, and upgrade backups can then be removed from ${XDG_STATE_HOME:-$HOME/.local/state}/crxctl and ${XDG_CACHE_HOME:-$HOME/.cache}/crxctl.

Development

(cd cli && bun test && bun run build)
(cd vicinae && bun install --frozen-lockfile && bun test && bun run build)
(cd chrome-bridge && node --test tests/*.mjs)
(cd host && python3 -m unittest test_host)

The isolated browser proof loads the real bridge and a dummy target into an owned Chromium profile, exercises both control paths, waits beyond the service worker idle interval, and deletes only its own resources:

E2E_IDLE_SECONDS=40 bun run e2e/run.ts

Contributions are welcome; start with CONTRIBUTING.md.

License

MIT

About

Enable, disable, and reload Chrome extensions from Vicinae or the terminal.

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages