@pi-claudian/sync-title
v0.2.1
Published
Pi extension that syncs Claudian conversation titles and Pi session names.
Downloads
1,614
Maintainers
Readme
@pi-claudian/sync-title
A Pi extension
that bridges Claudian and Pi: it does a two-way
sync of the Claudian conversation title with the Pi session name, so the two
stay in sync whether the title comes from Claudian's auto-generation or from a
Pi /name command.
Why
Claudian stores per-conversation metadata under .claudian/sessions/conv-*.meta.json
(including an auto-generated title) but never tells Pi about it, and Pi's
/name command never tells Claudian. This extension closes that gap in both
directions, with conflict resolution that never silently overwrites a name you
set yourself.
Installation
pi install npm:@pi-claudian/sync-titleUsage
Automatic: titles are reconciled when a conversation is opened/resumed and after each agent turn. No action required.
Manual: run the /sync-title command to reconcile the current session on
demand (it prompts on conflict and retries while Claudian's title is still
being generated).
Batch: run /sync-title-all to reconcile every Claudian conversation in
the current vault at once. This is the fix for conversations that ended after a
single turn and were never resumed — their Pi session name stays empty because
the per-session sync only fires on open/turn. It is non-destructive: it fills
empty names in both directions (Claudian → Pi, Pi → Claudian) and skips
conflicts without overwriting, reporting them so each can be resolved with
/sync-title. The current session is synced live; others are synced by
appending a session_info entry to their jsonl, which Pi picks up on the next
resume. A plan is shown for confirmation before any files are written.
Behavior
The extension resolves the Pi session name against the Claudian title using a single decision table:
| Pi name | Claudian title | Action |
| ------- | ----------------------------------------- | ---------------------------------------------------------- |
| empty | empty | wait and retry (title not ready yet) |
| empty | ready | Claudian → Pi |
| ready | empty | Pi → Claudian (skipped while Claudian is still generating) |
| ready | same | no-op |
| ready | different (automatic) | notify only, keep Pi name |
| ready | different (manual /name, /sync-title) | prompt: Pi→Claudian / Claudian→Pi / keep both / cancel |
Notes:
- Sync triggers: when a conversation is opened or resumed (the primary sync moment — Claudian has already persisted its meta, so the title is pulled in immediately) and after each agent turn.
- Claudian generates the conversation title asynchronously after the first turn and only then links the Pi session id into its meta. While the title is not ready yet, the extension waits and retries on a backoff (~2 minutes total) rather than giving up after the first attempt.
- Matches the Claudian meta file by Pi session UUID first, falling back to the
providerState.sessionFilepath (compared throughfs.realpath, so symlinked vaults match). - Vault resolution uses the session's own home directory (
ctx.cwd, which Pi sets to the resumed session's recordedcwd— notprocess.cwd()), walking upward to the nearest.claudian/sessions. So resuming a Claudian session from a sub-directory of the vault still syncs correctly. - Never silently overwrites a session you named yourself: automatic triggers (after a reply) only notify on a mismatch; interactive triggers let you choose to sync Pi→Claudian, Claudian→Pi, keep both unchanged, or cancel.
- Clears: clearing the Pi name with
/name(empty) does not erase the Claudian title. - Silent no-op outside of a Claudian-managed vault (e.g. plain TUI sessions).
Plain
pisessions run inside a Claudian vault are also left alone: the not-yet-linked meta is only probed once when the session starts, so there is no per-turn retry noise. - While Claudian's title status is
pending, the extension waits rather than writing back a Pi name that would race the generator. - Writes back to Claudian are atomic (tmp file + rename) so Claudian never reads a half-written meta file.
The interactive conflict prompt — shown on /name or /sync-title when the
two titles differ. Claudian is never overwritten without your say:
![]()
Debug
Trace matching, retries, and writes by enabling the shared @pi-claudian debug
switch (output goes to stderr):
PI_CLAUDIAN_DEBUG=1 pi # show debug output inline
PI_CLAUDIAN_DEBUG=1 pi 2>debug.log # capture to a fileLook for [pi-claudian]-tagged lines such as writing session name from Claudian
or conflict — prompting user.
License
MIT
