Skip to main content

Module protocol

Module protocol 

Source
Expand description

JSON protocol types for communication between the terminal and script subprocesses.

Scripts read ScriptEvent objects from stdin (one JSON object per line) and write ScriptCommand objects to stdout (one JSON object per line).

§Security Model

§Trust Assumptions

Scripts are user-configured subprocesses launched from ScriptConfig entries in ~/.config/par-term/config.yaml. The script binary is implicitly trusted (it was placed there by the user). However, this trust must be bounded because:

  1. Supply-chain attacks: A malicious package could replace a trusted script with one that emits dangerous command payloads.
  2. Injection through event data: Malicious terminal sequences could produce events whose payloads are forwarded to the script, which could reflect them back in commands (terminal injection risk).
  3. Compromised scripts: A script may be modified after initial deployment.

§Command Categories

Script commands fall into three security categories:

§Safe Commands (no permission required)

  • Log: Write to the script’s output buffer (UI only)
  • SetPanel / ClearPanel: Display markdown content in a panel
  • Notify: Show a desktop notification
  • SetBadge: Set the tab badge text
  • SetVariable: Set a user variable
  • SetWidget: Plugin-only status-bar text; a tab script sending it gets an error line (see the variant docs below)

§Restricted Commands (require permission flags)

These commands require explicit opt-in via ScriptConfig permission fields:

  • WriteText: Inject text into the PTY (requires allow_write_text: true)
    • Must strip VT/ANSI escape sequences before writing
    • Subject to rate limiting
    • Queued for user confirmation unless prompt_before_write_text: false (see crate::confirm) — stripping escapes leaves the printable text and newline that make up a command line
  • RunCommand: Spawn an external process (requires allow_run_command: true)
    • Must check against check_command_denylist() from par-term-config
    • Must use shell tokenization (not /bin/sh -c) to prevent metacharacter injection
    • Subject to rate limiting
  • ChangeConfig: Modify terminal configuration (requires allow_change_config: true)
    • Must validate config keys against an allowlist

§Implementation Status

All commands are implemented:

  • Log, SetPanel, ClearPanel: Safe, always allowed
  • Notify, SetBadge, SetVariable: Safe, always allowed
  • WriteText: Requires allow_write_text, rate-limited, VT sequences stripped, and confirmed by the user unless prompt_before_write_text is off
  • RunCommand: Requires allow_run_command, rate-limited, denylist-checked, tokenised without shell invocation
  • ChangeConfig: Requires allow_change_config, allowlisted keys only

§Dispatcher Responsibility

The command dispatcher in src/app/window_manager/scripting/mod.rs is responsible for:

  1. Checking command.requires_permission() before executing restricted commands
  2. Verifying the corresponding ScriptConfig.allow_* flag is set
  3. Applying rate limits, denylists, and input sanitization
  4. Routing WriteText through the confirmation dialog when it is not pre-approved

See par-term-scripting/SECURITY.md for the complete security model.

Structs§

OverlaySize
Overlay size as fractions of the window, clamped by the host (half the window per axis).
PluginOverlay
The host-side stored form of a live overlay. interactive is true only when the request asked for it AND the plugin’s manifest carries the overlay.interactive capability (phase 2) — the ingest path forces it off otherwise.
ScriptEvent
An event sent from the terminal to a script subprocess (via stdin).

Enums§

OverlayAnchor
Named overlay anchors (kebab-case on the wire).
OverlayPosition
Where a plugin overlay sits: a named anchor or a free rect as window fractions. Free rects are clamped on-screen by the host.
OverlayScene
A declarative scene tree the host renders through egui. Phase 1 vocabulary: text, row, markdown; phase 2 adds the interactive button / text_input / list (rendered only while the overlay may focus — see PluginOverlay::interactive). No images (deferred by design).
OverlayWidgetEvent
What a focused overlay widget reports to the plugin process.
ScriptCommand
A command sent from a script subprocess to the terminal (via stdout).
ScriptEventData
Event-specific payload data.

Constants§

OVERLAY_EVENT_KIND
Event kind for ScriptEventData::OverlayEvent: a focused overlay’s widget reported a semantic interaction (click / text_changed / select).
PLUGIN_ACTION_INVOKED_KIND
Event kind for ScriptEventData::PluginActionInvoked: a user invoked a plugin-contributed palette action.
THEME_CHANGED_KIND
Event kind for ScriptEventData::ThemeChanged: the window’s active theme changed, or a subscribed plugin is being greeted with the current one on (re)spawn. App-sourced: delivered by the plugin host’s sync_theme, never by a terminal observer.

Functions§

strip_vt_sequences
Strip VT/ANSI escape sequences from text before PTY injection.