Skip to content

fix: bug-hunt sweep — crash-safety, import data-loss, correctness (v7.14.5)#257

Merged
vakovalskii merged 1 commit into
mainfrom
fix/bug-hunt-sweep-7.14.5
Jul 20, 2026
Merged

fix: bug-hunt sweep — crash-safety, import data-loss, correctness (v7.14.5)#257
vakovalskii merged 1 commit into
mainfrom
fix/bug-hunt-sweep-7.14.5

Conversation

@vakovalskii

Copy link
Copy Markdown
Owner

Fixes from a multi-agent bug hunt (7 subsystem reviewers → adversarial verification of each finding; 21 confirmed). Ranked by severity.

HIGH

  • server.js — one-request DoS. GET /api/session/__proto__ (and preview/cost/replay/handoff) returned Object.prototype from the index and crashed the process. findSessionFile is now hasOwnProperty-guarded, read-route ids validated, and the whole route dispatch is wrapped in try/catch → 500 not crash.
  • terminals.js — WSL launch broken. if (fresh) referenced an undeclared var under strict mode → ReferenceError on every WSL launch. Now mode === 'fresh'.
  • migrate.js — import data loss. tar overwrote local history.jsonl before dedup, so local sessions were lost despite the "merge" promise. Now stashes local history first and truly merges+dedupes both Claude and Codex; tar runs via execFileSync (no shell → no path injection).

MEDIUM

  • server.js: delete / bulk-delete validate SAFE_SESSION_ID (+ Array check).
  • data.js: cost mem-cache keyed by file mtime/size, not sessionId (growing sessions now update); Copilot + Copilot-Chat included in full-text search.
  • app.js: live badges re-applied after render(); keyboard nav works on .list-row; Agent Board rebuilds on active-poll; confirmDelete captures its target before awaits (no false failure if Escape dismisses mid-request).
  • workspace.js: Escape cancels tab rename (was committing via the blur handler).
  • calendar.js: tool-filter sidebar highlight derived from filter state (stayed lit after toggling off).
  • handoff.js: "Original Task" uses the genuine first message, not the first within the truncated window.

LOW

  • data.js: Claude first/last timestamps normalized to ms (string<number was always NaN); server.js: IPv6-aware host check ([::1]); terminal.js: expand ~ in requested cwd before spawn; convert.js: assistant turns serialized as output_text for Codex.

Not in this PR (tracked)

  • LOW data.js OpenCode/Kilo brace-counting can truncate messages with unbalanced braces inside JSON strings — needs a different SQLite extraction framing; deferred.

Testing

node --test test/*.test.js → 184 pass, 2 skipped. Live-server: /api/session/__proto__|constructor|toString → 200, process stays up, normal session loads. Browser: filter-toggle highlight, list-layout keyboard nav, and post-render badge reset all verified; 0 console errors.

🤖 Generated with Claude Code

….14.5)

Fixes from a multi-agent bug hunt (21 findings, adversarially verified).

HIGH
- server.js: prototype-safe findSessionFile + validate read-route ids +
  wrap route dispatch in try/catch → a malformed id like
  /api/session/__proto__ no longer crashes the whole process (one-request DoS).
- terminals.js: WSL launch referenced an undeclared `fresh` (ReferenceError
  under strict) → use `mode === 'fresh'`.
- migrate.js: import overwrote local history.jsonl before dedup → real merge
  now (stash local, merge+dedup Claude AND Codex); tar via execFileSync (no
  shell → no path injection).

MEDIUM
- server.js: delete/bulk-delete validate SAFE_SESSION_ID + Array check.
- data.js: cost mem-cache keyed by file mtime/size (not sessionId) so growing
  sessions update; Copilot/Copilot-Chat now indexed for search.
- app.js: live badges re-applied after render(); keyboard nav works on
  .list-row; Agent Board refreshes on active-poll; confirmDelete captures its
  target before awaits (no false failure on Escape).
- workspace.js: Escape cancels tab rename instead of committing.
- calendar.js: tool-filter sidebar highlight derived from filter state.
- handoff.js: "Original Task" from the true first message, not the tail.

LOW
- data.js: Claude first/last timestamps normalized to ms (were NaN compares).
- server.js: IPv6-aware host-header check ([::1]).
- terminal.js: expand ~ in a requested cwd before spawn.
- convert.js: assistant turns serialized as output_text for Codex.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vakovalskii
vakovalskii merged commit 8178a9c into main Jul 20, 2026
6 checks passed
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