@nicknisi/pi-session-name
Auto-name pi sessions (heuristic or LLM) plus search/resume-by-name conveniences
Package details
Install @nicknisi/pi-session-name from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@nicknisi/pi-session-name- Package
@nicknisi/pi-session-name- Version
0.2.0- Published
- Nov 2, 2026
- Downloads
- 464/mo · 84/wk
- Author
- nicknisi
- License
- MIT
- Types
- extension
- Size
- 49.5 KB
- Dependencies
- 0 dependencies · 2 peers
Pi manifest JSON
{
"extensions": [
"./index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
@nicknisi/pi-session-name
Name pi sessions so they're easy to search and resume. Pi's built-in /name works but requires you to remember to use it; this extension derives a concise name automatically as soon as the first prompt is sent (heuristic by default, LLM-generated opt-in), mirrors the name into the terminal/window title, and adds /sn for manual naming and /sessions for a name-focused search-and-resume picker. Sessions already named via /sn, /name, or --name are never overwritten.
What it adds
- Commands
/sn [name]— Set the session name. With no argument, shows the current name viactx.ui.notify./sn clear(also-c,--clear) clears it. Argument completion suggestsclear./sessions [query] [--all]— Interactive picker of sessions for the current project (SessionManager.list(ctx.cwd)), or across every project with--all/-a(SessionManager.listAll()). Selecting an entry resumes that session viactx.switchSession. Requires interactive mode (ctx.hasUI).
- Terminal title — Sets the window/tab title via
ctx.ui.setTitleto reflect the session name (e.g.fix login bug — dotfiles). Reaches whatever pi's terminal layer drives (Ghostty, tmux panes, etc.). - Auto-naming — When the first prompt of an unnamed session starts a run (
before_agent_start), derives a name from that prompt (heuristic mode) or a one-off LLM call (llm mode), then callspi.setSessionName. Runs alongside the agent rather than delaying it. Fires at most once per session instance.
Events hooked
| Event | Purpose |
|---|---|
session_start |
Resets the auto-name guard; defers a title set (via setTimeout(0)) so it runs after pi's built-in updateTerminalTitle() on startup. |
session_info_changed |
Re-sets the title. setSessionName emits to built-in handlers first, so this runs after pi's built-in title update and wins. |
session_shutdown |
Aborts any in-flight LLM title call and clears the pending title timer so a resolved name never lands on a torn-down/replaced session. |
before_agent_start |
Triggers auto-naming when the first prompt is sent, without blocking the run. |
No custom tools, keybindings, widgets, or message/entry types.
Usage
/sn refactor auth flow # name the current session
/sn # show the current name
/sn clear # clear it (won't be re-auto-named)
/sessions # picker: all sessions in this project
/sessions auth # filter by name, first message, or session id
/sessions auth --all # search across every project
The picker lists sessions as:
★ fix login bug — 42 msgs — 2h ago — a1b2c3d4
· (first message preview…) — 5 msgs — 3d ago — e5f6g7h8
Named sessions (★) sort first, then most recently modified. The current session is excluded from the list.
Configuration
Config file: ~/.pi/agent/configs/session-name.json (JSON, all keys optional; missing file or parse errors fall back to all defaults). An example lives at session-name.example.json in this package.
| Key | Type | Default | Description |
|---|---|---|---|
autoName |
"off" | "heuristic" | "llm" |
"heuristic" |
Naming mode, applied when the first prompt is sent. heuristic uses the first non-empty line of the first user message (free, instant). llm makes a one-off title-generation call and falls back to the heuristic if it fails. off disables auto-naming. |
heuristicMaxLength |
number |
60 |
Max characters for derived names (applies to both heuristic and LLM titles; longer names are truncated with …). |
llmMaxWords |
number |
6 |
Max words requested in the LLM title-generation prompt. |
llmModel |
string | null |
null |
Model for LLM titles as "provider/model-id", e.g. "anthropic/claude-haiku-4-5". null uses the session model. If the configured model isn't found in the registry, falls back to the session model and warns once. |
notifyOnAutoName |
boolean |
true |
Show a Session named: … notification when auto-naming succeeds. |
setTitle |
boolean |
true |
Mirror the session name into the terminal/window title. |
titleFormat |
string |
"{summary} — {dir}" |
Title template. Placeholders: {summary} (session name), {dir} (basename of cwd) and {app} (what the host calls itself — π, or the brand name under a rebranded distribution such as arc). When the session is unnamed the title is {app} — {dir} regardless of format. |
Example (session-name.example.json):
{
"autoName": "heuristic",
"heuristicMaxLength": 60,
"llmMaxWords": 6,
"llmModel": null,
"notifyOnAutoName": true,
"setTitle": true,
"titleFormat": "{summary} — {dir}"
}
No environment variables are read.
How auto-naming works
- On
before_agent_start, skip if already named (via/sn,/name,--name, or a prior auto-name), ifautoNameis"off", or if the run was started by a custom message rather than a user prompt. Slash commands never start a run, so they never trigger naming. - Use the first user message already in the branch (
ctx.sessionManager.getBranch(), so a resumed unnamed session is named from its first prompt), else the prompt being sent. Naming then runs in the background; the agent run does not wait for it. - Heuristic mode: first non-empty line, whitespace-collapsed, truncated to
heuristicMaxLength. - LLM mode: one
ctx.modelRegistry.complete()call (appliesmodels.jsonoverrides, extension-registered providers, and request-time auth) with a system prompt asking for a ≤llmMaxWords-word title, fed the first user prompt (truncated to 1000 chars). The response is cleaned (first line, quotes and trailing punctuation stripped) and truncated toheuristicMaxLength. Actx.modelRegistry.getApiKeyAndHeaders(model)pre-check falls back to the heuristic when no API key is available. - A name manually set while the LLM call is in flight wins — the result is discarded. So does a session replaced or shut down meanwhile.
- Manually naming or clearing a session sets the per-session guard so auto-naming never fires afterward in that session instance.
Dependencies
@earendil-works/pi-coding-agent(peer,>=0.86.0) —ExtensionAPI,ExtensionContext,SessionEntry,SessionInfo,SessionManager(used forlist/listAllin/sessions).@earendil-works/pi-ai(peer) —Messagetype for the LLM title request.- Node builtins:
node:fs,node:os,node:path.
Caveats
- Depends on pi internals' event ordering: the title logic assumes built-in handlers (
updateTerminalTitle) run before extension handlers forsession_startandsession_info_changed, and uses asetTimeout(0)deferral on startup to win the race. A pi release that changes handler ordering could revert titles to pi's default format. - LLM title generation relies on
ctx.modelRegistry.complete()(stopReason, text content blocks) andctx.modelRegistry.getApiKeyAndHeaders. /sessionsexcludes the current session by comparingSessionInfo.pathtoctx.sessionManager.getSessionFile().- Clearing the name via pi's built-in
/name(empty) does not set the auto-name guard — only/sn cleardoes — so a cleared-via-/namesession may be auto-named again on the next turn. - Title behavior depends on the terminal honoring pi's title escape sequences (works in Ghostty and tmux panes as noted in the source header).
Install
pi install /Users/nicknisi/Developer/pi-extensions/packages/session-name