feat: one archive for Claude Code and Codex — codex-sync, shared-mcp, reconcile capture - #84
Merged
Conversation
… reconcile capture Longhand now captures Codex Desktop / CLI threads (the rollouts under ~/.codex/sessions) into the same ~/.longhand archive the Claude Code hooks write, and holds the second client to the same rules as the first: exact records, stable IDs, nothing stored twice, drift never silent. - `longhand codex-sync`: bounded, exact-record capture by default (no vector model); `--semantic` runs the full pipeline. Defaults 50 sessions / 16 MiB / 20k events; `--dry-run`, `--watch`, `--include-subagents`. - `reconcile --fix` captures Codex too, so the scheduled reconciler keeps both clients current with no extra setup. - `longhand shared-mcp`: four read-only keyword tools over the SQLite archive (no Chroma) — the server Codex talks to, and the way Claude searches Codex history by phrase. - Codex adapter with skip sets for UI mirrors / bookkeeping (Claude-parser precedent), subagent (guardian) threads skipped by default, git ops and error detection on the archive path — including `cmd:` literals inside Codex `exec` scripts — and a regression-gated shapes fixture. - doctor: "Codex capture" row, archived-session remedy (`codex-sync --semantic`; `analyze` never embeds events), Codex drift named by kind. - Fixed: CoreML ONNX ingest failures on macOS (shared CPU-pinned model); `frame-link` (Artifact publish link) triaged; `mcp>=1.2.0` floor (FastMCP). Originally drafted in Codex; reviewed, hardened for CI (mypy, ruff format), dogfooded on a live archive and a fresh-venv wheel install. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LzrMzN4dfuJJKc4UZP6SFb
Rich wraps and hyphenates long option names at the 80-column width CI runs with, so `--include-subagents` was not findable in the rendered text there (all five Linux legs, 578/579 otherwise green). Check the registered command's declared defaults and flags instead; keep the `--help` exit-code checks. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LzrMzN4dfuJJKc4UZP6SFb
Wynelson94
added a commit
that referenced
this pull request
Sep 7, 2026
Longhand now captures Codex Desktop / CLI threads into the same archive the Claude Code hooks write, and holds the second client to the same rules as the first: exact records, stable IDs, nothing stored twice, drift never silent. Version bump + sibling manifests + CHANGELOG heading; the feature itself landed in #84. Also re-pins fieldnote 0002 (project-inference-cwd-mode) to parser.py: #84 changed the file (Codex adapter dispatch, frame-link triage) but not build_session's cwd-mode attribution the note documents, so the prose still holds and only the pin was stale. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LzrMzN4dfuJJKc4UZP6SFb
Wynelson94
added a commit
that referenced
this pull request
Sep 7, 2026
The claim (cwd-mode project attribution in build_session) was re-read against the post-#84 parser and still holds. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LzrMzN4dfuJJKc4UZP6SFb
Wynelson94
added a commit
that referenced
this pull request
Sep 7, 2026
* v1.1.0: one archive for Claude Code and Codex Longhand now captures Codex Desktop / CLI threads into the same archive the Claude Code hooks write, and holds the second client to the same rules as the first: exact records, stable IDs, nothing stored twice, drift never silent. Version bump + sibling manifests + CHANGELOG heading; the feature itself landed in #84. Also re-pins fieldnote 0002 (project-inference-cwd-mode) to parser.py: #84 changed the file (Codex adapter dispatch, frame-link triage) but not build_session's cwd-mode attribution the note documents, so the prose still holds and only the pin was stale. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LzrMzN4dfuJJKc4UZP6SFb * chore: record fieldnote 0002 re-verification after #84 The claim (cwd-mode project attribution in build_session) was re-read against the post-#84 parser and still holds. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LzrMzN4dfuJJKc4UZP6SFb --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Longhand now keeps one archive for Claude Code and Codex. Codex Desktop / CLI threads (the rollouts under
~/.codex/sessions) are captured into the same~/.longhandarchive the Claude Code hooks write, and the second client is held to the same rules as the first: exact records, stable IDs, nothing stored twice, drift never silent.What's in it
longhand codex-sync— bounded, exact-record capture by default (no vector model loaded);--semanticruns the full pipeline sorecalland semanticsearchsee the sessions. Defaults: 50 sessions / 16 MiB / 20,000 events per run;--dry-run,--watch,--include-subagents.reconcile --fixcaptures Codex too, so an installed reconciler keeps both clients current with no extra setup. Report + MCP tool gainedcodex_*fields.longhand shared-mcp— four read-only keyword tools (list_sessionswithsource/projectfilters,search,get_session_timeline,get_event_text) over the SQLite archive, no Chroma. The server Codex talks to, and how Claude searches Codex history by phrase.longhand/codex.py): skip sets for Codex's UI mirrors and bookkeeping (same rule asKNOWN_SKIP_ENTRY_TYPES), encrypted-only reasoning skipped, subagent ("guardian") threads skipped by default, git ops + error detection on the archive path — including thecmd:literals inside Codexexecscripts — so commits made from Codex reachfind_commits.tests/fixtures/codex_shapes/(every record shape seen in the wild, both Codex CLI generations) +tests/test_codex_shapes.py. Unknown shapes are preserved asunknownevents;doctornames Codex drift by nested kind.doctor: "Codex capture" row (only when a Codex home exists); archived Codex sessions split out of "needing analysis" with the remedy that works (codex-sync --semantic—analyzenever embeds events).ONNXMiniLM_L6_V2);frame-link(the Artifact publish link) triaged likepr-link;mcp>=1.2.0floor (FastMCP first shipped there).docs/codex.md, README "Works with Codex", CLAUDE.md note,scripts/com.longhand.codex-sync.plist.template.Verification
ruff check,ruff format --check,mypy longhand,pytest— 580 passed (was 558).doctorgreen.shared-mcpstdio handshake (4 tools, search hit),--semanticupgrade + CLI semantic search hit,reconcile --fixcapturing a new rollout,doctorrows.Notes for review
reconcile) were made deliberately — see the CHANGELOG "Changed" section.CODEX_HOMEto a nonexistent path in the autouse fixture so no test can discover a developer's real~/.codex.Originally drafted in Codex; reviewed and hardened for CI here.
🤖 Generated with Claude Code
https://claude.ai/code/session_01LzrMzN4dfuJJKc4UZP6SFb