All pages

Docs > Change

Pane packs

A pane is a tab in Shift’s inspector that your project owns: a few lines of text, live values from the session, and commands that run through the same allowlisted machinery as the agent’s own runs. You declare it once, in .shift/panes.scm, and every Shift session opened in that folder shows it.

The file is Scheme the way a theme pack is Scheme: one form, read with read and never evaluated. There is no code to load, no plugin API to version, and nothing a pane can do that the session could not already do.

The shape

Shift’s own repository ships this pack. It adds a SHIFT tab beside Work, Diff, Session, Model and Log.

;; .shift/panes.scm
((pane "shift" "SHIFT"
   (text "Shift checkout health")
   (field source.loaded)
   (field session.model)
   (field usage.prompt)
   (command "git" "status" "--short")
   (command "git" "log" "--oneline" "-3")
   (command "make" "test")))

Grammar

PACK  = ( PANE ... )                    ; up to 4 panes, one form per file
PANE  = ( pane NAME TITLE ROW ... )     ; 1 to 24 rows
ROW   = ( text STRING )                 ; up to 120 printable characters
      | ( field FIELD )                 ; a live value, redrawn live
      | ( source SECTION )              ; a built-in sidebar section
      | ( command STRING ... )          ; argv of 1 to 16 strings, not a shell line
NAME  = "[a-z0-9-]{1,16}"               ; not work, diff, session, model or log
TITLE = up to 12 printable characters   ; the tab label

Names are what /pane run NAME and the tab strip use; titles are what you read. Comments and whitespace are yours to use. Anything outside this grammar, including any other list head, is rejected as a whole: an invalid pack is reported and skipped, and the last valid one stays loaded.

Fields

A field row names one of these symbols. It shows the label and the current value, or a dash before the session has reported it.

FieldShows
session.nameThe durable session name.
session.providerThe provider serving the model.
session.modelThe model the next turn will use.
session.modeThe tool policy: manual, plan or autopilot.
session.turnThe turn counter.
usage.promptPrompt tokens in the last reported round.
usage.limitThe context limit the session budgets against.
usage.roundThe model round within the current turn.
usage.max_roundsThe round ceiling for a turn.
receipt.statusThe last turn’s receipt status.
receipt.duration_msHow long the last turn took, in milliseconds.
source.loadedThe Shift checkout the running image was loaded from.
source.processThe Shift checkout the process started with.

Sources

A source row borrows one of the sections the built-in tabs are made of, so a project can compose its own status tab: skills next to the git status it cares about, or the running jobs beside a checklist.

SourceShows
sessionName, provider/model, mode and turn.
skillsSkills with source and loaded state; clicking loads one.
pluginsInstalled plugins with their state and what each contributes.
sessionsDurable sessions with status marks; clicking an idle one switches.
peersThe MCP endpoint and attached peers.
serversMCP servers the session can reach, with state and tool counts; clicking connects one.
receiptThe latest turn’s receipt.
telemetryExact context and round values.
sourceThe Shift checkout the session and process loaded.
jobsBackground jobs while they run.
runsThe run history the Log tab shows.
modelsThe provider’s models; clicking switches.

Commands

A command row is an argv, not a shell line, and it runs only when the session’s run allowlist already permits that prefix: the same rule that governs the agent’s run tool. Otherwise the row reports which /allow-run prefix is missing. Clicking a command row runs it; /pane run NAME runs every command row in the pane and /pane run NAME ROW one of them. Output shows under the row and in the Log tab, bounded to 300 lines or 16 KiB per run.

./bin/shift-agent --allow-run "git status" --allow-run "git log" --allow-run "make test"
shift> /pane run shift

Loading, precedence, checking

  • The pack loads whenever Shift runs in the project and reloads within half a second when the file changes.
  • An explicit panes preference, from /ui or the agent’s ui tool, takes precedence over the file. It carries the same panes as JSON objects with name, title and rows, validated by the same rules.
  • The file is committable. Shift’s own .gitignore keeps the rest of the state directory private and allows only the pack.
  • ./bin/shift-agent --check-panes lints the pack the way a session loads it and exits non-zero with the reason; pass a path to check another file.
$ ./bin/shift-agent --check-panes
pane shift: 7 rows
.shift/panes.scm: ok

Panes never load Python or Scheme code and never widen what the session may run. Details live in the terminal guide.