fix: bug-hunt sweep — crash-safety, import data-loss, correctness (v7.14.5)#257
Merged
Conversation
….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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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) returnedObject.prototypefrom the index and crashed the process.findSessionFileis nowhasOwnProperty-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. Nowmode === 'fresh'.migrate.js— import data loss. tar overwrote localhistory.jsonlbefore 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 viaexecFileSync(no shell → no path injection).MEDIUM
server.js: delete / bulk-delete validateSAFE_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 afterrender(); keyboard nav works on.list-row; Agent Board rebuilds on active-poll;confirmDeletecaptures 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 asoutput_textfor Codex.Not in this PR (tracked)
data.jsOpenCode/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