What Is the Purpose of parentSession Metadata in Pi Web Session Files?
The parentSession metadata field stores the absolute file path of the originating session, enabling Pi Web to render fork hierarchies in the UI and maintain lineage relationships without affecting runtime session logic.
Pi Web persists conversation state in .jsonl files where the first line contains the session header. This header includes the parentSession field that links forked sessions to their ancestors, creating the tree structure visible in the sidebar according to the agegr/pi-web source code.
parentSession in the Type System
SessionHeader Definition
The field is defined as an optional string property on the session header interface.
In lib/types.ts (lines 3-10), the type system declares:
interface SessionHeader {
type: "session";
version: 3;
id: string;
timestamp: string;
cwd: string;
parentSession?: string; // Absolute path to originating session file
}
This property holds the absolute file path (for example, /home/user/.pi/agent/sessions/abc.jsonl) of the session from which the current file was forked.
SessionInfo Resolution
While the file stores a filesystem path, the REST API exposes a session ID for client consumption.
In lib/session-reader.ts (lines 64-66), the code resolves the path to an identifier:
const parentSessionId = header?.parentSession
? await resolveSessionIdByPath(header.parentSession)
: undefined;
The GET /api/sessions/[id] endpoint returns this parentSessionId to the frontend, allowing the interface to display links such as "child of..." and enabling client-side sorting and grouping.
How parentSession Tracks Session Lineage
Recording Forks in rpc-manager.ts
When a user initiates a fork, the system immediately records the lineage in the new file's header.
According to lib/rpc-manager.ts (lines 66-70), the fork operation executes:
// Inside case "fork":
const currentSessionFile = this.inner.sessionFile;
const newManager = SessionManager.create(sessionManager.getCwd(), sessionDir);
newManager.newSession({ parentSession: currentSessionFile });
This writes a new JSONL file with a header containing the parentSession field pointing to the original file path. The UI sidebar then visualizes this connection as a branch in the tree.
Cascade Reparenting on Delete
The system maintains hierarchy integrity even when parent sessions are deleted.
In app/api/sessions/[id]/route.ts (lines 118-141), the DELETE handler implements cascade reparenting:
const parentSessionPath = readSessionHeader(filePath)?.parentSession;
for (const childFile of siblingFiles) {
const childHeader = JSON.parse(firstLine);
if (childHeader.parentSession && sessionPathKey(childHeader.parentSession) === targetPathKey) {
childHeader.parentSession = parentSessionPath; // Promote to grandparent
writeFileSync(childFile, updatedLines);
}
}
After deletion, direct children automatically point to the original session's parent (or clear the field if none exists), ensuring the tree remains valid and navigable without orphaning files.
Display-Only Semantics
The parentSession field is strictly metadata and does not influence runtime behavior.
As documented in AGENTS.md under "Fork must destroy the wrapper immediately," the field is metadata only; it does not impact how the Pi runtime merges messages, performs navigation, or executes logic. You can safely rewrite or remove this field without altering the session's substantive content—it exists solely to inform the web interface about file lineage.
Summary
parentSessionstores an absolute file path in the session header JSONL, linking a fork to its origin session file.- The REST API resolves this path to a
parentSessionIdinlib/session-reader.tsfor frontend consumption rather than exposing filesystem details. - Fork creation in
lib/rpc-manager.tswrites this metadata to establish the parent-child relationship at instantiation time. - The delete handler in
app/api/sessions/[id]/route.tsautomatically rewritesparentSessionon children to point to the grandparent, maintaining tree consistency. - This field is purely for UI visualization and has no effect on session execution logic or message merging.
Frequently Asked Questions
Does parentSession affect how Pi merges conversation messages?
No. According to the AGENTS.md specification and source analysis, the parentSession field is display-only metadata. It does not influence message merging, navigation logic, or runtime execution. It exists solely for visualization in the web interface.
What happens to child sessions when I delete a parent session?
The server automatically performs cascade reparenting. As implemented in app/api/sessions/[id]/route.ts, when a session is deleted, any direct children have their parentSession field updated to point to the deleted session's parent, or the field is cleared if no parent exists. This preserves the hierarchy without orphaning files.
Why does the API return parentSessionId instead of the file path?
The SessionHeader stores an absolute file path for internal consistency, but the REST API (GET /api/sessions/[id]) returns a parentSessionId. This abstraction, handled in lib/session-reader.ts, decouples the client from filesystem specifics and allows the UI to reference sessions by stable identifiers rather than volatile absolute paths.
Can I manually edit the parentSession field in a JSONL file?
Yes, it is safe to modify or remove the parentSession field manually. Since it is display-only metadata with no runtime impact, changing it only affects how the UI renders the session tree. However, ensure any edits maintain valid JSON syntax to prevent header parsing errors when the server reads the file.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →