Skip to content

fix: repair the tsc build broken by interruptAppServerTurn's JSDoc/param mismatch - #51

Merged
axisrow merged 1 commit into
mainfrom
fix/codex-mjs-interrupt-turn-jsdoc-build
Aug 3, 2026
Merged

fix: repair the tsc build broken by interruptAppServerTurn's JSDoc/param mismatch#51
axisrow merged 1 commit into
mainfrom
fix/codex-mjs-interrupt-turn-jsdoc-build

Conversation

@axisrow

@axisrow axisrow commented Aug 3, 2026

Copy link
Copy Markdown
Owner

Summary

npm run build (tsc -p tsconfig.app-server.json) currently fails on main:

plugins/codex/scripts/lib/codex.mjs(1209,53): error TS2339: Property 'threadId' does not exist on type '{}'.
plugins/codex/scripts/lib/codex.mjs(1209,63): error TS2339: Property 'turnId' does not exist on type '{}'.
plugins/codex/scripts/lib/codex.mjs(1209,71): error TS2339: Property 'timeoutMs' does not exist on type '{}'.

interruptAppServerTurn's second parameter is destructured directly in the signature ({ threadId, turnId, timeoutMs } = {}), while the JSDoc above it types a parameter named options. TS's JSDoc-to-signature binding matches by parameter name, not shape, so the destructuring pattern doesn't pick up the JSDoc type — TS instead infers the parameter's type from its = {} default (i.e. {}), then rejects every property access on the destructured names.

This landed via f67a09f (merged in #49) without a build check catching it — npm test alone doesn't run tsc. Noticed while validating #50; splitting the fix out separately since it's unrelated to that PR's broker work.

Fix: destructure inside the function body instead of the signature — the same pattern CodexAppServerClient#request already uses in app-server.mjs — so the JSDoc-typed options parameter name lines up with the actual parameter. No behavior change: same defaulting (options = {}), same property reads, just moved one line down into the body.

Test plan

  • Reproduced the three tsc errors on a clean main checkout (reverted this change, re-ran npm run build), then re-applied to confirm it's clean.
  • npm run build — clean, no errors.
  • npm test — 189/189 passing (all call sites of interruptAppServerTurn pass an object literal, e.g. { threadId, turnId }, which is unaffected by moving the destructuring into the body).

No version bump (build-only fix, no behavior change).

…ram mismatch

npm run build (tsc -p tsconfig.app-server.json) fails on main with:

  codex.mjs(1209,53): error TS2339: Property 'threadId' does not exist on type '{}'.
  codex.mjs(1209,63): error TS2339: Property 'turnId' does not exist on type '{}'.
  codex.mjs(1209,71): error TS2339: Property 'timeoutMs' does not exist on type '{}'.

interruptAppServerTurn's second parameter is destructured directly in the
signature (`{ threadId, turnId, timeoutMs } = {}`), while the JSDoc above
it types a parameter named `options`. TS's JSDoc-to-signature binding
matches by parameter position/name, not by shape, so the destructuring
pattern doesn't pick up the JSDoc type -- TS instead infers the parameter's
type from its `= {}` default, i.e. `{}`, and then rejects every property
access on the destructured names.

Fix: destructure inside the function body instead of the signature (same
pattern already used by CodexAppServerClient#request in app-server.mjs),
so the JSDoc-typed `options` parameter name lines up with the actual
parameter. No behavior change -- same defaulting, same property reads,
just moved one line down.

Landed via db52e28/f67a09f without a build check catching it (npm test
alone doesn't run tsc). Verified by reverting this change on a clean
main checkout and reproducing the same three errors, then re-applying to
confirm `npm run build` is clean.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HbkiKZR4w8hZUmNNTdb6kB
@axisrow

axisrow commented Aug 3, 2026

Copy link
Copy Markdown
Owner Author

@codex review PR #51 at exact head f6a307d.

Focus on critical issues: bugs, security vulnerabilities, logical errors, data loss risks, performance problems. Do NOT nitpick style, naming conventions, minor formatting, or subjective preferences — only flag issues that could break functionality or cause real harm in production.

Context: this PR repairs the tsc build, which is currently red on main with three TS2339 errors at plugins/codex/scripts/lib/codex.mjs:1209. The cause is that interruptAppServerTurn destructures its second parameter directly in the signature ({ threadId, turnId, timeoutMs } = {}) while the JSDoc above types a parameter named options — TS binds JSDoc to parameters by name, not by shape, so the destructuring pattern never picks up the JSDoc type and TS infers {} from the default.

The fix moves the destructuring into the function body so the JSDoc-typed options name lines up with the actual parameter — the same pattern CodexAppServerClient#request already uses in app-server.mjs. Claimed to be behavior-neutral: same defaulting, same property reads, one line lower.

Specifically worth checking:

  • Is the change genuinely behavior-neutral, or does moving the destructuring alter defaulting/evaluation order in any reachable case?
  • Are all call sites of interruptAppServerTurn unaffected?

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Nice work!

Reviewed commit: f6a307d9d1

ℹ️ 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".

@axisrow
axisrow merged commit 1affb08 into main Aug 3, 2026
@axisrow
axisrow deleted the fix/codex-mjs-interrupt-turn-jsdoc-build branch August 3, 2026 04:53
axisrow added a commit that referenced this pull request Aug 3, 2026
…rk in-process crashes failed immediately (#52)

Смерджено в ручную

* fix: repair the tsc build broken by interruptAppServerTurn's JSDoc/param mismatch

npm run build (tsc -p tsconfig.app-server.json) fails on main with:

  codex.mjs(1209,53): error TS2339: Property 'threadId' does not exist on type '{}'.
  codex.mjs(1209,63): error TS2339: Property 'turnId' does not exist on type '{}'.
  codex.mjs(1209,71): error TS2339: Property 'timeoutMs' does not exist on type '{}'.

interruptAppServerTurn's second parameter is destructured directly in the
signature (`{ threadId, turnId, timeoutMs } = {}`), while the JSDoc above
it types a parameter named `options`. TS's JSDoc-to-signature binding
matches by parameter position/name, not by shape, so the destructuring
pattern doesn't pick up the JSDoc type -- TS instead infers the parameter's
type from its `= {}` default, i.e. `{}`, and then rejects every property
access on the destructured names.

Fix: destructure inside the function body instead of the signature (same
pattern already used by CodexAppServerClient#request in app-server.mjs),
so the JSDoc-typed `options` parameter name lines up with the actual
parameter. No behavior change -- same defaulting, same property reads,
just moved one line down.

Landed via db52e28/f67a09f without a build check catching it (npm test
alone doesn't run tsc). Verified by reverting this change on a clean
main checkout and reproducing the same three errors, then re-applying to
confirm `npm run build` is clean.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HbkiKZR4w8hZUmNNTdb6kB

* fix: reap detached workers that die before reaching 'running', and mark in-process crashes failed immediately

Investigated upstream openai#425 ("detached task worker
that dies without throwing leaves job stuck 'running' forever") for
portability here. Verified against this fork's own job-tracking code
before porting anything.

This fork already had an independent equivalent of upstream's reader-side
reapDeadJobs: state.mjs's reconcileRunningJobs, called unconditionally
inside listJobs() itself (not as a separate wrapper every call site has
to remember to apply — architecturally tighter than upstream's approach,
which wraps 5 separate call sites in job-control.mjs/codex-companion.mjs/
stop-review-gate-hook.mjs with reapDeadJobs()). That closes the "running"
half of openai#425 and the whole of openai#392 (verified separately, see companion
report) without any change.

One real gap remained: reconcileRunningJobs only reconciled
job.status === "running", not "queued". enqueueBackgroundTask records the
detached worker's pid at enqueue time (status: "queued"), before that
worker has run far enough to flip its own record to "running" via
runTrackedJob. A worker that dies in that window — crash, immediate OOM
kill — left the job stuck "queued" forever with an already-dead pid,
invisible to the "running"-only check, permanently blocking
--resume-last and every other gate that treats queued/running as active.
Reproduced with a real dead pid recorded against a "queued" job; the
--resume-last gate threw "still running" forever. Fixed by also
reconciling "queued" jobs.

Ported registerWorkerCrashGuard on top of that gap fix: an in-process
uncaughtException/unhandledRejection handler installed in the task
worker (handleTaskWorker) that marks the job failed immediately, with
the actual crash reason logged, instead of waiting for the next
listJobs() read to lazily reconcile it. Adapted to this fork's
tracked-jobs.mjs/state.mjs helpers (readJobFile/writeJobFile/upsertJob)
rather than upstream's shape. Deliberately does NOT install signal
handlers (SIGTERM/SIGINT/SIGHUP): SIGKILL is uncatchable regardless, so
the reader-side reconciliation must cover process death either way, and
/codex:cancel's SIGTERM teardown races a "cancelled" write that this
guard must not clobber back to "failed" — the guard checks for an
already-terminal status before rewriting, same as upstream's guard.

Tests:
- tests/runtime.test.mjs: two end-to-end --resume-last tests — one
  proving the pre-existing "running" reconciliation already unblocks
  --resume-last (not just /status), one proving the "queued" gap and its
  fix (spawn a real dead pid, seed a stuck "queued" job, assert
  --resume-last succeeds instead of throwing "still running").
- tests/tracked-jobs.test.mjs (new): registerWorkerCrashGuard marks a
  job failed on an unhandled rejection with the reason logged; does not
  clobber an already-cancelled job on SIGTERM.

npm test: 193/193 passing (190 baseline + 3 new). npm run build: clean
(verified on top of #51, which this branch is stacked on, since main's
tsc currently fails on an unrelated pre-existing error #51 fixes).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HbkiKZR4w8hZUmNNTdb6kB

---------

Co-authored-by: axisrow <axisrow@users.noreply.github.com>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
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