claw-io: symlinks whose target resolves outside the workspace root were silently dropped; now emitted
with target_outside_workspace=True (display-only — safe_resolve_ws/open_anchored_fd still block
navigation). Dedup-winner over #4573 (stronger tests). Co-authored-by: claw-io <claw-io@users.noreply.github.com>
ROOT FIX (product bug): POST /api/settings never invalidated the session-list
cache, so toggling show_cli_sessions/show_cron_sessions could serve a stale
sidebar for up to the cache TTL when the settings-file mtime stamp collided with
a cached entry. The handler now clears the cache directly on those toggles. This
is also the root cause of the recurring test_gateway_sync CI flake (session
absent from /api/sessions right after the visibility toggle).
DEFENSE-IN-DEPTH: cleanup_test_sessions fixture now resets show_cli_sessions to
default BEFORE each test too, not only in teardown.
FLAKE FIX (test infra): bump 31 node-subprocess correctness-harness timeouts from
10s -> 30s across 23 test files. Node spawn + V8 warmup under parallel CI shard
load can exceed 10s, causing TimeoutExpired flakes (e.g. test_1325 on #4445).
Only real node subprocess.run() sites changed — mock signatures, HTTP urlopen,
and deliberate timeout-behavior tests (test_api_timeout, timeout=0/1/2) untouched.
Render symlinks in the workspace file tree with a distinct chain-link
icon (vs regular file/folder icons), and show "Symlink → {target}" on
hover with long targets middle-elided. Directory and file symlinks are
both handled; regular entries keep their normal icons.
Rebased onto master (v0.51.466) and code-diff verified byte-identical to
the contributor's PR head before staging.
Co-authored-by: Rod Boev <rod.boev@gmail.com>
Closes#1707 — single-click on a workspace tree filename did nothing.
#1698 was a regression where the filename's dblclick rename handler was
unreachable because the row's el.onclick (openFile) fired synchronously
on the first click. The fix in #1702 stopped click propagation on nameEl
— but that broke single-click activation entirely (#1707): clicking the
filename now did nothing, you had to click the icon or row whitespace
to open the file.
Restored fix preserves both intents via a 300ms debounced delegator:
let _nameClickTimer = null;
nameEl.onclick = (e) => {
e.stopPropagation();
if (_nameClickTimer) { clearTimeout(_nameClickTimer); _nameClickTimer = null; }
_nameClickTimer = setTimeout(() => {
_nameClickTimer = null;
if (typeof el.onclick === 'function') el.onclick(e);
}, 300);
};
nameEl.ondblclick = (e) => {
e.stopPropagation();
if (_nameClickTimer) { clearTimeout(_nameClickTimer); _nameClickTimer = null; }
// ... existing rename body
};
Single-click on nameEl schedules a setTimeout that calls el.onclick(e)
after the dblclick threshold passes (300ms — matches the OS dblclick
threshold on most platforms). Double-click cancels the pending timer
and triggers the existing rename input.
Cost: 300ms latency on file-open clicks. Acceptable trade for keeping
rename reachable on single-click.
Also updated tests/test_workspace_tree_rename.py to accept both the
pre-#1707 (pure stopPropagation) and post-#1707 (debounced delegator)
shapes — the original assertion was too narrow and would have rejected
the correct fix.
9 new regression tests in tests/test_1707_workspace_filename_click.py:
- 6 source-level static-analysis checks on the patched handler shape
- 3 behavioral tests via Node VM (synthesize click → 300ms delay,
click → dblclick within tick → assert rename mounts + openFile
is not called).
7 of 9 tests fail on master pre-fix (verified); all 9 pass after.