npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

pi-cutlery

v0.4.0

Published

Multi-session workflow toolbox for Pi, centered on session forking

Readme

pi-cutlery

Multi-session workflow tools for Pi.

Use it when plain Pi sessions are not enough and you want repeatable fork, move, and pane-backed child-session workflows.

pi-cutlery adds a workflow layer around Pi sessions:

  • startup forking with --fork-session
  • live session forking with /forkpi and fork_pi
  • live session relocation with /move
  • managed named child Pis with /pi and spawn_pi
  • managed Pi discovery and follow-up messaging with /pis and /tell
  • tmux resurrect metadata handoff for tmux-backed flows

install

npm:

pi install npm:pi-cutlery

git:

pi install git:github.com/lajarre/pi-cutlery

local path:

pi install /path/to/pi-cutlery

local project install:

pi install -l /path/to/pi-cutlery

Restart Pi after install.

For most users, install from npm. Use git or a local path when you want to track or modify the package itself.

surface map

| surface | kind | purpose | |---|---|---| | --fork-session <id-prefix> | startup flag | start Pi by forking another persisted session first | | /forkpi [suffix] [v\|h] | command | fork the current live session into an adjacent pane/surface via tmux or cmux | | fork_pi { suffix?, split? } | tool | tool form of /forkpi; requires tmux or cmux | | /move <targetCwd> | command | move the current session to another cwd and relaunch Pi there | | /pi [suffix] [v\|h] | command | spawn a managed named Pi in an adjacent pane/surface via tmux or cmux | | spawn_pi { suffix?, split? } | tool | tool form of /pi; requires tmux or cmux | | /pis | command | list known managed Pis from the local registry | | /tell <target> <message> | command | send a follow-up message to a managed Pi via session-control |

quick examples

Startup fork by full UUID or unique leading prefix:

pi --fork-session <session-id>
pi --fork-session 7649c823
pi --session-control --fork-session 7649c823 "continue from here"

Fork the current live session into an adjacent pane/surface:

/forkpi
/forkpi api
/forkpi api h

Move the current session to another directory and relaunch there:

/move ../other-worktree
/move ~/src/other-repo

Spawn a managed named Pi:

/pi
/pi api
/pi api h

List or message managed Pis:

/pis
/tell api "run a focused experiment"
/tell 1 "summarize the findings"

Agent-callable forms:

tool: fork_pi
tool: spawn_pi

choosing the right surface

1. startup fork: --fork-session

Use --fork-session when you are starting a new Pi process and want its initial session file to be a fork of an existing persisted session.

Properties:

  • works before the interactive session starts
  • does not require tmux
  • resolves the source by full UUID or unique leading prefix
  • re-execs Pi on the forked session file with --session <fork-path>
  • leaves the source session file unchanged
  • keeps the rest of the CLI arguments except the consumed --fork-session <id> pair

Conflict rules:

  • cannot combine with --session, --continue, --resume, --no-session, or --mode rpc|json
  • bypasses itself for help/version and Pi management subcommands such as install, remove, update, list, and config

Resolution rules:

  1. look in the current cwd/session-dir scope first
  2. prefer a unique match whose session.cwd === process.cwd()
  3. if there is no local match and no Pi --session-dir override, fall back to global listing
  4. fail clearly on no match or ambiguous match

When --session-control is also present and the source session has a name, cutlery derives a non-conflicting fork name such as <source>-fork1 before re-exec.

2. common pane-spawn contract

/forkpi, fork_pi, /pi, and spawn_pi share the same pane-launch contract:

  • require tmux or cmux
  • select the pane backend with precedence tmux > cmux
  • fail clearly if neither backend is available, and do not fall through to cmux when tmux is selected but unusable
  • materialize the child session in the parent after a backend is confirmed and before the pane/surface launch
  • create the target pane/surface through the selected backend
  • on tmux only, stamp the target pane with the child session UUID before launch
  • launch the child with pi --session <session-file> --session-control
  • emit a visible parent-side cutlery:spawn-report before focus moves to the child pane/surface
  • use native cmux commands on cmux launches rather than tmux-compat shims
  • default to vertical split; pass h for a horizontal split

If tmux metadata handoff fails, cutlery stops before child launch.

