Skip to content

feat(external-history): find Claude Code, Pi and OpenCode conversations without typed paths - #116

Open
ScriptedAlchemy wants to merge 18 commits into
mainfrom
t3/external-history-local-providers
Open

ScriptedAlchemy wants to merge 18 commits into
mainfrom
t3/external-history-local-providers

Conversation

@ScriptedAlchemy

@ScriptedAlchemy ScriptedAlchemy commented Nov 13, 2026 •

Copy link
Copy Markdown
Owner

Problem

External history found only Codex conversations automatically. Every other source needed a file path typed into the dialog, and the dialog opened on that path box. Conversations from Claude Code, Pi and OpenCode on the same machine were invisible.

Change

  • External history now finds Claude Code, Pi and OpenCode conversations in each provider's own folder, next to Codex. One table on the server decides how each provider is read, and a test fails when a built-in provider has no entry.
  • One search request walks many conversations, newest first, and both clients follow empty pages by themselves. Sessions that T3 already owns are hidden by their stored ids.
  • The typed ChatGPT export path feature is removed: the setting, the reader, and the path box on web and mobile.

Scope

  • Covers web, desktop and mobile, the t3_external_history tool text, and the user docs.
  • Grok, Antigravity, Cursor, Kiro, Muse, FX and ACP agents are listed in the dialog as not readable yet. Older OpenCode database formats show as unsupported.
  • Search is still per source. One search box across all sources is a follow-up.
  • This is a feature on the fork's own External history, requested by the maintainer in the T3 thread that produced this branch. Upstream has no External history.

Tradeoffs

  • No persistent index. A quick text check on the raw files skips sessions that cannot match, so a no-hit search over 1,645 Claude sessions takes about 2 to 3 seconds.
  • Codex keeps its app-server reader. Moving it to disk reads would lose archived threads.

Blast Radius

Saved export-path keys are ignored during settings decoding. The legacy export reader, path setting, and path-entry UI are fully removed. New source kinds are sent only to clients that ask for them, so older web and mobile builds still decode the source list. Reads never write to a provider folder, and folders under the T3 home or ~/Downloads are skipped.

Before and after

Before After
External history dialog with a ChatGPT export paths box External history dialog listing Codex, Claude Code and OpenCode as Ready with no path box

Web was rechecked on the current head after the export path removal: the dialog has no path input, Codex, Claude Code and OpenCode show as Ready with nothing typed, and a Claude Code search for one word returned matches from 2,108 items with no extra clicks.

Mobile (iPhone 17e simulator, iOS 27)

Sources, nothing typed Keyboard before Keyboard after
Mobile External history listing Codex, Claude Code and OpenCode as Ready Keyboard covering the search field Search field visible above the keyboard

Mobile was checked on a simulator paired to the same isolated dev server: the same three sources show as Ready, a Codex search and a Claude Code search both returned results (Claude Code: 2,108 items searched), and switching source clears the query. The run found that the keyboard covered the search field and the Search button; the screen now scrolls above the keyboard like the other settings screens.

Two JSONL history store tests failed on macOS only, because the temp folder resolves through a symlink there. The tests now use the resolved path. vp run check:changed passes on the pushed head.

Still not checked: the tool text against a live model (no ANTHROPIC_API_KEY and no Codex proxy on this machine; both cases build in a dry run), and Pi against real data (no Pi sessions on this machine; fixtures cover it).

