Set up browser integration when choosing Claude
This commit is contained in:
1 parent
47de63290f
commit
45e32c8c2d
7 files changed
+126
-5
No files matched your search
+1
-1
@@ -75,7 +75,7 @@ crush)
|
||||
fi
|
||||
;;
|
||||
claude)
|
||||
command=(claude --permission-mode auto)
|
||||
command=(claude --permission-mode auto --chrome)
|
||||
[[ -n ${prompt:-} ]] && command+=(-- "$prompt")
|
||||
;;
|
||||
grok)
|
||||
|
||||
@@ -86,6 +86,11 @@ if ! agent_install; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ $agent == "claude" ]] && ! omarchy-install-chromium-claude; then
|
||||
echo "Could not install the Claude browser extension" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "$(dirname "$agent_file")"
|
||||
printf '%s\n' "$agent" >"$agent_file"
|
||||
|
||||
|
||||
Executable
+43
@@ -0,0 +1,43 @@
|
||||
#!/bin/bash
|
||||
|
||||
# omarchy:summary=Install the Claude extension for Chromium-based browsers
|
||||
# omarchy:requires-sudo=true
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if (( EUID == 0 )); then
|
||||
export PATH=/usr/bin:/bin
|
||||
fi
|
||||
|
||||
EXTENSION_ID="fcoeoabgfenejglbffodgkkbkcdhcgfn"
|
||||
EXTENSION_JSON='{ "external_update_url": "https://clients2.google.com/service/update2/crx" }'
|
||||
PACKAGED_PATH=/usr/bin/omarchy-install-chromium-claude
|
||||
|
||||
# Brave and Brave Origin share Chromium's external extension directory.
|
||||
# Seed all supported browsers, including those installed after choosing Claude.
|
||||
EXTENSION_DIRS=(
|
||||
/usr/share/chromium/extensions
|
||||
/usr/share/google-chrome/extensions
|
||||
/usr/share/microsoft-edge/extensions
|
||||
)
|
||||
|
||||
installed=true
|
||||
for dir in "${EXTENSION_DIRS[@]}"; do
|
||||
if [[ ! -f $dir/$EXTENSION_ID.json ]] || [[ $(cat "$dir/$EXTENSION_ID.json") != "$EXTENSION_JSON" ]]; then
|
||||
installed=false
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ $installed == "true" ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if (( EUID == 0 )); then
|
||||
for dir in "${EXTENSION_DIRS[@]}"; do
|
||||
printf '%s\n' "$EXTENSION_JSON" | install -D -m 0644 /dev/stdin "$dir/$EXTENSION_ID.json"
|
||||
done
|
||||
elif [[ -t 0 ]]; then
|
||||
exec sudo "$PACKAGED_PATH"
|
||||
else
|
||||
exec pkexec "$PACKAGED_PATH"
|
||||
fi
|
||||
@@ -26,6 +26,8 @@ To wrap an additional CLI the same way, run `omarchy-mise-install <package> [com
|
||||
|
||||
Pick your default agent with `omarchy default agent <name>` or under _Setup > Defaults > Agent_ in the Omarchy Menu (`Super + Space`). If the agent isn't installed yet, picking it installs it first. A fresh Omarchy will invite you to make this choice with a one-time notification.
|
||||
|
||||
Choosing Claude also sets up its browser extension for Chromium, Chrome, Brave, Brave Origin, and Edge, and enables browser integration when launched through `omarchy agent`. The extension setup applies to all users and may ask for your system password; cancelling leaves your previous default agent selected. Restart your browser, enable the extension if prompted, and sign in to Claude to finish connecting it. Run `/chrome` in Claude to check the connection. Firefox and Zen do not support this extension. If Claude was already your default before this setup was added, select it again to install the extension.
|
||||
|
||||
[Muse Code](https://dev.meta.ai) — Meta's `muse` — uses a preinstalled mise stub like the other agents. Picking it as the default installs Meta's official launcher through mise's HTTP backend. The launcher verifies and updates the native binary for your machine.
|
||||
|
||||
Once you've chosen, `Super + Shift + Ctrl + A` launches the default agent in a dedicated terminal window (or brings up the picker if you haven't chosen yet). You can also launch it straight into a task with `omarchy agent prompt "Review this project"`. Agents launched this way run unattended in their respective don't-stop-to-ask modes, so be ready for them to actually do things! And since agents refuse to remember trust for your home directory, launches from `$HOME` start in `~/Work` instead.
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh"
|
||||
|
||||
# Exercise the privileged installer without writing to the host's /usr/share.
|
||||
if ! command -v bwrap >/dev/null || ! bwrap --ro-bind / / --unshare-user --uid 0 --gid 0 true 2>/dev/null; then
|
||||
pass "user namespaces unavailable; skipping isolated Claude extension installation"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
test_tmp=$(mktemp -d)
|
||||
trap 'rm -rf "$test_tmp"' EXIT
|
||||
mkdir -p "$test_tmp/share" "$test_tmp/bin"
|
||||
installer="$ROOT/bin/omarchy-install-chromium-claude"
|
||||
extension_id=fcoeoabgfenejglbffodgkkbkcdhcgfn
|
||||
sandbox=(bwrap --ro-bind / / --bind "$test_tmp" "$test_tmp" --dev /dev --proc /proc --unshare-user)
|
||||
|
||||
"${sandbox[@]}" --uid 0 --gid 0 --bind "$test_tmp/share" /usr/share bash "$installer"
|
||||
for browser in chromium google-chrome microsoft-edge; do
|
||||
file="$test_tmp/share/$browser/extensions/$extension_id.json"
|
||||
jq -e '.external_update_url == "https://clients2.google.com/service/update2/crx"' "$file" >/dev/null ||
|
||||
fail "$browser registers the official Claude Web Store extension"
|
||||
[[ $(stat -c '%a' "$file") == "644" ]] || fail "$browser extension registration is readable"
|
||||
done
|
||||
pass "Claude extension installer registers all supported browser families"
|
||||
|
||||
cat >"$test_tmp/bin/pkexec" <<'SH'
|
||||
#!/bin/bash
|
||||
printf '%s\n' "$@" >"$AUTH_LOG"
|
||||
exit 42
|
||||
SH
|
||||
chmod +x "$test_tmp/bin/pkexec"
|
||||
export AUTH_LOG="$test_tmp/auth-log"
|
||||
export PATH="$test_tmp/bin:$PATH"
|
||||
|
||||
# A read-only /usr/share and a failing auth stub prove that a repeated run
|
||||
# neither rewrites the files nor requests authentication.
|
||||
"${sandbox[@]}" --uid 1000 --gid 1000 --ro-bind "$test_tmp/share" /usr/share bash "$installer" </dev/null
|
||||
[[ ! -e $AUTH_LOG ]] || fail "configured Claude extensions need no authentication"
|
||||
pass "configured Claude extensions need neither writes nor authentication"
|
||||
|
||||
rm "$test_tmp/share/google-chrome/extensions/$extension_id.json"
|
||||
status=0
|
||||
"${sandbox[@]}" --uid 1000 --gid 1000 --ro-bind "$test_tmp/share" /usr/share bash "$installer" </dev/null || status=$?
|
||||
[[ $status == 42 ]] || fail "Claude extension installer propagates authentication failure"
|
||||
[[ $(cat "$AUTH_LOG") == "/usr/bin/omarchy-install-chromium-claude" ]] ||
|
||||
fail "menu installation elevates only the packaged installer"
|
||||
pass "missing registration uses pkexec and propagates authentication failure"
|
||||
@@ -22,6 +22,12 @@ menu_log="$test_tmp/menu"
|
||||
muse_login_log="$test_tmp/muse-login"
|
||||
mkdir -p "$mock_bin" "$test_home"
|
||||
|
||||
cat >"$mock_bin/omarchy-install-chromium-claude" <<'SH'
|
||||
#!/bin/bash
|
||||
echo claude-extension >>"$OMARCHY_TEST_STUB_LOG"
|
||||
[[ ${OMARCHY_TEST_EXTENSION_FAIL:-false} != "true" ]]
|
||||
SH
|
||||
|
||||
cat >"$mock_bin/omarchy-notification-send" <<'SH'
|
||||
#!/bin/bash
|
||||
printf '%s\0' "$@" >>"$OMARCHY_TEST_NOTIFICATION_HISTORY"
|
||||
@@ -406,9 +412,16 @@ declare -A expected_packages=(
|
||||
for selection in "${!expected_agents[@]}"; do
|
||||
expected=${expected_agents[$selection]}
|
||||
: >"$agent_open_log"
|
||||
: >"$stub_log"
|
||||
OMARCHY_TEST_AGENT_INSTALLED=true omarchy-default-agent "$selection"
|
||||
[[ $(omarchy-default-agent) == $expected ]] || fail "default agent canonicalizes $selection"
|
||||
|
||||
if [[ $expected == "claude" ]]; then
|
||||
grep -qx claude-extension "$stub_log" || fail "Claude selection installs the browser extension"
|
||||
else
|
||||
[[ ! -s $stub_log ]] || fail "other agents do not install the Claude extension"
|
||||
fi
|
||||
|
||||
mapfile -d '' -t mise_args <"$mise_log"
|
||||
[[ ${mise_args[0]} == "use" && ${mise_args[1]} == "-g" ]] ||
|
||||
fail "default agent installs $selection globally through mise"
|
||||
@@ -427,6 +440,11 @@ pass "default agent selects and opens every supported provider and alias"
|
||||
pass "default agent stores its selection in Omarchy user config"
|
||||
|
||||
OMARCHY_TEST_AGENT_INSTALLED=true omarchy-default-agent pi
|
||||
if OMARCHY_TEST_AGENT_INSTALLED=true OMARCHY_TEST_EXTENSION_FAIL=true omarchy-default-agent claude >"$test_tmp/extension-failure" 2>&1; then
|
||||
fail "Claude selection fails when browser extension installation fails"
|
||||
fi
|
||||
[[ $(omarchy-default-agent) == "pi" ]] || fail "extension installation failure preserves the default agent"
|
||||
pass "extension installation failure preserves the default agent"
|
||||
: >"$notification_history"
|
||||
: >"$agent_open_log"
|
||||
: >"$terminal_log"
|
||||
@@ -644,7 +662,7 @@ assert_launch pi pi "Review this project"
|
||||
assert_launch omp omp --auto-approve -- "Review this project"
|
||||
assert_launch opencode opencode --auto --prompt "Review this project"
|
||||
assert_launch ori ori code --interactive --prompt "Review this project"
|
||||
assert_launch claude claude --permission-mode auto -- "Review this project"
|
||||
assert_launch claude claude --permission-mode auto --chrome -- "Review this project"
|
||||
assert_launch codex codex --approve-for-me -- "Review this project"
|
||||
assert_launch muse muse --approval-mode never -- "Review this project"
|
||||
assert_launch crush crush run "Review this project"
|
||||
@@ -672,7 +690,7 @@ assert_bypass pi pi
|
||||
assert_bypass omp omp --auto-approve
|
||||
assert_bypass opencode opencode --auto
|
||||
assert_bypass ori ori code
|
||||
assert_bypass claude claude --permission-mode auto
|
||||
assert_bypass claude claude --permission-mode auto --chrome
|
||||
assert_bypass codex codex --approve-for-me
|
||||
assert_bypass muse muse --approval-mode never
|
||||
assert_bypass crush crush --yolo
|
||||
|
||||
@@ -31,10 +31,13 @@ allowed = {
|
||||
# them so the hook does not exist where it does not apply.
|
||||
"/usr/lib/systemd/system-sleep",
|
||||
# Written through a variable, so the scan below cannot see them at the point
|
||||
# they are written. Both drop configuration into another project's tree rather
|
||||
# than Omarchy's, which is why neither is a candidate for omarchy-settings.
|
||||
# they are written. These drop configuration into another project's tree
|
||||
# rather than Omarchy's and are not candidates for omarchy-settings.
|
||||
"/usr/share/chromium/extensions",
|
||||
"/usr/lib/firefox/distribution",
|
||||
# Claude's extension is registered only when the user selects Claude.
|
||||
"/usr/share/google-chrome/extensions",
|
||||
"/usr/share/microsoft-edge/extensions",
|
||||
# Static content that belongs in omarchy-settings. It cannot move there in the
|
||||
# same release that first ships omarchy-update-system-pkgs-when-conflicted: the
|
||||
# upgrade carrying the handler is the one that would hit the conflict, and the
|
||||
|
||||
Reference in new issue
Block a user