Keyboard shortcuts

Press ← or → to navigate between chapters

Press ? to show this help

Press Esc to hide this help

Tauri Commands Reference

Slice F exposes start_graph {target:{type:story|plan,id},expected_revision?,definition_id,definition_revision,request_id,limits?} through the existing owning-daemon service. Story starts require the current native revision and pin the selected publication; the request ID is bound to its payload. Omitted limits use Rust defaults. Plan dispatch remains unavailable in this build and its start control says so. The workflow_run MCP tool uses an inline schema generated from RunAction and the public RunCommand variants; it returns the same scoped snapshots and cursor-ordered events as IPC/HTTP. Run history shows pinned activations, decisions/evidence, repair counters, pause targets and complete event payloads across pages. Graph recovery uses resume_graph {execution_id,activation_id,resolution} after answering pending input; pause and cancel use the existing sequence-fenced commands. Legacy runs offer inspection and cancellation in the UI. No new persistence or client scheduler is added.

Workflow runs

CommandParametersResultDescription
workflow_run_actionproject, actiontagged RunReplyStarts, reads, lists plan runs, pages events, executes pinned checks, records checked integrations or canonical recertifications, or commands a durable project-scoped run. See Workflow runs.

Workflow definitions

CommandParametersResultDescription
workflow_definition_actionproject, actiontagged WorkflowReplyReads, edits, validates, and publishes project-scoped workflow definitions; update_closure sets the approval policy and update_checks pins executable checks. See Workflow definitions.

Native stories

CommandParametersResultDescription
story_action_commandproject, action, sessionId?tagged StoryReplyCreates, reads, claims, transitions, or removes a cancelled dependency from native stories. list_plan_sources discovers project Markdown plans and add_plan_source records one with its document title; both are also available through HTTP and MCP. plan_view returns a Rust-derived plan summary and transitive abandoned indicators; transition_history returns actor provenance. Removal requires a human caller, a Backlog dependent, a direct WontFix prerequisite, and the current revision. The backend checks project ownership and claim session identity. See HTTP API.
story_capabilitiesnonetrueInfallible capability probe used before loading the dialog. Its absence means the running desktop backend predates native stories.

Project Progress

CommandParametersResultDescription
report_progress_eventproject, report{id}Appends one done or blocked entry through the same core as MCP and HTTP.
progress_listproject, input.blockedOnly?, input.ptyId?, input.limit?, input.cursor?ProgressListA newest-first page (default 8, maximum 100), matching total, next cursor, available PTY IDs, and stored last-visit mark.
progress_projectsnonestring[]Journal projects ordered by their most recent entry, for clients without an active desktop repository.
progress_deleteproject, input.ids{deleted}Deletes entries by id, scoped to the project — one project cannot delete another’s.
progress_flowproject, input.ptyId?ProgressFlowThe journal as a delegation sequence: participants and ordered hand-off events (see docs/api/http-api.md → Project Progress).
progress_flow_detailinput.ptyId, input.agentId, input.part{text}Full redacted prompt or report of one subagent arrow, fetched on demand.
progress_mark_viewedproject, ptyId?{lastViewedMs}Moves the selected PTY’s or repository aggregate’s last-visit mark to now. Deliberately not an MCP action: it is the reader’s, not the agent’s.

The journal is append-only. There is no pause, clear, correction or export command: an entry is written once and either kept or deleted. intent entries are written by TUIC from the agent’s intent: marker and cannot be reported. Every stored entry has secret-shaped text and step values redacted; agent and target names are redacted and capped at 80 characters.

All commands are invoked from the frontend via invoke(command, args). In browser mode, these map to HTTP endpoints (see HTTP API).

Grid-frame channels and terminal_styled_rows share the optional TCX1 cell-text trailer with HTTP/WS. Complete cell text includes retained zero-width characters. terminal_search_buffer returns UTF-16 string ranges; terminal_search retains grid-cell coordinates. Both match the stored sequence without normalization.

PTY Session Management (pty.rs)

CommandArgsReturnsDescription
create_ptyconfig: PtyConfigString (session ID)Create PTY session
create_pty_with_worktreepty_config, worktree_configWorktreeResultCreate worktree + PTY
write_ptysession_id, data()Write to PTY
write_pty_partssession_id, parts: Vec<String>()Write several inputs under one writer lock. The parts stay separate on purpose: post-write bookkeeping runs once per part, and it is not a function of the joined bytes (a lone / opens slash mode, an exact option key answers a choice prompt)
enqueue_agent_commandsession_id, text, idempotency_key?{ accepted, typed, queued }Queue for the next idle window; optional key (1–128 UTF-8 bytes, wire name idempotencyKey) recognizes the last 128 accepted keys per live PTY without resubmitting; acceptance is not a model-turn receipt
clear_queued_agent_commandssession_idusizeDrop every queued command; returns how many
list_queued_agent_commandssession_id[{ id, text }]The queued user commands in delivery order; peer messages excluded
remove_queued_agent_commandsession_id, command_idboolDrop one queued command by id; false when it already drained
resize_ptysession_id, rows, cols()Resize PTY; alternate-screen resizes preserve primary-log continuity
pause_ptysession_id()Pause reader thread
resume_ptysession_id()Resume reader thread
close_ptysession_id, cleanup_worktree()Close PTY session
can_spawn_session–boolCheck session limit
get_orchestrator_stats–OrchestratorStatsActive/max/available
get_session_metrics–JSONSpawn/fail/byte counts
list_active_sessions–Vec<SessionInfo>List all sessions with display_name_is_custom, display_name_from_spawn, is_remote, optional live tuic_session, the optional resolved parent_session, and the same optional lifecycle state (shell_state, agent_state, background_work, queued_commands) returned by GET /sessions — one builder serves both. Sessions running on a connected remote machine are in the list too, each carrying connection_id; a local row has none (#791-055e)
list_worktrees–Vec<JSON>List managed worktrees
get_session_foreground_processsession_idJSONGet foreground process info
get_kitty_flagssession_idu32Get Kitty keyboard protocol flags for session
get_prompt_receiptsession_idPromptReceiptRead captured launch sections and observation gaps; async/blocking worker
get_last_promptsession_idOption<String>Get last user-typed prompt from input line buffer
get_shell_statesession_idOption<String>Get current shell state (“busy”, “idle”, or null); agent-specific semantic Working markers can repair a transient false-idle state
has_foreground_processsession_id: StringboolChecks if a non-shell foreground process is running
debug_agent_detectionsession_id: StringAgentDiagnosticsReturns diagnostic breakdown of agent detection pipeline
get_pty_capture–JSONRaw PTY capture tap state: enabled, session filter, directory, bytes per session. Browser parity: GET /diagnostics/capture.
set_pty_captureenabled: bool, session_id: Option<String>JSONStart/stop recording raw PTY bytes to <config dir>/captures/<id>.tcap or the absolute TUIC_CAPTURE_DIR override; a relative override returns an error and leaves recording disabled. Starting begins a fresh file. Surfaced as Capture Session in the tab context menu under isPerfDebug(). Browser parity: POST /diagnostics/capture.
set_session_namesession_id, name, is_custom?()Set a session display name and whether it represents an explicit user rename
get_input_buffer_contentsession_idStringGet the current content of the input line buffer (what the user is typing). Used by plugins with pty:read capability.
terminal_get_selection_textsession_id, start_row, start_col, end_row, end_col, history_base?Result<String, String>Read a scrollback-aware selection, join soft-wrapped rows, and remove coherent Claude visual gutter runs. Optional frame history_base rebases grid-relative rows atomically against history eviction; evicted endpoints are rejected. Browser parity: GET /sessions/:id/terminal/selection-text (historyBase query parameter).
get_process_stats–Vec<ProcessStat>CPU% and RSS memory for TUIC and all child process trees
subscribe_terminal_gridsession_id, channel: Channel<Response>u64 (epoch)Register the grid-frame channel for the calling WebView and install a fresh delivery gate (counting from zero). Navigation or destruction releases only that WebView’s subscriptions. Returns the subscription epoch the client must carry on ack_terminal_frame and unsubscribe_terminal_grid. Frames are raw bytes, not JSON. Browser parity: WS /sessions/:id/stream?format=grid
ack_terminal_framesession_id, epoch: u64, received: u64()Report the total number of frames this client has received. The gate opens when the echo catches up with what was sent, which is what tells a fresh ack from a late one for an abandoned frame. An ack whose epoch is not the live subscription’s is dropped. Browser parity: none — the WS path uses sequence numbers instead
unsubscribe_terminal_gridsession_id, epoch: u64()Tear down the grid channel and its gate. The pending scroll target is NOT torn down — it belongs to the session, so an attached browser keeps scrolling after the desktop terminal closes. A non-matching epoch is ignored: a remount subscribes before the outgoing instance unsubscribes, and honouring the stale call would blank a mounted terminal. Browser parity: closing the WS
chat_view_snapshotsession_id, epoch: Option<u64>, from_seq: Option<u64>ChatViewSnapshotChat view of a Claude terminal: transcript entries from the bound session file as ACP updates, with a bounded log, epoch and reset flag. Errors not_bound: <reason> for a terminal with no bound Claude agent. Browser parity: GET /sessions/:id/chat-view
terminal_styled_rowssession_id, start, countResult<Response, String> (packed bytes)A range of styled rows by absolute index, filling the client-side scroll cache. Raw bytes for the same reason as grid frames. Browser parity: GET /sessions/:id/terminal/styled-rows (application/octet-stream)

Every terminal grid read — the two rows above plus terminal_get_block_rows, terminal_scroll_info, terminal_search, terminal_search_buffer, terminal_get_row_text, terminal_get_logical_line, terminal_get_lines, terminal_get_cursor_line, terminal_hyperlink_at and terminal_hyperlink_span and read_vt_log — is an async fn that runs on the blocking pool via pty::vt_try_read, so it returns Result<T, String> rather than a bare T. The Err arm means the pool task itself failed; a session that is gone is still the old default (or a 404 over HTTP). See docs/backend/command-threading.md.

MCP session action=submit deliberately has no new Tauri command. It is a request-scoped orchestration contract in mcp_transport.rs: it reuses the PTY injection claim, writer, input FSM, and output ring, then keeps the MCP response open for a bounded terminal-movement receipt. Desktop write_pty and write_pty_parts remain raw input primitives and make no acknowledgement claim.

Design Mode (design_mode/tauri_commands.rs)

The desktop commands and their HTTP equivalents control the same per-repository Chrome inspector. A start is bound to the named agent session; a second start for the repository rebinds its existing Chrome window. A grab is inserted into that session’s input draft without submitting it.

CommandArgsReturnsDescription
start_design_modesessionId: StringDesignModeStatusStart or rebind inspection for an agent terminal; opens the repository’s configured URL or about:blank
stop_design_moderepoPath: StringDesignModeStatusStop inspection for a repository
get_design_mode_status–Vec<DesignModeStatus>Read the active per-repository modes

Command responses use { repoPath, sessionId, status }, with status equal to armed or stopped. The backend also emits design-mode-changed with a snake_case event payload { repo_path, session_id, status }; browser clients receive it on /events.

Generators (generators.rs)

CommandArgsReturnsDescription
generate_valuegenerator_id, optionsGeneratedValueGenerate a secure random value (password, uuid_v4, uuid_v7, ulid, cuid2, jwt_secret, totp_secret, nano_id, slug, ed25519_keypair)

Git Operations (git.rs)

CommandArgsReturnsDescription
get_repo_infopathRepoInfoRepo name, branch, status
get_git_diffpathStringFull git diff
get_diff_statspathDiffStatsAddition/deletion counts
get_changed_filespathVec<ChangedFile>Changed files with stats
get_file_diffpath, fileStringSingle file diff
get_gutter_changespath, file, scope?Vec<GutterChange>Per-line editor gutter/scrollbar change markers (diff parsed in Rust); empty for an untracked file
get_git_branchespathVec<JSON>All branches (sorted)
get_recent_commitspathVec<JSON>Recent git commits
rename_branchpath, old_name, new_name()Rename branch
check_is_main_branchbranchboolIs main/master/develop
get_initialsnameString2-char repo initials
get_merged_branchesrepo_pathVec<String>Branches merged into default branch
get_repo_summaryrepo_pathRepoSummaryAggregate snapshot: worktree paths + merged branches + per-path diff stats in one IPC
get_repo_structurerepo_pathRepoStructureFast phase: worktree paths + merged branches only (Phase 1 of progressive loading)
get_repo_diff_statsrepo_pathRepoDiffStatsSlow phase: per-worktree diff stats, last commit timestamps, and workspace_statuses keyed by opaque workspace id (Phase 2 of progressive loading)
run_git_commandpath, argsGitCommandResultRun allowlisted git command (success, stdout, stderr, exit_code)
get_git_panel_contextpathGitPanelContextRich context for Git Panel (branch, ahead/behind, staged/changed/stash counts, last commit, rebase/cherry-pick state). Cached 5s TTL.
get_working_tree_statuspathWorkingTreeStatusFull porcelain v2 status: branch, upstream, ahead/behind, stash count, staged/unstaged entries, untracked files
update_from_basepath, branch_name, strategy?StringFetch configured base ref and rebase or merge the branch onto it. Conflict cleanup reports (aborted) only after abort succeeds; abort failure includes manual recovery guidance.
git_stage_filespath, files()Stage files (git add). Path-traversal validated
git_unstage_filespath, files()Unstage files (git restore --staged). Path-traversal validated
git_discard_filespath, files()Discard working tree changes (git restore). Destructive. Path-traversal validated
git_commitpath, message, amend?String (commit hash)Commit staged changes; optional --amend. Returns new HEAD hash
get_commit_logpath, count?, after?Vec<CommitLogEntry>Paginated commit log (default 50, max 500). after is a commit hash for cursor-based pagination
get_stash_listpathVec<StashEntry>List stash entries (index, ref_name, message, hash)
git_stash_applypath, index()Apply stash entry by index
git_stash_poppath, index()Pop stash entry by index
git_stash_droppath, index()Drop stash entry by index
git_stash_showpath, indexStringShow diff of stash entry
git_apply_reverse_patchpath, patch, scope?()Apply a unified diff patch in reverse (git apply --reverse). Used for hunk/line restore. scope="staged" adds --cached. Patch passed via stdin (no temp files). Path-traversal validated
get_file_historypath, file, count?, after?Vec<CommitLogEntry>Per-file commit log following renames (default 50, max 500)
get_file_blamepath, fileVec<BlameLine>Per-line blame: hash, author, author_time (unix), line_number, content
get_branches_detailpathVec<BranchDetail>Rich branch listing: name, ahead/behind, last commit date, tracking upstream, merged status
delete_branchpath, name, force()Delete a local branch. force=false uses the shared integration proof and compares the ref with its proved tip; content-based proof requires an exact-tip archive. force=true preserves the exact tip at refs/archive/<branch> before deleting, archives at refs/archive/<branch>-<sha7> when that name holds a different tip, and cannot delete a checked-out branch. Refuses to delete the current branch or default branch
create_branchpath, name, start_point, checkout()Create a new branch from start_point (defaults to HEAD). checkout=true switches to it immediately
get_recent_branchespath, limitVec<String>Recently checked-out branches from reflog, ordered by recency

Commit Graph (git_graph.rs)

CommandArgsReturnsDescription
get_commit_graphpath, count?Vec<GraphNode>Lane-assigned commit graph for visual rendering. Default 200, max 1000. Returns hash, column, row, color_index (0–7), parents, refs, and connection metadata (from/to col/row) for Bezier curve drawing

GitHub Authentication (github_auth.rs)

CommandArgsReturnsDescription
github_start_login—DeviceCodeResponseStart OAuth Device Flow, returns user/device code
github_poll_logindevice_codePollResultPoll for token; saves to keyring on success
github_logout—()Delete OAuth token from keyring, fall back to env/CLI
github_auth_status—AuthStatusCurrent auth: login, avatar, source, scopes
github_disconnect—()Disconnect GitHub (clear all tokens from keyring and env cache)
github_diagnostics—JSONDiagnostics: token sources, scopes, API connectivity

GitHub Integration (github.rs)

CommandArgsReturnsDescription
get_github_statuspathGitHubStatusPR + CI for current branch
get_ci_checkspathVec<JSON>CI check details
get_pr_review_threadspath, pr_number{bot, human}Unresolved review threads of one PR, split bot vs human
get_repo_pr_statusespath, include_mergedVec<BranchPrStatus>Batch PR status (all branches)
approve_prrepo_path, pr_numberStringSubmit approving review via GitHub API
update_pr_branchrepo_path, pr_number, expected_head_sha()Update a BEHIND PR branch from its base, pinned to the shown head
close_prrepo_path, pr_number()Close a PR without merging
merge_pr_via_githubrepo_path, pr_number, merge_method, expected_head_shaStringMerge PR via GitHub API, pinned to the reviewed head
get_all_pr_statusespathVec<BranchPrStatus>Batch PR status for all branches (includes merged)
get_pr_diffrepo_path, pr_numberStringGet PR diff content
get_merged_prsrepo_path, since_tag?Vec<MergedPr>Merged PRs via GraphQL, optionally since a tag’s date
start_conflict_assistrepo_path, pr_numberConflictAssistResultWorktree on PR head + rebase onto base; reports verified/unverified clean or conflicts, base provenance/warning, and agent prompt (push gated, never auto-merge)
fetch_ci_failure_logsrepo_path, branch, check_url?, head_sha?StringFetch failed-job logs for the local branch head, or select a check at the supplied PR head SHA
circleci_token_status—CircleCiTokenStatusReport token presence and source without returning the token
circleci_set_tokentoken()Store a read-only CircleCI token
circleci_delete_token—()Remove the stored CircleCI token
check_github_circuitpathCircuitStateCheck GitHub API circuit breaker state

Review, Changelog and Improvement Scan (pr_review.rs, changelog.rs, improvement_scan.rs)

Each of the first three is one unattended acp::oneshot turn (#795-320b): the whole input goes inline, ego is offered no host tools, and every permission request is refused. No API key is stored and no provider HTTP call is made from TUICommander; which model runs is ego’s own configuration. An ego that cannot be reached is an error carrying ego’s own sentence, never an empty result.

CommandArgsReturnsDescription
run_pr_reviewrepo_path, pr_numberPrReviewResultReview a PR’s diff. Findings under the confidence threshold (default 0.7, TUIC_REVIEW_CONFIDENCE_THRESHOLD overrides) are dropped before the result is built. Emits review-progress
generate_changelogrepo_path, since_tag?ChangelogResultChangelog over the merged PRs since a tag. { markdown, json }; json is null when ego answered in prose only
run_improvement_scanrepo_path, focusImprovementScanResultUp to five proposals for refactor, testing or perf. Emits proposals-ready
create_issue_from_proposalrepo_path, proposalCreatedIssueFile one proposal as a GitHub issue through gh. No model call

Worktree Management (worktree.rs)

CommandArgsReturnsDescription
create_worktreebase_repo, branch_name, create_branch?, base_ref?{ status: "ok", name, path, workspace_id, branch, base_repo, instructions }Create a linked worktree and start warming in the background. instructions.warm_artifacts.status is pending, matching HTTP/MCP. Parent tracked changes are not carried over.
remove_worktreerepo_path, workspace_id, delete_branch?, force?, override_lock?, expected_fingerprint?, confirm_missing_checkout?{ branch_delete_warning?: string, branch: string, removal_rule: string }Remove a linked worktree by workspace_id. Branch deletion defaults to true, or false when force is true. Without force, a clean checkout and submodules with no Git operation in progress are required even when the branch is kept. force permits discarding dirty files but does not skip branch proof or override a lock; override_lock is separate. A live checkout requires expected_fingerprint for force removal. A missing registered checkout instead requires force and explicit confirm_missing_checkout; its absence is rechecked before cleanup and module refs are preserved before pruning. Branch deletion uses the same integration proof as MCP, including no-op merges, corroborated squash messages and archived content heuristics, alongside ancestry, patch equivalence and verified merged GitHub PRs; it uses the captured OID and warns if the proof fails or the ref moves. Keeping the branch skips only branch proof. Before Git removes a live checkout, owner write permission is restored inside it so read-only ignored artifacts cannot block deletion. A leftover unregistered directory is reported with its path. removal_rule names the matching rule.
delete_local_branchrepo_path, branch_name, workspace_id, keep_worktree?()Delete a local branch and dispose of the workspace workspace_id names. Two identifiers because there are two objects: branch_name is the ref to delete, workspace_id the checkout holding it. Refuses to delete the default branch, and refuses when the resolved workspace is on a different branch than the one asked for. Uses safe git branch -d
check_worktree_dirtyrepo_path, workspace_idboolCheck if the workspace workspace_id names has uncommitted changes. Addressed by id because the answer gates an irreversible cleanup — a sibling on the same branch being clean must never authorise destroying this one. Returns false if the id resolves to no checkout. When git cannot answer (the worktree list or status call fails) it returns an error, never false — callers that gate a destructive action must see the failure
get_worktree_pathsrepo_pathHashMap<String, { branch, path, kind: "worktree", warm_artifacts }>Every linked worktree of a repo, keyed by workspace id. warm_artifacts.status is pending, done, or failed.
get_worktrees_dir–StringWorktrees base directory
generate_worktree_name_cmdexisting_namesStringGenerate unique name
list_local_branchespathVec<String>List local branches
checkout_remote_branchrepo_path, branch_name()Check out a remote-only branch as a new local tracking branch
detect_orphan_worktreesrepo_pathVec<String>Detect worktrees in detached HEAD state (branch deleted)
assess_orphan_cleanuprepo_pathVec<{ path, safe, reason?, live_sessions? }>Classify every orphan for automatic removal using tracked/untracked status, branch reachability and live sessions in the checkout.
begin_orphan_cleanuprepo_path, paths()Register the open Ask dialog for an agent answer.
pending_orphan_cleanup_answerrepo_pathbool?Read the pending answer, or null while unanswered.
clear_orphan_cleanuprepo_path()Clear the pending answer when the dialog closes.
remove_orphan_worktreerepo_path, worktree_path, safe_only?, confirmed_sessions?()Remove a registered detached orphan by filesystem path. With safe_only, recheck clean status, branch reachability and live sessions immediately before removal. Without it, refuse when a live session in the checkout is not in confirmed_sessions (the session ids the user saw).
switch_branchrepo_path, branch_name()Switch main worktree to a different branch (with dirty-state and process checks)
merge_and_archive_worktreerepo_path, branch_name, workspace_id, target_branch, after_merge, force?, expected_fingerprint?MergeArchiveResultMerge worktree branch into base and archive or delete. A pre-flight counts commits and checks the exact checkout. For archive or delete, an unverified or dirty checkout or one with a live session returns action: "needs_confirmation" before merging. Re-call with force: true and the confirmed lifecycle expected_fingerprint to proceed; a changed fingerprint aborts. A locked checkout is not archived. If conflict cleanup abort fails, the error includes the manual abort command.
finalize_merged_worktreerepo_path, workspace_id, action, force?, expected_fingerprint?MergeArchiveResultClean up after a completed merge. Uses the same lifecycle review as one-click cleanup and also requires merged commit status before automatic cleanup. Without force, a dirty, unverified, or live checkout returns action: "needs_confirmation" (merged: true — only cleanup stopped). Force requires the confirmed lifecycle expected_fingerprint and rejects changed state. A lock stops archiving. Delete may include branch_delete_warning if safe branch deletion kept the branch.
get_workspace_lifecyclerepo_path, workspace_id{ dirty_files, untracked_files, live_sessions, warnings, missing_checkout, dirty_fingerprint?, submodule_unpushed_commits, commit_status, removal_safety, error? }Fresh workspace-id-addressed removal preflight. missing_checkout: true identifies a registered checkout whose directory is gone; it has no dirty fingerprint and requires force confirmation. dirty_files counts files a removal discards (null when unavailable — not 0); commit_status is unmerged, in_sync, merged, or unknown; removal_safety is safe, requires_force, or unknown. Unknown never authorizes removal. HTTP twin: GET /worktrees/lifecycle.
list_base_ref_optionsrepo_pathVec<String>List valid base refs for worktree creation
run_setup_scriptscript, cwdJSONRun a setup script through sh -c / cmd /C in cwd; returns exit code and captured output
generate_clone_branch_name_cmdbase_name, existing_namesStringGenerate hybrid branch name for clone worktree

Configuration (config.rs)

CommandArgsReturnsDescription
load_app_config–AppConfigLoad app settings
save_app_configbase, config()Save app settings
load_notification_config–NotificationConfigLoad notifications
save_notification_configbase, config()Save notifications
show_native_notificationtitle, body, target()macOS desktop-only alert that retains the Notification Center click and emits native-notification-click for a terminal or Progress target; browser/remote clients cannot call it
load_ui_prefs–UIPrefsConfigLoad UI preferences
save_ui_prefsbase, config()Save UI preferences
get_config_defaults–ConfigDefaultsRead-only defaults for Settings “expert mode”
load_repo_settings–RepoSettingsMapLoad per-repo settings
save_repo_settingsbase, config()Save per-repo settings
check_has_custom_settingspathboolHas non-default settings
load_repo_defaults–RepoDefaultsConfigLoad repo defaults
save_repo_defaultsbase, config()Save repo defaults
load_repositories–JSONLoad saved repositories
save_repositoriesconfig (mutationVersion: 1 keyed delta)()Apply repository/group/order/active-selection changes to the latest locked document; same-record conflicts are returned to the caller
list_stale_temp_repository_candidates–StaleTempCandidate[] ({path, displayName})Read-only preview of rows classified as stale-temp ghosts (#763-d219); never mutates
repair_stale_temp_repositoriespaths (string[])StaleTempRepairSummary ({removed, backupPath})Re-validates every path against the classifier on the current on-disk document, refusing the whole request if any no longer matches, then removes the validated rows in one transactional write after backing up the pre-repair document
load_prompt_library–PromptLibraryConfigLoad prompts
save_prompt_librarybase, config()Save prompts
load_notes–JSONLoad notes
save_notesbase, config()Save notes
save_note_imagenote_id, data_base64, extensionString (absolute path)Decode base64 image, validate ≤10 MB, write to config_dir()/note-images/<note_id>/<timestamp>.<ext>
delete_note_assetsnote_id()Remove note-images/<note_id>/ directory recursively (no-op if missing)
get_note_images_dir–StringReturn config_dir()/note-images/ absolute path
load_keybindings–JSONLoad keybinding overrides
save_keybindingsbase, config()Save keybinding overrides
load_agents_config–AgentsConfigLoad per-agent run configs, including optional model defaults, and prevent_alt_screen overrides
save_agents_configbase, config()Save per-agent run configs, including optional model defaults, and prevent_alt_screen overrides
get_agent_native_status_signalsagent_typeboolRead the default-on Claude/Codex launch-scoped status setting
set_agent_native_status_signalsagent_type, enabled()Change launch-scoped status injection for future sessions
load_activity–ActivityConfigLoad activity dashboard state
save_activitybase, items()Save activity dashboard state
load_repo_local_configrepo_pathRepoLocalConfig?Read .tuic.json from repo root; returns null if absent or malformed
save_repo_local_configrepo_path()Write the repo’s effective resolved worktree/branch settings (global defaults + per-repo overrides) to .tuic.json at its root (committable, team-shareable). Preserves fields already in the file (e.g. mcp_upstreams); never writes script fields

SSH Tunnels (tunnels/tauri_commands.rs)

CommandArgsReturnsDescription
list_tunnel_profiles–Vec<TunnelProfile>Load all tunnel profiles (global + per-repo merged)
save_tunnel_profileprofile: JSONString (profile ID)Create or update a tunnel profile. Auto-generates UUID if id is empty. Validates before saving
delete_tunnel_profileidboolDelete a tunnel profile by ID. Stops the tunnel if running
start_tunnelidStringStart a tunnel by profile ID. Loads the profile, validates, and spawns the SSH process
stop_tunnelid()Stop a running tunnel by profile ID
list_active_tunnels–Vec<JSON>List all active tunnels with ID, status, and started_at
get_tunnel_statusidJSONGet the current status of a specific tunnel (starting, connected, reconnecting, stopped, error)
list_ssh_config_hosts–Vec<String>Parse ~/.ssh/config and return all non-negated, non-wildcard Host entries
list_discovered_ssh_hosts–DiscoveredSshHostsList non-wildcard ~/.ssh/config aliases and plain ~/.ssh/known_hosts names deduplicated by resolved host and port; hashed known_hosts entries are counted in hashed_count
probe_discovered_ssh_hosttarget, port?SshHostStatusProbe one discovered entry (known_hosts entries use StrictHostKeyChecking=yes); refuses a host not in the discovered list
probe_ssh_config_hosts–Vec<SshHostStatus>Probe the ~/.ssh/config aliases (known_hosts names excluded) with bounded concurrency and classify shell, no-shell, authentication-failed and unreachable results
get_tunnel_auditid, limit?Vec<JSON>Query audit log events for a tunnel (default limit 20). Returns timestamp, kind, and extracted message
list_ssh_agent_keys–SshAgentInfoDetect SSH agent type (1Password, Secretive, GPG, generic) and list loaded keys via ssh-add -l

Remote Connections (remote_connection.rs)

CommandArgsReturnsDescription
list_remote_connections–Vec<RemoteConnection>Load every configured remote machine from connections.json
save_remote_connectionbase, connection()Create with null base or update a remote machine from its loaded snapshot; merges changed fields into the latest record under the config file lock
delete_remote_connectionid()Tear down and delete a remote machine, both vault credentials, and its ephemeral daemon best-effort; an installed service is left for explicit uninstall
set_remote_connection_passwordid, password()Store the Basic Auth password in the OS credential vault, or forget it when password is empty. Never written to connections.json
remote_connection_password_existsidboolWhether a password is stored. The password itself is never readable — this and the token exchange are the only answers given about it
fetch_remote_connection_tokenid, baseUrl, usernameStringTrade the stored password for the daemon’s in-memory session token over GET /api/auth/session-token. Runs in the backend so the password never reaches the WebView. Re-run on every connect: the daemon mints a new token on restart
install_remote_daemonid()Stage the matching daemon and install/start a systemd user unit or launchd agent, then persist deploy = installed
uninstall_remote_daemonid()Stop and remove the systemd/launchd service files and persist deploy = on_connect

Remote Connection Runtime (remote_runtime.rs)

remote_connection.rs above says what a connection is; these say whether it is up. The state machine — health probe, token exchange, status poll, SSH tunnel and base URL — runs in Rust so that backend tasks, not only the WebView, can reach a remote daemon.

CommandArgsReturnsDescription
connect_remote_connectionid()Bring a connection up. SSH connections may deploy a matching loopback-only daemon first, then authenticate with the vault pairing token; direct and unmanaged connections use the stored password exchange. Idempotent while connecting or connected, so a double click opens one tunnel. Every transition is announced as a remote-connection-status event
disconnect_remote_connectionid()Stop the status poll, forget the token, stop the tunnel
remote_connection_statuses–Vec<RemoteConnectionStatus>Live status of every connection. base_url, token and protocol_version are present only while connected; update_in_progress is true during a manual or unattended update. A disconnected machine has no route to hand out
prepare_remote_updateidUpdatePreviewSelect the release or matching local daemon binary and report both build identities and the live session count
update_and_restart_remoteid, confirmedSessions, expectedSha256UpdatePreviewCheck the confirmation, update by Direct upload or SSH deployment, and verify the new build after reconnect

Agent Detection (agent.rs)

CommandArgsReturnsDescription
detect_agent_binarybinaryAgentBinaryDetectionCheck binary name in PATH or an exact absolute path, version, and cached supports_no_alt_screen help probe
prepare_agent_launch_argsagent_type, binary_path, argsVec<String>Add a supported native-scrollback flag according to the agent setting; probes in a blocking worker with a deadline. HTTP parity: POST /agents/launch-args
detect_all_agent_binariesbinariesHashMap<String, AgentBinaryDetection>Detect the named binaries in parallel, path only (no version or screen-capability lookup)
detect_claude_binary–StringDetect Claude binary
detect_installed_ides–Vec<String>Detect installed IDEs
open_in_apppath, app, line?, col?()Open path in application; line/col are used only by editors that support them
spawn_agentpty_config, agent_configString (session ID)Spawn agent in PTY

Agent Session Discovery (agent_session.rs)

CommandArgsReturnsDescription
discover_agent_sessionagent_type, cwd, claimed_ids, agent_pid, env_overridesOption<{ sessionId, launchCommand }>Discover the agent’s session UUID for session-aware resume. Claude and grok resolve it exactly from their pid→session registry when agent_pid is known; every other agent (and any Claude/grok too old to publish one) falls back to the newest unclaimed session file, which cannot tell two tabs in one folder apart. launchCommand is the command the live process really runs, rebuilt from its argv and env (CLAUDE_CONFIG_DIR=… claude --dangerously-skip-permissions) — a shell alias is expanded before exec, so it is the only record of which config dir holds the session. null for agents with no verified session-flag list, and on Windows, where argv is unreadable
verify_agent_sessionagent_type, session_id, cwd, agent_pid, env_overridesboolVerify that the session file exists in the agent’s selected profile. A live PID can supply process environment; saved launch environment selects the profile after restart. HTTP parity: POST /agents/verify-session

Panel Windows (panel_window.rs)

Detaching a panel into its own OS window. Used by the AI Chat panel, the Activity Dashboard and the Git panel.

CommandArgsReturnsDescription
open_panel_windowpanel_id, title?, params?, width?, height?()Open (or focus) a detached panel window. panel_id becomes the window label prefix (panel-{id}). URL: /?mode=panel&panel={id}&{params}. Emits panel-window-closed { panelId } on destroy
close_panel_windowpanel_id()Close a detached panel window by ID
focus_main_window—()Bring the main window to foreground (used by detached panels after cross-window actions)

The embedded AI engine is gone (#784-0aec)

There is no ai_chat.rs, ai_chat_registry.rs, provider_registry.rs, llm_api.rs, diff_triage.rs, improvement_scan.rs or changelog.rs, and ai_agent/ holds only knowledge.rs and tui_detect.rs. Every command those modules registered is unregistered, every /ai/* route is unmounted, and the matching COMMAND_TABLE entries are removed from src/transport.ts. TUICommander makes no provider HTTP call and stores no model API key.

ego supplies the intelligence over ACP — see ACP client for ego below. What comes back where is tabulated in docs/sync-matrix.md under What #784-0aec removed.

Command knowledge is the one thing that stayed, because recording it involves no model: pty.rs still writes CommandOutcome rows per session and ai_agent::knowledge::spawn_persist_task still flushes them to <config_dir>/ai-sessions/<session_id>.json. No command reads them back — the get_session_knowledge, list_knowledge_sessions and get_knowledge_session_detail accessors went with the UI that called them.

MCP OAuth 2.1 (mcp_oauth/commands.rs)

OAuth 2.1 authorization for upstream MCP servers. Full RFC 9728 (Protected Resource Metadata) + RFC 8414 (Authorization Server Discovery) flow with PKCE S256. Completion via the tuic://oauth-callback deep link.

CommandArgsReturnsDescription
start_mcp_upstream_oauthname: StringStartOAuthResponseBegin an OAuth flow for the named upstream. Transitions status to authenticating, returns the authorization URL + AS origin for the consent dialog. PKCE challenge is generated and stored per pending flow
mcp_oauth_callbackcode: String, oauth_state: String()Consume the tuic://oauth-callback?code=…&state=… deep link. Exchanges the code for tokens, persists OAuthTokenSet to the OS keyring, transitions upstream to connecting
cancel_mcp_upstream_oauthname: String()Abort an in-flight OAuth flow. Drops the pending entry and resets upstream status

MCP Upstream Proxy (mcp_upstream_config.rs, mcp_upstream_credentials.rs)

Commands for managing upstream MCP servers proxied through TUICommander’s /mcp endpoint.

CommandArgsReturnsDescription
load_mcp_upstreams–UpstreamMcpConfigLoad upstream config from mcp-upstreams.json
save_mcp_upstreamsbase: UpstreamMcpConfig, config: UpstreamMcpConfig()Apply the caller’s ID-keyed base-to-config delta to the latest locked mcp-upstreams.json, validate it, and hot-reload the exact persisted change. Removing a server or its optional auth field is an explicit deletion; unrelated concurrent changes are preserved
reconnect_mcp_upstreamname: String()Disconnect and reconnect a single upstream by name. Useful after credential changes or transient failures
get_mcp_upstream_status–Vec<UpstreamStatus>Get live status of all upstream MCP servers. Status values: connecting, ready, circuit_open, disabled, failed, authenticating, needs_auth
save_mcp_upstream_credentialname: String, token: String, url: String, header?: {name, credential_ref}()Store a Bearer token or scoped header secret with its intended HTTP origin in the OS credential vault
delete_mcp_upstream_credentialname: String, header?: {name, credential_ref}()Remove a Bearer/OAuth token or a scoped custom header secret (idempotent)

UpstreamMcpConfig schema

interface UpstreamMcpConfig {
  servers: UpstreamMcpServer[];
}

interface UpstreamMcpServer {
  id: string;              // Unique UUID, used for config diff tracking
  name: string;            // Namespace prefix — must match [a-z0-9_-]+
  transport: UpstreamTransport;
  enabled: boolean;        // Default: true
  timeout_secs: number;    // Default: 30 (0 = no timeout, HTTP only)
  tool_filter?: ToolFilter; // Optional allow/deny filter
}

type UpstreamTransport =
  | { type: "http"; url: string }
  | { type: "stdio"; command: string; args: string[]; env: Record<string, string> };

interface ToolFilter {
  mode: "allow" | "deny";
  patterns: string[];  // Exact names or trailing-* glob prefix patterns
}

Upstream status values

The live registry exposes status via SSE events (upstream_status_changed). Valid status strings:

ValueMeaning
connectingHandshake in progress
readyTools available
circuit_openCircuit breaker open, backoff active
disabledDisabled in config
failedPermanently failed, manual reconnect required

Agent MCP Configuration (agent_mcp.rs)

CommandArgsReturnsDescription
get_agent_mcp_statusagentAgentMcpStatusCheck MCP config for an agent
install_agent_mcpagentStringInstall TUICommander MCP entry
remove_agent_mcpagentStringRemove TUICommander MCP entry
get_agent_config_pathagentStringGet agent’s MCP config file path
get_mcp_bridge_info—McpBridgeInfoBridge path + ready-to-paste JSON config snippet

Prompt Processing (prompt.rs)

CommandArgsReturnsDescription
extract_prompt_variablescontentVec<String>Parse {var} placeholders
process_prompt_contentcontent, variablesStringSubstitute variables
resolve_context_variablesrepo_path: StringHashMap<String, String>Resolve git context variables (branch, diff, changed_files, commit_log, etc.) for smart prompt substitution. Best-effort: variables that fail are omitted

Smart Prompt Execution (smart_prompt.rs)

CommandArgsReturnsDescription
execute_headless_promptcommand: String, args: Vec<String>, stdin_content: Option<String>, timeout_ms: u64, repo_path: String, env: Option<HashMap<String,String>>Result<String, String>Spawn a one-shot agent process in argv form (no shell — metacharacters in args are literal). Prompt content piped via stdin. Timeout capped at 5 minutes
execute_shell_scriptscript_content: String, timeout_ms: u64, repo_path: StringResult<String, String>Execute shell script content directly via platform shell (sh/cmd). No agent involved — runs the content as-is. Captures stdout. Timeout capped at 60 seconds

Claude Usage (claude_usage.rs)

CommandArgsReturnsDescription
get_claude_usage_apisessionId?UsageApiResponseFetch rate-limit usage for the Claude session’s credential profile; omitted session selects the default profile
get_claude_usage_timelinescope, days?Vec<TimelinePoint>Hourly token usage from session transcripts
get_claude_session_statsscopeSessionStatsAggregated token/session stats from JSONL transcripts
get_claude_project_list–Vec<ProjectEntry>List project slugs with session counts
get_codex_usage_api–CodexUsageApiResponseFetch rate-limit usage through the official Codex App Server
get_codex_usage_stats–CodexStatsResponseFetch daily token history and supported lifetime stats through the Codex App Server
get_grok_usage_api–GrokUsageApiResponseFetch billing-period usage through Grok Build’s _x.ai/billing ACP extension
set_terminal_theme_colorsforeground: [u8;3], background: [u8;3], cursor: [u8;3]()Publish the resolved terminal theme so the emulator can answer OSC 10/11/12 colour queries

scope values: "all" (all projects) or a specific project slug. days defaults to 7.

Uses incremental parsing with a file-size-based cache (claude-usage-cache.json) so only newly appended JSONL data is processed on each call. The cache is persisted across app restarts.

Voice Dictation (dictation/)

These commands stay in the root dictation/commands.rs adapter; their audio and speech operations use tuic-dictation. The command names and payloads are unchanged by the crate split.

CommandArgsReturnsDescription
start_dictationsource? ("fn", "hotkey", "ui")()Start recording; Fn starts are refused after native key release
stop_dictation_and_transcribe–TranscribeResponseStop + transcribe. Returns {text, skip_reason?, duration_s, truncated_s}; a capture without sustained speech returns no sustained speech before Whisper, a final transcription skip keeps its specific reason, an empty successful result says no speech detected, and truncated_s counts captured audio lost before transcription
inject_texttextStringApply corrections
get_dictation_status–DictationStatusModel/recording status plus normalized audio_level (0–1)
get_model_info–Vec<ModelInfo>Available models
download_whisper_modelmodel_nameStringDownload model
delete_whisper_modelmodel_nameStringDelete model
get_speech_assets–Vec<SpeechAssetInfo>The ONNX runtime, the speech languages, then every catalogue voice (kind: "voice", with language and voice), each absent/downloading/incomplete/ready
download_speech_assetassetStringDownload and install, verifying every pinned sha256. asset is an id from the catalogue allowlist
cancel_speech_downloadassetStringAbandon a download in flight
delete_speech_assetassetStringUnload the engine, then remove the files
get_speech_voiceslanguageVec<VoiceChoice>The voices a language (Whisper code) can speak with now: { id, source } with source "default", "downloaded" or "user"; empty while the language is not fully downloaded
import_speech_voicelanguage, name, dataBase64StringStore a user voice file (base64) at <speech>/user-voices/<language>/<name>.safetensors. Refused with the reason for a bad name, a catalogue voice name, more than 64 MB, a file that is not safetensors, or a voice that does not fit the language’s model
delete_speech_voicelanguage, nameStringRemove a user voice file. Absent is success
preview_speech_voicelanguage, voice, text()Speak text (max 200 characters) in voice on this machine’s speaker with the saved loudness. Needs no hands-free conversation and does not change speech_voice. Refused while a hands-free reply is queued, rendering or playing
speak_replytext, turn?SpokenReplyQueue one spoken reply, max 2000 characters. Returns state: "queued" — never "finished"; poll get_speech_status with the id. turn refuses a reply written for a turn the user talked over
stop_speech–SpeechStatusStop now, drop the queue, open a new turn. Returns the status so the caller learns that turn
pause_speech–SpeechStatusHold the reply where it is; paused true, speaking false. No-op with nothing playing
resume_speech–SpeechStatusContinue a reply the user held
get_speech_statusutterance?SpeechStatusWhether anything can be spoken, and optionally what became of one reply. An id no longer remembered reports state: "unknown". language is the conversation’s language — empty under auto before the first turn, which is the one state in which nothing can be spoken
get_correction_map–HashMap<String,String>Load corrections
set_correction_mapmap()Save corrections
list_audio_devices–Vec<AudioDevice>List input devices
get_dictation_config–DictationConfigLoad saved config. With an activation phrase, the hands-free runtime applies at least 5000 ms of hold-back even when the saved hands_free_hold_back_ms is shorter; hands-free status reports the effective value
get_hands_free_default_notice–stringThe built-in hands-free start notice, sent while hands_free_start_notice is empty
set_dictation_configbase, config()Save only the changes between the loaded base and edited config. A changed language, speechCommand or speech_voice also drops the voice built for the previous one, cancelling what it was speaking; hands_free_spoken_replies=false also cancels it and refuses new speech while dictation stays armed. Edge 401/403 rejection makes speech unavailable for five minutes. Other fields leave the voice alone. hands_free_earcons (default true) turns the hands-free earcons off; only the frontend reads it. hands_free_notify_model (default true) is read at arm time only — turning it off mid-conversation does not cancel the end notice the model is already owed. hands_free_start_notice (default empty = built-in text) replaces the start notice, also at arm time only, folded to one line
check_microphone_permission–StringCheck macOS microphone TCC permission status
open_microphone_settings–()Open macOS System Settings > Privacy > Microphone

Native file dialogs (native_dialog.rs)

Desktop-only, therefore INTENTIONALLY_UNMAPPED in transport.ts: the panel browses the host’s filesystem, and a remote client uses the in-app file browser instead.

CommandArgsReturnsDescription
pick_pathkind ("file"|"files"|"folder"|"save"), title?, defaultPath?, fileName?, filters?Option<Vec<String>>Open a native file/folder/save panel. null when the user cancels; always an array otherwise, even for a single pick. Err — never a crash — when the panel cannot be built

Call it through src/utils/nativeDialog.ts (openDialog/saveDialog), not directly, and do not import open/save from @tauri-apps/plugin-dialog. The plugin builds NSOpenPanel/NSSavePanel inside its own main-thread closure, so when AppKit’s window-server link is interrupted — the state the Mac wakes into after standby — the binding’s NULL check panics on the main thread and the process dies with every live PTY session. native_dialog.rs owns that closure so the unwind is caught and returned as an error. The plugin’s confirm/message are unaffected (they build NSAlert) and stay as they are.

Filesystem (fs.rs)

upload_attachment is the desktop IPC twin of POST /attachments/upload. It accepts kind, id, name, and binary bytes, returns the same { path, size } receipt, and uses the same destination, cap, and cleanup rules.

CommandArgsReturnsDescription
resolve_terminal_pathcwd, candidateOption<ResolvedFilePath>Resolve one terminal path candidate against cwd; null on a miss
resolve_terminal_pathscwd, candidatesVec<Option<ResolvedFilePath>>Batched form, answered positionally: entry i is the result for candidates[i]. One IPC round-trip per terminal screen instead of one per candidate
resolve_markdown_linkroot, currentFile, hrefMarkdownLinkTargetDecode and resolve a rendered Markdown link relative to its file; return a heading, file, missing path, or blocked network path. Runs filesystem work on the blocking pool
list_directorypathVec<DirEntry>List directory contents
get_home_directory—StringReturn this machine’s home directory for local or remote browsing
fs_read_filepathStringRead file contents
write_filepath, content()Write file
write_file_if_unchangedrepo_path, file, expected, contentboolWrite only when the file still equals expected; false = changed on disk, nothing written (mobile Markdown review)
create_directorypath()Create directory
delete_pathpath()Delete file or directory
rename_pathsrc, dest()Rename/move path
copy_pathsrc, dest()Copy file or directory
copy_path_absfrom, to()Copy a file by absolute paths (cross-repo paste). Rejects directories.
move_path_absfrom, to()Move a file by absolute paths (cross-repo cut+paste); copy+remove fallback across filesystems.
fs_transfer_remote_pathsconnectionId, destDir, paths, allowRecursiveTransferResultSender-side coordinator for copying local OS paths onto a connected remote repository using its existing endpoint/token. Streams bounded archives; preserves recursion confirmation and skips existing names. Desktop IPC only (INTENTIONALLY_UNMAPPED): data leaves the machine; Finder source paths cannot be gated to registered roots; HTTP token holders must not trigger exfiltration.
fs_transfer_pathsdestDir, paths, mode ("move"|"copy"), allowRecursiveTransferResult { moved, skipped, errors, needs_confirm }Move/copy OS paths into a destination directory. Skips silently on name conflicts; returns needs_confirm=true (no-op) when a source is a directory and allowRecursive=false. Used by the drag-drop handler when dropping files onto a folder in the file browser.
add_to_gitignorepath, pattern()Add pattern to .gitignore
search_filespath, queryVec<SearchResult>Search files by name in directory
search_contentrepoPath, query, searchId, caseSensitive?, useRegex?, wholeWord?, limit?()Full-text content search; streams results progressively via content-search-batch events, each echoing searchId. Binary files and files >1 MB are skipped. Supports cancellation.
search_content_allquery, searchId, caseSensitive?, limit?()Cross-repo BM25 content search over every ready index; streams via the same content-search-batch events with each match tagged repo_path and every batch echoing searchId. Only repos whose index is built participate (depends on Content Indexing strategy). Shares the cancellation slot with search_content.
warm_content_indexrepoPath()Build a repo’s content index in the background, invoked on repo switch. Strategy-gated: under disabled or active_only it returns without scheduling anything, so a repo switch cannot index behind a setting that asked it not to. The POST /fs/warm-index route applies the same gate.

search_content_all reports why a repo produced nothing, so the UI can tell “no match” apart from “not searched yet”. Every ContentSearchResult and every content-search-batch carries repos_searched, repos_pending, and repos_indexing — the last being the subset of repos_pending with a build actually in flight. Only that subset justifies telling the user to retry; the rest are waiting on a scheduling event that may never come.

For both commands, every ContentMatch.match_start/match_end pair is a zero-based, end-exclusive UTF-16 code-unit range within line_text, matching JavaScript String.slice semantics for ASCII, accented text, and non-BMP emoji.

Plugin Management (plugins.rs)

CommandArgsReturnsDescription
list_user_plugins–Vec<PluginManifest>List valid plugin manifests
get_plugin_readme_pathidOption<String>Get plugin README.md path
read_plugin_dataplugin_id, pathOption<String>Read plugin data file
write_plugin_dataplugin_id, path, content()Write plugin data file
delete_plugin_dataplugin_id, path()Delete plugin data file
install_plugin_from_zippathPluginManifestInstall from local ZIP
install_plugin_from_urlurlPluginManifestInstall from HTTPS URL
uninstall_pluginid()Remove plugin and all files
install_plugin_from_folderpathPluginManifestInstall from local folder
register_loaded_pluginplugin_id()Register a plugin as loaded (for lifecycle tracking)
unregister_loaded_pluginplugin_id()Unregister a plugin (on unload/disable)
set_plugin_output_watchersclient_id, seq, watchers: [{ id, pattern, flags }]{ applied, rejected }Replace the OutputWatcher set of one frontend — the patterns the PTY reader thread matches lines against. The frontend pushes its whole set on every add or remove; sets are per client_id, and seq orders the mutations so a stale sync answers applied: false and changes nothing. Tauri IPC sets are released when their WebView navigates or closes. Browser clients have no reliable disconnect signal, so they re-send every 30 s to recover from bounded eviction and keep live sets recent. rejected lists the ids the Rust regex crate cannot compile (lookaround, backreferences, a negated class escape inside a character class); those watchers keep matching in the WebView, which then receives every line.

Plugin Filesystem (plugin_fs.rs)

CommandArgsReturnsDescription
plugin_read_filepath, plugin_idStringRead file as UTF-8 (within $HOME, 10 MB limit)
plugin_read_file_base64path, max_bytes?, plugin_idStringRead file bytes as base64 within $HOME; default 10 MiB, positive custom budgets clamped to 512 MiB
plugin_write_file_base64path, content, max_bytes?, plugin_id()Atomically replace a file from base64 bytes within $HOME; default 10 MiB, positive custom budgets clamped to 512 MiB
plugin_read_file_tailpath, max_bytes, plugin_idStringRead last N bytes of file, skip partial first line
plugin_list_directorypath, pattern?, plugin_idVec<String>List filenames in directory (optional glob filter)
plugin_watch_pathpath, plugin_id, recursive?, debounce_ms?String (watch ID)Start watching path for changes
plugin_unwatchwatch_id, plugin_id()Stop watching a path
plugin_write_filepath, content, plugin_id()Write file within $HOME (path-traversal validated)
plugin_rename_pathsrc, dest, plugin_id()Rename/move path within $HOME (path-traversal validated)

Plugin HTTP (plugin_http.rs)

CommandArgsReturnsDescription
plugin_http_fetchurl, method?, headers?, body?, allowed_urls, plugin_idHttpResponseMake HTTP request (validated against allowed_urls)

Code Intelligence / MDKB (mdkb_commands.rs)

CommandArgsReturnsDescription
mdkb_status—MdkbStatusCheck if mdkb binary is available and daemon connected
mdkb_outlinerepo_path, file_pathVec<OutlineSymbol>Get symbol outline (functions, types) for a file
mdkb_goto_definitionrepo_path, file_path, line, col?DefinitionLocation?Find definition of symbol at position
mdkb_referencesrepo_path, symbol_nameVec<ReferenceLocation>Find all callers of a symbol via code_graph
mdkb_code_findrepo_path, name, kind?CodeFindResultExact symbol lookup by name, optionally filtered by kind. symbols is capped by mdkb; total is the unclamped match count and capped says whether rows were held back (both null when mdkb sent no count)
install_mdkb—StringDownload and install mdkb binary
uninstall_mdkb—()Remove mdkb binary (errors for homebrew/cargo installs)

Line numbers are 1-based on this boundary. mdkb stores symbol ranges 0-based but takes a 1-based line as input to symbol_at_position. mdkb_commands::editor_line shifts every response so line/line_start/line_end reaching the frontend match CodeMirror’s doc.line(n). Request args (mdkb_goto_definition’s line) are already 1-based and pass through unchanged.

Each mdkb method has a different response shape — do not assume “a JSON array of symbols”:

mdkb hook methodresult shape
symbols_in_filetext = stringified bare array
symbol_at_positiontext = stringified object, or the literal "null"
code_findtext = stringified envelope {total, showing, symbols}
code_graphtext = prose for agents; the symbols are a separate symbols array on result

code_graph’s symbols field was added after mdkb 3.7.17. Against an older daemon the field is absent and the call fails loudly — “no callers” is symbols: [], so an absent field can only mean a stale daemon and must never be reported as an empty result.

Plugin CLI Execution (plugin_exec.rs)

CommandArgsReturnsDescription
plugin_exec_clibinary, args, cwd?, plugin_idStringExecute whitelisted CLI binary, return stdout. Allowed: mdkb. 30s timeout, 5 MB limit.

Plugin Credentials (plugin_credentials.rs)

CommandArgsReturnsDescription
plugin_read_credentialservice_name, plugin_idString?Read credential from system store (Keychain/file)

Plugin Registry (registry.rs)

CommandArgsReturnsDescription
fetch_plugin_registry–Vec<RegistryEntry>Fetch remote plugin registry index

Watchers

CommandArgsReturnsDescription
start_head_watcherpath()Watch .git/HEAD for branch changes
stop_head_watcherpath()Stop watching .git/HEAD
start_repo_watcherpath()Watch .git/ for repo changes
stop_repo_watcherpath()Stop watching .git/
start_dir_watcherpath()Watch directory for file changes (non-recursive)
stop_dir_watcherpath()Stop watching directory
set_hot_repospaths: Vec<String>()Set repos with active terminals (cold repos get throttled watchers/polling)

System (lib.rs)

CommandArgsReturnsDescription
load_config–AppConfigAlias for load_app_config
save_configbase, config()Alias for save_app_config
hash_passwordpasswordStringBcrypt hash
list_markdown_filespathVec<MarkdownFileEntry>List .md files in dir
read_filepath, fileStringRead file contents
get_mcp_status–JSONMCP server status plus unfiltered native_tools: [{name, summary, description}] Settings inventory (no token — use get_connect_url for QR)
session_suspend_responserequest_id, ok, reason?()The tab’s verdict on MCP session action=suspend; the MCP call returns it. HTTP: POST /mcp/suspend-response. Unknown or already-answered ids are a no-op
mcp_confirm_responserequest_id, confirmed()Answer a pending ui(action=confirm). HTTP: POST /mcp/confirm-response. Every client is shown the same request and the first answer wins, so an unknown or already-answered id is a no-op, not an error
get_connect_urlipStringBuild QR connect URL server-side (token stays in backend)
check_update_channelchannelUpdateCheckResultCheck beta/nightly channel for updates (hardcoded URLs, SSRF-safe)
clear_caches–()Clear in-memory caches
get_local_ip–Option<String>Get primary local IP
get_local_ips–Vec<LocalIpEntry>List local network interfaces
regenerate_session_token–()Regenerate MCP session token (invalidates all remote sessions)
fetch_update_manifesturlJSONFetch update manifest via Rust HTTP (bypasses WebView CSP)
read_external_filepathStringRead file outside repo (standalone file open)
get_relay_status–JSONCloud relay connection status
get_tailscale_status–TailscaleStateTailscale daemon status (NotInstalled/NotRunning/Running with fqdn, https_enabled)

Global Hotkey

CommandArgsReturnsDescription
set_global_hotkeycombo: Option<String>()Set or clear the OS-level global hotkey. There is no getter: the current combo is the global_hotkey field of AppConfig, read through load_config.

App Logger (app_logger.rs)

CommandArgsReturnsDescription
push_loglevel, source, message()Push entry to ring buffer (survives webview reloads)
get_logslevel?, source?, limit?Vec<LogEntry>Query ring buffer with optional filters
clear_logs–()Flush all log entries

Notification Sound (notification_sound.rs)

CommandArgsReturnsDescription
play_notification_soundsound, volume, device?()Play a Rust rodio notification sound (question, completion, error, warning, info, or attention) on device, or the system default; every tone releases to zero and drains a short silent tail before the output stream closes
block_sleep–()Prevent system sleep
unblock_sleep–()Allow system sleep

ACP client for ego (acp_commands.rs)

Drives an ego agent over the Agent Client Protocol. Every command is a one-line pass-through to AcpClientManager; each has an identical HTTP route (see docs/api/http-api.md) so a browser or the PWA gets the same answers, including the same error bodies. The shared event stream sends turnFailed {message, state} when an accepted prompt later fails; the event envelope identifies its session and turn.

The binary this launches is not an argument. It comes from the ego_executable setting, read at each connect, so no caller over IPC or HTTP can choose what the host runs.

CommandArgsReturnsDescription
acp_workspace_root—StringThe directory AI Chat runs in, from ai_chat_workspace (empty = home directory of this host). A missing folder is created; an unusable one is refused with a message naming the setting
acp_connectrootAcpConnectionSnapshotLaunch the configured ego in root and initialize a connection
acp_reconnectconnectionId, rootAcpConnectionSnapshotSettle the old connection and start a new generation
acp_disconnectconnectionIdAcpConnectionSettlementAsk the child to exit; the snapshot is retained
acp_killconnectionIdAcpConnectionSettlementKill the child without asking
acp_connection_snapshotconnectionIdAcpConnectionSnapshotState, capabilities, attachments, and the journal’s readable range
acp_subscribeconnectionId, afterSequence, channel()Stream AcpStreamFrames over a dedicated Channel. The browser equivalent is a WebSocket, not an HTTP route
acp_session_newconnectionId, authorityAcpAttachmentSnapshotsession/new
acp_session_listconnectionId, cwd?, cursor?ListSessionsResponsesession/list
acp_session_loadconnectionId, sessionId, authorityAcpAttachmentSnapshotsession/load
acp_session_resumeconnectionId, sessionId, authorityAcpAttachmentSnapshotsession/resume
acp_session_forkconnectionId, sessionId, authorityAcpAttachmentSnapshotsession/fork
acp_session_deleteconnectionId, sessionId()session/delete — the session is gone for good
acp_session_closeconnectionId, sessionId()Detach without deleting
acp_session_promptconnectionId, sessionId, prompt, viewedRepo?AcpTurnIdStart a turn or accept it into the server-owned FIFO when one is running. viewedRepo is sent as _meta.tuicommander/viewedRepo, a hint for that turn only
acp_session_cancelconnectionId, sessionId()Cancel the running turn
acp_queued_prompt_cancelconnectionId, sessionId, turnId()Remove one queued prompt before it reaches ego
acp_session_set_config_optionconnectionId, sessionId, configId, valueVec<SessionConfigOption>Set one option; the agent returns the whole resulting set
acp_turn_pauseconnectionId, sessionId, requestIdEgoHoldResponse_ego/pause. state may be pending — the hold has not landed yet
acp_turn_resumeconnectionId, sessionId, requestIdEgoHoldResponse_ego/resume
acp_session_compactconnectionId, sessionId, requestIdEgoCompactResponse_ego/compact. A durability_uncertain publication is never retry-safe
acp_pending_interactionsconnectionIdVec<AcpPendingInteraction>Questions the agent is waiting on, for a client that was not listening when they were asked
acp_respond_permissionconnectionId, requestId, outcomeAcpInteractionSettlementAnswer a session/request_permission
acp_respond_elicitationconnectionId, requestId, actionAcpInteractionSettlementAnswer a session/create_elicitation
acp_one_shot_promptroot, promptEgoTurnOne unattended turn: launch, prompt, shut down. No connection id — it owns the whole lifetime

Errors are an AcpClientError — code, message, connectionId, sessionId, operation, retryable — identical on both transports.

acp_one_shot_prompt is the odd one out and deliberately so. It is what a Smart Prompt in api mode runs on, with no panel open and nobody watching, so its session is opened with no MCP server and every permission request and elicitation is refused the instant it arrives. EgoTurn is { text, stopReason, declined }; declined separates “ego had nothing to say” from “ego wanted a tool this mode cannot grant”. The turn is abandoned after 300s, a server-side constant rather than an argument.

ego command line (ego_cli.rs)

Reads and writes ego’s configuration by running ego, for the Settings → AI Chat page. TUIC stores no API key and makes no provider HTTP call; the one network call is ego models --refresh, which ego makes, and only when asked.

Four rules hold this surface down:

  • The binary is the configured ego_executable, read per call. No argument names a program.
  • There is no key parameter. Dedicated operations write only model, roots and network, so a caller cannot reach sandbox or permissions.judge at all.
  • A model value may not look like a flag, carry whitespace or a control character, or contain " or \ — the last two would break out of ego’s TOML string.
  • A failure carries what ego printed.
CommandArgsReturnsDescription
ego_providersrefresh?EgoProvidersconfig ls --json + models --json + doctor --json, joined. refresh: true adds --refresh, the only call that reaches a provider
ego_set_default_modelmodelEgoProvidersconfig set model="<slug>", then a fresh read — the answer is what ego persisted, not what was sent
ego_perimeter–PerimeterViewStored config ls --json plus config ls --effective --json in the AI Chat workspace/profile
ego_set_perimeter_rootsroots: {rootDir, rootAccess, readAllowlist, writableDirs}PerimeterViewEncode a typed roots=[...] assignment, run config set --, then read back
ego_set_perimeter_networkenabled: boolPerimeterViewconfig set -- network="on" or network="off", then read back

Perimeter operations select --profile from ego_profile and cwd from ai_chat_workspace (empty means host HOME); that directory must exist. They remove ambient EGO_PROFILE so the preview matches the configured ACP profile. Path strings are TOML-encoded in Rust, never written to the TOML file by TUIC. Each allowlist is newline-delimited; the primary root is one path. rootAccess is read or read-write. Paths must be absolute or start with ~/; limits are 128 entries and 64 KiB of path input. Empty fields encode explicit roots=[]. The response contains the edit fields, networkEnabled, selected profile, effective (ego’s original snake_case JSON schema), execEnforcement (enforcedByOs, promptOnly, notChecked), and a display-ready preview. Capability evidence remains exactly what ego reports: a measured string array or not_checked, with optional capabilities_reason and probe_evidence. Rust classifies the exec badge: ro needs read_scoped + write_denied, workspace needs read_scoped + write_scoped, and offline adds no_ip_network. An empty/partial measured set is Prompt only; unknown evidence is unverified. The measured form needs its probe reference. off + online is Prompt only, never a vacuous OS-enforcement success. Headless inspection currently has no measurement, so it reports not checked and its reason.

All three reads must succeed. A partial answer would render as a tab silently missing one of the three things it exists to show.

Errors are an EgoCliError — code (notConfigured, invalidInput, launchFailed, commandFailed, unreadableOutput), message, command, stdout, stderr, exitCode — identical on both transports. command is spelled by file name only, and the captured output is clipped to 4000 characters on a character boundary.

Private secret form commands

secret_form_bootstrap takes no arguments and checks the native caller window against the backend-created private window. It is intentionally unmapped: an HTTP client must already possess the privately delivered capability. secret_form_submit {submission} checks the same native identity and uses the same schema and consumption logic as POST /secrets/forms/submit.

Workflow definition and human-decision IPC commands use host Human authority. HTTP equivalents require verified credentials for that authority; local address admission grants LocalApi only. Native story plan_state and plan_view use current integration receipts for workflow-owned plans.

Stored terminal marker coordinates

OSC 133 event line and hook-generated UserInput.line use all-time rows. terminal_scroll_to, terminal_get_lines and search results keep their retained-grid coordinates; callers subtract the current frame historyBase when using stored markers.

Telegram Settings

  • telegram_settings: safe settings snapshot (enabled, token_set, bot_alias, registered_agent_name (nullable), decimal-string chats, connected, last_error, last_message_time). Never returns a token or message text.
  • telegram_setup { change }: change.action is token (password token, checks getMe), pair (returns code, expires_in_seconds), add_chat/remove_chat (chat_id), or configure (enabled). Errors are typed safe Telegram categories.

The daemon executor now owns recovery and duration timers under an OS run-database lock. Reads never recover live work, and a non-owner daemon refuses run mutations. Graph resume uses resume_graph {execution_id,activation_id,resolution} with an explicit pending activation; status-only resume cannot bypass graph position. Graph start controls, Agent effects and delivery policy remain unavailable until their later slices.

acp_session_fork accepts optional atMessageId, with the same behavior as the ACP HTTP fork route. Capability snapshots expose forkAtMessage separately from tip fork support.

acp_session_list uses the same complete ancestry projection as HTTP: original ego lineage plus _meta.tuicommander.lineageDepth and disabled deleted-parent placeholders.

workflow_run_action also accepts the read-only incidents action with run_id. It returns the same project-scoped camelCase incident entries as POST /workflows/run/action; see the HTTP API run incident projection.

acp_chat_open

Arguments: { request: { sessionId?, profile?, workspace?, executable? } }. Returns { connection, sessionId, launch, replayed }. Creates a conversation with its own durable launch options, or reopens the saved sessionId. HTTP equivalent: POST /acp/chat/open with the request object as the body. Global ACP connect defaults remain unchanged.

MCP session action=declare_worktree is intentionally not a Tauri command. It requires a bound managed caller, which window IPC does not supply. Call it via HTTP POST /mcp. Its session-worktree-declared push is also emitted to Tauri; list_active_sessions and HTTP GET /sessions report the persisted declaration in their existing worktree fields. See MCP backend.

Desktop text clipboard

CommandParametersReturnsDescription
write_clipboard_texttext: String()Write UTF-8 text to the local OS clipboard through arboard. Errors reject the call so copy actions show failure.
read_clipboard_text—StringRead UTF-8 text directly from the local OS clipboard without the macOS Web Clipboard Paste pill.

Both commands require the desktop feature and run blocking clipboard operations on worker threads. They have no focus or user-gesture requirement. The clipboard owner stays alive between calls and is released on application exit. They are INTENTIONALLY_UNMAPPED: browser clients use navigator.clipboard on their own machine; HTTP clients cannot read or write the host pasteboard.

Automations

automation_action(input: serde_json::Value) -> Result<serde_json::Value, String> is an async command that shares parsing, definition edits, history, schedule previews/presets, UTC run summaries and owner-guarded Run Now with POST /automations/action. Invoke with {input:{action:"list"}}; response values and application error messages match HTTP. See the HTTP Automations action table for every field and reply. Blocking storage/schedule work runs off the main thread. Run Now executes only on the addressed backend; phase 1 is Once-only.