By Emasoft
Universal terminal-menu system for Claude Code plugins. Any agent invokes scripts/menu_write.py via Bash to render a JSON menu spec to a tempfile; a bundled Stop hook emits it as systemMessage at main-session turn end — the menu appears in the user terminal exactly when they can type a reply. ~25ms, no subagent fork, no extended thinking overhead.
Render a menu from a JSON spec file (ad-hoc — useful for testing your own plugin's menu specs without integrating yet).
Run the claude-menu-system self-test — renders a demo menu so you can verify the plugin is wired correctly. Use after install or after upgrading.
Claude Code's built-in option prompt is awkward for a large number of choices.
Just run this command and you get a nice menu with as many entries as you need:
cat > /tmp/my-menu.json <<'EOF'
{
"spec_version": 1,
"mode": "menu",
"plugin": "my-plugin",
"slug": "main",
"header": "What do you want to do?",
"rows": [
{"key": "1", "action_id": "scan", "label": "Scan the codebase"},
{"key": "2", "action_id": "validate", "label": "Validate the manifest"},
{"key": "3", "action_id": "publish", "label": "Publish to marketplace"},
{"key": "0", "action_id": "cancel", "label": "Cancel"}
],
"footer": "Type a number to choose:"
}
EOF
python3 "$CLAUDE_PLUGIN_ROOT/scripts/menu_write.py" /tmp/my-menu.json
That's it. The menu appears in the user's terminal at the end of the
current turn (a bundled Stop hook does the emit). The user's reply
arrives in your next turn.
Add as many rows as you need — no option-count limit, no truncation.
claude plugin install Emasoft/claude-menu-system@emasoft-plugins
/reload-plugins
Self-test:
/menu-test
If your plugin lives in a different marketplace, $CLAUDE_PLUGIN_ROOT
points at YOUR plugin — not this one. Resolve the cache path:
CMS_ROOT=$(ls -d ~/.claude/plugins/cache/emasoft-plugins/claude-menu-system/*/ | sort -V | tail -1)
python3 "$CMS_ROOT/scripts/menu_write.py" /tmp/my-menu.json
menu_write.py also writes a sibling .actions.json file mapping
rendered key → action_id. It does not live at the spec path —
it sits beside the queued menu file inside the session queue dir.
menu_write.py prints that queue path to stdout, so capture it and
derive the sidecar from it:
QUEUE_PATH=$(python3 "$CLAUDE_PLUGIN_ROOT/scripts/menu_write.py" /tmp/my-menu.json)
ACTIONS=$(cat "${QUEUE_PATH%.menu.md}.actions.json")
# ACTIONS is JSON like: {"1":"scan","2":"validate","3":"publish","0":"cancel"}
Read the sidecar in the same turn you queue the menu, and keep the
mapping in mind. The bundled Stop hook emits the menu and deletes
both the menu file and its .actions.json sidecar at turn-end — so
the files are gone by the time the user's reply arrives in your next
turn. The action map is small; read it now, remember it, and route the
reply next turn from what you already know.
mode: menu is the common case. Seven more modes ship for richer
output:
| Mode | Purpose |
|---|---|
menu | Numbered table with action map (above) |
summary | Severity counts + verdict + report path |
breakdown | Per-category × per-severity matrix |
status_table | Component / Status / Notes table (✓/✗/⚠/◐/○) |
panel | Single titled box with body text |
multi_box | Stack of panels |
progress | Title + bar + counter (12/20 (60%)) |
confirm | Yes / No / Cancel prompt |
See examples/ for one canonical spec per mode — copy and adjust.
These can appear in any spec on top of the per-mode required fields.
| Field | Type | Default | Meaning |
|---|---|---|---|
truncate_at | int > 0 / null | absent | Per-menu cap (chars) consumed by the emit hook. null disables per-menu shaping entirely (overflow fails loudly under the 9500-char queue cap). Absent = default heuristic shaping. |
Reserved keys (always preserved verbatim even with renumber:true):
0, A, M, B, X — the last three are CPV's navigation letters
(Main / Back / eXit) so menus that route through CPV's fixed-key contract
keep their nav glyphs stable across rerenders.
MIT — see LICENSE.
Own this plugin?
Verify ownership to unlock analytics, metadata editing, and a verified badge. GitHub access is read-only (username + org membership).
Sign in to claimOwn this plugin?
Verify ownership to unlock analytics, metadata editing, and a verified badge. GitHub access is read-only (username + org membership).
Sign in to claimBased on adoption, maintenance, documentation, and repository signals. Not a security audit or endorsement.
npx claudepluginhub emasoft/emasoft-plugins --plugin claude-menu-systemTask distribution, agent coordination, progress monitoring - executes plans via subagents. Requires AI Maestro for inter-agent messaging.
Comprehensive validation, management, and standardization suite for Claude Code plugins and marketplaces. Includes 190+ validation rules, plugin lifecycle management, marketplace operations, health checks, security auditing, GitHub repo validation, plugin/marketplace repo scaffolding, and standardization tooling. Features severity hierarchy, --strict mode, language-aware token estimation, and universal plugin/marketplace templates.
GHE (GitHub-Elements) - Automated project management for Claude Code using GitHub Issues as persistent memory with orchestrated DEV/TEST/REVIEW workflow.
Portable utility tools for Claude Code plugin marketplaces. Includes release automation and markdown TOC generation.
Exports current session segment (since last compaction) with system-reminder stripping -- main conversation, subagent transcripts, sidechains, and debug logs in structured markdown
Multi-model consensus engine integrating OpenAI Codex CLI, Gemini CLI, and Claude CLI for collaborative code review and problem-solving.
Easily create hooks to prevent unwanted behaviors by analyzing conversation patterns
Harness-native ECC operator layer - 67 agents, 271 skills, 92 legacy command shims, reusable hooks, rules, selective install profiles, and production-ready workflows for Claude Code, Codex, OpenCode, Cursor, and related agent harnesses
Complete collection of battle-tested Claude Code configs from an Anthropic hackathon winner - agents, skills, hooks, and rules evolved over 10+ months of intensive daily use
Complete AI coding workflow system. Self-correcting memory + persistent FTS5-indexed research wikis + auto-research loop + multi-LLM council on a single SQLite store. 33 skills, 8 agents, 22 commands, 37 hook scripts across 24 events. Cross-agent via SkillKit.