feat(task): add --background --await + await subcommand for completion-bound process#347
feat(task): add --background --await + await subcommand for completion-bound process#347iamrain2008 wants to merge 1 commit into
Conversation
…n-bound process
Plain task --background returns the launching CLI in 1-2 seconds while the
daemon worker runs for 10-30+ minutes with no observable completion signal.
Callers must remember an out-of-band polling protocol; reminder-based fixes
are unreliable.
Add two additive APIs so the launching process can represent actual daemon
completion:
- await <job-id> [--timeout-ms <ms>] [--poll-interval-ms <ms>] [--json]
- polls until terminal (completed / failed / cancelled)
- on completed: prints same content as result <job-id>, exits 0
- on failed / cancelled: prints stored failure, exits non-zero
- on timeout: prints current status, exits 124
- default timeout 6 hours (current status --wait 4 min is too short for
real delegated work)
- task --background --await
- enqueues detached worker as today
- keeps launching CLI alive as awaiter
- prints final result + exits with terminal status on completion
Used with a background-style invocation, the caller-visible completion
signal now matches actual daemon completion. The "background task
notification = work done" mental model finally holds.
Docs updates:
- commands/rescue.md: switch background examples to --background --await,
drop "subagent must never monitor or fetch results" instruction
- agents/codex-rescue.md + skills/codex-cli-runtime/SKILL.md: sync
- launch message for plain --background adds hint pointing to --await
Backward compatibility:
- plain task --background (no --await) keeps current behavior
- all existing subcommands unchanged
- new API is purely additive
Tests:
- await <job-id> for completed / failed / cancelled / running-to-completed /
timeout
- task --background --await output + exit behavior
- existing plain --background tests continue passing
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 423612c43b
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
|
||
| function renderQueuedTaskLaunch(payload) { | ||
| return `${payload.title} started in the background as ${payload.jobId}. Check /codex:status ${payload.jobId} for progress.\n`; | ||
| return `${payload.title} queued as ${payload.jobId}.\nThis command is only launch-complete; daemon completion is not signaled here.\nCheck /codex:status ${payload.jobId} for progress.\nFor completion notification, use: task --background --await ...\n`; |
There was a problem hiding this comment.
Use
await <job-id> in background launch hint
After task --background finishes, the launch message tells users to run task --background --await ... for completion notification, but that command starts a new task instead of waiting on the queued job that was just created. In real usage this can duplicate expensive work or apply changes twice when users follow the suggested command literally. The hint here should point to await <job-id> (using the emitted job id) for observing completion of the existing job.
Useful? React with 👍 / 👎.
Problem
task --backgroundreturns the launching CLI process in 1-2 seconds, while the daemon worker continues running for 10-30+ minutes. There is no observable completion signal for the launching caller — the worker is detached (stdio: "ignore",child.unref()) and writes terminal state into plugin state files asynchronously.Callers (including LLM-driven agents acting on behalf of users) must remember an out-of-band protocol to detect daemon completion: poll
statuswith a specific grep pattern, retryresult <job-id>, etc. Reminder-based fixes are unreliable; in practice, callers repeatedly conflate "launching CLI returned" with "Codex task finished" and end up waiting for a completion signal that never arrives.Root cause
The plugin currently exposes split-brain async semantics:
Out-of-band polling protocols cannot be enforced reliably across callers. The plugin should expose a completion-bound process as a first-class primitive.
Solution
Two additive APIs that make the launching process represent actual daemon completion:
New subcommand:
await <job-id>completed | failed | cancelled)completed: prints same content asresult <job-id>+ exits 0failed/cancelled: prints stored failure + exits non-zerostatus --wait4-minute default is too short for real delegated work)New flag on
task:--awaitUsed together with a background-style invocation, the caller-visible completion signal now matches actual daemon completion. The "background task notification = work done" mental model finally holds.
Documentation updates
Backward compatibility
Tests