Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: CI

on:
push:
pull_request:

permissions:
contents: read

jobs:
validate:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 22.19.0
cache: npm

- name: Install dependencies
run: npm ci --ignore-scripts

- name: Typecheck
run: npm run typecheck

- name: Test
run: npm test
44 changes: 41 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ Multiple Pi sessions can stay alive concurrently. Exactly one session owns the t

![pi-sessions switcher UI](screenshot.png)

## Compatibility

- Node.js `>=22.19.0`
- Tested with `@earendil-works/pi-coding-agent` and `@earendil-works/pi-tui` 0.84.4
- No tmux, Zellij, Ghostty, or other external multiplexer is required

`pi-sessions` uses pi's advanced runtime and interactive-mode APIs. It checks the host capabilities it relies on at startup. An incompatible host leaves pi running and shows a warning naming the missing capability instead of silently disabling behavior.

## Install

```bash
Expand Down Expand Up @@ -37,7 +45,7 @@ All session operations happen inside that switcher.
- `Enter` β€” switch to selected live session. Selecting `parent` switches back to parent.
- `Ctrl-O` β€” open `FileExplorer`; selecting a folder creates a new child session in that folder and switches to it.
- `Ctrl-R` β€” open a one-off resume flow; selecting a saved Pi session opens it as a live child and switches to it.
- `Ctrl-K` β€” stop selected live child session.
- The configured `killKey` (`Ctrl-K` by default) β€” stop the selected live child session.
- `Esc` β€” close switcher.

## Runtime model
Expand All @@ -57,6 +65,36 @@ Child sessions are real native `InteractiveMode` instances, not embedded panels.

## Path locks

All live sessions share one in-process lock manager. Before write/edit/mutating shell tools run, `pi-sessions` checks for conflicting path locks and blocks conflicting writes.
All live sessions in one pi process share a lock manager. Before a write, edit, redirect, or recognized mutating shell command runs, `pi-sessions` checks for overlapping paths and blocks a conflicting tool call from another session. Recognized shell mutations include common filesystem commands plus mutating `git`, package-manager, `make`, `cargo`, `terraform`, and `dbt` operations.

A lock starts at `tool_call` and is released at `tool_result`. It is a **per-tool-call race guard**, not transactional isolation across a session's multi-command workflow. Separate pi processes do not share locks.

Use one live session per repository when a task requires a coherent sequence of reads and writes. Running multiple sessions in the same repository can still interleave changes between tool calls even though simultaneous conflicting calls are blocked.

## Configuration

Create `~/.pi/agent/pi-sessions.json` to override package-specific keys:

```json
{
"killKey": "ctrl+shift+k"
}
```

`killKey` uses pi's key format, such as `delete`, `ctrl+shift+k`, or `alt+k`. The default remains `ctrl+k`. Restart pi after changing this file. Invalid JSON or key names produce a visible warning and fall back to the default.

## Development

```bash
npm ci --ignore-scripts
npm run typecheck
npm test
```

Interactive changes also require a terminal smoke test:

This prevents two live sessions from editing the same path tree at once.
1. Start `pi -e <path-to-pi-sessions>`.
2. Open the switcher with `Ctrl-R`.
3. Spawn a child session in a selected folder.
4. Switch between the parent and child.
5. Confirm working and idle indicators follow agent activity.
Loading