Compatibility note: paneId remains the shared field name in reports and tool details. On tmux it is a tmux pane id; on cmux it may temporarily carry a cmux surface ref.

3. forking the current session: /forkpi and fork_pi

Use these when you are already inside Pi and want a neighboring pane with copied conversation state.

Requirements:

  • tmux or cmux is available in the parent environment
  • current session has a name via /name <name>
  • current session file is persisted
  • current session contains forkable entries

Naming behavior:

  • default names are <name>:fork1, <name>:fork2, and so on
  • explicit suffixes become <name>:<suffix> after sanitization
  • collision checks include stored session names and existing session-control alias files
  • explicit suffix collisions fail clearly instead of silently renaming the fork

Tool behavior:

  • fork_pi accepts { suffix?: string, split?: "v" | "h" }
  • tool results include the spawned child session id in details

4. moving the current session: /move

Use /move when the current session belongs under a different cwd bucket and you want Pi relaunched there on a moved copy of the session.

Properties:

  • works inside or outside tmux
  • requires a target directory argument
  • requires a persisted current session
  • normalizes ~ and relative paths against the current session cwd
  • rejects missing paths and non-directories before forking
  • forks the current session file into the target cwd
  • clears the forked header's parentSession field so the moved session does not keep stale fork ancestry
  • relaunches with pi --session <moved-session-file>

/move replaces the current Pi process. Old-session cleanup is best-effort only, tmux-gated when relevant, and never hard-deletes the source file.

5. managed named Pis: /pi, spawn_pi, /pis, /tell

Use the managed-Pi family when you want fresh child Pis that are easy to address later.

This is distinct from /forkpi:

  • /forkpi copies current conversation state into a sibling pane
  • /pi creates a fresh child session and gives it a durable managed name plus registry entry

/pi and spawn_pi

Requirements:

  • tmux or cmux is available in the parent environment
  • parent session has a name via /name <name>

Naming behavior:

  • the namespace is captured from the parent session name when spawn state is first created
  • default names are <namespace>:wrkr-<n>
  • explicit suffixes become <namespace>:<suffix> after sanitization
  • slot numbers continue increasing even when a custom suffix is used

Tool contract:

  • spawn_pi accepts { suffix?: string, split?: "v" | "h" }
  • success keeps backward-compatible ok: true details
  • success details also include cutlery-owned identity fields:
    • sessionId
    • sessionFile
    • sessionName
    • paneId (compatibility field name; may hold a cmux surface ref)
  • failures keep ok: false plus error

/pis

/pis lists the known managed-Pi registry.

Behavior:

  • current namespace entries are shown first when state exists
  • older entries from other namespaces remain visible
  • registry entries include the compatibility paneId value, slot, and age
  • if no Pis are known, cutlery tells you to run /pi

/tell

/tell sends a follow-up message to a managed Pi over session-control.

Resolution order:

  1. exact managed Pi name
  2. wrkr-<n>
  3. numeric slot n

Delivery behavior:

  • prefers the child sessionId when available
  • falls back to the older name-based path for legacy registry entries
  • validates routing into the target child session
  • does not forward child replies back into the parent session
  • returns a fallback shell command when the bridge call fails

architecture

pi-cutlery is organized around one startup preflight path, one shared pane launcher with tmux > cmux backend selection, one move/relaunch path, one managed-worker state layer, and one tmux metadata helper.

architecture schematic

flowchart TD
  User([user command or tool call])
  ForkFlag([--fork-session])
  ForkPi([/forkpi or fork_pi])
  SpawnPi([/pi or spawn_pi])
  Move([/move])
  Tell([/tell or /pis])

  User --> ForkFlag
  User --> ForkPi
  User --> SpawnPi
  User --> Move
  User --> Tell

  ForkFlag --> Preflight([fork-session preflight])
  ForkPi --> Launcher([shared pane launcher (tmux > cmux)])
  SpawnPi --> Launcher
  Move --> MovePath([move and relaunch path])
  Tell --> Registry([managed worker registry])

  Launcher --> Materialize([parent-side session materialization])
  Launcher --> Metadata([tmux metadata helper (tmux only)])
  Launcher --> Report([parent-side spawn report])
  Launcher --> Focus([child pane/surface focus])

  MovePath --> Metadata
  MovePath --> Relaunch([pi --session moved-session-file])

  Metadata --> PaneOption([resurrect metadata pane option])
  Metadata --> PaneTitle([cosmetic pane title])

  SpawnPi --> ManagedState([naming state plus managed child metadata])
  ManagedState --> Registry
  Registry --> Bridge([session-control bridge])
  Tell --> Bridge

