Separate shared gateway auth from cached device-token signing in Control UI browser auth. Preserves shared-token validation while keeping cached device tokens scoped to signed device payloads.
Co-authored-by: Frad LEE <fradser@gmail.com>
1. fix(security): prevent JSON DoS via size cap on auto-parse
- Add MAX_JSON_AUTOPARSE_CHARS (20KB) to detectJson()
- Prevents UI freeze from multi-MB JSON in assistant/tool messages
- Addresses Aisle Security High severity CWE-400
2. fix(ux): prevent STT transcripts going to wrong session
- Add cleanupChatModuleState() export in chat.ts
- Call cleanup in applyTabSelection when leaving chat tab
- Stops active recording to prevent voice input to unintended session
- Addresses Greptile critical UX bug
3. fix(security): redact sensitive values in config diff panel
- Add renderDiffValue() with stream-mode + sensitive-path checks
- Use in diff panel rendering instead of raw truncateValue()
- Prevents secrets from appearing during screen sharing
- Addresses Aisle Security Medium severity CWE-200
- Updated config form tests to ensure sensitive values are properly managed and revealed based on user interactions.
- Refactored sensitive input rendering logic to support toggling visibility and redaction based on stream mode.
- Improved state management for sensitive paths, allowing for better control over when sensitive data is displayed.
- Added utility functions to identify and handle sensitive configuration data throughout the application.
- Enhanced UI components to reflect changes in sensitive data handling, ensuring a consistent user experience.
- Added a test to ensure chat.history preserves usage and cost metadata for assistant messages.
- Updated chat message sanitization to retain usage and cost information for UI rendering.
- Enhanced the AppViewState and UI components to include lastErrorCode for improved error handling.
- Implemented new utility functions in overview hints to manage authentication and context errors.
- Updated tests to cover new functionality and ensure correct behavior in various scenarios.
- Added support for loading and displaying a tools catalog in the agent management interface.
- Enhanced the AppViewState to include loading, error, and result states for the tools catalog.
- Implemented loadToolsCatalog function to fetch tools based on the selected agent.
- Updated UI components to reflect tools catalog loading states and errors.
- Refactored agent tools rendering logic to utilize the new tools catalog data structure.
- Enhanced the executeSlashCommand function to support the /kill command, allowing users to abort sub-agent sessions.
- Added logic to handle both "kill all" and "kill <agentId>" scenarios, providing appropriate feedback based on the number of sessions aborted.
- Introduced a new utility function, resolveKillTargets, to identify matching sub-agent sessions based on the provided target.
- Added unit tests for the /kill command to ensure correct functionality and response messages.
- Prevent Control UI session render crashes when `marked.parse()` encounters pathological recursive markdown by safely falling back to escaped `<pre>` output.
- Tighten markdown fallback regression coverage and keep changelog attribution in sync for this crash-hardening path.
Co-authored-by: Bin Deng <dengbin@romangic.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
* fix(gateway): pass actual version to Control UI client instead of "dev"
The GatewayClient, CLI WS client, and browser Control UI all sent
"dev" as their clientVersion during handshake, making it impossible
to distinguish builds in gateway logs and health snapshots.
- GatewayClient and CLI WS client now use the resolved VERSION constant
- Control UI reads serverVersion from the bootstrap endpoint and
forwards it when connecting
- Bootstrap contract extended with serverVersion field
Closes#35209
* Gateway: fix control-ui version version-reporting consistency
* Control UI: guard deferred bootstrap connect after disconnect
* fix(ui): accept same-origin http and relative gateway URLs for client version
---------
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
The parent `.chat-text` applies `overflow-wrap: anywhere; word-break: break-word;`
which forces long tokens (UUIDs, hashes) inside inline `<code>` to break across
visual lines. When copied, the browser injects spaces at those break points,
corrupting the pasted value.
Override with `overflow-wrap: normal; word-break: keep-all;` on inline `<code>`
selectors so tokens stay intact.
Fixes#32230
Signed-off-by: HCL <chenglunhu@gmail.com>
- Pass gfm:true + breaks:true explicitly to marked.parse() so table
support is guaranteed even if global setOptions() is bypassed or
reset by a future refactor (defense-in-depth)
- Add display:block + overflow-x:auto to .chat-text table so wide
multi-column tables scroll horizontally instead of being clipped
by the parent overflow-x:hidden chat container
- Add regression tests for GFM table rendering in markdown.test.ts
* fix(types): resolve pre-existing TS errors in agent-components and pairing-store
- agent-components.ts: normalizeDiscordAllowList returns {allowAll, ids, names},
not an array — use ids.values().next().value instead of [0] indexing
- pairing-store.ts: add non-null assertions for stat after cache-miss guard
(resolveAllowFromReadCacheOrMissing returns early when stat is null)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(webchat): suppress NO_REPLY token in chat transcript rendering
Filter assistant NO_REPLY-only entries from chat.history responses at
the gateway API boundary and add client-side defense-in-depth guards in
the UI chat controller so internal silent tokens never render as visible
chat bubbles.
Two-layer fix:
1. Gateway: extractAssistantTextForSilentCheck + isSilentReplyText
filter in sanitizeChatHistoryMessages (entry.text takes precedence
over entry.content to avoid dropping messages with real text)
2. UI: isAssistantSilentReply + isSilentReplyStream guards on all 5
message insertion points in handleChatEvent and loadChatHistory
Fixes#32015
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(webchat): align isAssistantSilentReply text/content precedence with gateway
* webchat: tighten NO_REPLY transcript and delta filtering
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
When an agent streams text and then immediately runs tool calls, the
webchat UI drops the streamed content: the "final" event arrives with
message: undefined (buffer consumed by sub-run), and the client clears
chatStream without saving it to chatMessages.
Before clearing chatStream on a "final" event, check whether the stream
buffer has content. If no finalMessage was provided but the stream is
non-empty, synthesize an assistant message from the buffered text —
mirroring the existing "aborted" handler's preservation logic.
Closes#31895
The config form marks models.providers as unsupported because
SecretInputSchema creates a oneOf union that the form analyzer
cannot handle. Add detection for secret-ref union variants and
normalize them to plain string inputs for form display.
Closes#31490
- Change margin from -12px -16px -32px to 0 -16px -32px
- Preserves zero top offset required for onboarding mode
- Prevents clipping of top edge/actions area when padding-top: 0