Getting it into your agent
One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.
npx agentmods add agents/multiplex-term/multiplex/agent-helpersgit clone --depth 1 https://github.com/multiplex-term/MultiplexWhat it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5 | $0.00000 | $0.04831 |
| Opus 5 | $0.00000 | $0.02416 |
| Sonnet 5 | $0.00000 | $0.00966 |
| Haiku 4.5 | $0.00000 | $0.00483 |
Grade A, and why
agent-helpers scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured yesterday.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
How it starts
The opening of the file, as written. The whole thing — 263 lines — stays where its author put it; the contents beside it link to each section on GitHub.
CLI-agent detection, helpers & history
Load-bearing decisions split from AGENTS.md — read before touching AgentSignature, helper chips, launch model overrides, the keychain tip, or HISTORY/jump.
- An agent launch's model override is one verified flag, picked from
host-configured lists, fail-soft
(
AgentKind.launchCommand(model:initialPrompt:)+normalizedLaunchModel, pure + tested): every supported CLI spells it--model <value>(verified 2026-07-27: Claude Code 2.1.220, Codex rust 0.145.0, Pi 0.81.1). Values are NOT app-curated (names churn faster than releases); full ids are typed once intoHost.agentLaunchModels(keyed by agent rawValue, host-scoped — Pi's models genuinely differ per machine) and every surface offers them as a picker with free text as escape hatch. The normalizer enforces argv-token shape only (no whitespace/controls, no leading-, ≤64 chars); rejection means "agent default", never an error; UNKNOWN agent keys are preserved verbatim across edit-saves. The composed value is always shell-quoted (Claude'ssonnet[1m]would glob in zsh). Surfaces: New Session sheet (REMEMBER per agent, device-local; + TAB agent variants inherit it), the Open Agent Shortcut (String, for variables), the Host widget's Model setting (lists ride the App Group projection as names;&model=validated app-side), and the ASK prompt sheet. Both option providers lead with an "Agent Default" row and are NEVER empty (a zero-item options query makes the widget-config picker open and immediately dismiss). Synced record, zeroed fromconnectionModelConfiguration; external actions never inherit the remembered model. - Agent detection is multi-signal and fail-soft (
AgentSignature, fed by the probe's P lines +MULTIPLEX_PSps table):pane_current_command→ pane title (✳ Claude Code;π - …while Pi's node wrapper owns the pane — Pi leaves it stale on exit) → bare-semver comm (macOS native Claude launcher) → ps-tree walk frompane_pidmatching argv[0] basename only (never substring — Claude Desktop helpers false-positive; catches npm Codex/Pi wrappers). The 5 s probe retains every pane, reuses its onelist-panesresult to root ONE subtree-clipped host-wide ps snapshot; FleetWall aggregates split panes, helper chips follow only the active pane. Between full probes onlyTerminalFocusArbiter.currentruns a 1 s focused check: tmux uses current-windowlist-panes(with a cached single-TTY ps fallback for ambiguous wrappers), while herdr's smallpane currentresponse names the globally focused pane and its canonical agent definitively. A tick is skipped while that terminal saw a keystroke within ~1.5 s (TerminalView.hasRecentUserInput, reading the fork's send-path stamp — the pane under the fingers isn't changing, and detection must not compete with input handling; chips settle a beat after typing stops, and mid-burst the shown chip is left alone rather than dropped to the wall verdict). Settled full probes coalesce for 4 s. Plain.shelltabs use their own PTY authority (ShellAgentProbe: exec channel's$PPID→ sibling PTY under sshd → foreground pgid/tpgid only, so a suspended background agent leaves no helpers); title/visible-screen signatures are a narrow fallback for direct mosh shells or ps-less hosts; Pi's stale title is never trusted without the process probe. A direct shell alerts in its UMD rail keyed by tab UUID. Any failing stage disables that signal only, never the session list. Helper chips only type throughTerminalSessionController.sendInput(Enter = CR, Shift+Tab = CSI Z, Codex TRANSCRIPT = Ctrl+T, Pi THINK/TOOLS/THINKING = Shift+Tab/Ctrl+O/Ctrl+T; Claude PG UP/DN chips are visionOS-only); never ship a Ctrl+B payload — it's the remote tmux prefix — and no chip types a bare Escape: the STOP chip did and was withdrawn 2026-08-05 (Escape interrupts a running turn, and every platform already carries a real ESC key beside the terminal — the iPad/iPhone key rail, visionOS's ornament cluster). Pinned bytestNoBuiltInChipTypesABareEscape. The strip and agent alerts (AttentionCenter) are Pro-gated; detection and wall telemetry stay free. Pi's attention stays fail-soft idle — no RUNNING/turn-end claims without a separate reliable signal. Grok Build (added 2026-08-16 from the xai-org/grok-build source, not a live process — verify on a real host before tightening anything): binaryxai-grok-pager, shipped asgrok; the installer symlinks~/.grok/bin/grok → downloads/grok-<semver>-<os>-<arch>, so the pane's comm is the clipped target (grok-1.0.4-macoseen live on macOS 27) while argv[0] staysgrok—classify(command:)acceptsgrok,xai-grok-pager, andgrok-<n>.<n>…; Rust, no interpreter wrapper;grok --model <id> "prompt"is the documented interactive shape (top-level-m/--model, positional prompt); Shift+Tab cycles Normal → Plan → Always-approve (so MODE fits), Ctrl+T toggles the todos pane (TODOS chip), and its own Ctrl+B means "background this command" — one more reason no chip may carry the tmux prefix. Its OSC title is composed byTitleManager(default items:⚠ Action Required, Braille spinner, activity verb, session name,grok, joined by-) and resets to a baregrokon exit — so the direct-shell fallback matches only the- groksuffix, and no tmux title rule exists (the process signal is enough). Attention has its own classifier (AgentAttention.classifyGrok):⚠ Action Requiredanywhere in the title = permission (itspermission_queueis non-empty; the spinner keeps running behind it, so ⚠ outranks it), any Braille scalar anywhere = busy (title items are user-orderable — never key on position), and a question card is read from the tail as ≥2 option rows shaped<1-9|a-f> (○|●) label/<n> [ ]|[x] label(anask_user_questiondoes not touch the title). Trap: the ⚠ item blinks (~500 ms on/off) once Grok has seen a terminal focus-out — itsFocusTrackerstarts focused and tmux shipsfocus-events off, so over a Multiplex attach it holds still; a host withfocus-events oncould re-fire the permission alert on alternate probes. Busy/idle titles and the turn-ended alert were verified live (grok 1.0.4 in tmux on this Mac, sim build, 2026-08-16:⠋ - Sleep for 20 seconds… - <session> - grok→<session> - grok→alert posted for grok); the ⚠ permission title and the question card are still source-derived — first live capture that disagrees wins (sim proof recipe:e2e-headless.md, attention). herdr's canonical id for it is assumed to begrok. Antigravity CLI (added 2026-08-22 from official docs + live binary): binaryagy(symlink / aliasantigravity); launch syntaxagy [--model <model>] [-i <prompt>](interactive prompt requires-i/--prompt-interactive, unlike Claude/Codex/Pi which take positional strings); slash commands include primary (/clear,/resume,/diff,/model,/permissions,/agents,/skills) and overflow (/planning,/usage,/mcp,/credits,/tasks,/context,/statusline,/title,/fork,/rewind,/config); attention fails soft (hasVerifiedAttentionSignals = false) until dynamic title/dialog signals are pinned against live captures. herdr canonical IDs:antigravity,agy. Hermes Agent (added 2026-08-23 from the NousResearch/hermes-agent source + install.sh, no live process yet): a Python venv program — the installed~/.local/bin/hermes(or/usr/local/bin/hermes) is a bash wrapper that execs…/.hermes/hermes-agent/venv/bin/python …/hermes-agent/hermes, so the pane's comm ispython3.x/Pythonand only argv[1] names it;AgentSignature.matchtherefore has apython*interpreter rung besidenode/bun(argv[1] basename must still be exactlyhermesor the pyproject scripthermes-agent— never a substring). Launch: top-level-m/--model, but no interactive-with-prompt flag —-qis one-shot (answers, exits), so a prompt launch chainshermes -q '<prompt>' && hermes --continue(-cresumes the most recent session; the model rides both legs). Source-derived, unverified live. No OSC title is written (its status bar is in-band), so there is no title rule, no direct-shell fallback, and attention fails soft (hasVerifiedAttentionSignals = false). Chips:/new /compress /undo /model /approvals /diff /status+ overflow fromCOMMAND_REGISTRY(/context /retry /title /history /tools /skills /memory /usage /sessions /yolo); no/resumechip — Hermes's/resumetakes a session id, not a picker (Jhen, 2026-08-23); no MODE chip (approval mode is/approvals//yolo, not a Shift+Tab cycle). herdr canonical IDs assumedhermes,hermes-agent. Unknown-agent profiles in a synced Host record are now skipped on decode instead of failing the record — from this build on, a device that predates a newly added CLI keeps the host (older builds still drop the whole record; that ship has sailed). Slash chips submit with a CR sent ~160 ms after the text (separate write — Codex treats a same-burst Enter as a pasted newline; verified rust-v0.144; Claude/Pi accept the shape). Bar/More choices persist per host + agent as deviations from the curated defaults (stale overrides discarded). Custom commands share UUIDs across a host's agent profiles (shared); part of the Codable Host record (updatedAtbump, Keychain sync). Custom taps use the daily meter, ordered pump, optional delayed CR; labels keep 9 chars +...; the editor strips terminal controls incl. Ctrl-B, and its rows must bind by command UUID —ForEach($commands)index capture crashes on delete/reorder under a late text write. Research:local-plan/agent-harness-helpers.md. Command Setup uses the UIKit-hosted, content-sized iPad popover boundary (like tmux shortcuts):preferredContentSizefromsizeThatFits, hostingsizingOptions = .preferredContentSize(so ADD/DELETE live-resizes),safeAreaRegions = .container, adaptive sheet disabled — a plain SwiftUI.popovergrows a blank tail beside a floating keyboard, and a one-shot size clips after edits; padding or.fixedSizefix neither. visionOS keeps its native popover. One vertical scroll owner sized from measured rendered height; never restore a command-count multiplier (multiline rows have no stable height). - The deck's KEYCHAIN LOCKED tip mirrors Claude Code's own credential
read (
KeychainLockCheck, pure + tested): an SSH-reached Mac never unlocks its login keychain, so Claude Code starts signed out there. Only when a probe sees a Claude pane parked on a sign-in screen (phrase-exact needles, verified v2.1.218; "API Usage Billing" is deliberately NOT a needle — signed-in Console users show it) AND that pane's detected agent is Claude does the model run onesecurityexec on the probe connection. LOCKED is decided structurally, never by error text — on macOS 27 a locked keychain'sfind-generic-password -wfails silently over SSH (exit 128, empty stderr): data readable → unlocked; item findable but data unreadable → LOCKED; only "could not be found" is string-matched. Every stdout is discarded host-side (-w's stdout is the secret) — onlyMPX_KEYCHAINsentinels cross the wire; aunamegate answers NA once per connection on non-Macs. Only LOCKED lights the tip (MISSING is a genuine first login). Two surfaces: the deck rail and the affected tabs' terminal chrome (UMD cluster / rail lamp). Clears the moment the screen moves on; 60 s TTL re-confirm while the symptom persists. Verdicts log under categorywall(debug).security unlock-keychainadvice re-verified on macOS 27 (the registered login keychain persists unlock across processes). Copy is shared throughHostGuide(deck sheets, NO TMUX dialog, FAQ) so surfaces can't drift. - HISTORY reads Claude Code's own session file; jump walks Claude's
pager with the header oracle (
AgentSessionHistory, pure + fixture-tested; Pro viacanBrowseAgentHistory). Claude Code only — Codex/Pi history was withdrawn 2026-07-16; don't re-add a lesser variant. Both backends (E2E-verified on herdr 0.7.5, 2026-08-03): the walk's four touchpoints are backend-parameterized (JumpTarget: capture / key send / literal send / prologue), everything else — oracle, needles, twin counting, restore discipline — is shared. herdr specifics: context cwd from oneapi snapshot(the drop path's parser) and the registry walk rooted atpane process-info --current'sshell_pid(thepane_pidanalog; both work clientless, unlikepane current, which the jump prologue may use because a live tab IS an attached client); captures viapane read --source visible --format text; 0.7.5'ssend-keyshas no page/end names, so keys go as RAW escape bytes (\e[5~/\e[6~/\e[1;5F) each in ONEsend-textwrite — a split ESC would read as bare Escape and can interrupt a turn; the prologue title must be rawterminal_title(the stripped variant removes exactly the spinner/✳ glyphs the idle classifier reads); pane width is measured from the capture's widest row (no column oracle exists); header clicks and the client-size census stay off (no mouse-flag or client-list surface). File selection: pane cwd (list-panes -F) → descendants of#{pane_pid}→ Claude's live<config root>/sessions/<pid>.jsonregistry → that exactprojects/<munged-cwd>/<sessionId>.jsonl; never regress to newest-mtime-only (multiple Claude panes per cwd are common; the wrong file makes every JUMP miss).CLAUDE_CONFIG_DIRresolves per candidate pid:/procenviron (Linux) →ps -E(pre-Darwin-27 only; 27 strips same-user procargs env) → the exec shell's export →~/.claude— each rung accepted only if it holds the pid's registry; the winner ridesMULTIPLEX_HIST_CONFIG_DIR(no cross-root rescue)..shelltabs honor the exec shell's var alone. Reads are sentinel-framed with server-side grep pre-filters, and long base64"data"values are blanked BEFORE the tail byte cut (one pasted screenshot otherwise crowds out every older prompt). Claude ≥2.x owns the alternate screen under tmux — the transcript never enters tmux scrollback; jump is ONE server-side exec (RTT-independent). Pager facts (2.1.211): PgUp/PgDn move half the region; row 1 of a scrolled view is the sticky❯header of the owning turn; Ctrl+End/Home = bottom/top; no line-granular scroll. The sticky is click-to-jump (2.1.214; only the sticky reacts): when the prologue sees SGR mouse on (#{mouse_any_flag}/#{mouse_sgr_flag}), a unique-target walk clicks every sticky it climbs past (~2 sends/turn); a click that moves nothing disarms clicking; twin targets never click (a warp breaks the from-the-bottom count). The find ships the WHOLE loaded message list as an index (longest-needle-first; an awk classifier reportspin= which turn owns row 1 andreal= the target's❯row, bottom chrome excluded): pin ≥ two turns newer → 6-page leaps; one newer / equal / unknown → viewport-safe 2-page steps; pin older → single PgDn from above. Landing accepts only a real row in the TOP half (a lower sighting takes one PgDn); a UNIQUE target lands on any sighting, descent included. Two upward crossings past the target without its row = needle mismatch → one retry with the 24-column fallback; scroll-top with the fallback unused retries too; both restart from live so twin counting stays valid. A rebuilt transcript (resume, or reflow after ANY resize) can omit a long multiline prompt's body entirely — when both needles cross the pinned turn without its row, the walk descends to the turn's first view and reports MPXJ_NEAR (the sticky IS the flattened text; treat it as the destination, don't lie "not found"). A mid-walk capture-height change means another client resized (window-size latest): restart once, then MPXJ_RESIZED; multi-size sessions surface "ANOTHER CLIENT RESIZES THIS SESSION". The send budget is a runaway stop, not a search radius: base 400 scaled byjumpSendBudget(paneWidth:paneHeight:)up to 1600 (a 44-column pane rewraps ~2.3×). Under 12 rows → MPXJ_SHORT ("TERMINAL TOO SHORT TO JUMP"). Misses, cancellation, and BACK TO LIVE use Ctrl+End in constant time — never Esc (Esc can interrupt a running turn); every restore-then-capture polls to stability (stab). Needles are wrap-safe (wrapSafePrefix: normalized first-line prefix cut to min(width − 6, 60) columns, word-boundary retreat, wide glyphs cost two; only the STICKY flattens a prompt to one truncated row — a real row word-wraps the full body); pure-paste messages may stay peek-only. Identical prompts count from the bottom: each twin's row counted once while climbing, upward batches capped under one viewport (twinSafeBatch), prefix matching ("commit everything" sights as "commit"); twins embed in the oracle as the 0 sentinel, and the 24-column fallback carries its own count. Slash commands (bare and<command-…>-wrapped, either tag order) are filtered from the list. Only the typed/compactline is a transcript-reset boundary (verified 2.1.211) — earlier prompts keep peek withreachable=false, which withholds JUMP; the pager genuinely cannot reach them, don't search harder.isCompactSummaryentries are NOT boundaries (auto-compaction keeps the rendered transcript; treating them as resets hid working JUMPs — a wrongly hidden button is unexplainable, a wrongly shown one ends in the honest miss pill). Only.findingblocks a new jump (a lingering JUMPED state is superseded); while.finding, the input pump is locked and a veil says so..shelltabs list history (cwd viareadlink /proc,lsoffallback) but never jump. Record:local-plan/agent-message-history.md.
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- yesterday First seen · 263 lines · 0 tokens per session scan A 623778a9e651
agent-helpers is an agent published in the GitHub repository multiplex-term/Multiplex (10 stars, last pushed 5d ago), licensed Apache-2.0. It costs nothing until one of its globs matches a file; then it loads 4,831 tokens. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-31.
Other agents, from other repositories
layer3-issue-detection
Layer 3 systematically scans ALL entry points from Layer 1 and applies issue detection rules. Unlike Layer 2 (which traces specific flows in depth), Layer 3 does a breadth-first scan to categorize issues across the entire codebase.
layer4-semantic-evaluation
Layer 4 evaluates workflows from the user's perspective. While Layers 1-3 analyze code structure, Layer 4 asks: "Does this workflow help the user achieve their goal?".
layer2-methodology
Layer 2 takes entry points from Layer 1 and traces the complete user journey.
mobile-architect
Mobile architecture expert. Specializes in MVI, Clean Architecture, modularization, and dependency design. Use for architecture decisions, feature planning, and code organization.
kmp-architect
KMP architecture expert. Designs shared module structures, expect/actual patterns, navigation, and DI for Kotlin Multiplatform projects.
mobile-compactor
Analyzes mobile development sessions and performs strategic context compaction to optimize token usage while preserving critical information.