launcher contract

For pane launches, cutlery does this in order:

  1. confirm a supported pane backend with precedence tmux > cmux
  2. materialize the child session in the parent
  3. create the target pane/surface
  4. on tmux only, write @resurrect-metadata-pi-session=<child-uuid> onto that pane as tmux resurrect metadata
  5. best-effort update the tmux pane title
  6. send pi --session <session-file> --session-control into the pane/surface
  7. emit the parent-side cutlery:spawn-report message
  8. focus the child pane/surface

cmux launches use native cmux new-split, cmux send, cmux focus-pane, and best-effort cmux close-surface commands rather than tmux-compat shims.

cmux surface lifecycle

cmux distinguishes surfaces from panes. Cutlery creates and sends input to the child surface, but focuses the owning pane. The launcher therefore keeps two cmux handles for successful cmux launches:

  • caller context: stable workspace and caller-surface refs derived from CMUX_WORKSPACE_ID and CMUX_SURFACE_ID
  • child surface ref: returned by cmux new-split
  • child pane ref: resolved with cmux identify against the child surface and used for final focus

When the env-provided cmux handles are UUIDs or order-sensitive numeric indexes, cutlery resolves them through cmux --id-format both tree --all --json before creating the child surface. If that resolution is required and fails, launch fails instead of reusing unstable indexes.

sequenceDiagram
  participant Parent as parent Pi session
  participant Backend as selectPaneBackend
  participant Cmux as cmux CLI
  participant Child as child Pi surface

  Parent->>Backend: read CMUX_WORKSPACE_ID and CMUX_SURFACE_ID
  alt env IDs need stable refs
    Backend->>Cmux: cmux --id-format both tree --all --json
    Cmux-->>Backend: workspace:<n> and surface:<n>
  else env already stable refs
    Backend-->>Parent: use caller context as-is
  end

  Parent->>Parent: materialize child session file
  Parent->>Cmux: new-split right/down --workspace <workspace> --surface <caller>
  Cmux-->>Parent: child surface ref
  Parent->>Cmux: identify --workspace <workspace> --surface <child-surface>
  Cmux-->>Parent: child pane ref
  Parent->>Cmux: send --workspace <workspace> --surface <child-surface> "pi --session ...\n"
  Parent->>Parent: emit cutlery:spawn-report
  Parent->>Cmux: focus-pane --pane <child-pane> --workspace <workspace>
  Cmux-->>Child: child surface receives focus

  Note over Parent,Cmux: Before report success, identify/send/report failures close the child surface and keep the session file for recovery.

For restore correctness, the tmux pane metadata option is authoritative. Pane titles are cosmetic only.

prerequisites and limits

Prerequisites:

  • Pi with package/extension support
  • tmux or cmux for /forkpi, fork_pi, /pi, and spawn_pi
  • when both are present, pane launching uses tmux > cmux
  • a persisted current session for /forkpi and /move
  • a parent session name for /pi and spawn_pi
  • an existing persisted session id for --fork-session

Current limits:

  • pane-launch surfaces fail clearly outside tmux or cmux; there is no non-pane fallback
  • there is no message-level fork primitive
  • there is no session browsing UI
  • this package does not replace Pi's session-control API; it builds on it

provenance and licensing

pi-cutlery is MIT-licensed.

Adapted third-party sources:

  • move-session.ts is adapted from dot314/extensions/move-session.ts
  • src/move-session/normalize-target-cwd.ts is adapted from dot314/extensions/_shared/normalize-target-cwd.ts
  • upstream repository: w-winter/dot314
  • upstream license: MIT

First-party provenance:

  • /pi, /pis, /tell, and spawn_pi are adapted from pi-extensions/spawn-worker.ts
  • cutlery keeps that provenance in code comments and docs while owning the runtime surface locally

For shipped notice text, see THIRD-PARTY-NOTICES.md.

Deeper design history lives under doc/feature/. Those feature folders intentionally keep durable specs and summaries alongside archival planning and review artifacts.