Release DB — v0.51.130 (stage-batch12, 3-PR profile-isolation + boot-precedence + Artifacts tab)
What's in this batch
Profile isolation fix (brick-class-adjacent)
- #2827 by @Koraji95-coder — Closes #2762. WebUI cookie-switched profiles were leaking session token-usage / title writes to the previously-active profile's state.db (sidecar messages + workspace files already routed correctly; only the state.db sidecar sync leaked). Root cause: cookie middleware sets
_tls.profileon the HTTP thread, but the daemon thread spawned in_run_agent_streamingdoesn't inherit it. Fix plumbsprofile=throughsync_session_usage→_get_state_dbinstead of relying on TLS. Adds defensive_validate_profile_name(rejects path traversal, leading-dash, whitespace, over-long, Unicode bidi). 11 regression tests.
Boot model precedence follow-up
- #2726 by @starship-s — Refines v0.51.105 #2709 boot-default precedence fix. Original was over-broad in 2 ways: unconditionally cleared persisted browser model state even on restored sessions, and reapplied default on every dropdown repopulate clobbering the in-page selection. Fix gates the default-reapply behind opt-in
{preferProfileDefaultOnFreshBoot: true}parameter. +306 LOC tests using a Node DOM shim.
Workspace Artifacts tab
- #2673 by @AJV20 — Closes #2655. New tab in workspace panel showing files mentioned/edited during the session. MVP frontend-scoped; surfaces from existing tool-call event stream. Empty-state copy: "Open a conversation to see files changed in this session." Composes cleanly with #2716's session stale-guard pattern via
typeof === 'function'defensive check.
Cherry-pick mechanics + in-stage fixes
All 3 PRs on stale-base merge-bases. Used git apply --3way of each PR's net delta onto current stage HEAD. Two JS conflicts resolved manually:
- boot.js (#2726 vs post-#2716 master): kept PR's parameterized
populateModelDropdowncall - workspace.js (#2673 vs post-#2716 master): kept master's
sessionIdstale-guard AND added PR'srenderSessionArtifacts()refresh
Test fixes:
- 3 brittle source-string assertions patched to accept both pre-#2716 and post-#2716 JS shapes (variable name changes, semantics preserved)
tests/test_issue2762_state_sync_profile_kwarg.py::_read_sessionhelper patched to query real state.db schema (sessions.idPRIMARY KEY, notsession_id; test was always broken against the actual schema — verified by checkingapi/state_sync.py:174which UPDATEsWHERE id = ?)
Conflict-resolution bug caught + fixed: My earlier resolution between #2716 and #2726 dropped the const sessionModelState=... declaration in _hydrateBootModelDropdown, but the callback body references it on 6 lines. Boot.js would have ReferenceError'd on every boot. Caught by tests/test_new_chat_default_model_frontend.py::test_boot_model_hydration_prefers_active_session_over_persisted_model brittle source-string assertion. Restored.
Opus pre-release advisor verdict
SHIP, with 1 MUST-FIX patched inline (1 LOC):
api/routes.py:9007— parity fix forsync_session_usagecall site in_handle_chat_sync. The PR fixedapi/streaming.py:5078(worker thread, where the leak manifested), but a second production call site atapi/routes.py:9007(HTTP thread, where TLS works fine today) didn't receive the parity update. Safe TODAY, but defense-in-depth: anyone wrapping that handler in a worker pool later silently regresses the fix. Addedprofile=getattr(s, 'profile', None).
All 7 risk areas verified clean (sessionModelState near-miss restoration byte-equivalent to pre-cherry-pick; #2726 preserves #2709's brick-class fix without destructive localStorage delete; profile validation regex tight against bidi/null-byte/traversal/leading-dash/whitespace/over-long; test schema patch matches production SQL; Artifacts tab composition correct).
Follow-up issue to file: Artifacts tab false-positive — read-only tool calls (read_file, search_files) appear in the Artifacts list despite empty-state copy promising "created or edited". Gate _artifactCandidatesFromToolCall args-path extraction on ARTIFACT_MUTATION_TOOLS.has(name) (preferred) or relax the empty-state copy to "Files touched by this session". ~10 LOC, not blocking.
Verification
- ✅ Full pytest: 6,485 passed / 6 skipped / 3 xpassed / 8 subtests passed in 2m30s
- ✅ JS syntax green on all touched files (boot.js, ui.js, workspace.js, messages.js, sessions.js)
- ✅ Python syntax green on api/state_sync.py + api/streaming.py + api/routes.py
- ✅ Agent self-verified: profile= threading on _get_state_db / sync_session_usage / production call sites, populateModelDropdown opt-in parameterization, sessionModelState definition restored, renderSessionArtifacts defined + called from stale-guarded loadDir
- ✅ Browser-verified at 1920×1080: Artifacts tab renders in workspace panel with proper segmented tabs and empty-state copy
- ✅ Opus pre-release advisor reviewed 7 risk areas — 1 MUST-FIX patched inline, 1 follow-up filed
Closes
🤖 Generated and reviewed end-to-end by the agent pipeline. The pipeline caught 1 conflict-resolution bug mid-stage (sessionModelState declaration), 4 brittle source-string assertions needing post-cherry-pick updates, and 1 test schema mismatch — all fixed inline. Opus pre-release advisor caught 1 defense-in-depth gap; patched inline. Net: +906/-46 across 13 files.
What's Changed
- Release DB — v0.51.130 (stage-batch12, 3-PR profile-isolation + boot-precedence + workspace Artifacts tab) by @nesquena-hermes in #2869
Full Changelog: v0.51.129...v0.51.130