Commit graph

5243 commits

Author SHA1 Message Date
nesquena-hermes
55a2e698a9
Release XM (v0.51.657): expanded shell tool card full command + broadened redaction (#4926, #4925)
Release XM (v0.51.657): expanded shell tool card shows full command + broadened redaction (#4926, #4925)
2026-06-25 11:11:36 -07:00
nesquena-hermes
a5bf6b9f76 Release XM (v0.51.657): expanded shell tool card shows full command + broadened redaction (#4926, #4925) 2026-06-25 18:08:07 +00:00
nesquena-hermes
64cb4cef4e fix(#4926): env-assignment redaction must not eat URL query tails
Codex re-gate: the env/AUTH '=' redaction regex matched 'token=' INSIDE a URL
(?token=...&mode=debug&signature=...) before the dedicated URL-query redactor,
and its \S+ value swallowed the rest of the URL incl later params + closing
quote. Anchor the env-assignment match to a shell-token boundary (^|[\s;|(]) so
it can't match keys preceded by ? or & — URL query params are left to the
dedicated query-param redactor, which masks the secret-looking ones while
preserving the command tail. + regression tests (URL-tail-preserved,
benign-PATH-not-over-redacted).
2026-06-25 17:58:12 +00:00
nesquena-hermes
ed21bd20cd fix(#4926): broaden _redactToolTargetLabel to mask env/flag/header secrets in the full command
Codex gate: exposing the full multi-line command in the expanded shell card
newly surfaces secrets on non-first lines (the collapsed header only ever showed
line 1). The old redactor masked only password-shaped fields. Broaden it to mask
common secret forms across the WHOLE command: env/colon assignments for
*TOKEN/*API_KEY/*SECRET/*ACCESS_KEY/*PRIVATE_KEY/*CREDENTIAL/*CLIENT_SECRET/
*SESSION_KEY and *AUTH*=, --token/--api-key/--secret style flags,
Authorization: Bearer/Bot/Token headers, and secret-looking URL query params.
Test now drives the REAL redactor (not an identity stub) and asserts non-first-line
secrets are masked while the collapsed header stays first-line.
2026-06-25 17:52:41 +00:00
nesquena-hermes
99b6a5e30b fix(#4926): expanded shell tool card shows the full multi-line command
In the transparent activity stream, a shell tool card's collapsed header
correctly shows only the first line of the command, but the EXPANDED detail
lead (`$ <command>`) reused that same first-line-only value via
_toolTargetLabel, so a multi-line script still rendered as line 1 when expanded.
The full command is available frontend-side; the truncation was purely in the
label derivation.

Adds _toolFullCommandLabel(tc) (full multi-line, redacted, no first-line
collapse) and uses it in _toolDetailLeadText for the shell kind, while the
collapsed header keeps the first-line _toolTargetLabel. Part of #4925.
2026-06-25 17:39:05 +00:00
nesquena-hermes
773a36dd91
Release XL (v0.51.656): stream writeback timing diagnostics (#4923, #4918)
Release XL (v0.51.656): stream writeback timing diagnostics (#4923, #4918)
2026-06-25 09:58:27 -07:00
nesquena-hermes
7d5a7ebd2f Release XL (v0.51.656): stream writeback timing diagnostics (#4923, #4918) 2026-06-25 16:54:53 +00:00
nesquena-hermes
f377215a0d harden: wrap _log_stream_writeback_timings in try/except so a misbehaving log handler can't skip the bg-title thread (Opus gate nicety, #4923) 2026-06-25 16:54:20 +00:00
Frank Song
8b1f8fe5ca Add final stream writeback diagnostics 2026-06-25 16:42:53 +00:00
nesquena-hermes
c33657434f
Release XK (v0.51.655): avoid repeated session loads in live usage metering (#4922, #4918)
Release XK (v0.51.655): avoid repeated session loads in live usage metering (#4922, #4918)
2026-06-25 09:38:20 -07:00
nesquena-hermes
f0448a9cee Release XK (v0.51.655): avoid repeated session loads in live usage metering (#4922, #4918) 2026-06-25 16:26:05 +00:00
Frank Song
7d69b80012 Avoid repeated session loads in live usage metering 2026-06-25 16:12:18 +00:00
nesquena-hermes
1fcb61cc04
Release XJ (v0.51.654): narrow session-index save LOCK window (#4921, #4918)
Release XJ (v0.51.654): narrow session-index save LOCK window (#4921, #4918)
2026-06-25 09:07:47 -07:00
nesquena-hermes
0e5de32c20 Release XJ (v0.51.654): narrow session-index save LOCK window (#4921, #4918) 2026-06-25 16:04:11 +00:00
nesquena-hermes
3ca84b61d3 docs: clarify _INDEX_WRITE_LOCK serializes the on-disk index RMW (Opus gate nicety) 2026-06-25 16:03:36 +00:00
Frank Song
3fd88903b0 Remove contributor changelog entry 2026-06-25 22:55:27 +08:00
Frank Song
3bae596ae8 Reduce session index global lock window 2026-06-25 22:02:34 +08:00
nesquena-hermes
cdb70ee547
Release XI (v0.51.653): keep gateway approval failures actionable (#4917, closes #4771)
Release XI (v0.51.653): keep gateway approval failures actionable (#4917, closes #4771)
2026-06-25 06:35:12 -07:00
nesquena-hermes
c0d65c8c2f Release XI (v0.51.653): keep gateway approval failures actionable (#4917, closes #4771) 2026-06-25 13:32:15 +00:00
Rod Boev
e67870caa5 test(#4771): align approval CI assertions with helper flow 2026-06-25 13:09:42 +00:00
Rod Boev
7d617d91f7 fix(#4771): block duplicate approval submits 2026-06-25 13:09:42 +00:00
Rod Boev
0b12b3b1fb test(#4771): cover both approval rejection paths 2026-06-25 13:09:42 +00:00
Rod Boev
528fa72390 fix(#4771): keep gateway approval failures actionable 2026-06-25 13:09:42 +00:00
nesquena-hermes
584dfa3c45
Release XH (v0.51.652): deliver async_delegation subagent completions to chat (#4912)
Release XH (v0.51.652): deliver async_delegation subagent completions to chat (#4912)
2026-06-25 04:56:07 -07:00
nesquena-hermes
7160cc26b5 test(#4912): make async_delegation wakeup test CI-robust
The first cut asserted against the REAL tools.process_registry.format_process_notification,
which isn't importable in WebUI-only CI shards (shard 2 failed: returned None).
Inject a stub agent module via sys.modules so the test validates the delegation
WIRING independent of agent-module availability, plus a graceful-degradation
test confirming async_delegation returns None (not raise) when the agent
formatter can't be imported. Production behavior is unchanged: async_delegation
events only occur when the agent is running, so the import resolves where the
events actually exist.
2026-06-25 11:53:13 +00:00
nesquena-hermes
1a3417bfa2 Release XH (v0.51.652): deliver async_delegation subagent completions to chat (#4912) 2026-06-25 11:47:29 +00:00
nesquena-hermes
0cecfb13a3 fix(#4912): deliver async_delegation completions to the parent chat
format_wakeup_prompt() in api/background_process.py returned None for any event
type other than 'completion'/watch_*, so async_delegation events (produced when
a background delegate_task subagent finishes) were silently dropped — the
subagent showed as perpetually 'running' and its consolidated result never
re-entered the parent conversation.

Add an async_delegation branch that delegates to the agent-side
tools.process_registry.format_process_notification (which already knows the
async_delegation shape), so the subagent result is rendered into the wakeup
prompt and re-enters chat. Scoped to async_delegation specifically (not all
unknown types) so genuinely-unrecognized events are still skipped — preserving
the existing skip-unknown-event contract.

Reported + root-caused by @mydelren.

Co-authored-by: mydelren <mydelren@users.noreply.github.com>
2026-06-25 11:38:02 +00:00
nesquena-hermes
56931500a7
Release XG (v0.51.651): force update non-fatal on undeletable untracked files (#4914)
Release XG (v0.51.651): force update non-fatal on undeletable untracked files (#4914)
2026-06-25 04:26:05 -07:00
nesquena-hermes
a0e78a7306 Release XG (v0.51.651): force update non-fatal on undeletable untracked files (#4914) 2026-06-25 11:23:13 +00:00
nesquena-hermes
fb76846b38 fix(#4914): don't abort force update when git clean -fd fails
On Windows a reserved-device-name file (nul/con/prn/aux/com1-9/lpt1-9) can land
in the working tree (e.g. a shell command redirecting to `> nul` under Git Bash,
which treats it as a literal filename). git can't delete it via the normal Win32
path, so `git clean -fd` exits non-zero — and force_apply_update treated that as
fatal, aborting the whole force update with 'Failed to remove untracked files
before force reset' and leaving the user stuck.

The clean is now best-effort: a failure is logged (stderr captured for
diagnostics) but non-fatal, because the subsequent `git reset --hard` overwrites
any tracked-file collisions regardless, and residual untracked files git can't
delete are harmless. Updates the prior test that asserted the (buggy) fatal
behavior to the corrected non-fatal contract, plus a new regression test.

Reported + root-caused by @rodboev.

Co-authored-by: Rod Boev <rod.boev@gmail.com>
2026-06-25 11:13:57 +00:00
nesquena-hermes
6403c8d459
Release XF (v0.51.650): protect table-cell pipes inside inline code (#4896)
Release XF (v0.51.650): protect table-cell pipes inside inline code (#4896)
2026-06-25 01:40:06 -07:00
nesquena-hermes
94513dd0f2 Release XF (v0.51.650): protect table-cell pipes inside inline code (#4896) 2026-06-25 08:37:05 +00:00
luandnh
91af4de845 fix: protect pipes inside <code> tags, not backticks
Inline code pass converts `code` to <code>...</code> BEFORE the table
pass runs, so the _protectPipes backtick regex never matched. Changed
to protect pipes inside <code>...</code> tag pairs instead.
2026-06-25 08:25:58 +00:00
luandnh
dba6340661 test: add regression test for pipe inside inline code in renderMd tables 2026-06-25 08:25:58 +00:00
luandnh
c1c039ff80 fix: protect pipes inside backtick code spans in renderMd tables
The _protectPipes function protected | inside brackets but not inside
backtick inline-code spans, so || in `code || here` inside a table
cell was split into extra columns. Added a second replace for matched
backtick pairs in the same iterative loop.
2026-06-25 08:25:58 +00:00
luandnh
f82e786c99 fix: table pipe | inside inline code breaks markdown table rendering
The smd parser treated | characters as table column separators even
when inside backtick inline code (token 11). Added e.token!==m (code
span) guards in both table | handlers so pipes inside code are
output as literal text instead of creating table cells.
2026-06-25 08:25:58 +00:00
nesquena-hermes
aaa70157fd
Release XE (v0.51.649): activate gallery-installed extensions + fix subdir asset URLs (#4907)
Release XE (v0.51.649): activate gallery-installed extensions + fix subdir asset URLs (#4907)
2026-06-25 00:24:20 -07:00
nesquena-hermes
22845e3f42 Release XE (v0.51.649): activate gallery-installed extensions + fix subdir asset URLs (#4907) 2026-06-25 07:21:25 +00:00
Frank Song
5f17ba55ed Fix gallery-installed extension activation 2026-06-25 07:10:17 +00:00
nesquena-hermes
cea9244460
Release XD (v0.51.648): restore tool-card result body on settled rebuild path (#4904, #4622)
Release XD (v0.51.648): restore tool-card result body on settled rebuild path (#4904, #4622)
2026-06-25 00:06:18 -07:00
nesquena-hermes
0f3eaa4c9a Release XD (v0.51.648): restore tool-card result body on settled rebuild path (#4904, #4622) 2026-06-25 07:03:22 +00:00
nesquena-hermes
89d7fae347 fix(#4622): restore full body for CAPPED-PREVIEW settled snippets, not just empty
Codex gate caught that the enrich only restored when the settled snippet was
fully EMPTY — but the backend persists a 4000-char capped preview
(_TOOL_RESULT_SNIPPET_MAX), so long terminal/tool output settles to a truncated
4000-char prefix, not empty (the actual #4622 symptom). Now also restore when
the settled snippet is a bounded preview of the live one (live longer + settled
is a prefix + settled length >= the 4000 cap), without clobbering a genuinely
short non-preview value. Adds capped-preview restore + short-prefix-not-clobbered
tests (proven non-vacuous).
2026-06-25 06:51:33 +00:00
nesquena-hermes
8d2d8b1f98 fix(#4622): trim dead enrichment branches per Opus gate
Opus + Codex both SAFE TO SHIP. Opus flagged two cosmetic redundancies (not
blockers): the snippet guard checked payload.result/payload.output which
_anchorSceneToolRowFromCall never sets, and the tool.result/tool.output writes
are never read by the consumer _anchorSceneToolCallFromRow (it reads
tool.snippet||payload.snippet||payload.result||payload.output). Removed both —
tool.snippet/payload.snippet is what actually restores the visible body.
Behavior-identical; 18 settled/reconnect tests still green.
2026-06-25 06:40:27 +00:00
nesquena-hermes
ef3092434f fix(#4622): restore tool-card result body on the settled rebuild path
In the Transparent Stream / Worklog view, terminal tool cards lost their stdout
and patch/edit cards lost their diff AFTER a turn settled (live cards were fine).

Root cause (proven via a node harness driving the real settled chain
_anchorSceneRowsByMessageIndex -> _anchorSceneToolRowFromCall ->
_anchorSceneToolCallFromRow): the settled rebuild builds each tool row from the
persisted messages[].tool_calls (state.db/sidecar), which can carry only a short
preview — or, on a cold/paginated load, nothing — for the result body. The full
output lives on the live S.toolCalls entry at settle time, but the dedup loop in
_anchorSceneRowsByMessageIndex SKIPPED the matching live entry (continue) instead
of restoring the missing body onto the surviving settled row. So buildToolCard
got tc.snippet='' -> empty output region, and the patch/edit diff (detected from
the snippet) never rendered. This also blanks the transparent 'Output' tab and
the 'Full' (detailed-input) tab.

Fix: new _enrichSettledToolRowBodyFromLive() restores snippet/result/output,
command, and args onto a settled row from the matched live call, ONLY when the
settled value is empty (never clobbers a genuinely persisted body). Wired into
the dedup loop: on a tid match that would have been skipped, enrich the existing
pooled row instead of dropping the live data.

The prior #4625 guard only exercised the LIVE buildToolCard path, which is why it
stayed green while the settled path regressed. New
tests/test_issue4622_settled_toolcard_body.py drives the full SETTLED chain and
asserts: terminal stdout restored + full output in data-full + transparent Output
tab non-empty; patch diff body restored + renders as a diff + Full-tab args kept;
genuine persisted body not clobbered; args restored when dropped; no-live-match
leaves the row untouched; no duplicate row after enrich. Verified to FAIL on clean
master (assertions) and pass with the fix. Also registered the new helper in the
and now references the new symbol).

Reusable proof harness saved to ~/WebUI/qa/harnesses/.

Closes #4622.
2026-06-25 06:40:27 +00:00
nesquena-hermes
a64978c7ca
Release XC (v0.51.647): restore mobile-PWA task-detail action buttons (#4891)
Release XC (v0.51.647): restore mobile-PWA task-detail action buttons (#4891)
2026-06-24 23:37:05 -07:00
nesquena-hermes
896afe4ff1 Release XC (v0.51.647): restore mobile-PWA task-detail action buttons (#4891) 2026-06-25 06:33:56 +00:00
nesquena-hermes
856aa1d48d fix(#4891): show header in read-only Memory sections + Profiles help view
Gate (Codex) caught two SILENT regressions in the original fix: explicitly
hiding the header in the 'else'/'empty' branches also hid populated read views.
- _setMemoryHeaderButtons('read') now shows the header for ALL read views
  (incl. read-only Project Context / External Notes), gating only the Edit btn.
- _renderProfileConceptHelp() now uses a new 'help' header mode (shows header,
  hides all action buttons) instead of 'empty' (which hid the help title).
Adds tests/test_issue4891_detail_header_visibility.py (proven non-vacuous).

Co-authored-by: luandnh <luandnh@users.noreply.github.com>
2026-06-25 06:20:20 +00:00
luandnh
561369a261 fix: task detail actions hidden on mobile PWA
The main-view header (and its action buttons) used a CSS :has(.main-view-title:empty)
rule to stay hidden until the title populated; on some mobile browsers / PWA
WebViews that pseudo-class doesn't re-evaluate after textContent is set
dynamically, leaving the header permanently hidden. Explicitly set header
display in the read/create/edit/closed header-button setters (tasks, skills,
memory, workspaces) instead of relying on :has() reactivity.

Co-authored-by: luandnh <luandnh@users.noreply.github.com>
2026-06-25 06:08:00 +00:00
nesquena-hermes
10b9ba7429
test: class-level regression guard for the #4856 mobile-transcript-collapse family
test: class-level regression guard for the #4856 mobile-transcript-collapse family
2026-06-24 22:54:11 -07:00
nesquena-hermes
f1fee4ec7e test: remove unused 'rules' var (ruff F841 forward-gate) 2026-06-25 05:51:09 +00:00