Additional audit fixes

  • Version search continuations with a digest of the ordered conversation listing. Additions, removals, reordering, or changes to the resumed transcript now return the existing changed-history error instead of silently skipping or repeating results. Search cursors are now V3; read/evidence cursors retain V2.
  • Skip individual missing or inaccessible filesystem entries without aborting healthy history sources. Incomplete listings are not cached, so recovered access is retried even when the parent directory timestamp stays unchanged. Root and unexpected filesystem errors still propagate.
  • Ignore malformed Claude profile settings while discovering sources, so one invalid disabled profile cannot prevent valid Claude profiles or other providers from loading.
  • Reproduced four regressions before fixing them. The complete focused history selection passes: 23 tests across 5 suites, including file-access recovery and cursor consistency.
  • Required changed-file validation passed the native addon, formatting, lint, both knip stages, server GraphQL validation, and 22 selected tests across 5 files. The cached typecheck could not start because this workspace lacks the required task-cache sandbox; the fresh CI run supplies full typecheck/build/browser coverage.
  • The legacy ChatGPT export reader, export-path setting, and path-entry UI remain fully deleted. No model-facing prompt/schema changes were needed for these fixes.
  • Published commit: f2c52b2. Its Git tree exactly matches the tested local files.
  • Fresh checks for this commit: Fork CI and Agent Context Budget. Both were queued when this section was written. The prior commit's complete Fork CI run passed.

Initial audit follow-up

  • Merged current main and retained full deletion of the legacy ChatGPT export implementation. No export reader, export-path setting, or path-entry UI remains. The only old-key reference is a regression test confirming stored unknown keys are ignored.
  • Fixed JSONL and OpenCode prefilters dropping decoded matches containing JSON escapes or Unicode case folds.
  • Refresh cached transcript metadata so appending an existing conversation updates newest-first ordering.
  • Match Pi ownership by the session-file path T3 actually stores, so T3-owned Pi sessions are excluded.
  • Keep OpenCode evidence tied to its own session while retaining database consistency checks and item-digest validation; unrelated conversations no longer invalidate references.
  • Skip individual unavailable transcripts and keep conversation imports from allocating discarded tool payloads.
  • Shortened the external-history tool description. The measured tool budget is 67,387 bytes, 32 bytes below current main (67,419); no budget gate was weakened.
  • Seven backend regression failures were reproduced before fixing them. Afterward, 232 tests pass across all 18 selected non-browser files: 183 server, 8 mobile component, 23 web unit, 7 client-runtime, 3 contracts, and 8 OpenCode usage tests. Changed-file formatting, lint, generated GraphQL, dependency-patch checks, and the React compiler checks (5 changed files / 10 assertions) pass.
  • The context-budget GitHub workflow passes on the published commit.
  • The required changed-file checker was invoked. This workspace cannot start the task-cache sandbox; its broad root test and unused-export processes exited without diagnostics. A direct no-cache typecheck also terminated with exit 137 at the server package, even with one-CPU affinity, without TypeScript error diagnostics. Full typecheck verification remains outstanding for CI. Focused tests pass as listed above.
  • Both external-history model-evaluation cases pass dry-run prompt/schema construction. Live evaluation is blocked by missing ANTHROPIC_API_KEY; browser verification is blocked before assertions by the environment's Unix-socket restriction. Native device verification remains incomplete.
  • Published commit: 8e267c3. Its Git tree exactly matches the audited local files.
  • Initial workflows: Fork CI and Agent Context Budget.

Original implementation verification

  • Web, real browser, dev server on isolated state against real provider folders: with the switch on and nothing typed, Codex, Claude Code and OpenCode showed as Ready. A Claude search returned 9 matches from 2,108 messages in 5.3 s with no clicks, and a match opened its original text. The same flow was repeated on the current head; see Before and after.
  • A read-only count over 1,645 real Claude sessions: 5 failed to load before the size fix, 0 after.
  • vp run check:changed passes after the rebase (format, lint, knip, typecheck of 42 packages, 19 test files).

Built by Claude Fable 5.2 in Claude Code inside T3 Code, with Codex GPT-6.1 Sol and Claude Sonnet 5.5 as delegates.

🤖 Generated with Claude Code

ScriptedAlchemy and others added 11 commits November 12, 2026 16:52
Show source availability and supported filters before search on web and mobile. Keep manual ChatGPT exports in a collapsed section and describe automatic discovery to agents and users.

Co-Authored-By: Claude Fable 5.2 <[email protected]>
… has 20 matches

A search examined one thread per request, so a no-hit search over 1,843 Claude sessions took about 1,800 "Continue search" clicks. A request now walks threads newest first until it has 20 matches or has read about 4M characters of text or 2,000 threads, then returns a stateless cursor bound to source, query and cwd. Threads that cannot be parsed or change mid-search are skipped instead of ending the search.

