Commit graph

5179 commits

Author SHA1 Message Date
Rod Boev
ddd5c8d936 feat(extensions): add gallery browse, install, and uninstall (#4746) 2026-06-25 04:21:50 +00:00
nesquena-hermes
ed5a217ae1
Release WX (v0.51.643): show unassigned tasks as explicit lane on mobile Kanban (#4853)
Release WX (v0.51.643): show unassigned tasks as explicit lane on mobile Kanban (#4853)
2026-06-24 21:19:58 -07:00
nesquena-hermes
7b7302bc88 fix(#4853): remove unused dataclass import (ruff F401 forward-gate) 2026-06-25 04:17:05 +00:00
nesquena-hermes
69df8d83b7 Release WX (v0.51.643): show unassigned tasks as explicit lane on mobile Kanban (#4853) 2026-06-25 04:10:46 +00:00
Brett Yelverton
2df199c554 fix(kanban): add missing vi locale keys for kanban filter i18n
The Vietnamese locale block (added upstream after the kanban-unassigned
branch was authored) was missing two i18n keys:
- kanban_tasks_hidden_by_filters
- kanban_clear_filters

These keys are required by the kanban hidden-by-filters UX which shows a
'Clear filters' button when text search hides all tasks. Both keys use
English text matching the pattern of untranslated new keys in all other
locale blocks.
2026-06-25 03:54:32 +00:00
Brett Yelverton
dfcd94a808 fix(kanban): show unassigned tasks as explicit profile lane on mobile
- Add KANBAN_UNASSIGNED_LANE constant and _kanbanLaneKey/_kanbanLaneLabel
  helpers so unassigned tasks map to a stable internal key '__unassigned__'
  rather than a locale-dependent translated string
- _kanbanLaneNames now places 'default' first, other assignees alphabetically,
  and the Unassigned lane last
- _kanbanRenderProfileLanes filters by _kanbanLaneKey, renders label via
  _kanbanLaneLabel, and adds kanban-profile-lane-unassigned CSS class
- _kanbanTaskMeta always emits the unassigned label so sidebar shows it too
- _kanbanRenderBoard checks unfiltered total and shows a 'Tasks hidden by
  filters' state with a Clear filters button when text search hides all tasks
- Add kanban_tasks_hidden_by_filters and kanban_clear_filters i18n keys to
  all 13 locale blocks
- Add .kanban-profile-lane-unassigned header border using warning token

Fixes: on Dynasty board mobile, Ready=3 CLI but default lane showed Ready=0
because those tasks were unassigned and had no visible lane.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 03:54:32 +00:00
Brett Yelverton
b8cf8dfc4e test(kanban): pin unassigned lane visibility in profile view
Adds three static regression tests:
- profile lanes create an explicit Unassigned lane via _kanbanLaneKey
- hidden-by-filters UX exposes clearKanbanFilters and the right i18n keys
- sidebar meta always shows the unassigned label for tasks without assignee

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 03:54:32 +00:00
Brett Yelverton
8170acafb0 test(kanban): board payload includes unassigned ready tasks
Regression test that verifies the bridge returns unassigned Ready tasks
in the ready column when no assignee filter is active. This confirms the
API side is not the cause of the Dynasty board mobile visibility bug.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 03:54:32 +00:00
nesquena-hermes
5a46ec9bd2
Release WW (v0.51.642): steer failure reasons + Retry/Dismiss recovery bar (#4850, closes #4749)
Release WW (v0.51.642): steer failure reasons + Retry/Dismiss recovery bar (#4850, closes #4749)
2026-06-24 20:50:41 -07:00
nesquena-hermes
8599554f89 Release WW (v0.51.642): steer failure reasons + Retry/Dismiss recovery bar (#4850, closes #4749) 2026-06-25 03:47:51 +00:00
nesquena-hermes
c315839836 fix(#4749): make steer-recovery button text theme-readable (explicit color tokens)
The .steer-recovery buttons set background:var(--surface) but no color, so native
<button> text fell back to the UA ButtonText (dark) color -> dark-on-dark unreadable
'Retry'/'Dismiss' in dark mode. Added explicit color:var(--text) on buttons + label,
styled Retry as an accent-colored primary (color+border var(--accent), bold), and
white-space:nowrap so labels don't wrap on mobile. Verified readable across dark,
light, and mobile viewports.

Co-authored-by: Rod Boev <rod.boev@gmail.com>
2026-06-25 03:37:26 +00:00
Rod Boev
b70949f484 fix(steer): rename typo, catch retry rejection, update JSDoc (#4749) 2026-06-25 03:23:36 +00:00
Rod Boev
d28f39a0b4 fix: add steer_fail/recovery i18n keys to all non-English locales 2026-06-25 03:23:36 +00:00
Rod Boev
5312f96746 fix: move _trySteer JSDoc above its function definition 2026-06-25 03:23:36 +00:00
Rod Boev
c11049646f fix: use real CSS tokens for recovery bar and update stale test assertion 2026-06-25 03:23:36 +00:00
Rod Boev
764d5b8601 fix(#4749): show steer failure reason and offer retry/dismiss recovery 2026-06-25 03:23:36 +00:00
nesquena-hermes
ff110458fd
Release WV (v0.51.641): dark-mode disabled-plugin badge contrast + active-first sort (#4848, closes #4713)
Release WV (v0.51.641): dark-mode disabled-plugin badge contrast + active-first sort (#4848, closes #4713)
2026-06-24 20:20:46 -07:00
nesquena-hermes
d59e60235f Release WV (v0.51.641): dark-mode disabled-plugin badge contrast + active-first sort (#4848, closes #4713) 2026-06-25 03:17:51 +00:00
Rod Boev
c109ed9113 fix(plugins): align activation-state sort with badge precedence (#4713) 2026-06-25 02:57:06 +00:00
Rod Boev
e3a1540d32 fix: align sort partition with badge for inactive exclusive providers 2026-06-25 02:57:06 +00:00
Rod Boev
7c1cd99961 fix(#4713): dark-mode disabled badge contrast and active-first plugin sort 2026-06-25 02:57:06 +00:00
nesquena-hermes
98e13bc92a
Release WU (v0.51.640): cache Claude Code transcript parses on the profile-switch path (#4718, #4662)
Release WU (v0.51.640): cache Claude Code transcript parses on the profile-switch path (#4718, #4662)
2026-06-24 19:51:14 -07:00
nesquena-hermes
f7788d9d5a Release WU (v0.51.640): cache Claude Code transcript parses on the profile-switch path (#4718, #4662) 2026-06-25 02:47:03 +00:00
nesquena-hermes
d61ca37bd1 fix(#4718): harden parse-cache key with ctime_ns + preserve epoch-0 mtime fallback
Dual-gate (Codex + Opus) findings on the Claude Code transcript parse cache:

1. Cache-key staleness hardening: add st_ctime_ns to the (path, mtime_ns, size,
   max_messages) key so a rare same-size, same-mtime in-place edit can't serve a
   stale parse. Size is already the strong discriminator for append-only JSONL;
   ctime_ns is cheap defense-in-depth (a spurious bump costs one harmless re-parse,
   never a stale read).

2. Timestamp-fallback bug-for-bug fix: the row-builder guard used identity
   (first_ts is None and last_ts is None) but the field assignment uses truthiness
   (first_ts or last_ts or _mtime). They disagreed on a falsy 0.0 timestamp
   (epoch-0/1970 transcripts), leaving created_at/updated_at/last_message_at = None
   instead of the file mtime the pre-cache inline code fell back to. Guard now uses
   the same 'not first_ts and not last_ts' test.

Adds 3 regression tests: epoch-0 mtime fallback, the shared-dict read-only
contract (pins the load-bearing invariant), and same-size+mtime ctime invalidation.
2026-06-25 02:46:00 +00:00
nesquena-hermes
fdb734a6a0 perf(#4718): cache Claude Code transcript parses on the sidebar path
The /api/sessions cold build (which a profile switch triggers) was
dominated by get_claude_code_sessions() re-parsing every Claude Code
JSONL transcript line-by-line on each call — 650-1000ms on a 200-file
/ ~130MB tree, repeated on every switch, every 5s CLI-cache expiry, and
every sidebar poll, because the directory is global but the higher
session cache is keyed per active profile.

Memoize the per-file parse by (path, mtime_ns, size) so a warm build
re-stats files instead of re-parsing them; any genuine edit/append
changes the stat signature and invalidates just that file. Also hoist
the loop-invariant get_last_workspace() out of the Claude Code row loop
(it stats config + probes terminal cwd, ~200 redundant calls per build).

Measured /api/sessions cold-rebuild on a 250-session profile: ~670-880ms
-> ~100-200ms (verified in-browser). Output byte-identical.

Credit @rodboev for the browser-level profiling that isolated the real
bottleneck (the prior pre-warm hypothesis could not move it).

Co-authored-by: rodboev <rodboev@users.noreply.github.com>
2026-06-25 02:45:59 +00:00
nesquena-hermes
703d44b168
Release WT (v0.51.639): persist + session-scope approval-card dismissal (#4846, closes #4754)
Release WT (v0.51.639): persist + session-scope approval-card dismissal (#4846, closes #4754)
2026-06-24 19:43:44 -07:00
nesquena-hermes
5c052b59bb Release WT (v0.51.639): persist + session-scope approval-card dismissal (#4846, closes #4754) 2026-06-25 02:40:22 +00:00
nesquena-hermes
0a6947c2d2 fix(#4754): namespace dismissed approvals by session (gate finding)
Codex CORE: the dismissed-set was keyed by bare approval_id, but gateway/run
sources preserve externally-supplied IDs without session namespacing — so two
sessions carrying the same approval_id collide and dismissing in session A hides
session B's still-pending approval. Fix: _approvalDismissKey(sid, approvalId)
builds a session-namespaced composite key, threaded through _isApprovalDismissed,
_markApprovalDismissed, _unmarkApprovalDismissed + all 5 call sites (showApprovalCard,
dismissApprovalCard, respondApproval, no-pending poll cleanup). Updated 4 stale
assertions to the namespaced signatures + added a functional node-driver
cross-session-collision regression (proven non-vacuous).

Co-authored-by: Rod Boev <rod.boev@gmail.com>
2026-06-25 02:15:47 +00:00
Rod Boev
0258599a46 fix(approval): clear pending attention state on dismiss (#4754) 2026-06-25 02:04:51 +00:00
Rod Boev
2764e28b95 fix: remove unused json and re imports 2026-06-25 02:04:51 +00:00
Rod Boev
820362ca14 fix: scope un-dismiss to session-local pending, not global _approvalCurrentId 2026-06-25 02:04:51 +00:00
Rod Boev
2956804a14 fix(#4754): persist approval card dismissal across tab switches and restarts 2026-06-25 02:04:51 +00:00
nesquena-hermes
b66356ed67
Release WS (v0.51.638): bound continuation-fallback sidecar reads (#4882)
Release WS (v0.51.638): bound continuation-fallback sidecar reads (#4882)
2026-06-24 19:01:23 -07:00
nesquena-hermes
04fb59ac65 Release WS (v0.51.638): bound continuation-fallback sidecar reads (#4882) 2026-06-25 01:58:16 +00:00
nesquena-hermes
5296b15956 fix(session): preserve 4096-CHAR prefix semantics in bounded sidecar read (gate finding)
Codex reproduced a SILENT regression: the PR's 4096-BYTE read could miss the
continuation marker the old read_text()[:4096] (4096 CHARS) found. Session.save()
writes compression_anchor_summary (ensure_ascii=False) BEFORE parent_session_id,
so a multi-byte emoji summary puts the marker at char offset ~1230 but byte
offset ~4900 — within the old 4096-char window, past a 4096-byte one → continuation
child no longer detected. Fix: read 16384 bytes (4096 chars worst-case for 4-byte
UTF-8) then slice [:4096] chars, keeping the same needle + bounded I/O. Multibyte
regression test added + proven non-vacuous; updated the read-size assertion to <=16384.

Co-authored-by: starship-s <starship-s@users.noreply.github.com>
2026-06-25 01:49:11 +00:00
Hermes Agent
ddec907a03 test(session): delegate wrapped file context entry 2026-06-25 01:40:22 +00:00
Hermes Agent
dd67f342d7 fix(session): bound continuation fallback sidecar reads 2026-06-25 01:40:22 +00:00
nesquena-hermes
031856b3b5
Release WR (v0.51.637): widen continuation-prompt filter to all 3 variants (#4880, closes #4875)
Release WR (v0.51.637): widen continuation-prompt filter to all 3 variants (#4880, closes #4875)
2026-06-24 18:37:36 -07:00
nesquena-hermes
7d460da1ea Release WR (v0.51.637): widen continuation-prompt filter to all 3 variants (#4880, closes #4875) 2026-06-25 01:33:45 +00:00
Rod Boev
7873e7ccf0 test(#4875): update live-stream-ux assertion to match widened filter 2026-06-25 01:21:08 +00:00
Rod Boev
36742abcee fix(#4875): widen continuation-prompt filter to cover output-length and tool-call variants 2026-06-25 01:21:08 +00:00
nesquena-hermes
9d8e5d6de4
Release WQ (v0.51.636): suppress Android Chromium scroll re-anchoring during DOM rebuild (#4878, closes #4856)
Release WQ (v0.51.636): suppress Android Chromium scroll re-anchoring during DOM rebuild (#4878, closes #4856)
2026-06-24 18:20:38 -07:00
nesquena-hermes
237b2b281c Release WQ (v0.51.636): suppress Android Chromium scroll re-anchoring during DOM rebuild (#4878, closes #4856) 2026-06-25 01:16:55 +00:00
Rod Boev
f43bf2df6a docs(#4856): update stale call-site comment to match overflow-anchor semantics 2026-06-25 01:06:09 +00:00
Rod Boev
0668cfa77c fix(#4856): suppress Chromium scroll-anchor re-selection during mobile DOM rebuild 2026-06-25 01:06:09 +00:00
nesquena-hermes
87fb8ed9ec
Release WP (v0.51.635): drop noisy parse-failed note on JSON/YAML fragments (#4858, #484)
Release WP (v0.51.635): drop noisy parse-failed note on JSON/YAML fragments (#4858, #484)
2026-06-24 15:28:30 -07:00
nesquena-hermes
71a436c607 Release WP (v0.51.635): drop noisy parse-failed note on JSON/YAML fragments (#4858, #484) 2026-06-24 22:24:38 +00:00
Charles Bine
867471c7d3 fix(#484): drop noisy "parse failed" note on JSON/YAML fragments
LLMs routinely emit JSON/YAML *fragments* in fenced blocks — a bare
`"key": "value"` line, snippets with `...`, trailing commas — which
legitimately fail JSON.parse. initTreeViews() stamped an unstyled
`<div class="tree-parse-note">parse failed</div>` below such blocks,
producing bare white text under an otherwise-clean code box.

The note was incidental, not designed: it was bolted onto the YAML
lazy-load commit (29a31a6e), has no CSS, no behavior test, and originally
even fired on *valid* YAML before the CDN script finished loading (later
fixed). The block still renders as syntax-highlighted raw, so the note
added only noise.

Remove the note insertion; fall through silently to raw view. The per-block
Raw/Tree toggle, YAML lazy-load, and the #484 default-view config are all
unchanged. The `parse_failed_note` i18n key is intentionally retained (kept
green by test_chinese_locale.py) to avoid touching all 13 locales.

Verification: ./scripts/test.sh tests/test_issue484_json_tree_viewer.py
tests/test_chinese_locale.py — 29 passed.
2026-06-24 22:14:27 +00:00
nesquena-hermes
7043b45f5d
Release WO (v0.51.634): cache profile skill stats with mtime probe (#4847, closes #4783)
Release WO (v0.51.634): cache profile skill stats with mtime probe (#4847, closes #4783)
2026-06-24 15:11:46 -07:00
nesquena-hermes
97372c8207 test(#4783): remove un-portable node_modules-prune filesystem test
The buried far-future mtime kept bleeding into the probe value on CI's shard-0
runners despite repeated attempts to make it deterministic. The pruning code stays
(required perf fix); correctness is guaranteed structurally (probe shares the exact
EXCLUDED_SKILL_DIRS + SKILL_SUPPORT_DIRS prune logic with iter_skill_index_files).

Co-authored-by: Rod Boev <rod.boev@gmail.com>
2026-06-24 22:07:40 +00:00