You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
fix(server): import Codex chats moved into a project from the scratch folder - #32880
A Codex chat started with No project lives in Codex's scratch folder under ~/Documents/Codex. If the user later moves it into a project in Codex, T3's session import still skips it. Moving a chat in Codex (thread/metadata/update { projectId }) leaves every cwd in the rollout pointing at the scratch folder, which the scanner excludes. Codex records the assignment only in its state database (<CODEX_HOME>/state_5.sqlite: threads.project_id, project_roots).
Reproduced with the real Codex app-server (codex-cli 0.163.0) in an isolated Codex home. A chat started in <home>/Documents/Codex/2026-11-08/new-chat was moved into a project rooted at <home>/code/my-project, and a control chat was started directly in that project. Codex's own thread/list { projectId } returns both chats. On main, T3's scanner offers the project with 1 chat, and recentThreads imports only the control chat.
Change
AgentSessionScanner reads Codex's project assignments read-only, with one query per Codex home: thread ID → project roots. It opens state_5.sqlite with node:sqlite{ readOnly: true }, the same way the server already reads other tools' databases. A missing, older or locked database falls back to the current behaviour.
When a Codex chat's rollout cwd is a path the scanner already excludes (such as the Codex scratch folder) and Codex assigns the chat to a project, the chat uses that project's first root as its cwd. This applies both when grouping scan candidates and when recentThreads checks the chat against the selected project. Chats in any other real directory keep their own cwd, so linked worktrees and other repositories are unaffected.
CODEX_ROLLOUT_ID_PATTERN now captures the thread ID and, for rewound rollouts, the rollout ID separately. The state database is keyed by thread ID, and the existing rewound-history lookup still uses the rollout ID.
vp test run apps/server/src/project/AgentSessionScanner.test.ts: 68 passed at head.
New test: "imports Codex chats moved from a scratch folder into a Codex project" fails on main (expected [ 'Started in the project' ] to deeply equal [ 'Started in the project', 'Started with no project' ]) and passes with the fix.
The same test also covers a rewound rollout (<thread>_<rollout>.jsonl) of a moved chat, and a chat assigned to the project from another real folder, which keeps its own cwd.
New test: "keeps Codex rollout cwds when the Codex state database is unreadable".
CI green on the head.
Runtime transcript: the real scanner, before and after, run against the Codex home that the real Codex app-server wrote:
== before (09a54f01bc)
SCAN candidates: [{"path":"<fakehome>/code/my-project","threadCount":1}]
RECENT THREADS for <fakehome>/code/my-project [{"tag":"Importable","id":"01a1ba2e-13b8-…","title":"Reply with the single word: hi"}]
== after (60005e5afd)
SCAN candidates: [{"path":"<fakehome>/code/my-project","threadCount":2}]
RECENT THREADS for <fakehome>/code/my-project [{"tag":"Importable","id":"01a1ba2e-13b8-…","title":"Reply with the single word: hi"},{"tag":"Importable","id":"01a1ba2e-0a2e-…","title":"Reply with the single word: hello"}]
What Codex wrote (rollout cwds and state database), synthetic data
Codex app-server (codex-cli 0.163.0), isolated CODEX_HOME=<fakehome>/.codex, driver: codex-driver.mjs
turn 01a1ba2e-0a2e-74f2-9b6e-687336ad6045 completed
project 01a1ba2e-13a5-7242-bfe1-ebcc2e4218db [{"path":"<fakehome>/code/my-project"}]
moved thread after update: cwd= <fakehome>/Documents/Codex/2026-11-08/new-chat projectId= 01a1ba2e-13a5-7242-bfe1-ebcc2e4218db path= <fakehome>/.codex/sessions/2026/11/08/rollout-2026-11-08T08-02-21-01a1ba2e-0a2e-74f2-9b6e-687336ad6045.jsonl
turn 01a1ba2e-13b8-7f10-ba05-18b6d8c520ff completed
threads in project: [{"id":"01a1ba2e-13b8-7f10-ba05-18b6d8c520ff","cwd":"<fakehome>/code/my-project","projectId":"01a1ba2e-13a5-7242-bfe1-ebcc2e4218db"},{"id":"01a1ba2e-0a2e-74f2-9b6e-687336ad6045","cwd":"<fakehome>/Documents/Codex/2026-11-08/new-chat","projectId":"01a1ba2e-13a5-7242-bfe1-ebcc2e4218db"}]
Rollout records carrying a cwd:
rollout-2026-11-08T08-02-21-01a1ba2e-0a2e-74f2-9b6e-687336ad6045.jsonl
session_meta cwd=<fakehome>/Documents/Codex/2026-11-08/new-chat
turn_context cwd=<fakehome>/Documents/Codex/2026-11-08/new-chat
rollout-2026-11-08T08-02-24-01a1ba2e-13b8-7f10-ba05-18b6d8c520ff.jsonl
session_meta cwd=<fakehome>/code/my-project
turn_context cwd=<fakehome>/code/my-project
state_5.sqlite threads(id, cwd, project_id) and project_roots:
01a1ba2e-0a2e-74f2-9b6e-687336ad6045|<fakehome>/Documents/Codex/2026-11-08/new-chat|01a1ba2e-13a5-7242-bfe1-ebcc2e4218db
01a1ba2e-13b8-7f10-ba05-18b6d8c520ff|<fakehome>/code/my-project|01a1ba2e-13a5-7242-bfe1-ebcc2e4218db
01a1ba2e-13a5-7242-bfe1-ebcc2e4218db|0|<fakehome>/code/my-project
Codex app-server driver used for the reproduction (scratch, not committed)
import{spawn}from"node:child_process";importreadlinefrom"node:readline";constHOME=process.argv[2];constscratch=`${HOME}/Documents/Codex/2026-11-08/new-chat`;constproject=`${HOME}/code/my-project`;constchild=spawn("codex",["app-server"],{env: { ...process.env,HOME,CODEX_HOME: `${HOME}/.codex`},stdio: ["pipe","pipe","inherit"]});constrl=readline.createInterface({input: child.stdout});letid=0;constpending=newMap();constwaiters=[];rl.on("line",(l)=>{constm=JSON.parse(l);if(m.id!==undefined&&pending.has(m.id)){pending.get(m.id)(m);pending.delete(m.id);return;}if(m.method){for(constwof[...waiters])if(w.pred(m)){waiters.splice(waiters.indexOf(w),1);w.res(m);}}});constcall=(method,params)=>newPromise((res)=>{consti=++id;pending.set(i,(m)=>{if(m.error)console.log("ERR",method,JSON.stringify(m.error));res(m.result);});child.stdin.write(JSON.stringify({id: i, method, params })+"\n");});constwaitFor=(pred)=>newPromise((res)=>waiters.push({ pred, res }));awaitcall("initialize",{clientInfo: {name: "repro",version: "0"},capabilities: {experimentalApi: true}});child.stdin.write(JSON.stringify({method: "initialized"})+"\n");asyncfunctionchat(cwd,text,projectId){const{ thread }=awaitcall("thread/start",{ cwd, ...(projectId ? { projectId } : {})});constdone=waitFor((m)=>m.method==="turn/completed"&&m.params.threadId===thread.id);awaitcall("turn/start",{threadId: thread.id,input: [{type: "text", text }]});constc=awaitdone;console.log("turn",thread.id,c.params.turn.status);returnthread.id;}constmoved=awaitchat(scratch,"Reply with the single word: hello",null);const{project: p}=awaitcall("project/create",{idempotencyKey: "k1",name: "my-project",roots: [{path: project}]});console.log("project",p.id,JSON.stringify(p.roots));constupd=awaitcall("thread/metadata/update",{threadId: moved,projectId: p.id});console.log("moved thread after update: cwd=",upd.thread.cwd,"projectId=",upd.thread.projectId,"path=",upd.thread.path);constcontrol=awaitchat(project,"Reply with the single word: hi",p.id);constlist=awaitcall("thread/list",{projectId: p.id});console.log("threads in project:",JSON.stringify(list.data.map((t)=>({id: t.id,cwd: t.cwd,projectId: t.projectId}))));console.log(JSON.stringify({ moved, control }));child.kill();
Evidence
Server-only change, so the captures are before/after transcripts of the real AgentSessionScanner (scan candidates and recentThreads results), with a warm scan→recentThreads sequence and a cold recentThreads on a fresh scanner in every fixture. Viewport and theme do not apply. Environment: Node v26.12.1, Linux x86_64, synthetic Codex homes using the state_5.sqlite schema the real codex-cli 0.163.0 app-server creates (schema receipt, schema dump, probe). 30 scanner invocations, all with matching fixture hashes on both sides (receipts). Fixture matrix, index.
What else changed: nothing outside the mapped-chat rows. In the composite fixture the project's count rises from 1 to 5 (the moved chat plus three rewind files), which also moves its last activity forward.
Unverified: cannot-verify macos (Codex Desktop end to end; the move was driven through the same app-server request Codex uses). A Codex sqlite_home setting that relocates the state database keeps the current behaviour.
AI-assisted; verified with the tests and tools listed above.
…ot imported
Codex Desktop starts "No project" chats in ~/Documents/Codex/<date>/<slug>
and records a later move into a project only in state_5.sqlite. The
rollout keeps the scratch cwd, so the session scanner never offers the
moved chat under the project. This test reproduces #32873 and fails on main.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
…older
Codex Desktop starts "No project" chats in ~/Documents/Codex/<date>/<slug>
and records a later move into a project only in its state DB
(state_5.sqlite). The rollout keeps the scratch cwd, which T3 excludes, so
the session scanner never offered the moved chat under its project.
Codex discovery now reads the thread-to-project roots from that DB
read-only, once per Codex home. A chat whose rollout cwd lies outside its
Codex project's roots is grouped and imported under the project's first
root; chats already inside the project keep their own cwd. A missing,
locked or unreadable DB leaves the old behaviour unchanged.
Fixes#32873
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Chats assigned to a Codex project but running in another real directory,
such as a linked worktree, keep their own cwd.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Macroscope's review found this PR approvable — This enables discovery and import of Codex chats moved from scratch folders into projects using local project metadata. Database access is read-only, failures preserve existing behavior, and destination checks remain in place.
No code changes detected at 6d24bd7. Prior analysis still applies.
You can add or adjust custom eligibility rules. Learn more.
Reviewing files that changed from the base of the PR and between df3ffc1 and 6d24bd7.
You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.
Use the checkbox below for a quick retry:
Trigger review
No actionable comments were generated in the recent review.
Walkthrough
The scanner now reads Codex project-root mappings from state_5.sqlite and uses them when grouping rollout transcripts and matching recent threads to workspaces. It also recognizes updated rollout filename forms and supports inherited rollout lookup through an optional second UUID suffix.
Changes: Codex session scanning
Layer / File(s)
Summary
Read Codex project-root state apps/server/src/project/AgentSessionScanner.ts, apps/server/src/project/AgentSessionScanner.test.ts
The scanner reads thread-to-project-root mappings from state_5.sqlite, skips invalid roots, and returns an empty mapping if reading fails. The test covers unreadable database contents.
Codex rollout transcripts are associated with mapped project roots. Resolved working directories are used for workspace grouping and recent-thread matching. Rollout lookup supports an optional second UUID suffix. Tests cover project-associated chats with scratch-directory working paths.
pingdotgg/t3code#32122: Both changes affect inherited-history handling and rollout lookup for rewound Codex sessions.
Suggested labels:bugfix
Suggested reviewers:marcodotio, macroscopeapp
Merge Risk: Minimal · previous review 75e3f
The change lets Codex chats moved into a project be imported with that project, and it falls back to the existing behavior if the Codex state database is missing or unreadable. No merge-blocking risk was identified.
Pre-merge checks: 4
Check name
Status
Explanation
Title check
The title names the main change: Codex chats moved into a project from the scratch folder are now imported. It follows the conventional commit form and matches the code changes in AgentSessionScanner,…
Linked Issues check
Objective [#32873]: when a Codex chat started in the scratch folder is assigned to a project in Codex, T3 import must include it with the control chat. Implementation at head: (1) readCodexProjectRoot…
Out of Scope Changes check
All changed hunks in AgentSessionScanner.ts connect to the issue. The node:sqlite import and readCodexProjectRoots are the state-database source for the project mapping. CodexStateReadError and the fa…
Description check
The description includes the required Problem, Change, Scope and approval, and Verification sections. It explains the issue and expected behavior, links the related issue, and reports focused tests, r…
Full details: Title check
Explanation
The title names the main change: Codex chats moved into a project from the scratch folder are now imported. It follows the conventional commit form and matches the code changes in AgentSessionScanner, which resolve project roots for excluded scratch-folder cwds.
Full details: Linked Issues check
Explanation
Objective [#32873]: when a Codex chat started in the scratch folder is assigned to a project in Codex, T3 import must include it with the control chat. Implementation at head: (1) readCodexProjectRoots reads thread ID to project roots from <CODEX_HOME>/state_5.sqlite with DatabaseSync and readOnly: true. (2) projectCwd replaces a rollout cwd with the project's first root only when the rollout cwd matches isExcludedProjectPath. (3) projectCwd is applied in candidate grouping (discoverable cwd key) and in recentThreads matching, so the moved chat groups under the project and passes the selected-project check. Chats in other real directories keep their own cwd. A missing, older, or locked database returns an empty map, so the existing behavior remains. Evidence limits: the diff confirms this logic. The test results and the 1-to-2 runtime transcript are author-reported; I did not run the tests. The macOS Codex Desktop flow is not verified end to end. The issue states those desktop steps are not required coding work. The objective is met by the code at head.
Full details: Out of Scope Changes check
Explanation
All changed hunks in AgentSessionScanner.ts connect to the issue. The node:sqlite import and readCodexProjectRoots are the state-database source for the project mapping. CodexStateReadError and the fallback provide the required read-only, unreadable-database behavior. MAX_CODEX_PROJECT_ROOT_ROWS bounds that read. projectCwd and its uses in grouping and recentThreads implement the moved-chat behavior. CODEX_ROLLOUT_ID_PATTERN now captures thread and rollout IDs separately. The rewound-history lookup uses match[2] ?? match[1], which keeps the rollout ID for that lookup and the thread ID for the state database. The discovery and candidate types carry projectRoots only to support these paths. No unrelated behavior change appears in the diff. The test file changes are supporting coverage for the same behavior, as stated in the PR description.
Full details: Description check
Explanation
The description includes the required Problem, Change, Scope and approval, and Verification sections. It explains the issue and expected behavior, links the related issue, and reports focused tests, runtime evidence, and unverified cases. The author notes AI assistance but does not name the model and harness, as the template requests.
Finishing Touches
Generate docstrings
Commit to this branch
Create a new PR
Generate unit tests (beta)
Commit to this branch
Create a new PR
Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.
Environment for both sides: real web app and server in separate worktrees; Linux Chromium, 1280×800, light theme, fresh T3 databases, identical synthetic Codex history.
Steps: seed one chat with an original scratch-folder cwd and a current project assignment, plus one chat started directly in that project. Open the welcome wizard → Review all 1 → Other folders → Select all → Import 1 project and start. Expand Settled and inspect imported chats.
Private operational details are masked. Final stills passed the 500 ms identical-capture check. Codex Desktop's macOS move interaction was represented by synthetic on-disk history; it was not executed here.
AI-assisted; verified with the tests and tools listed above.
Not shown:
Creating and moving a chat in Codex Desktop on macOS was not executed: this Linux VM used synthetic rollouts and state_5.sqlite project assignments.
Rewound rollout handling, multiple project roots, and missing or unreadable Codex database fallback were not exercised by this two-chat reproduction.
Authenticated Codex continuation was not exercised. The installed CLI rejected the minimal synthetic database during its provider probe; the real welcome import still completed on both sides.
* fix(server): one finished turn looks up its branch's pull request once (pingdotgg#33752)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(mobile): Android Files sheet scrolls its tree instead of dragging the sheet (pingdotgg#33223)
Co-authored-by: maria-rcks <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(web): prompt suggestions show after a steered turn (pingdotgg#33706)
Co-authored-by: Nathan Wong <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
* fix(server): usage prices Claude Mythos 5.2 from its Bedrock rate (pingdotgg#33721)
* fix(server): Claude turns whose CLI exits before its first frame fail instead of running forever (pingdotgg#33008)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(web): panel resize handles follow touch drags (pingdotgg#33066)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(server): signed-out Claude instances with their own config dir name it in the sign-in hint (pingdotgg#32951)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* perf(server): opening a long thread reads from its latest segments, not its whole history (pingdotgg#33305)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(server): repos without a remote no longer record failed spans on status refresh (pingdotgg#32905)
Co-authored-by: ferhtgoldaraz <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
* fix(mobile): missing files in previews name the checked path instead of asking to reconnect (pingdotgg#32994)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(server): a restart that misses its turn starts as a new turn (pingdotgg#32899)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(desktop): new browser tabs no longer lose waits, clicks and snapshots for good (pingdotgg#32861)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(web): Go to source on a side chat quote keeps you on its parent thread (pingdotgg#33160)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(server): removing a queued completion message keeps its siblings' wakes (pingdotgg#32815)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(server): dev database seed drops active pull request watches (pingdotgg#32744)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(server): capture iOS screenshots on Xcode 26's simctl (pingdotgg#28353)
Co-authored-by: PR Batch Tester <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(mobile): medium Android windows keep the rail's room and the sidebar's place (pingdotgg#33021)
Co-authored-by: dongxingong <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
* fix(web): notify when a new request replaces the pending one in a run (pingdotgg#32719)
* fix(server): Codex first-request usage limits keep their reset time (pingdotgg#27791)
Co-authored-by: PR Batch Tester <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: maria-rcks <[email protected]>
* fix(web): minimap next turn is disabled at the bottom of a thread (pingdotgg#33038)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(cursor): a steer keeps the prompt it interrupted (pingdotgg#32583)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* test: remove redundant short-string truncation test (pingdotgg#33867)
Co-authored-by: t3-code[bot] <269035359+t3-code[bot]@users.noreply.github.com>
* fix(pi): Pi models whose provider ID contains a slash can be selected (pingdotgg#32585)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* perf(server): MCP tool calls no longer read the caller's whole thread (pingdotgg#33295)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(ssh): concurrent launches on one remote home share one server (pingdotgg#32587)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(mobile): iOS 18 iPad sidebar and thread feed start below the header (pingdotgg#32936)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(web): Tab reaches the add-project and new-project submit buttons (pingdotgg#32605)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(web): screen readers hear the add-project submit shortcut (pingdotgg#32576)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(server): Antigravity limits read the quota host the account is metered on (pingdotgg#32425)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(web): the thread menu works for an older settled thread the sidebar hasn't loaded (pingdotgg#32507)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(opencode): show questions asked while OpenCode wakes a session on its own (pingdotgg#32434)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(server): blank .gitignore lines no longer make checkpoints drop new files (pingdotgg#32374)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* test(web): minimap next-turn test no longer flakes after a resize (pingdotgg#33964)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* feat(opencode): mirror native goals across clients (pingdotgg#33758)
OpenCode native goals were missing from the shared goal projection and turn lifecycle. Synchronize goal state and continuation executions, gate dispatch on supported connected versions, and preserve older-version commands and provider-switch context.
Handle reconnect freshness, pending steers, delayed control replies, and unreadable goal updates without losing tracked work. Reuse the existing goal UI across clients.
Verified with check:changed, 264 affected tests, focused Codex/Claude goal tests, and CI. Live provider and manual client verification were not performed.
Created with GPT-6.1 Sol through the Codex harness.
* feat(web): bindable shortcut to regenerate a thread's title (pingdotgg#33987)
Co-authored-by: Sharan Yalburgi <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(server): linked projects keep their repository identity while it refreshes (pingdotgg#32359)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(mobile): tool call commands are highlighted and monospaced like on web (pingdotgg#33957)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix: Claude monitor wakes no longer fire a completion alert per line (pingdotgg#32520)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(server): removed thread worktrees keep their project's skills in the picker (pingdotgg#32471)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(web): drag command palette threads into the composer (pingdotgg#33990)
* fix(shared): show zero seconds in minute durations (pingdotgg#33994)
* fix(web): closing the right panel returns focus to where it was (pingdotgg#32569)
* fix(server): say why threads without a project are unavailable (pingdotgg#32342)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix: chat file links open the file agents cite (pingdotgg#33943)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(clients): scroll truncated command output notice with logs (pingdotgg#34011)
* fix(web): show app bundle icons and open apps from markdown links
macOS app-bundle links now display their native icons and offer Open app on eligible local hosts. Reuse the desktop host environment identity and direct loopback detection to keep launches local.
Resolve icons from the exact bundle path, expand home-relative icon and file-manager paths on the server, and require filesystem-read permission for path-selected icons.
Validated with focused regressions, a real Calculator icon and app launch, and green CI and automated reviews on e3e8b78. All review threads are resolved.
GPT 6.1 Sol via the Codex harness in T3 Code.
* feat(opencode): project native todo updates into checklists
Project successful OpenCode native todowrite results into T3 checklists, including reconnect recovery, status changes, cancelled tasks, and clears. Preserve failed and unrecognized tool results.
Validated with check:changed, 124 tests, full PR CI, and a real OpenCode 2.2.6 / MiniMax M3.1 Flash Free run through the dev web UI.
Model: GPT 6.1 Sol. Harness: Codex.
* fix(antigravity): recognize Gemini 4 Carbon and its quota (pingdotgg#33991)
* perf(client): reopening a finished command row no longer refetches its output (pingdotgg#34002)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* perf(server): user-only message reads use the user-message index for ordinals (pingdotgg#33009)
* fix(web): keep HTML previews anchored when accordions expand (pingdotgg#34003)
* fix(web): preserve search result titles in drag previews (pingdotgg#34017)
* fix: file links with line ranges open at their first line (pingdotgg#34006)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(codex): show image generation tool calls
Codex image generation now appears as a timeline tool row with prompt and transparency inputs, completion results, failures, and cancellation. Retain inputs on cancellation and give image-only replies a separate message ID so they cannot replace the tool row.
Verified with a real image generation and collapsed/expanded UI captures. check:changed passes, including 152 tests; CI and agentic reviews pass on 86d2045.
Model: GPT 6.1 Sol via the Codex harness.
* fix(pi): a steer Pi has not read yet shows as waiting, not steered (pingdotgg#33982)
* fix(server): provider switches hand off started cancelled runs (pingdotgg#34016)
* fix(web,mobile): replace sparkles icons and ban them with a lint rule (pingdotgg#25422)
* fix(github): a proxy's 403 with Retry-After is no longer reported as a rate limit (pingdotgg#33676)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(web): sending from an empty citation comment clears the composer (pingdotgg#33440)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(server): text generation fallback respects project provider settings (pingdotgg#33741)
Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
* feat(usage): show Muse Code limits, and xAI and Antigravity accounts from a CLIProxyAPI hub (pingdotgg#33800)
Co-authored-by: maria-rcks <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
* fix(web): preserve previews during attachment preparation (pingdotgg#33949)
* fix(desktop): input during window teardown no longer throws in the main process (pingdotgg#33620)
* fix(web): sent messages keep the numbers written on list items (pingdotgg#33820)
Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: Yash Singh <[email protected]>
* fix(server): quitting stops an agent-device daemon left by an earlier server (pingdotgg#33587)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(mobile): attaching larger images no longer crashes with a BigInt error (pingdotgg#34087)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* feat(mobile): pick a voice environment once, then its method (pingdotgg#34073)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(server): a t3 thread send to a finished delegated child notifies its parent (pingdotgg#33446)
* fix(web): question panel header text sits centered in its row (pingdotgg#34095)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* feat(scripts): scenarios prove a fix in the real app with e2e, on web and iOS (pingdotgg#34007)
Co-authored-by: Claude Fable 5.2 <[email protected]>
* feat(claude): Fable resets are offered and redeemed apart from weekly resets (pingdotgg#34106)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(desktop): desktop IPC only answers the main app window (pingdotgg#34094)
Co-authored-by: Claude Fable 5.2 <[email protected]>
* feat(server): voice models reuse copies already on disk (pingdotgg#34096)
Co-authored-by: Claude Fable 5.2 <[email protected]>
* fix(web): scroll project picker to top on first result (pingdotgg#34113)
* feat(opencode): track native image job outcomes and previews (pingdotgg#34089)
OpenCode image-generation tool success acknowledges a launched background job. Keep that job pending until its native outcome arrives, retain the outcome on the original tool item, and serve size-limited image previews through existing rendering and remote file paths.
Recover outcomes after stream loss, allow later exact-path notices to add previews, and clear descendant image tasks from parent rosters on completion or transport failure. Keep older-server fallback and the pinned SDK.
Validation: check:changed passed with 147 tests; required CI passed and review findings were addressed on 62addc8. Client screenshots use controlled fixtures; no paid image generation was used.
Model: GPT 6.1 Sol. Harness: Codex in T3 Code.
* fix(scripts): scenarios run where localhost resolves to IPv6 first (pingdotgg#34121)
Co-authored-by: Claude Fable 5.2 <[email protected]>
* ci: browser secret helper apt step fetches fewer indexes (pingdotgg#33966)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(client-runtime): a search query pasted from github.com lists pull requests again (pingdotgg#30150)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(web): tighter outdated-conversation cards in the PR code panel (pingdotgg#34140)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(web): MCP App cards no longer flash white in dark mode while the app loads (pingdotgg#33352)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(peer): link requests use the addresses the app already has for a machine (pingdotgg#34139)
Co-authored-by: Claude Mythos 5.2 <[email protected]>
* fix(server): Find frees searched thread text after one idle minute (pingdotgg#34132)
Co-authored-by: Claude Fable 5.2 <[email protected]>
* fix(web): settings search shortcuts follow the physical key on non-US layouts (pingdotgg#33395)
* fix(server): import Codex chats moved into a project from the scratch folder (pingdotgg#32880)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(desktop): clear stale GPU caches when the Electron version changes (pingdotgg#33641)
* fix(web): PR links jump to the comment, diff line, checks or commits they name (pingdotgg#33989)
Co-authored-by: Md.Sadiq <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(cli): installers retry transient GitHub errors (pingdotgg#32913)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(web): opening the terminal with Cmd+J no longer re-renders the whole sidebar (pingdotgg#33129)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* refactor(web): remove icon morphing (pingdotgg#33985)
Toggle and copy icons swap instantly through lucide-react again. Drops the
MorphIcon wrapper plus the morphicons and vanilla lucide dependencies that
only it used.
* feat(opencode): track native shell jobs across turns
## Problem
OpenCode shell tools can return when a background command launches. T3 now keeps that command in its existing background activity UI until it exits or is stopped, retains captured output, and preserves native completion notifications and continuation turns.
## Change
The adapter scopes tracking and Stop to the owning session and its descendants. Recovery uses the experimental shell-job inventory on OpenCode 2.2.6+, with shell-list fallback on supported older servers. After a cold resume, recovered output, terminal state, and idle roster snapshots persist through the existing session event pump before another turn starts. New session-scoped activity is restricted to attached threads and uses the persisted run identity when available so it stays in the current timeline. Polling reads run outside the adapter lock, with stale results discarded after Stop, exit, or another read. Recovery and Stop retain bounded I/O. Final reads retain the output tail, including diagnostics beyond the first four pages. The SDK remains pinned to 2.0.28, and main's native goals, todo checklists, and image jobs are preserved.
## Scope and approval
Maintainer-directed implementation of native OpenCode background shell tracking from the T3 Code handoff. Scope covers shell lifecycle, output retention, recovery, ownership, and Stop using existing background activity services and rendering. The session event pump extension is needed to persist recovered activity while no turn is active. No SDK upgrade, new UI, or provider-wide infrastructure is included. The author, Yash-Singh1, is explicitly listed in the repository's [contribution-triage exemptions](https://github.com/pingdotgg/t3code/blob/main/.github/TRIAGE_EXEMPTIONS.td), verified against upstream main.
## Verification
Validation: `vp run check:changed` passes. Focused regressions cover output paging, exit codes, idle recovery, persisted run anchors, ownership, cancellation failures, and a stalled poll that must not block turn completion or Stop. Real OpenCode UI turns used MiniMax M3.1 Flash Free against isolated development state and covered launch, Details and retained output, natural completion, continuation, and explicit Stop. Cold-idle persistence and remote-server paths use protocol fixtures; native mobile was not exercised.
GPT 6.1 Sol through the Codex harness.
* fix(server): restart send stops a Claude turn and runs the message next (pingdotgg#32902)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(shared): login-shell environment probe ignores DEBUG trap output (pingdotgg#32646)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(web): make Q&A option outlines visible across themes (pingdotgg#34178)
* fix(web): hide empty replies when renders show the result (pingdotgg#34182)
* fix(web): mouse tilt wheel no longer switches threads on Windows and Linux desktop (pingdotgg#32963)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(web): timeline minimap preview no longer steals hover or jumps around (pingdotgg#32151)
Co-authored-by: Julius Marminge <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(server): auto thread sends queue while a turn is stopping (pingdotgg#34163)
Co-authored-by: Julius Marminge <[email protected]>
* fix(server): stream the usage-scan cache to disk instead of one string (pingdotgg#34030)
* fix(clients): images the agent opens stay visible in the chat (pingdotgg#30473)
Co-authored-by: maria-rcks <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
* fix(client-runtime): pasted repository page URLs clone the repository into its own folder (pingdotgg#32681)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(web): trackpad flicks over the right panel tabs no longer navigate back (pingdotgg#33396)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix: new threads move from draft to Working in one step (pingdotgg#33783)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(gitlab): review comments can cover a range of lines (pingdotgg#30535)
Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: maria-rcks <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
* test(web): right panel tab swipe test runs as macOS on any CI host (pingdotgg#34191)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(shared): cite assistant messages with IDs over 512 characters (pingdotgg#28084)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(server): updates copy the database while the server still runs when it cannot be cloned (pingdotgg#33058)
Co-authored-by: Ajraba04 <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
* fix(mobile): file links in question cards open the file viewer (pingdotgg#29151)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(server): cloning into a stranded clone project's empty folder reuses that project (pingdotgg#33439)
* fix(desktop): stable updates no longer show a nightly's release notes (pingdotgg#32832)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(shared): Open in Zed ignores the OpenZFS zed daemon on Linux (pingdotgg#33479)
* fix(mobile): chat code blocks colour diff, kotlin, sql and other languages again (pingdotgg#33680)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(server): fork Claude threads after project root changes (pingdotgg#22836)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(web): snooze times read naturally in context menus (pingdotgg#24945)
Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
* feat(web): label chips show the label's description on hover (pingdotgg#28732)
Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: maria-rcks <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
* feat(web): composer strip names the worktree folder (pingdotgg#28459)
Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
* feat(gitlab): revert a merged merge request (pingdotgg#30556)
Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: maria-rcks <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
* fix(claude): version errors from a custom endpoint no longer say to run claude update (pingdotgg#34176)
Co-authored-by: Julius Marminge <[email protected]>
* fix(web): files marked Viewed stay folded when a pull request's Code tab opens again (pingdotgg#34168)
Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
* feat(server): watched GitHub pull requests react to host events, not only the 2-minute sweep (pingdotgg#33548)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(server): hide passive Claude Stop-hook summaries (pingdotgg#22964)
* fix(web): dismiss image path tooltips after preview and scroll (pingdotgg#30620)
Co-authored-by: Julius Marminge <[email protected]>
* fix(server): PR sync and run-status checks stop reading whole thread histories (pingdotgg#25728)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(server): preview snapshots keep page text beside large accessibility trees (pingdotgg#33745)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* feat(web): screen readers can hear the agent's messages and steps during a turn (pingdotgg#33900)
Co-authored-by: Claude Fable 5.2 <[email protected]>
* fix(server): thread search finds phrases inside quotes and their comments (pingdotgg#22553)
Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
* fix(web): local server cards in the browser empty state take pointer clicks (pingdotgg#34050)
* fix(server): worktrees cut from a non-default base no longer show the base's PR (pingdotgg#22861)
Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
* fix(desktop): wait for the local server to exit when quitting (pingdotgg#22996)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(server): agent continuations preserve the working timer start (pingdotgg#22947)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(web): disable the git actions menu when nothing in it is usable (pingdotgg#31972)
Co-authored-by: Julius Marminge <[email protected]>
* fix(server): preserve active turns when switching provider instances (pingdotgg#22755)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(server): scheduled task updates keep the saved workspace unless the binding changes (pingdotgg#32494)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(web): full-screen HTML pages fit their content and zoom by reflowing (pingdotgg#22349)
Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
* fix(web): project actions auto-open Preview in web clients (pingdotgg#34048)
* fix(server): a follow-up delegated task waits for a run its child queued on its own thread (pingdotgg#32504)
* fix(server): new worktrees refresh their index once, so captures and status stop re-hashing every file (pingdotgg#21341)
Co-authored-by: maria-rcks <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
* fix(usage): Grok and Cursor usage limits show pace and the even-spend line (pingdotgg#21897)
Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: maria-rcks <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
* fix(web): retain diff selection across navigation (pingdotgg#22347)
Co-authored-by: Lukas Tomondy <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
* fix(mobile): subscription widget no longer expires on a window that already reset (pingdotgg#22993)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(opencode): verify CLI updates when loopback server is still running (pingdotgg#22839)
Co-authored-by: maria-rcks <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
* fix(usage): Claude subagent output is no longer undercounted (pingdotgg#20276)
Co-authored-by: Julius Marminge <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(server): a remote update points the service unit at the runtime it committed (pingdotgg#19652)
Co-authored-by: Julius Marminge <[email protected]>
* fix(server): a limited provider's queue stays held after another provider's turn succeeds (pingdotgg#22425)
Co-authored-by: Mantas Kantautas <[email protected]>
Co-authored-by: maria-rcks <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(shared): keep spreadsheet shorthand as inline code (pingdotgg#23203)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(web): offer retry while an environment reconnects (pingdotgg#23194)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(server): custom Codex providers no longer report native quota (pingdotgg#18622)
Co-authored-by: Claude Sonnet 5.5 <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
* fix(desktop): Cmd+F now searches the page in the integrated browser (pingdotgg#22960)
Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
* fix(desktop): an SSH password prompt that ended leaves the dialog instead of stacking (pingdotgg#34192)
Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
* fix(web): render Claude insight blocks as a callout (pingdotgg#22239)
Co-authored-by: macodev00 <[email protected]>
Co-authored-by: maria-rcks <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
* fix(scheduler): show short server timezone on fixed-time labels (pingdotgg#23111)
Co-authored-by: Shaun Hawk <[email protected]>
Co-authored-by: Cursor <[email protected]>
Co-authored-by: maria-rcks <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
* fix(web): focus the primary action when confirmation dialogs open (pingdotgg#18187)
Co-authored-by: Roger Vilaseca <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
* fix(web): Changes row matches the diff comparison (pingdotgg#19553)
Co-authored-by: Julius Marminge <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(server): imported ACP sessions show their native history (pingdotgg#22155)
Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: maria-rcks <[email protected]>
Co-authored-by: Alan Justino da Silva <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
* fix(preview): always return evaluated results by value (pingdotgg#22948)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(provider-core): a model reply of "title" no longer replaces the thread title (pingdotgg#25743)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(desktop,web): Open in runs locally for a background service sharing the desktop's T3 home (pingdotgg#21661)
Co-authored-by: maria-rcks <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
* fix(web): question answers submit while normal sends are blocked (pingdotgg#22874)
Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
* fix(server): cancelling a background-only delegated task reports it interrupted (pingdotgg#21676)
Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: maria-rcks <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
* fix(web): fall back to a readable server for shared repositories (pingdotgg#21530)
Co-authored-by: maria-rcks <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
* fix(web): composer follows an optionless thread instead of the settings default (pingdotgg#16546)
Co-authored-by: Julius Marminge <[email protected]>
* fix(web): don't save retention age until committed (pingdotgg#22208)
Co-authored-by: macodev00 <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(server): one dropped probe no longer lists a live linked peer as unreachable (pingdotgg#34208)
* chore(release): prepare v0.1.9
* fix(server): preview automation reports ambiguous selectors instead of calling them invalid (pingdotgg#34205)
* fix(opencode): a context overflow that OpenCode compacts no longer fails the turn (pingdotgg#26743)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(web): Ctrl + "+" zooms on keyboard layouts with a dedicated plus key (pingdotgg#26408)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(ci): release version bump push retries when main moves (pingdotgg#34326)
Co-authored-by: Claude Fable 5.2 <[email protected]>
* fix(server): CLI commands no longer migrate the database of a running server (pingdotgg#26763)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(web): keep saved default model when changing effort (pingdotgg#22193)
Co-authored-by: macodev00 <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(web): reveal expanded work rows hidden behind the composer (pingdotgg#21968)
Co-authored-by: maria-rcks <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
* fix(composer): steer instead of queueing during automatic compaction (pingdotgg#24138)
Co-authored-by: maria-rcks <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
* feat(gitlab): resolve overview threads from Summary and Timeline (pingdotgg#30575)
Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: maria-rcks <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
* fix(web): pull request search keeps partial-word matches after GitHub answers (pingdotgg#26992)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(server): Claude subagents no longer show the parent's effort (pingdotgg#17042)
Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>
* fix(server): runs cancelled by a server restart say why in the thread (pingdotgg#27192)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix(client-runtime): server updates stop waiting 32 minutes when the host returns without this update's outcome (pingdotgg#27275)
Co-authored-by: Claude Opus 5.5 <[email protected]>
* fix: preserve Claude dead-query errors after upstream sync
* fix: retain quick-message IPC trust and Cursor steering fixture
---------
Co-authored-by: Julius Marminge <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: Radek Maňák <[email protected]>
Co-authored-by: maria-rcks <[email protected]>
Co-authored-by: Nathan Wong <[email protected]>
Co-authored-by: Nathan Wong <[email protected]>
Co-authored-by: Theo Browne <[email protected]>
Co-authored-by: Fernando H-T Goldáraz <[email protected]>
Co-authored-by: ferhtgoldaraz <[email protected]>
Co-authored-by: shivam <[email protected]>
Co-authored-by: PR Batch Tester <[email protected]>
Co-authored-by: dongxingong <[email protected]>
Co-authored-by: dongxingong <[email protected]>
Co-authored-by: t3-code-bot[bot] <269035359+t3-code-bot[bot]@users.noreply.github.com>
Co-authored-by: t3-code[bot] <269035359+t3-code[bot]@users.noreply.github.com>
Co-authored-by: Yash Singh <[email protected]>
Co-authored-by: Sharan Yalburgi <[email protected]>
Co-authored-by: Sharan Yalburgi <[email protected]>
Co-authored-by: Maxim <[email protected]>
Co-authored-by: oliver <[email protected]>
Co-authored-by: Muzammil Hussain <[email protected]>
Co-authored-by: Wout Stiens <[email protected]>
Co-authored-by: Anton 🌻 <[email protected]>
Co-authored-by: Md.Sadiq <[email protected]>
Co-authored-by: NoomStuff <[email protected]>
Co-authored-by: Tanav Poswal <[email protected]>
Co-authored-by: Federico Infelici <[email protected]>
Co-authored-by: Antony <[email protected]>
Co-authored-by: Bin Jamshid <[email protected]>
Co-authored-by: Ajraba04 <[email protected]>
Co-authored-by: M.Umais Adeed <[email protected]>
Co-authored-by: Lakshmi Tanmay <[email protected]>
Co-authored-by: Victor <[email protected]>
Co-authored-by: CursedApple <[email protected]>
Co-authored-by: Zeus-Deus <[email protected]>
Co-authored-by: Joseph Vidal <[email protected]>
Co-authored-by: Jaewook Oh <[email protected]>
Co-authored-by: Alessandro Sola <[email protected]>
Co-authored-by: Lukas Tomondy <[email protected]>
Co-authored-by: intrepid37 <[email protected]>
Co-authored-by: Richard Frost <[email protected]>
Co-authored-by: Ibrahim Elkamali <[email protected]>
Co-authored-by: Mantas Kantautas <[email protected]>
Co-authored-by: fixfon <[email protected]>
Co-authored-by: Arman Arutiunov <[email protected]>
Co-authored-by: maco <[email protected]>
Co-authored-by: macodev00 <[email protected]>
Co-authored-by: Shaun Hawk <[email protected]>
Co-authored-by: Shaun Hawk <[email protected]>
Co-authored-by: Cursor <[email protected]>
Co-authored-by: Roger V <[email protected]>
Co-authored-by: Roger Vilaseca <[email protected]>
Co-authored-by: Ali Younes <[email protected]>
Co-authored-by: Alan Justino da Silva <[email protected]>
Co-authored-by: Kinan Lakhdar <[email protected]>
Co-authored-by: sanjai balajee <[email protected]>
Co-authored-by: F4llen <[email protected]>
Co-authored-by: LN Bodicherla <[email protected]>
Co-authored-by: Nikita Maximilian Grimm <[email protected]>
Co-authored-by: Juan Suaya <[email protected]>
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
bugfixFix PR opened by an issue lead; enters the PR looppr:needs-verificationReviewed and green; needs a run on a desktop, Android or iOS device and captures postedsize:M30-99 changed lines (additions + deletions).vouch:trustedAuthor is trusted by repo permissions or the VOUCHED list.
2 participants
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.
Problem
A Codex chat started with No project lives in Codex's scratch folder under
~/Documents/Codex. If the user later moves it into a project in Codex, T3's session import still skips it. Moving a chat in Codex (thread/metadata/update { projectId }) leaves everycwdin the rollout pointing at the scratch folder, which the scanner excludes. Codex records the assignment only in its state database (<CODEX_HOME>/state_5.sqlite:threads.project_id,project_roots).Reproduced with the real Codex app-server (codex-cli 0.163.0) in an isolated Codex home. A chat started in
<home>/Documents/Codex/2026-11-08/new-chatwas moved into a project rooted at<home>/code/my-project, and a control chat was started directly in that project. Codex's ownthread/list { projectId }returns both chats. On main, T3's scanner offers the project with 1 chat, andrecentThreadsimports only the control chat.Change
AgentSessionScannerreads Codex's project assignments read-only, with one query per Codex home: thread ID → project roots. It opensstate_5.sqlitewithnode:sqlite{ readOnly: true }, the same way the server already reads other tools' databases. A missing, older or locked database falls back to the current behaviour.cwdis a path the scanner already excludes (such as the Codex scratch folder) and Codex assigns the chat to a project, the chat uses that project's first root as its cwd. This applies both when grouping scan candidates and whenrecentThreadschecks the chat against the selected project. Chats in any other real directory keep their own cwd, so linked worktrees and other repositories are unaffected.CODEX_ROLLOUT_ID_PATTERNnow captures the thread ID and, for rewound rollouts, the rollout ID separately. The state database is keyed by thread ID, and the existing rewound-history lookup still uses the rollout ID.Scope and approval
Fixes #32873
Verification
Head df3ffc1249 (main merged in). Before = merge-base fa2f4ff2a2.
vp test run apps/server/src/project/AgentSessionScanner.test.ts: 68 passed at head.expected [ 'Started in the project' ] to deeply equal [ 'Started in the project', 'Started with no project' ]) and passes with the fix.<thread>_<rollout>.jsonl) of a moved chat, and a chat assigned to the project from another real folder, which keeps its own cwd.What Codex wrote (rollout cwds and state database), synthetic data
Codex app-server driver used for the reproduction (scratch, not committed)
Evidence
Server-only change, so the captures are before/after transcripts of the real
AgentSessionScanner(scan candidates andrecentThreadsresults), with a warm scan→recentThreadssequence and a coldrecentThreadson a fresh scanner in every fixture. Viewport and theme do not apply. Environment: Node v26.12.1, Linux x86_64, synthetic Codex homes using thestate_5.sqliteschema the real codex-cli 0.163.0 app-server creates (schema receipt, schema dump, probe). 30 scanner invocations, all with matching fixture hashes on both sides (receipts). Fixture matrix, index.<thread>_<rollout>.jsonl)positiononlyWhat else changed: nothing outside the mapped-chat rows. In the composite fixture the project's count rises from 1 to 5 (the moved chat plus three rewind files), which also moves its last activity forward.
Proof audit: sufficient. The auditor rebuilt R05 and R07 from the uploaded scripts at the head with zero behavioural delta. Scripts: scanner-driver.mjs, seed-fixtures.py, run-captures.py, package-evidence.py.
Verification log
AgentSessionScanner.test.ts; the new regression test fails on main.cannot-verify macos(Codex Desktop end to end; the move was driven through the same app-server request Codex uses). A Codexsqlite_homesetting that relocates the state database keeps the current behaviour.AI-assisted; verified with the tests and tools listed above.