Add message context menu, thread editing, and keyboard navigation (#282)
* AGI: curl-like http.request + 60min LLM timeout
http library:
- Add http.request(options) supporting method selection, custom headers,
raw/JSON/form/binary(base64) request bodies, HTTP basic auth, per-request
timeout, redirect-follow control and text/base64 response bodies. Returns a
{ok, status, statusText, headers, body, error} response object.
- Add http.put/patch/delete/postForm/postJSON helpers built on http.request.
- http.get and http.post now accept optional headers (backward compatible:
the classic no-header signatures behave exactly as before).
- Add agi.http_test.go covering the body builder, request execution
(methods, headers, form/binary bodies, basic auth, redirect handling) and
the JS bindings.
llm library:
- Raise the AI completion request timeout from 120s to 60 minutes so long
reasoning/agentic replies are not cut short.
Docs: update mod/agi/README.md and Terminal api.json; bump AgiVersion to 3.5.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N7iat5zMwn2N5xDVEAvgpN
* UnitTest: add http.request example backend script
Add src/web/UnitTest/backend/http.request.js demonstrating the new
curl-like http.request(options) call (method, custom headers, JSON body,
timeout, response object) plus the http.postForm helper, matching the
existing http.get/post/head/download unit-test examples.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N7iat5zMwn2N5xDVEAvgpN
* Chatspace: keyboard-driven composers + PWA Back for threads
Full keyboard control across the app:
- @mention picker is now arrow-navigable: Up/Down move the highlight
(wrapping), Enter/Tab insert, Esc dismisses. Rows confirm on mousedown
so the composer keeps focus/selection.
- Mentions and the same key affordances now work in the thread composer
too, not just the main composer (shared composerKeydown handler).
- Up-arrow-to-edit works inside threads (edits your last reply); Esc
cancels an in-progress inline edit without closing the panel.
- Layered Esc: closes the top-most popover, then an open modal, then the
thread/profile panel.
PWA: opening a thread/profile panel pushes a history entry so the device
or browser Back button closes the panel instead of leaving the installed
app. A single sentinel is reused across convo switches to avoid an async
popstate race; UI dismissals consume it via history.back(). Bumped the
service-worker shell cache to v2 and refreshed the in-app shortcut help.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CfKyJV4zkj4AyME6XjH5q6
* Chatspace: stop thread panel overflowing off-screen when narrow
The desktop layout grid used `68px 1fr` for the rail/body columns. A bare
`1fr` track is floored at its min-content, so once the thread (right)
panel is open the sidebar + content + panel minimum widths force the body
track wider than the viewport. The body then overflows to the right and
the thread panel - along with its close button - is pushed off-screen and
unreachable at narrow desktop / resized floatWindow widths (roughly
769-1040px), where the mobile full-screen breakpoint has not yet kicked
in.
Floor the body track with `minmax(0, 1fr)` and let `#body` shrink
(`min-width: 0`) so the flex row collapses to the available width instead
of overflowing; `overflow: hidden` on `#app` is a belt-and-suspenders
guard (in-app popovers and modals live outside `#app`, so they are not
clipped). Verified in Chromium from 760px through 1280px: zero body /
document overflow and the panel close button stays on-screen at every
width.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CfKyJV4zkj4AyME6XjH5q6
* Chatspace: fix channel-header overlap and email-username mentions
Two narrow-width / naming bugs in the channel view:
1. Channel header overlap. When the content pane is squeezed (e.g. a
thread panel open on a mid-size window), the channel name spilled out
of `.ch-left` and rendered on top of the star / members / call buttons,
producing the mangled "name + overlapping box + star" seen in the
header. `.ch-left` now clips its overflow, the channel name truncates
with an ellipsis instead of pushing its siblings out (`#chNameBtn` is a
flex row with `min-width:0`, `#chName` ellipsizes), the star keeps its
size (`flex-shrink:0`), and the secondary topic yields space first
(`flex-shrink:100`). Verified: no element overlaps from 230px through
full width, and the name shows in full once there is room.
2. Email-style @mentions. The mention token stopped at an embedded "@",
so mentioning a user named "admin@example.com" only highlighted
"admin". The mention render + typing-detection character classes now
include "@", so the whole "admin@example.com" is captured and matched.
Exact-username lookup is unchanged, so plain names, dotted names and
@everyone/@ai still resolve and bare emails in prose (bob@example.com,
no leading @) are still not treated as mentions.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CfKyJV4zkj4AyME6XjH5q6
* Chatspace: sidebar, search empty-state, mention + details fixes
- Sidebar: starred channels / DMs stay listed under their own Channels /
Direct messages section instead of being removed once starred, and the
collapse caret on each section title is aligned to the same column as
the row icons (# / lock / +) for a clean left rail.
- Search: focusing the (blank) search box now opens a Slack-style empty
state - a "Search messages, files and more" hint plus recent
conversations as quick jumps - instead of showing nothing.
- Mentions: only real-user mentions (which carry data-user) open a profile
on click; @everyone / @channel / @ai are not people and no longer pop a
blank profile panel.
- Details modal: the topic "Edit" link is no longer glued to the value
("Add a topicEdit") - .rp-editlink is now a global class so its left
margin applies outside .rp-section too.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CfKyJV4zkj4AyME6XjH5q6
* Chatspace: keyboard nav for search + pickers, tidy presence dot
Audit pass 1 (search / people pickers):
- Search dropdown is now keyboard driven: Down/Up move the highlight
(wrapping), Enter opens the highlighted result, Esc closes the panel;
hovering syncs the cursor. Previously it was mouse-only.
- The New message / Add people pickers gain the same arrow + Enter
navigation, with a visible keyboard-cursor highlight (.kbfocus).
- Presence dot in picker rows now overlays the avatar's corner (like the
sidebar) instead of floating as a separate column between the avatar and
the name, which left an empty gap for offline users.
Verified in Chromium: search arrow nav cycles 1->2->1->0, Esc hides the
dropdown, no page errors.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CfKyJV4zkj4AyME6XjH5q6
* Chatspace: browse-modal keyboard nav + document list shortcuts
Audit pass 2 (browse + docs):
- Browse channels list is now keyboard navigable: Up/Down move a visible
cursor (.kbfocus) and Enter triggers the highlighted row's Open / View
button; hovering syncs the cursor. This completes arrow-key control
across every list surface (search, quick switcher, @mention picker,
people pickers, browse).
- Documented the search / picker navigation in the About > Shortcuts help.
Swept the remaining views (help, details Settings, profile panel, thread
panel, Threads/Drafts/Later lists) - all icons and spacing check out, no
further misalignments found. Verified browse nav in Chromium: arrows move
the cursor and Enter activates the row's button.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CfKyJV4zkj4AyME6XjH5q6
* Chatspace: fix thread image overflow + add right-click context menu
- Thread panel image overflow: .msg-img was capped at a fixed 360px, wider
than the ~330px thread panel, forcing a horizontal scrollbar. Cap with
min(360px, 100%) so it keeps the 360px limit in the wide pane but never
exceeds a narrow container; same fix for the text-file preview (520px).
- Right-click context menu for messages (Slack style): Add reaction, Reply
in thread, Copy text, Save for later, Pin/Unpin, Edit (own text),
Delete (own or manager), with a separator layout and danger styling.
The single-key hints shown on the right (R/T/C/A/P/E, Del) are live while
the menu is open; Ctrl/Cmd combos are left to the browser, and a native
menu still appears when text is selected inside the message. Edit routes
to the thread composer when the message is in the thread panel.
Verified in Chromium end to end: a real message right-clicks open the menu
with the expected items, the A shortcut runs its action and closes the
menu, and the thread-panel image no longer overflows (360px cap preserved
in the main pane).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CfKyJV4zkj4AyME6XjH5q6
* Chatspace: put the thread-reply bar below an image, not beside it
The thread summary bar was display:inline-flex, so after an image (whose
.file-preview is display:inline-block) the two shared a line and the
"N replies / Last reply ..." pill floated to the right of the image.
Make the bar block-level (display:flex) with width:fit-content so it drops
onto its own line under the image while keeping its compact pill shape.
Verified in Chromium: the bar's top is below the image's bottom and its
width stays content-sized (~194px, not full width).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CfKyJV4zkj4AyME6XjH5q6
---------
Co-authored-by: Claude <noreply@anthropic.com>