en un clic
freshell-orchestration
// Use when interacting with Freshell panes, panels, or tabs from the CLI for tmux-style automation and multi-pane workflows, outside external-browser automation tasks.
// Use when interacting with Freshell panes, panels, or tabs from the CLI for tmux-style automation and multi-pane workflows, outside external-browser automation tasks.
| name | freshell-orchestration |
| description | Use when interacting with Freshell panes, panels, or tabs from the CLI for tmux-style automation and multi-pane workflows, outside external-browser automation tasks. |
Freshell injects FRESHELL_URL and FRESHELL_TOKEN into every spawned terminal. They are already set in your environment.
If you have the freshell MCP tool available, use it directly -- it's faster and doesn't require Bash approval for each command.
Quick start:
freshell({action: "help"}) -- see all available commandsfreshell({action: "list-tabs"}) -- see open tabsfreshell({action: "new-tab", params: {name: "Work", mode: "claude"}}) -- create a tabfreshell({action: "send-keys", params: {target: "p1", keys: "hello\n"}}) -- send inputThe MCP tool accepts the same commands as the CLI below but with structured JSON input instead of positional arguments.
If the MCP tool is not available (e.g., running outside Freshell or in a context without MCP support), use the CLI:
FSH="npx tsx server/cli/index.ts"
$FSH health
Use absolute paths for --cwd and --editor.
/api/*, not a local tmux socket client.layoutStore.terminalRegistry.terminal, editor, browser, agent-chat (Claude/Codex), picker (transient).--mode/--browser/--editor starts as a picker pane while the user chooses what to launch. Once they select, the picker is replaced by the real pane with a new pane ID. Never target a picker pane for splits or other mutations — wait until it resolves to its final kind, or use --mode/--browser/--editor flags on new-tab/split-pane to skip the picker entirely.new-tab/split-pane -> send-keys -> wait-for -> capture-pane/screenshot-*.split-pane. Use new-tab only when the user explicitly says "tab", "window", or "new [thing]" with no spatial reference. When unsure, split-pane is the safer default.cat/vim/nano/curl/wget when a dedicated pane type fits.
split-pane --editor /path/to/filesplit-pane --browser URL or open-browser URLsplit-pane --mode shell or new-tab --mode shellsend-keys -l for natural-language prompts or multi-word text. Do NOT append "ENTER" as literal text — send the command with -l, then send ENTER as a separate call.FRESHELL_TAB_ID/FRESHELL_PANE_ID), not the user's active viewport. split-pane without a target splits your own pane.split-pane defaults to vertical (top/bottom). Use -h for horizontal (left/right).Output behavior:
list-tabs and list-panes print TSV unless --json.list-panes --titles appends a fifth TSV column with the pane title.capture-pane and display print plain text.Targets:
tabRef.paneIndex.rename-tab means the active tab.rename-pane means the active pane in the active tab.split-pane (MCP) means your own pane, not the user's active viewport.-t/-n form when you want to make the target and name explicit.Tab commands:
new-tab [-n NAME] [--claude|--codex|--mode MODE] [--shell SHELL] [--cwd DIR] [--browser URL] [--editor FILE] [--resume SESSION_ID] [--prompt TEXT]list-tabs [--json]select-tab [TARGET] or select-tab -t TARGETkill-tab [TARGET] or kill-tab -t TARGETrename-tab NEW_NAME - rename the active tabrename-tab TARGET NEW_NAMErename-tab -t TARGET -n NEW_NAMEhas-tab TARGET or has-tab -t TARGETnext-tabprev-tabPane/layout commands:
split-pane [-t PANE_TARGET] [-h] [--mode MODE] [--shell SHELL] [--cwd DIR] [--browser URL] [--editor FILE]list-panes [-t TAB_TARGET] [--json] [--titles]select-pane PANE_TARGET or select-pane -t PANE_TARGETrename-pane NEW_NAME - rename the active panerename-pane TARGET NEW_NAMErename-pane -t TARGET -n NEW_NAMEkill-pane PANE_TARGET or kill-pane -t PANE_TARGETresize-pane PANE_TARGET [--x X_PCT] [--y Y_PCT]swap-pane PANE_TARGET --other OTHER_PANE_TARGETrespawn-pane PANE_TARGET [--mode MODE] [--shell SHELL] [--cwd DIR]attach TERMINAL_ID [PANE_TARGET] or attach -t TERMINAL_ID -p PANE_TARGETTerminal interaction:
send-keys [-t PANE_TARGET] [-l] KEYS...capture-pane [-t PANE_TARGET] [-S START] [-J] [-e]wait-for [-t PANE_TARGET] [-p PATTERN] [--stable SECONDS] [--exit] [--prompt] [-T TIMEOUT_SECONDS]display -p FORMAT [-t PANE_TARGET] or display FORMAT [PANE_TARGET]run [--capture|-c] [--detach|-d] [-T TIMEOUT_SECONDS] [-n NAME] [--cwd DIR] COMMAND...summarize PANE_TARGET or summarize -t PANE_TARGETlist-terminalsBrowser/navigation:
open-browser URL [-n NAME]navigate URL [PANE_TARGET] or navigate --url URL -t PANE_TARGETScreenshot commands:
screenshot --scope pane|tab|view --name NAME [--path DIR_OR_FILE] [--overwrite] [-t TARGET]screenshot-pane -t PANE_TARGET --name NAME [--path ...] [--overwrite]screenshot-tab -t TAB_TARGET --name NAME [--path ...] [--overwrite]screenshot-view --name NAME [--path ...] [--overwrite]--name is required.--path is optional; default output root is OS temp dir.Session/service:
list-sessionssearch-sessions QUERY or search-sessions -q QUERYhealthlan-infotmux-style aliases:
new-window, new-session -> new-tablist-windows -> list-tabsselect-window -> select-tabkill-window -> kill-tabrename-window -> rename-tabnext-window -> next-tabprevious-window, prev-window -> prev-tabsplit-window -> split-panedisplay-message -> displayscreenshot-pane, screenshot-tab, screenshot-view -> screenshotNew tab:
FILE="/absolute/path/to/file.ts"
$FSH new-tab -n "Edit $(basename "$FILE")" --editor "$FILE"
Split current tab:
FILE="/absolute/path/to/file.ts"
$FSH split-pane --editor "$FILE"
FSH="npx tsx server/cli/index.ts"
CWD="/absolute/path/to/repo"
FILE="/absolute/path/to/repo/README.md"
WS="$($FSH new-tab -n 'Triager' --codex --cwd "$CWD")"
TAB_ID="$(printf '%s' "$WS" | jq -r '.data.tabId')"
P0="$(printf '%s' "$WS" | jq -r '.data.paneId')"
P1="$($FSH split-pane -t "$P0" --editor "$FILE" | jq -r '.data.paneId')"
$FSH rename-tab -t "$TAB_ID" -n "Issue 166 work"
$FSH rename-pane -t "$P0" -n "Codex"
$FSH select-pane -t "$P1"
$FSH rename-pane "Editor"
FSH="npx tsx server/cli/index.ts"
CWD="/absolute/path/to/repo"
PROMPT="Implement <task>. Run tests. Summarize tradeoffs."
SEED_JSON="$($FSH new-tab -n 'Claude x4 Eval' --claude --cwd "$CWD")"
P0="$(printf '%s' "$SEED_JSON" | jq -r '.data.paneId')"
J1="$($FSH split-pane -t "$P0" --mode claude --cwd "$CWD")"
P1="$(printf '%s' "$J1" | jq -r '.data.paneId')"
J2="$($FSH split-pane -t "$P0" -h --mode claude --cwd "$CWD")"
P2="$(printf '%s' "$J2" | jq -r '.data.paneId')"
J3="$($FSH split-pane -t "$P1" -h --mode claude --cwd "$CWD")"
P3="$(printf '%s' "$J3" | jq -r '.data.paneId')"
for p in "$P0" "$P1" "$P2" "$P3"; do
$FSH send-keys -t "$p" -l "$PROMPT"
$FSH send-keys -t "$p" ENTER
$FSH wait-for -t "$p" --stable 8 -T 1800
$FSH capture-pane -t "$p" -S -120 > "/tmp/${p}.txt"
done
x-auth-token: <TOKEN> (not Bearer).POST /api/tabs with { name, mode: "shell", shell: "wsl", cwd } creates a tab with a terminal, bypassing the picker.POST /api/panes/:id/split with { direction: "horizontal"|"vertical", browser?, editor?, mode?, cwd? } — defaults to vertical; always 50/50.POST /api/panes/:id/resize with { sizes: [left, right] } (percentages summing to 100) — call immediately after split to fix proportions.DELETE /api/terminals/:id removes orphaned terminals. Freshell has a 50 PTY limit; orphans from scripted runs accumulate silently.send-keys -l for natural-language prompts.wait-for --stable is usually more reliable than prompt heuristics across providers.list-tabs and list-panes --json, then retry with explicit IDs.Use when preparing a Freshell release — before bumping versions, writing release notes, tagging, etc on GitHub.
Use when reviewing, triaging, or landing pull requests — especially batches of open PRs that need inspection, fixes, and merging. Also triages open issues after the PR queue is clear.
Use when installing, creating, or setting up Freshell extensions — from GitHub repos, local directories, or from scratch as custom panes.
Use when producing screen-recorded demos that need scenario-specific pane layouts, live interaction walkthroughs, and machine-readable timecodes for automated video editing.
Use when producing screen-recorded demos that need scenario-specific pane layouts, live interaction walkthroughs, and machine-readable timecodes for automated video editing.