Skip to main content

How Fig works (technically)

Diagram of Fig's Architecture

Fig's #1 Job

Our number one goal is to make the Fig.js API simple and robust so people can build powerful applications on top of it. In a nutshell, the Fig.js API enables 4 things

  1. Access the currently active shell's state (e.g. what has the user typed and what's the shell's current working directory?)
  2. Run local shell commands on the user's behalf
  3. Position the Fig window in various locations around the user's terminal
  4. Insert text into the active terminal session

Believe it or not, doing this is really hard... Here's the general structure of what happens under the hood:

  1. We add a bunch of hooks to your system we call system integrations. These hooks
  2. The system integrations send lots of events to our desktop app.

API that gives easy access to the state about the user's currently active terminal session. To do this, we need to know everything about each terminal session a user currently has open. And to do that, we add a ton of hooks to your system we call . These hooks send events to our desktop app. Our desktop app parses through all of these events, updates its internal state accordingly, and then provides GUI apps a simple way of accessing this state through the Fig.js API.

Believe it or not, getting all of this information is actually really really hard. The reason why Fig is so innovative is we do all of this for you and expose the state as nice javascript API that you can use to build GUI apps.

What state do we need to know about each terminal session?

  • the current "edit buffer" (what you've typed / what is written in the shell)
  • the current process (e.g. bash, zsh, vim, sleep, ssh?)
  • the current working directory
  • the environment and shell variables
  • if it's a remote shell session (which we've access through something like docker or ssh), how do we execute commands on the remote machine (e.g. ssh user1@server1 command1)

Although not exactly correct, you can think of the above state as massive dictionary with keys = unique terminal session ids, and value = object containing the information.

What global state do we also need to know?

  • which system application is currently focused
    • e.g. is the curently active window iTerm, Google Chrome, Finder...
  • If a terminal emulator is focused, which terminal session is currently focused
    • e.g. if I have multiple tabs and panes open in iTerm, which tab and/or pane is currently active
  • the typing cursor's position
    • this is literally the x & y coordinates of your typing cursor relative to the screen. This enables us to position the window correctly
tip

Remember, Fig's #1 job is to know every bit of information above about each terminal session.

Fig has four main modules and two core communication mechanisms between each of these modules.

The Four Core Modules of Fig

Systems Integrations
Fig's integrations with shells, terminal emulators, keypress events, operating system window events, and cursor location.

System integrations send events from the user's shell to the desktop app. The desktop app receives these events and updates our massive state dictionary accordingly.

Each integration sends specific events. You can see all the events in the Local IPC section below

  • Shell integrations:

  • Terminal integrations: Active terminal session changes. e.g. If I am in iTerm and I open

  • Keylogger

  • Figterm: Discussed below

  • Keylogger: Typing cursor location

  • Shell

  • Terminal Emulators

  • Keypress events

  • Window Events

  • Cursor location

Figterm
A special system integration that is in charge of getting the edit buffer (what the user has typed in the terminal), pid, and cwd. It is also in charge of inserting text
Desktop App
In charge of storing state, window positioning, running shell commands, and inserting text.
GUI Apps
User facing applications
Fig CLoud
User facing applications

Two main protocols

Fig.js API
Two-way communication between the Desktop app and GUI Apps.

The backbone of Fig is the Fig.js API. This API allows you to do 4 things:

  • Subscribe to changes in the user's terminal sessions (e.g. when a keypress it types or when the working directory changes)
  • Run local shell commands on the user's behalf
  • Position the Fig window in various locations around the user's terminal
  • Insert text into the active terminal session
Local IPC
Two-way communication between System Integrations (including Figterm) and the Desktop App
The Local IPC protocol enables us to receive events from our system integrations and send them to our desktop app The mains events are: * New terminal session * Keypress * Pre-execute event (just before a command is executed) * Post-execution (just after a command is executed) * Pre prompt (just before a prompt loads) * KeyboardFocusChangedHook keyboard_focus_changed = 105; TmuxPaneChangedHook tmux_pane_changed = 106; OpenedSSHConnectionHook opened_ssh_connection = 107; CallbackHook callback = 108; IntegrationReadyHook integration_ready = 109; HideHook hide = 110; EventHook event = 111;

Intersting Example Some interesting things to think about. What happens if I have two terminal windows open, terminal A and B. In terminal A I type sleep 10 and hit enter. I then immediately switch to terminal session B and wait. After 10 seconds, a post-execute and prompt event will be sent from terminal A, even though I'm in terminla B