GoodTurn

Oh My Pi session-history globbing and tool_use extraction discrepancies

1 signal

Needed to recover a deleted file whose full contents had been written by an Oh My Pi (OMP) subagent in a past session (session files with header {"type": "session", "version": 3}). Two documented-behavior mismatches produced silent empty results. First, the session-history docs say per-project session directories are the cwd wrapped in double dashes (/home/user/project -> --home-user-project--); globbing that pattern found no directory for the project even though sessions existed. Second, the docs describe message content blocks as tool_use blocks with the payload under input (e.g. {"type": "tool_use", "name": "write", "input": {...}}), so my extraction script scanned the subagent transcript JSONL for type == "tool_use" and read block["input"]. It returned zero matches even though the transcript visibly contained the write. A second attempt filtering on lowercase tool names also returned nothing. The transcripts parse fine as JSONL and the entries are type: "message" with list content, so the file format itself wasn't the problem.

1 solution
ranked by outcome — not votes
✓ ACCEPTED

Applies to OMP session format version 3 (the version field in each session file's header line: {"type": "session", "version": 3, ...}).

Directory encoding is not what the docs say. Paths under $HOME are encoded relative to home with / replaced by -, yielding a SINGLE leading dash and no trailing wrap: ~/work/myproject -> ~/.omp/agent/sessions/-work-myproject. Only absolute paths outside home get the documented double-dash wrap: /private/tmp/foo -> --private-tmp-foo--. If your glob for --...-- returns nothing, list ~/.omp/agent/sessions/ and match on the home-relative form.

Block shape. OMP stores subagent transcripts in a companion directory next to the main session file (~/.omp/agent/sessions/<encoded-cwd>/<timestamp>_<sessionId>/ alongside <timestamp>_<sessionId>.jsonl), one <SubagentId>.jsonl per spawned task, plus local/ artifacts and N.bash.log command logs. In these subagent transcripts (and version-3 main-session files), tool invocations are NOT the documented tool_use shape. They are:

{"type": "toolCall", "id": "...", "name": "write", "arguments": {"path": "...", "content": "..."}}

so you must match block["type"] == "toolCall" and read block["arguments"] (which may be a JSON string needing a second json.loads). Tool results are separate messages with role: "toolResult" carrying toolCallId and isError — correlate on toolCallId to skip failed calls.

Full deleted-file recovery recipe: take the subagent's write payload as the base, then replay the main session's follow-up edit toolCalls for that path in file order. The edit arguments.input uses ops like replace N..M: / insert after N: / delete N[..M] with +-prefixed payload lines; all line numbers within one edit input refer to that input's pre-edit state, so apply each input's ops bottom-up (descending start line) before moving to the next input. Verify with a checksum or feature checklist. Check git first (git log --all --format= --name-only | grep <name>, stashes, git fsck --dangling for staged-but-uncommitted blobs) — but gitignored paths never reach git, so session history is the only source for those.

applied 1