agents/openai.yaml
interface:
display_name: "cmux Diagnostics"
short_description: "Check cmux hooks, restore, CLI, and settings."
default_prompt: "Use $cmux-diagnostics to collect a read-only cmux health report and explain any hook or session restore problems."
scripts/cmux-diagnostics
#!/usr/bin/env bash
set -euo pipefail
include_context=0
while [[ $# -gt 0 ]]; do
case "$1" in
--include-context)
include_context=1
shift
;;
-h|--help)
cat <<'EOF'
Usage: cmux-diagnostics [--include-context]
Print a read-only, support-safe cmux diagnostics report. By default this avoids
workspace names, cwd paths, hook contents, session JSON, and secrets.
EOF
exit 0
;;
*)
printf 'cmux-diagnostics: unknown option: %s\n' "$1" >&2
exit 1
;;
esac
done
section() {
printf '\n== %s ==\n' "$1"
}
safe_path() {
local path="$1"
if [[ "$path" == "$HOME" ]]; then
printf '~'
elif [[ "$path" == "$HOME"/* ]]; then
printf '~/%s' "${path#"$HOME"/}"
else
printf '%s' "$path"
fi
}
run_status() {
local label="$1"
shift
printf '%s: ' "$label"
if "$@" >/dev/null 2>&1; then
printf 'ok\n'
else
printf 'failed\n'
fi
}
file_summary() {
local path="$1"
if [[ -f "$path" ]]; then
local bytes modified
bytes="$(wc -c <"$path" 2>/dev/null | tr -d ' ' || true)"
modified="$(stat -f '%Sm' -t '%Y-%m-%d %H:%M:%S %z' "$path" 2>/dev/null || stat -c '%y' "$path" 2>/dev/null || printf 'unknown')"
printf 'present bytes=%s modified=%s\n' "${bytes:-unknown}" "$modified"
elif [[ -e "$path" ]]; then
printf 'non-regular\n'
else
printf 'missing\n'
fi
}
marker_summary() {
local path="$1"
local marker="$2"
if [[ -f "$path" ]]; then
if grep -Fq "$marker" "$path" 2>/dev/null; then
printf 'marker-present\n'
else
printf 'marker-missing\n'
fi
elif [[ -e "$path" ]]; then
printf 'non-regular\n'
else
printf 'missing\n'
fi
}
script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
skill_dir="$(cd -- "$script_dir/.." >/dev/null 2>&1 && pwd)"
skills_root="$(cd -- "$skill_dir/.." >/dev/null 2>&1 && pwd)"
settings_helper="$skills_root/cmux-settings/scripts/cmux-settings"
if [[ ! -x "$settings_helper" && -x "$HOME/.agents/skills/cmux-settings/scripts/cmux-settings" ]]; then
settings_helper="$HOME/.agents/skills/cmux-settings/scripts/cmux-settings"
elif [[ ! -x "$settings_helper" && -x "$HOME/.codex/skills/cmux-settings/scripts/cmux-settings" ]]; then
settings_helper="$HOME/.codex/skills/cmux-settings/scripts/cmux-settings"
fi
section "cmux diagnostics"
printf 'date: %s\n' "$(date -u '+%Y-%m-%dT%H:%M:%SZ')"
printf 'shell: %s\n' "${SHELL:-unknown}"
printf 'inside_cmux: '
if [[ -n "${CMUX_WORKSPACE_ID:-}" || -n "${CMUX_SURFACE_ID:-}" ]]; then
printf 'yes\n'
else
printf 'no\n'
fi
printf 'cmux_workspace_id_set: %s\n' "$([[ -n "${CMUX_WORKSPACE_ID:-}" ]] && printf yes || printf no)"
printf 'cmux_surface_id_set: %s\n' "$([[ -n "${CMUX_SURFACE_ID:-}" ]] && printf yes || printf no)"
if [[ "${CMUX_SOCKET_PATH+x}" == "x" ]]; then
printf 'cmux_socket_path: %s (from CMUX_SOCKET_PATH)\n' "$(safe_path "$CMUX_SOCKET_PATH")"
elif [[ "${CMUX_SOCKET+x}" == "x" ]]; then
printf 'cmux_socket_path: %s (from CMUX_SOCKET)\n' "$(safe_path "$CMUX_SOCKET")"
else
printf 'cmux_socket_path: unset\n'
fi
printf 'cmux_socket_password_set: %s\n' "$([[ -n "${CMUX_SOCKET_PASSWORD:-}" ]] && printf yes || printf no)"
section "cli"
if command -v cmux >/dev/null 2>&1; then
printf 'cmux_path: %s\n' "$(safe_path "$(command -v cmux)")"
if cmux --version >/dev/null 2>&1; then
printf 'cmux_version: %s\n' "$(cmux --version 2>/dev/null | head -n 1)"
else
printf 'cmux_version: unavailable\n'
fi
run_status "cmux_ping" cmux ping
run_status "cmux_capabilities" cmux capabilities --json
if [[ "$include_context" -eq 1 ]]; then
printf 'identify_json:\n'
cmux identify --json 2>/dev/null || printf ' unavailable\n'
fi
else
printf 'cmux_path: missing\n'
fi
section "settings"
printf 'cmux_json: '
file_summary "$HOME/.config/cmux/cmux.json"
printf 'legacy_settings_json: '
file_summary "$HOME/.config/cmux/settings.json"
if [[ -x "$settings_helper" ]]; then
run_status "cmux_settings_validate" "$settings_helper" validate
printf 'auto_resume_agent_sessions: '
"$settings_helper" get terminal.autoResumeAgentSessions 2>/dev/null || printf 'default-or-unset\n'
else
printf 'cmux_settings_helper: missing (%s)\n' "$(safe_path "$settings_helper")"
fi
section "hook configs"
declare -a hook_checks=(
"codex:$HOME/.codex/hooks.json:cmux hooks codex"
"codex-config:$HOME/.codex/config.toml:codex_hooks"
"opencode-session:$HOME/.config/opencode/plugins/cmux-session.js:cmux hooks opencode"
"opencode-feed:$HOME/.config/opencode/plugins/cmux-feed.js:cmux hooks feed --source opencode"
"pi:$HOME/.pi/agent/extensions/cmux-session.ts:cmux hooks pi"
"amp:$HOME/.config/amp/plugins/cmux-session.ts:cmux hooks amp"
"cursor:$HOME/.cursor/hooks.json:cmux hooks cursor"
"gemini:$HOME/.gemini/settings.json:cmux hooks gemini"
"rovodev:$HOME/.rovodev/rovodev.yml:cmux hooks rovodev"
"hermes-agent:$HOME/.hermes/config.yaml:cmux hooks hermes-agent"
"copilot:$HOME/.copilot/settings.json:cmux hooks copilot"
"codebuddy:$HOME/.codebuddy/settings.json:cmux hooks codebuddy"
"factory:$HOME/.factory/settings.json:cmux hooks factory"
"qoder:$HOME/.qoder/settings.json:cmux hooks qoder"
)
for entry in "${hook_checks[@]}"; do
IFS=: read -r name path marker <<<"$entry"
printf '%s: %s ' "$name" "$(safe_path "$path")"
marker_summary "$path" "$marker"
done
section "session stores"
shopt -s nullglob
stores=("$HOME"/.cmuxterm/*-hook-sessions.json)
if [[ "${#stores[@]}" -eq 0 ]]; then
printf 'session_store_files: none\n'
else
printf 'session_store_files: %s\n' "${#stores[@]}"
for path in "${stores[@]}"; do
printf '%s: ' "$(basename "$path")"
file_summary "$path"
done
fi
section "agent binaries"
for bin in claude codex opencode pi amp cursor-agent gemini rovo rovodev hermes-agent gh copilot codebuddy droid qodercli; do
if command -v "$bin" >/dev/null 2>&1; then
printf '%s: present (%s)\n' "$bin" "$(safe_path "$(command -v "$bin")")"
else
printf '%s: missing\n' "$bin"
fi
done
SKILL.md
---
name: cmux-diagnostics
description: "Run end-user cmux diagnostics. Use when cmux hooks, notifications, session restore, settings, browser automation, socket access, CLI control, or agent resume behavior is not working, or when the user asks for a cmux health check, doctor report, or support-safe debug summary."
---
# cmux Diagnostics
Collect and interpret support-safe cmux diagnostics for end users. Default to read-only checks. Never dump hook config files, session stores, prompt logs, tokens, or environment secrets.
## Quick report
Run the bundled read-only script first, from whichever install path exists:
```bash
skills/cmux-diagnostics/scripts/cmux-diagnostics # cmux checkout
~/.agents/skills/cmux-diagnostics/scripts/cmux-diagnostics # installed skill
~/.codex/skills/cmux-diagnostics/scripts/cmux-diagnostics # Codex-only skills.sh install
```
Add `--include-context` only when workspace names, cwd paths, and current cmux identifiers are relevant to the reported issue.
## What to check
1. **CLI and socket health**: `command -v cmux`, `cmux ping`, `cmux capabilities --json`. If socket commands fail, check whether the agent is running inside a cmux terminal and whether socket automation is enabled.
2. **Settings health**: `cmux-settings validate` and `cmux-settings get terminal.autoResumeAgentSessions` (from `~/.agents/skills/cmux-settings/scripts/`, or `~/.codex/skills/...` for a `skills.sh` install). When `terminal.autoResumeAgentSessions` is false, cmux restores panes but does not resume saved agent sessions.
3. **Hook installation**: `cmux hooks setup --agent codex`, `--agent opencode`, or bare `cmux hooks setup` (installs supported agents found on PATH, skips missing ones). Run install or uninstall commands only after the user agrees.
4. **Session restore evidence**: `ls -lh ~/.cmuxterm/*-hook-sessions.json 2>/dev/null`. Missing stores usually mean the agent has not run inside cmux since hooks were installed, hooks are disabled, or the integration does not support resume capture.
5. **Notification path**: `cmux notify "cmux diagnostic test"`, only when the user is ready for a visible test notification.
## Interpretation
- `cmux` not found: the CLI is not installed or not on PATH for this shell.
- `cmux ping` fails: the app is closed, unreachable through the current socket path, or automation access is disabled.
- No `CMUX_WORKSPACE_ID` or `CMUX_SURFACE_ID`: the command is running outside a cmux terminal. Some hooks intentionally no-op there.
- Hook config but no session store: run one supported agent inside cmux after installing hooks, then re-check.
- Session store but no agents on restore: check `terminal.autoResumeAgentSessions` and whether the saved executable still exists on PATH.
- Settings validation fails: fix the config first. Invalid config makes later symptoms misleading.
## Rules
- Stay read-only until the user asks to fix something.
- Never print raw hook files, session JSON, prompt logs, shell history, tokens, or API keys. Summarize file presence, size, modified time, and marker presence instead.
- Prefer a narrow fix such as `cmux hooks setup --agent codex` over reinstalling every integration.
- After a fix, rerun the diagnostic script and report the changed lines.