Claude and OpenCode stores answer "can this thread contain the query" from raw bytes (a streamed regex over the JSONL file, an instr over message data) before the full parse, only for plain ASCII queries. A skipped thread can only be a thread that the full parse would also have missed, except for an OpenCode hit made solely of U+212A or U+017F.

Measured on this Mac (load average 30+, 1,645 Claude files / 1.1 GiB, 184 OpenCode sessions): a no-hit Claude search went from 26 s of parsing in 1,645 requests to 1.8 to 2.9 s in 1 request, OpenCode from 4.8 s to 0.5 to 0.9 s.

Co-Authored-By: Claude Fable 5.2 <[email protected]>
… by stored id

Only Claude records with the t3-code entrypoint were skipped, and older T3 runs lack it. T3 keeps each provider's native session id on its provider thread, so one batched ProjectionStore lookup per search request now answers which of the listed session ids are T3 threads, and the engine skips those without loading them.

On this Mac the stored id equals the Claude session id and file name for all 1,645 sessions: 304 are T3 threads and only 6 of those carried the marker. For OpenCode it equals the session id for 179 of 184 top-level sessions. Pi stays unmatched because T3 stores Pi's session file path, not its session id.

Co-Authored-By: Claude Fable 5.2 <[email protected]>
Keep valid messages when another JSONL record cannot decode. Accept repeated native IDs using the latest record, skip messages without an ID, and reject files with no transcript records.

Raise the cumulative selected-parser allocation budget from 32 MiB to 128 MiB. A read-only census of 1,645 real Claude sessions changed from 1,640 successful loads and five allocation failures to 1,645 successful loads and no failures. Selected allocation in the failed files peaked at 58,058,328 bytes. One file also contained 12 malformed JSON lines. These are single census runs, not latency benchmarks.

Keep the 32 MiB cache, 100,000-record ceiling, depth ceiling, 64 KiB read chunks, and search budgets. Focused store and engine tests cover malformed-line recovery and search plus digest-verified reads of a 34 MiB session.

Implemented with GPT-6.1 Sol through the Codex harness.

Co-Authored-By: Claude Fable 5.2 <[email protected]>
Keep searching through empty pages until matches appear or the source is exhausted. Show cumulative progress and let the user stop and resume scanning.

Share paging transitions between web and mobile in a pure reducer. Only pages with matches enter previous-page navigation. Ignore stale and duplicate responses, and unsubscribe from the query while stopped or displaying results. Query hooks have no component result callback, so each client delivers completed responses through a reasoned effect.

Update the existing client tests and user guide for automatic following. Pure reducer tests cover consecutive empty pages, exhaustion, previous navigation, and stop and resume. Focused tests and check:changed against ee442a979a pass.

Implemented with GPT-6.1 Sol through the Codex harness.

Co-Authored-By: Claude Fable 5.2 <[email protected]>
…istory

External history now only lists automatically discovered sources. Drops the
chatGptExportPaths setting, the chatgpt_export source kind, the export reader,
the path editor in web and mobile, and the related copy and docs. Stored settings
and older-client patches that still carry chatGptExportPaths decode and ignore it.

Co-Authored-By: Claude Fable 5.2 <[email protected]>
The page still said external history reads configured ChatGPT exports, which
no longer exist.

Co-Authored-By: Claude Fable 5.2 <[email protected]>
@changeset-bot

changeset-bot Bot commented Nov 13, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: cf6ddc2

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Merge current main; fix escaped-text matching, updated-session ordering, Pi ownership, stable OpenCode evidence, unavailable transcripts, and scanner memory bounds. Keep the legacy ChatGPT export reader, configuration and UI deleted. Reduce external-history tool context below the main baseline.
Bind search continuations to the ordered listing and resumed transcript version. Recover from individual inaccessible or disappearing entries without caching incomplete listings. Isolate invalid Claude profiles while retaining full deletion of legacy export history.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant