Skip to content

fix(misc): cryptographic taskId, hoisted fs import, graceful shutdown, awaited transport#20

Open
sergei-aronsen wants to merge 1 commit into
RapierCraft:mainfrom
sergei-aronsen:fix/misc-cleanups
Open

fix(misc): cryptographic taskId, hoisted fs import, graceful shutdown, awaited transport#20
sergei-aronsen wants to merge 1 commit into
RapierCraft:mainfrom
sergei-aronsen:fix/misc-cleanups

Conversation

@sergei-aronsen
Copy link
Copy Markdown

Summary

Small reliability / hygiene fixes — independently small but unrelated, hence bundled. Happy to split.

`crypto.randomUUID` for task IDs

`generateTaskId` used `Math.random().toString(36).substring(2, 8)` — six base36 chars, ~31 bits, disambiguated only by the `Date.now()` prefix. Two concurrent callers in the same millisecond have a real birthday-collision risk, and `Math.random` triggers every standard "no insecure RNG" lint rule.

Switched to `crypto.randomUUID()` (Node ≥ 14.17). Same shape (`task__`), collision-free for any reasonable volume. Existing test regex updated to the UUID v4 shape.

Hoisted `fs` import

`comet_upload` did `const fs = await import('fs')` on every call. Cached after the first, but adds an unnecessary microtask each request and prevents bundlers from tree-shaking. Hoisted to a top-level `import { existsSync } from "fs"`.

Awaited `server.connect()`

`server.connect(transport)` was fire-and-forget. If the transport failed to attach (e.g. stdin already closed in a misconfigured parent) the promise silently rejected and the process exited with no logs. Now `await server.connect(transport).catch(...)` logs the error before exiting non-zero.

Graceful SIGINT / SIGTERM handler

Added handlers that call `cometClient.disconnect()` before exiting, so the WebSocket to Comet closes cleanly instead of sitting half-open until Comet times it out. Exits 130 on SIGINT (POSIX convention for Ctrl+C), 0 on SIGTERM.

Test plan

  • `npm run test:unit` passes (updated session-state test included)
  • Manual: Ctrl+C exits cleanly with no CDP error logs
  • Manual: `kill ` exits cleanly
  • Manual: 100 concurrent `comet_ask` task IDs are all unique

🤖 Generated with Claude Code

@RapierCraft
Copy link
Copy Markdown
Owner

Code Review: PR #20 — fix(misc): cryptographic taskId, hoisted fs import, graceful shutdown, awaited transport

Reviewed commit: 871befc


1. Cryptographic taskId (src/session-state.ts) — Approved

The switch from Math.random().toString(36).substring(2, 8) (~31 bits) to crypto.randomUUID() (~122 bits) is a clear improvement. randomUUID() is available since Node 14.17, and the project requires >=18.0.0, so no compatibility concern. Test regex correctly matches UUID v4 format.


2. Hoisted fs import (src/index.ts) — Approved

Replacing dynamic await import('fs') with top-level import { existsSync } from "fs" is correct. Node's fs is always available; the dynamic import added a needless microtask per call.


3. Awaited transport (src/index.ts) — Approved with Note

.catch() without await — still fire-and-forget at top level, but now with error handling. Acceptable bootstrap pattern. Rejection is caught and exits non-zero.

Subtle note: If server.connect() rejects before the event loop ticks, SIGINT/SIGTERM handlers below never fire. Unlikely with StdioServerTransport. Not blocking.


4. Graceful Shutdown (src/index.ts) — Approved with Recommendation

4a. Exit code comment (LOW): Comment says "exit code 0 for graceful signal" but code exits 130 for SIGINT. Code is correct (130 = 128+2, POSIX). Comment slightly misleading.

4b. disconnect() scope — Correct: Only closes CDP WebSocket. Appropriate since server doesn't own browser lifecycle.

4c. No timeout on disconnect (MEDIUM):

If cometClient.disconnect() hangs, process never exits. Suggest:

await Promise.race([
  cometClient.disconnect(),
  new Promise(resolve => setTimeout(resolve, 3000))
]);

Recommended hardening, not blocking.


Summary

Change Verdict Issues
Cryptographic taskId Correct None
Hoisted fs import Correct None
Awaited transport Correct Minor race (non-blocking)
Graceful shutdown Correct Recommend disconnect timeout

Overall: APPROVE — All changes are clear improvements. No security issues, bugs, or correctness problems. Safe to merge.


Single-reviewer analysis focused on: crypto randomness, import ordering, shutdown logic, transport awaiting.

Copy link
Copy Markdown
Owner

@RapierCraft RapierCraft left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

APPROVED: commit 871befc after code review (1 reviewer). 0 blocking issues. 1 non-blocking recommendation (disconnect timeout for graceful shutdown). Safe to merge.

@RapierCraft
Copy link
Copy Markdown
Owner

This PR has merge conflicts with main after recent merges (PRs #11, #12, #16, #18 landed).

The conflicts should be straightforward — crypto taskId, hoisted fs import, and shutdown logic don't overlap semantically with what merged. Please rebase against main.

…, awaited transport

Small reliability / hygiene fixes — independently small but mutually
unrelated, hence bundled here. Happy to split if reviewer prefers.

`generateTaskId` used `Math.random().toString(36).substring(2, 8)` —
six base36 chars, roughly 31 bits of entropy, disambiguated only by
the `Date.now()` prefix. Two concurrent callers in the same
millisecond have a real birthday collision risk (and `Math.random` is
flagged by every standard "no insecure RNG" lint rule even for
non-security uses).

Switched to `crypto.randomUUID()` (Node ≥ 14.17). Same shape
(`task_<unix-ms>_<rand>`), now collision-free for any reasonable
volume. Existing test regex updated to the UUID v4 shape.

`comet_upload` did `const fs = await import('fs')` per call. Cached
after the first call but added an unnecessary microtask on every
upload and prevented bundlers from tree-shaking. Hoisted
`existsSync` to a top-level import.

`server.connect(transport)` was fire-and-forget. If the transport
failed to attach (e.g. stdin already closed in a misconfigured
parent process) the promise silently rejected and the process
exited with no logs. Now `await server.connect(transport).catch(...)`
logs the error before exiting non-zero.

Added handlers that call `cometClient.disconnect()` before exiting, so
the underlying WebSocket to Comet closes cleanly instead of sitting
half-open until Comet times it out. Exits 130 on SIGINT (POSIX
convention for Ctrl+C), 0 on SIGTERM.

Co-Authored-By: Claude Opus 4.7 (1M context) <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.

2 participants