Skip to content

Instantly share code, notes, and snippets.

@dewdad
Last active July 15, 2026 07:53
Show Gist options
  • Select an option

  • Save dewdad/d60ef27605f6e7c8dfa590366e5d12b2 to your computer and use it in GitHub Desktop.

Select an option

Save dewdad/d60ef27605f6e7c8dfa590366e5d12b2 to your computer and use it in GitHub Desktop.
oh-my-openagent efficiency optimizer — disable telemetry, reduce noise, keep diagnostics

oh-my-openagent Efficiency Optimizer

Two phases, run in order:

  1. refresh-omo.* (precursor) — force the plugin cache to the latest published version, then restart OpenCode.
  2. optimize-omo.* (debloat) — apply the efficiency configuration.

The debloat applies best-practice configuration to an existing oh-my-openagent installation:

  • Disables PostHog telemetry (no network calls home)
  • Disables noisy hooks (update checker, startup toast, agent-usage reminders)
  • Preserves all logging and error recovery for troubleshooting
  • Updates runtime cache to latest version
  • Runs doctor health check

Step 0 — Refresh plugin cache (precursor)

refresh-omo.sh / refresh-omo.ps1 force the OhMyOpenCode plugin cache to the true npm latest.

Why it's needed: OpenCode installs each configured plugin into a per-spec cache directory (~/.cache/opencode/packages/<plugin>@<spec>/) and pins the resolved version there. Because of that pin, oh-my-openagent@latest in your config never re-resolves on its own — it can stay stuck several versions behind even though it says @latest. Updating the cache root (as the debloat's own step 4 does) does not fix this: OpenCode loads the plugin from the per-spec dir. This script clears that per-spec cache and reinstalls the newest version.

Bash (Mac / Linux)

curl -fsSL https://gist.githubusercontent.com/dewdad/d60ef27605f6e7c8dfa590366e5d12b2/raw/refresh-omo.sh | bash

or with wget:

wget -qO- https://gist.githubusercontent.com/dewdad/d60ef27605f6e7c8dfa590366e5d12b2/raw/refresh-omo.sh | bash

PowerShell (Windows)

irm https://gist.githubusercontent.com/dewdad/d60ef27605f6e7c8dfa590366e5d12b2/raw/refresh-omo.ps1 | iex

Then restart OpenCode (the running process keeps the old plugin in memory) and run the debloat below.

What the precursor does

