feat: add task --thread <id> to resume a specific Codex thread - #719
feat: add task --thread <id> to resume a specific Codex thread#719y-cruce wants to merge 2 commits into
task --thread <id> to resume a specific Codex thread#719Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
sylvesterkaczmarek
left a comment
There was a problem hiding this comment.
--thread accepts any known thread ID without checking the thread’s repository. That can resume context from repo A while executing with repo B’s current cwd, which risks cross-repo context leakage and wrong-repo edits. Please verify the saved thread cwd/repository before resuming, with an explicit override only if cross-repo resume is intended.
…tory unless --allow-other-repo
|
Good catch, thanks. Added in the latest commit: before resuming, the thread id must appear in the current workspace's tracked task jobs (any Claude session). Otherwise the run fails before any resume request is sent, with an error pointing to Threads created outside the plugin (plain Tests cover: tracked thread from another Claude session resumes; untracked thread rejected in foreground and background; |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8ecb158f7b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (listJobs(workspaceRoot).some((job) => job.threadId === threadId)) { | ||
| return; |
There was a problem hiding this comment.
Preserve foreign-thread provenance after an override
When a thread from repo A is first resumed in repo B with --allow-other-repo, the successful run records that thread ID in repo B's job state. On a later invocation this predicate therefore accepts task --thread <id> without the required override, even though the thread still contains repo A's history. Track whether a thread was admitted through the override, or verify its original workspace, rather than treating every local job record as proof of repository ownership.
Useful? React with 👍 / 👎.
| if (request.resumeThreadId && !request.allowOtherRepo) { | ||
| requireTrackedThreadForWorkspace(workspaceRoot, request.resumeThreadId); |
There was a problem hiding this comment.
Validate the tracked thread before inserting the new job
When the state already contains the maximum 50 jobs and the requested thread appears only in the oldest record, runTrackedJob (or the background enqueue path) inserts the new job before this validation runs. saveState then prunes that oldest record via pruneJobs(...).slice(0, MAX_JOBS), so this check rejects a thread that was tracked when the command started and incorrectly demands --allow-other-repo. Validate against the pre-insertion state or preserve thread ownership separately from the bounded job history.
Useful? React with 👍 / 👎.
Summary
task --resume-lastcan only continue the newest finished task thread of the current Claude session in the repo. When a caller drives several Codex threads in one session (for example one thread per problem, or a review that ran as a task in between), the older threads become unreachable even though the app-server can resume them by id.This adds
task --thread <id>to resume a specific thread through the same path--resume-lastuses.Changes
plugins/codex/scripts/codex-companion.mjs: parse--thread, validate it (non-empty, not flag-like, mutually exclusive with--resume/--resume-last/--fresh), passresumeThreadIdthroughbuildTaskRequest/executeTaskRunin both foreground and--backgroundmodes. The thread id is not pre-written into the job record; it is stored by the existingThread readyprogress handling after a successful resume, so a failed resume of an unknown id does not pollute the next--resume-last.tests/runtime.test.mjs: resume by id (foreground and background), flag not leaked into the prompt, conflicting and invalid values rejected, failed resume does not pre-write the id.tests/commands.test.mjs,README.md,plugins/codex/commands/rescue.md,plugins/codex/agents/codex-rescue.md,plugins/codex/skills/codex-cli-runtime/SKILL.md: document the flag and its routing.No changes under
lib/;--resume-last,--resume, and--freshbehave as before. Version not bumped.Verification
npm test: the new tests pass; no new failures relative to the clean tree on the same machine (the remaining failures there are environment-relatedsetup/status/result/resolveStateDircases that fail identically without this change).task-resume-candidate,task --thread <older-id> "..."resumed the older thread (Thread ready (<older-id>)) and Codex answered from that thread's context.Notes
--threadintentionally bypasses the current-session filter used by--resume-last. It does not check repository ownership of the thread; the resume request carries the currentcwd.