Step Action
1 Scans ~/.cache/opencode/packages/oh-my-*@* for the cached plugin
2 Compares the installed version against npm latest — skips if already current
3 Clears the stale per-spec cache (node_modules + lockfiles)
4 Reinstalls the exact latest with --ignore-scripts (the plugin's postinstall would otherwise delete the freshly-installed dir to force a re-resolve)
5 Verifies the main package and its platform binary landed on the same version (prevents a stale startup banner)

Options: --force / -Force (reinstall even if already current), --dry-run / -DryRun (report only, no writes). Safe and idempotent; only touches the oh-my-*@* plugin cache.

Debloat one-liner

Bash (Mac / Linux)

curl -fsSL https://gist.githubusercontent.com/dewdad/d60ef27605f6e7c8dfa590366e5d12b2/raw/optimize-omo.sh | bash

or with wget:

wget -qO- https://gist.githubusercontent.com/dewdad/d60ef27605f6e7c8dfa590366e5d12b2/raw/optimize-omo.sh | bash

PowerShell (Windows)

irm https://gist.githubusercontent.com/dewdad/d60ef27605f6e7c8dfa590366e5d12b2/raw/optimize-omo.ps1 | iex

What it does

Step Action
1 Sets OMO_SEND_ANONYMOUS_TELEMETRY=0 and OMO_DISABLE_POSTHOG=1 persistently
2 Adds disabled_hooks to oh-my-opencode.json (idempotent, won't duplicate)
3 Cleans stale .tmp files
4 Updates the runtime cache root to latest via bun or npm (for a reliable plugin update, run the Step 0 precursor first)
5 Runs oh-my-openagent doctor health check

Hooks disabled

Hook Why
auto-update-checker Periodic npm registry calls during sessions — adds latency
startup-toast Startup banner noise
agent-usage-reminder "Use explore/librarian instead" reminders in tool output

What's preserved

  • Internal log() diagnostics (viewable via opencode --debug)
  • Session recovery
  • All error recovery hooks (edit, JSON, delegate-task-retry, etc.)
  • Background notification
  • All agent orchestration functionality

Options

Precursor (refresh-omo.*)

# PowerShell
& ./refresh-omo.ps1 -DryRun   # report only, no writes
& ./refresh-omo.ps1 -Force    # reinstall even if already on latest
# Bash
./refresh-omo.sh --dry-run    # report only, no writes
./refresh-omo.sh --force      # reinstall even if already on latest

Debloat (optimize-omo.*)

# Dry run (no changes written)
& ./optimize-omo.ps1 -DryRun

# Skip updating the runtime cache
& ./optimize-omo.ps1 -SkipUpdate

The bash debloat script auto-detects:

  • Shell type (zsh, bash, fish) for correct profile file
  • Platform (macOS vs Linux) for sed compatibility
  • JSON tool (jq preferred, falls back to python3)

Prerequisites

  • opencode must be installed and initialized (run opencode once first)
  • npm (required by the precursor) or bun for cache updates
  • Precursor (refresh-omo.*): npm in PATH; node/python3 used for version reads when present (falls back to grep)
  • Bash debloat (optimize-omo.sh): jq or python3 for JSON manipulation
  • PowerShell scripts: PowerShell 5.1+ (built into Windows)

Idempotent

Safe to run multiple times. The precursor skips when already on latest (unless --force/-Force) and only touches the oh-my-*@* plugin cache; the debloat won't duplicate hooks and checks env vars before writing.

<#
.SYNOPSIS
Optimize oh-my-openagent for efficiency — disable telemetry, reduce noise, keep diagnostics.
.DESCRIPTION
Applies best-practice configuration to an existing oh-my-openagent/oh-my-opencode installation:
- Disables PostHog telemetry (environment variables)
- Disables non-essential hooks (auto-update-checker, startup-toast, agent-usage-reminder)
- Updates runtime cache to latest version
- Cleans stale tmp files
- Runs doctor health check
.NOTES
One-liner: irm https://gist.githubusercontent.com/RAW_URL | iex
#>
param(
[switch]$SkipUpdate,
[switch]$DryRun
)
$ErrorActionPreference = "Stop"
Set-StrictMode -Version Latest
# --- Helpers ---
function Write-Step($msg) { Write-Host " [*] $msg" -ForegroundColor Cyan }
function Write-Ok($msg) { Write-Host " [+] $msg" -ForegroundColor Green }
function Write-Warn($msg) { Write-Host " [!] $msg" -ForegroundColor Yellow }
function Write-Err($msg) { Write-Host " [-] $msg" -ForegroundColor Red }
Write-Host ""
Write-Host " oh-my-openagent efficiency optimizer" -ForegroundColor Magenta
Write-Host " =====================================" -ForegroundColor DarkGray
Write-Host ""
# --- Locate config ---
$configDir = Join-Path $env:USERPROFILE ".config" "opencode"
$configFile = Join-Path $configDir "oh-my-opencode.json"
$cacheDir = Join-Path $env:USERPROFILE ".cache" "opencode"
if (-not (Test-Path $configDir)) {
Write-Err "OpenCode config directory not found: $configDir"
Write-Err "Is opencode installed? Run 'opencode' first to initialize."
exit 1
}
# --- 1. Environment variables (persistent user-level) ---
Write-Step "Setting telemetry opt-out environment variables..."
$envVars = @{
"OMO_SEND_ANONYMOUS_TELEMETRY" = "0"
"OMO_DISABLE_POSTHOG" = "1"
}
foreach ($kv in $envVars.GetEnumerator()) {
$current = [Environment]::GetEnvironmentVariable($kv.Key, "User")
if ($current -eq $kv.Value) {
Write-Ok "$($kv.Key) already set to $($kv.Value)"
} else {
if (-not $DryRun) {
[Environment]::SetEnvironmentVariable($kv.Key, $kv.Value, "User")
# Also set for current process
[Environment]::SetEnvironmentVariable($kv.Key, $kv.Value, "Process")
}
Write-Ok "$($kv.Key) = $($kv.Value) (persistent)"
}
}
# --- 2. Config file: add disabled_hooks ---
Write-Step "Configuring oh-my-opencode.json..."
$hooksToDisable = @("auto-update-checker", "startup-toast", "agent-usage-reminder")
if (Test-Path $configFile) {
$json = Get-Content $configFile -Raw | ConvertFrom-Json
# Ensure disabled_hooks exists
if (-not ($json.PSObject.Properties.Name -contains "disabled_hooks")) {
$json | Add-Member -NotePropertyName "disabled_hooks" -NotePropertyValue @()
}
# Merge hooks (don't duplicate)
$existing = @($json.disabled_hooks)
$added = @()
foreach ($hook in $hooksToDisable) {
if ($hook -notin $existing) {
$existing += $hook
$added += $hook
}
}
$json.disabled_hooks = $existing
if ($added.Count -gt 0) {
if (-not $DryRun) {
$json | ConvertTo-Json -Depth 10 | Set-Content $configFile -Encoding UTF8
}
Write-Ok "Added disabled_hooks: $($added -join ', ')"
} else {
Write-Ok "All hooks already disabled"
}
} else {
# Create minimal config
$newConfig = @{
'$schema' = "https://raw.githubusercontent.com/code-yeongyu/oh-my-opencode/master/assets/oh-my-opencode.schema.json"
disabled_hooks = $hooksToDisable
agents = @{}
categories = @{}
}
if (-not $DryRun) {
$newConfig | ConvertTo-Json -Depth 10 | Set-Content $configFile -Encoding UTF8
}
Write-Ok "Created $configFile with disabled hooks"
}
# --- 3. Clean stale tmp files ---
Write-Step "Cleaning stale files..."
$tmpFiles = @(
(Join-Path $configDir "oh-my-openagent.json.tmp"),
(Join-Path $configDir "oh-my-opencode.json.tmp")
)
foreach ($f in $tmpFiles) {
if (Test-Path $f) {
if (-not $DryRun) { Remove-Item $f -Force }
Write-Ok "Removed $((Split-Path $f -Leaf))"
}
}
# --- 4. Update runtime cache ---
if (-not $SkipUpdate) {
Write-Step "Updating oh-my-opencode in runtime cache..."
if (Test-Path $cacheDir) {
if (-not $DryRun) {
$bunPath = Get-Command bun -ErrorAction SilentlyContinue
$npmPath = Get-Command npm -ErrorAction SilentlyContinue
if ($bunPath) {
Push-Location $cacheDir
& bun add oh-my-opencode@latest 2>&1 | Out-Null
Pop-Location
Write-Ok "Updated via bun"
} elseif ($npmPath) {
Push-Location $cacheDir
& npm install oh-my-opencode@latest 2>&1 | Out-Null
Pop-Location
Write-Ok "Updated via npm"
} else {
Write-Warn "Neither bun nor npm found — skipping cache update"
}
}
} else {
Write-Warn "Cache directory not found: $cacheDir (will update on next opencode launch)"
}
} else {
Write-Step "Skipping update (--SkipUpdate)"
}
# --- 5. Doctor check ---
Write-Step "Running health check..."
if (-not $DryRun) {
$npxPath = Get-Command npx -ErrorAction SilentlyContinue
if ($npxPath) {
Push-Location $configDir
& npx oh-my-openagent@latest doctor 2>&1 | ForEach-Object { Write-Host " $_" }
Pop-Location
} else {
Write-Warn "npx not found — skipping doctor"
}
}
# --- Summary ---
Write-Host ""
Write-Host " Done! Changes take effect on next opencode launch." -ForegroundColor Green
if ($DryRun) {
Write-Warn "DRY RUN — no changes were written"
}
Write-Host ""
#!/usr/bin/env bash
# optimize-omo.sh — Optimize oh-my-openagent for efficiency
# Disables telemetry, reduces noise, keeps diagnostics.
#
# One-liner install:
# curl -fsSL https://gist.githubusercontent.com/RAW_URL | bash
# wget -qO- https://gist.githubusercontent.com/RAW_URL | bash
set -euo pipefail
# --- Helpers ---
step() { printf ' \033[36m[*]\033[0m %s\n' "$1"; }
ok() { printf ' \033[32m[+]\033[0m %s\n' "$1"; }
warn() { printf ' \033[33m[!]\033[0m %s\n' "$1"; }
err() { printf ' \033[31m[-]\033[0m %s\n' "$1"; }
echo ""
printf ' \033[35moh-my-openagent efficiency optimizer\033[0m\n'
printf ' \033[90m=====================================\033[0m\n'
echo ""
# --- Detect OS ---
OS="$(uname -s)"
case "$OS" in
Darwin) PLATFORM="macos" ;;
Linux) PLATFORM="linux" ;;
*) err "Unsupported OS: $OS"; exit 1 ;;
esac
# --- Locate config ---
CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/opencode"
CONFIG_FILE="$CONFIG_DIR/oh-my-opencode.json"
CACHE_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/opencode"
if [ ! -d "$CONFIG_DIR" ]; then
err "OpenCode config directory not found: $CONFIG_DIR"
err "Is opencode installed? Run 'opencode' first to initialize."
exit 1
fi
# --- 1. Environment variables ---
step "Setting telemetry opt-out environment variables..."
# Determine shell profile
SHELL_NAME="$(basename "${SHELL:-/bin/bash}")"
case "$SHELL_NAME" in
zsh) PROFILE="$HOME/.zshrc" ;;
bash)
if [ "$PLATFORM" = "macos" ]; then
PROFILE="$HOME/.bash_profile"
else
PROFILE="$HOME/.bashrc"
fi
;;
fish) PROFILE="$HOME/.config/fish/config.fish" ;;
*) PROFILE="$HOME/.profile" ;;
esac
set_env_var() {
local key="$1" val="$2"
# Set for current session
export "$key=$val"
# Check if already in profile
if [ -f "$PROFILE" ] && grep -q "^export ${key}=" "$PROFILE" 2>/dev/null; then
# Update existing
if [ "$PLATFORM" = "macos" ]; then
sed -i '' "s|^export ${key}=.*|export ${key}=\"${val}\"|" "$PROFILE"
else
sed -i "s|^export ${key}=.*|export ${key}=\"${val}\"|" "$PROFILE"
fi
ok "$key already in $PROFILE (updated)"
elif [ -f "$PROFILE" ] && [ "$SHELL_NAME" = "fish" ] && grep -q "^set -gx ${key}" "$PROFILE" 2>/dev/null; then
if [ "$PLATFORM" = "macos" ]; then
sed -i '' "s|^set -gx ${key}.*|set -gx ${key} \"${val}\"|" "$PROFILE"
else
sed -i "s|^set -gx ${key}.*|set -gx ${key} \"${val}\"|" "$PROFILE"
fi
ok "$key already in $PROFILE (updated)"
else
# Append
if [ "$SHELL_NAME" = "fish" ]; then
echo "set -gx ${key} \"${val}\"" >> "$PROFILE"
else
echo "export ${key}=\"${val}\"" >> "$PROFILE"
fi
ok "$key = $val (added to $PROFILE)"
fi
}
set_env_var "OMO_SEND_ANONYMOUS_TELEMETRY" "0"
set_env_var "OMO_DISABLE_POSTHOG" "1"
# --- 2. Config file: add disabled_hooks ---
step "Configuring oh-my-opencode.json..."
# We need jq or python3 for JSON manipulation
if command -v jq &>/dev/null; then
JSON_TOOL="jq"
elif command -v python3 &>/dev/null; then
JSON_TOOL="python3"
else
err "Neither jq nor python3 found. Install one to continue."
exit 1
fi
HOOKS_TO_DISABLE='["auto-update-checker","startup-toast","agent-usage-reminder"]'
if [ -f "$CONFIG_FILE" ]; then
if [ "$JSON_TOOL" = "jq" ]; then
# Merge disabled_hooks without duplicates
UPDATED=$(jq --argjson hooks "$HOOKS_TO_DISABLE" '
.disabled_hooks = ((.disabled_hooks // []) + $hooks | unique)
' "$CONFIG_FILE")
echo "$UPDATED" > "$CONFIG_FILE"
else
python3 -c "
import json, sys
hooks_to_add = $HOOKS_TO_DISABLE
with open('$CONFIG_FILE', 'r') as f:
config = json.load(f)
existing = config.get('disabled_hooks', [])
merged = list(dict.fromkeys(existing + hooks_to_add)) # unique, order preserved
config['disabled_hooks'] = merged
with open('$CONFIG_FILE', 'w') as f:
json.dump(config, f, indent=2)
f.write('\n')
"
fi
ok "disabled_hooks configured in $CONFIG_FILE"
else
# Create minimal config
if [ "$JSON_TOOL" = "jq" ]; then
jq -n --argjson hooks "$HOOKS_TO_DISABLE" '{
"$schema": "https://raw.githubusercontent.com/code-yeongyu/oh-my-opencode/master/assets/oh-my-opencode.schema.json",
"disabled_hooks": $hooks,
"agents": {},
"categories": {}
}' > "$CONFIG_FILE"
else
python3 -c "
import json
config = {
'\$schema': 'https://raw.githubusercontent.com/code-yeongyu/oh-my-opencode/master/assets/oh-my-opencode.schema.json',
'disabled_hooks': $HOOKS_TO_DISABLE,
'agents': {},
'categories': {}
}
with open('$CONFIG_FILE', 'w') as f:
json.dump(config, f, indent=2)
f.write('\n')
"
fi
ok "Created $CONFIG_FILE with disabled hooks"
fi
# --- 3. Clean stale tmp files ---
step "Cleaning stale files..."
for tmp in "$CONFIG_DIR/oh-my-openagent.json.tmp" "$CONFIG_DIR/oh-my-opencode.json.tmp"; do
if [ -f "$tmp" ]; then
rm -f "$tmp"
ok "Removed $(basename "$tmp")"
fi
done
# --- 4. Update runtime cache ---
step "Updating oh-my-opencode in runtime cache..."
if [ -d "$CACHE_DIR" ]; then
if command -v bun &>/dev/null; then
(cd "$CACHE_DIR" && bun add oh-my-opencode@latest 2>/dev/null) && ok "Updated via bun" || warn "bun update failed (non-critical)"
elif command -v npm &>/dev/null; then
(cd "$CACHE_DIR" && npm install oh-my-opencode@latest 2>/dev/null) && ok "Updated via npm" || warn "npm update failed (non-critical)"
else
warn "Neither bun nor npm found — will update on next opencode launch"
fi
else
warn "Cache directory not found: $CACHE_DIR (will update on next opencode launch)"
fi
# --- 5. Doctor check ---
step "Running health check..."
if command -v npx &>/dev/null; then
(cd "$CONFIG_DIR" && npx oh-my-openagent@latest doctor 2>&1) | while IFS= read -r line; do
echo " $line"
done
else
warn "npx not found — skipping doctor"
fi
# --- Summary ---
echo ""
printf ' \033[32mDone! Changes take effect on next opencode launch.\033[0m\n'
printf ' \033[90mReload your shell or run: source %s\033[0m\n' "$PROFILE"
echo ""
<#
.SYNOPSIS
Precursor to the oh-my-openagent debloat: force-refresh the plugin cache to latest.
.DESCRIPTION
OpenCode installs each configured plugin into a PER-SPEC cache directory
(~/.cache/opencode/packages/<plugin>@<spec>/) and PINS the resolved version there.
Because of that pin, `oh-my-openagent@latest` in your config never re-resolves on
its own -- it can stay stuck several versions behind even though it says "@latest".
(Updating the cache ROOT, as the older debloat step did, does NOT fix this: OpenCode
loads the plugin from the per-spec dir, not the root.)
This script clears the per-spec cache and reinstalls the true npm `latest`, so a
subsequent RESTART of OpenCode actually loads the newest plugin. Run it BEFORE the
debloat optimizer (optimize-omo.ps1).
Safe and idempotent:
- Only touches ~/.cache/opencode/packages/oh-my-*@* (never your config or other plugins)
- Skips work when already on latest (unless -Force)
- Installs with --ignore-scripts (the plugin's own postinstall DELETES this dir)
- Verifies the main package and its platform binary end up on the same version
.PARAMETER Force
Reinstall even if the cached version already equals npm latest.
.PARAMETER DryRun
Report what would change without writing anything.
.NOTES
One-liner: irm https://gist.githubusercontent.com/dewdad/d60ef27605f6e7c8dfa590366e5d12b2/raw/refresh-omo.ps1 | iex
#>
param(
[switch]$Force,
[switch]$DryRun
)
$ErrorActionPreference = "Stop"
Set-StrictMode -Version Latest
# --- Helpers ---
function Write-Step($msg) { Write-Host " [*] $msg" -ForegroundColor Cyan }
function Write-Ok($msg) { Write-Host " [+] $msg" -ForegroundColor Green }
function Write-Warn($msg) { Write-Host " [!] $msg" -ForegroundColor Yellow }
function Write-Err($msg) { Write-Host " [-] $msg" -ForegroundColor Red }
function Get-JsonVersion($path) {
if (-not (Test-Path $path)) { return $null }
try { return (Get-Content $path -Raw | ConvertFrom-Json).version } catch { return $null }
}
Write-Host ""
Write-Host " oh-my-openagent cache refresh (debloat precursor)" -ForegroundColor Magenta
Write-Host " =================================================" -ForegroundColor DarkGray
Write-Host ""
# --- Locate the plugin cache ---
$cacheDir = Join-Path $env:USERPROFILE ".cache\opencode"
$packagesDir = Join-Path $cacheDir "packages"
if (-not (Test-Path $packagesDir)) {
Write-Warn "No plugin cache found: $packagesDir"
Write-Warn "OpenCode will install the latest plugin on next launch -- nothing to do."
return
}
$npm = Get-Command npm -ErrorAction SilentlyContinue
if (-not $npm) { Write-Err "npm not found in PATH -- required to query/refresh."; exit 1 }
# --- Find per-spec OhMyOpenCode plugin dirs (e.g. oh-my-openagent@latest) ---
$specDirs = Get-ChildItem $packagesDir -Directory -ErrorAction SilentlyContinue |
Where-Object { $_.Name -match '^(oh-my-openagent|oh-my-opencode)@' }
if (-not $specDirs) {
Write-Warn "No oh-my-openagent/oh-my-opencode plugin cached under $packagesDir"
Write-Warn "It will resolve to latest on next OpenCode launch."
return
}
$refreshed = 0
foreach ($spec in $specDirs) {
$pkg = ($spec.Name -split '@')[0] # part before '@'
$instFile = Join-Path $spec.FullName "node_modules\$pkg\package.json"
Write-Step "Checking $($spec.Name)"
$current = Get-JsonVersion $instFile
$latest = (& npm view $pkg version 2>$null | Out-String).Trim()
if (-not $latest) { Write-Warn "Could not query npm latest for $pkg -- skipping"; continue }
Write-Host " installed: $(if ($current) { $current } else { 'none' }) npm latest: $latest"
if (($current -eq $latest) -and (-not $Force)) {
Write-Ok "$pkg already at latest ($latest) -- skipping (use -Force to reinstall)"
continue
}
if ($DryRun) {
Write-Warn "DRY RUN -- would refresh $pkg $(if ($current) { $current } else { 'none' }) -> $latest"
continue
}
# 1. Clear the stale install (this is the cache being "cleared")
Write-Step "Clearing stale cache for $pkg..."
Remove-Item (Join-Path $spec.FullName "node_modules") -Recurse -Force -ErrorAction SilentlyContinue
Remove-Item (Join-Path $spec.FullName "package-lock.json") -Force -ErrorAction SilentlyContinue
Remove-Item (Join-Path $spec.FullName "bun.lock") -Force -ErrorAction SilentlyContinue
Remove-Item (Join-Path $spec.FullName "bun.lockb") -Force -ErrorAction SilentlyContinue
# 2. Pin the manifest to the exact latest version (matches OpenCode's own bookkeeping)
$manifest = [ordered]@{ dependencies = [ordered]@{ $pkg = $latest } } | ConvertTo-Json -Depth 5
Set-Content -Path (Join-Path $spec.FullName "package.json") -Value $manifest -Encoding UTF8
# 3. Install. --ignore-scripts is REQUIRED: the plugin postinstall wipes this very dir
# (it is designed to force a re-resolve after a global install).
Write-Step "Installing $pkg@$latest ..."
Push-Location $spec.FullName
try {
& npm install --ignore-scripts --no-audit --no-fund --silent 2>&1 | Out-Null
} finally { Pop-Location }
# 4. Verify main package
$newVer = Get-JsonVersion $instFile
if ($newVer -ne $latest) {
Write-Err "Verification FAILED for ${pkg}: expected $latest, got $(if ($newVer) { $newVer } else { 'none' })"
continue
}
# 5. Verify platform binary version matches (prevents stale startup banner)
$platDirs = Get-ChildItem (Join-Path $spec.FullName "node_modules") -Directory -ErrorAction SilentlyContinue |
Where-Object { $_.Name -like "$pkg-*" }
if ($platDirs) {
foreach ($pd in $platDirs) {
$pv = Get-JsonVersion (Join-Path $pd.FullName "package.json")
if ($pv -eq $latest) { Write-Ok "platform binary $($pd.Name) @ $pv matches" }
else { Write-Warn "platform binary $($pd.Name) @ $pv (main $latest) -- banner may show stale version" }
}
} else {
Write-Warn "no platform binary package found (unusual -- CLI may still work)"
}
Write-Ok "$pkg refreshed: $(if ($current) { $current } else { 'none' }) -> $newVer"
$refreshed++
}
# --- Summary ---
Write-Host ""
if ($DryRun) {
Write-Warn "DRY RUN -- no changes were written"
} elseif ($refreshed -gt 0) {
Write-Host " Cache refreshed. RESTART OpenCode to load the new plugin version." -ForegroundColor Green
Write-Host " Then run the debloat optimizer: optimize-omo.ps1" -ForegroundColor DarkGray
} else {
Write-Host " Already up to date -- nothing refreshed." -ForegroundColor Green
}
Write-Host ""
#!/usr/bin/env bash
# refresh-omo.sh -- Precursor to the oh-my-openagent debloat.
# Force-refresh the OhMyOpenCode plugin cache to the latest published version.
#
# WHY: OpenCode installs each configured plugin into a PER-SPEC cache directory
# (~/.cache/opencode/packages/<plugin>@<spec>/) and PINS the resolved version there.
# Because of that pin, `oh-my-openagent@latest` in your config never re-resolves on
# its own -- it can stay stuck several versions behind even though it says "@latest".
# (Updating the cache ROOT, as the older debloat step did, does NOT fix this: OpenCode
# loads the plugin from the per-spec dir, not the root.)
#
# This clears the per-spec cache and reinstalls the true npm `latest`, so a subsequent
# RESTART of OpenCode actually loads the newest plugin. Run it BEFORE optimize-omo.sh.
#
# SAFE & IDEMPOTENT:
# - only touches ~/.cache/opencode/packages/oh-my-*@* (never your config or other plugins)
# - skips when already latest (unless --force)
# - installs with --ignore-scripts (the plugin postinstall DELETES this dir)
# - verifies the main package and its platform binary end up on the same version
#
# Usage:
# ./refresh-omo.sh [--force] [--dry-run]
# One-liner:
# curl -fsSL https://gist.githubusercontent.com/dewdad/d60ef27605f6e7c8dfa590366e5d12b2/raw/refresh-omo.sh | bash
# wget -qO- https://gist.githubusercontent.com/dewdad/d60ef27605f6e7c8dfa590366e5d12b2/raw/refresh-omo.sh | bash
set -euo pipefail
FORCE=0
DRYRUN=0
for arg in "$@"; do
case "$arg" in
--force) FORCE=1 ;;
--dry-run|--dryrun) DRYRUN=1 ;;
-h|--help)
grep '^#' "$0" | sed 's/^# \{0,1\}//'
exit 0 ;;
esac
done
# --- Helpers ---
step() { printf ' \033[36m[*]\033[0m %s\n' "$1"; }
ok() { printf ' \033[32m[+]\033[0m %s\n' "$1"; }
warn() { printf ' \033[33m[!]\033[0m %s\n' "$1"; }
err() { printf ' \033[31m[-]\033[0m %s\n' "$1"; }
# Read a "version" field from a package.json (node preferred, then python3, then grep)
read_ver() {
local f="$1"
[ -f "$f" ] || { printf ''; return; }
if command -v node >/dev/null 2>&1; then
node -e "const fs=require('fs');try{process.stdout.write((JSON.parse(fs.readFileSync(process.argv[1],'utf8')).version)||'')}catch(e){}" "$f"
elif command -v python3 >/dev/null 2>&1; then
python3 -c "import json,sys;print(json.load(open(sys.argv[1])).get('version',''))" "$f" 2>/dev/null
else
grep -o '"version"[[:space:]]*:[[:space:]]*"[^"]*"' "$f" | head -1 | sed 's/.*"\([^"]*\)"$/\1/'
fi
}
echo ""
printf ' \033[35moh-my-openagent cache refresh (debloat precursor)\033[0m\n'
printf ' \033[90m=================================================\033[0m\n'
echo ""
# --- Locate the plugin cache ---
CACHE_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/opencode"
PACKAGES_DIR="$CACHE_DIR/packages"
if [ ! -d "$PACKAGES_DIR" ]; then
warn "No plugin cache found: $PACKAGES_DIR"
warn "OpenCode will install the latest plugin on next launch -- nothing to do."
exit 0
fi
command -v npm >/dev/null 2>&1 || { err "npm not found in PATH -- required to query/refresh."; exit 1; }
# --- Find per-spec OhMyOpenCode plugin dirs (e.g. oh-my-openagent@latest) ---
shopt -s nullglob
found=0
refreshed=0
for spec in "$PACKAGES_DIR"/oh-my-openagent@* "$PACKAGES_DIR"/oh-my-opencode@*; do
[ -d "$spec" ] || continue
found=1
base="$(basename "$spec")"
pkg="${base%@*}" # part before '@'
inst_file="$spec/node_modules/$pkg/package.json"
step "Checking $base"
current="$(read_ver "$inst_file")"
latest="$(npm view "$pkg" version 2>/dev/null | tr -d '[:space:]')"
if [ -z "$latest" ]; then warn "Could not query npm latest for $pkg -- skipping"; continue; fi
printf ' installed: %s npm latest: %s\n' "${current:-none}" "$latest"
if [ "$current" = "$latest" ] && [ "$FORCE" -eq 0 ]; then
ok "$pkg already at latest ($latest) -- skipping (use --force to reinstall)"
continue
fi
if [ "$DRYRUN" -eq 1 ]; then
warn "DRY RUN -- would refresh $pkg ${current:-none} -> $latest"
continue
fi
# 1. Clear the stale install (this is the cache being "cleared")
step "Clearing stale cache for $pkg..."
rm -rf "$spec/node_modules" "$spec/package-lock.json" "$spec/bun.lock" "$spec/bun.lockb" 2>/dev/null || true
# 2. Pin the manifest to the exact latest version (matches OpenCode's own bookkeeping)
printf '{\n "dependencies": {\n "%s": "%s"\n }\n}\n' "$pkg" "$latest" > "$spec/package.json"
# 3. Install. --ignore-scripts is REQUIRED: the plugin postinstall wipes this very dir
# (it is designed to force a re-resolve after a global install).
step "Installing $pkg@$latest ..."
( cd "$spec" && npm install --ignore-scripts --no-audit --no-fund --silent >/dev/null 2>&1 )
# 4. Verify main package
newver="$(read_ver "$inst_file")"
if [ "$newver" != "$latest" ]; then
err "Verification FAILED for $pkg: expected $latest, got ${newver:-none}"
continue
fi
# 5. Verify platform binary version matches (prevents stale startup banner)
checked=0
for plat in "$spec"/node_modules/"$pkg"-*; do
[ -d "$plat" ] || continue
pv="$(read_ver "$plat/package.json")"
[ -n "$pv" ] || continue
checked=1
if [ "$pv" = "$latest" ]; then
ok "platform binary $(basename "$plat") @ $pv matches"
else
warn "platform binary $(basename "$plat") @ $pv (main $latest) -- banner may show stale version"
fi
done
[ "$checked" -eq 0 ] && warn "no platform binary package found (unusual -- CLI may still work)"
ok "$pkg refreshed: ${current:-none} -> $newver"
refreshed=$((refreshed + 1))
done
if [ "$found" -eq 0 ]; then
warn "No oh-my-openagent/oh-my-opencode plugin cached under $PACKAGES_DIR"
warn "It will resolve to latest on next OpenCode launch."
exit 0
fi
# --- Summary ---
echo ""
if [ "$DRYRUN" -eq 1 ]; then
warn "DRY RUN -- no changes were written"
elif [ "$refreshed" -gt 0 ]; then
printf ' \033[32mCache refreshed. RESTART OpenCode to load the new plugin version.\033[0m\n'
printf ' \033[90mThen run the debloat optimizer: optimize-omo.sh\033[0m\n'
else
printf ' \033[32mAlready up to date -- nothing refreshed.\033[0m\n'
fi
echo ""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment