Commit Graph

130 Commits

Author SHA1 Message Date
pewdiepie-archdaemon 39331fafb5 Email reader: primary action row literally inside the From row
Restructured the DOM so the Reply / Reply-all / Forward row lives
INSIDE the email-reader-meta-from div (after the chips span), and
the Summary / AI / More row sits directly below as a sibling of
From inside the meta. Killed the outer email-reader-actions
wrapper that kept letting the buttons drift out of position.

CSS now pushes the primary row right via margin-left:auto on the
From row and right-aligns the secondary row below it.
2026-06-11 19:46:06 +09:00
pewdiepie-archdaemon 05f87b0f50 Email reader: Reply group on From row, Summary/AI/More below
Reorganized the action cluster into two visible rows so each fits
the available width:
- Top row (on the From line): Reply / Reply-all / Forward
- Bottom row (under it):      Summary / AI reply / More

Action cluster goes back to flex-direction:column, the row
wrappers are flex rows again (no more display:contents flatten).
2026-06-11 19:39:13 +09:00
pewdiepie-archdaemon 432b41cede Email reader: top-align action cluster against From row
align-items: flex-start on the header keeps the action cluster
locked to the From line when the user expands the To/Cc details
— previously it drifted to vertical center as the meta grew taller.
2026-06-11 19:34:20 +09:00
pewdiepie-archdaemon 5bf7caecc9 Email reader (mobile): top-align meta with the two-row action cluster
After the toolbar reshuffle the action block is now two stacked rows
(Summary/More above Reply/Forward/AI), making it taller than the meta
block. The mobile header rule was align-items:center, which then pulled
the From:/To: rows down into the vertical middle of the header — the
'From: is in the middle' symptom. Switch to flex-start so meta sticks
to the top edge where the user expects it.
2026-06-11 19:29:41 +09:00
pewdiepie-archdaemon 4bf389ed09 Email reader: actions inline on the From row
With the meta collapsed to a single visible From row + chevron,
there is room to put the action cluster on that same row as a
right-aligned sibling. Dropped the absolute positioning and
gradient-fade overlap — actions now flex-end via margin-left:auto
so From sits on the left and Reply / Reply-all / Forward / AI /
Summary / More all sit on the right of the same row.

Also moved the chevron inside the recipient-chips span so it sits
adjacent to the sender chip instead of wrapping onto a second line.
2026-06-11 19:23:34 +09:00
pewdiepie-archdaemon 6e6b860f04 Email reader: collapse To/Cc behind Gmail-style chevron
Only the From row shows by default. When the email has To and/or
Cc recipients, a small chevron sits next to the From chip — click
it to inline-expand the To/Cc rows below (rotates 180deg open).

Trims the header to a single visible row in the common case,
leaving the action cluster plenty of vertical headroom to stay
on a single row.
2026-06-11 19:19:12 +09:00
pewdiepie-archdaemon e4c7a3aad9 Email reader: keep From/To/Cc on separate rows, label tight to chips
Reverted the single-row meta strip — misread the user's ask. Each
meta field gets its own row (From / To / Cc stacked), label sits
tight to the chips on the same line, recipient chips inside the
row still scroll horizontally so long lists slide under the
floating action cluster.
2026-06-11 19:15:55 +09:00
pewdiepie-archdaemon ac4627b69d Email reader: collapse From/To/Cc into a single inline row
Three stacked meta rows wasted vertical space — From, To, Cc now
share one horizontal strip with each label tight to its chips. The
strip itself scrolls horizontally so the action cluster (still
floating top-right) can cover the right edge and the user can drag
to reveal recipients hidden underneath.

This also gives the actions a single shared row, since the meta
no longer dictates a multi-row header height.
2026-06-11 19:12:06 +09:00
pewdiepie-archdaemon f91f37ef70 Email reader: flatten action rows with display:contents
The primary/secondary row wrappers were still creating nested flex
containers — even with parent flex-direction:row the two row divs
sized to content and could stack visually. Switching the wrappers
to display:contents collapses them entirely so all 6 buttons
become direct flex children of .email-reader-actions and lay out
on a single row guaranteed.
2026-06-11 19:08:22 +09:00
pewdiepie-archdaemon 41c0ffbb52 Email reader: collapse action cluster to a single row
Reply / Reply all / Forward / AI / Summary / More now flow inline
on one row instead of being split into a primary (Summary+More) and
secondary (Reply group) stack. Mobile + docked overrides also
flipped from column to row.
2026-06-11 18:59:50 +09:00
pewdiepie-archdaemon be430fc4a4 Email reader: actions float top-right over scroll-able recipient row
From/To/Cc back on the left, action cluster (Reply / Reply-all /
Forward / AI / Summary / More) absolute-positioned top-right with a
gradient fade so chips that overflow slide cleanly underneath. The
recipient-chips lists no longer wrap — they scroll horizontally,
matching the account-chip strip pattern, so users can drag/swipe
to reveal recipients hidden under the action cluster.

Mobile (@media max-width:768px) gets the same row+absolute layout
instead of the previous column with actions on top. The narrow
container query (docpane max-width:460px) still falls back to
in-flow column so it doesn't overlap on very narrow panes.
2026-06-11 18:55:31 +09:00
pewdiepie-archdaemon 15f2b106ab Email reader: move action toolbar to the TOP, meta below
Was: from/to/cc/date meta on the left, action cluster (Reply / Reply
all / Forward / AI reply / Summary / More) pinned to the right of
the header. Now: actions stretch across the top in their two existing
sub-rows, the from/to/cc meta sits below.

Pure CSS — no template restructure. The .email-reader-header flexbox
flips to flex-direction:column, .email-reader-actions gets order:-1
to render first, and the existing flex-end aligned action-row rules
swap to flex-start so buttons read left-to-right across the top
toolbar. Mobile media query overrides bend the same way so the
layout is consistent across breakpoints.
2026-06-11 18:48:34 +09:00
pewdiepie-archdaemon 6a392542f3 Email reader: two-row action layout — Summary+More above, Reply/Forward/AI reply below
Restructure the action cluster so it stays as two visible rows inside
.email-reader-actions instead of flattening via display:contents:
- Top row: Summary, More
- Bottom row: Reply, Reply all (conditional), Forward, AI reply
Dropped the Search button — wasn't part of the requested layout.

CSS: .email-reader-actions becomes flex column with both rows
right-aligned; .email-reader-actions-row becomes a real flex row
(no more display:contents flattening) so each row stays on its own
line. Whole block continues to sit beside the From/To meta inside
.email-reader-header.
2026-06-11 18:40:16 +09:00
pewdiepie-archdaemon 537f492762 Email reader: pin More to far right + allow actions to wrap beside meta
- .email-reader-actions flex-wrap nowrap → wrap so when the cluster
  exceeds the room next to a tall multi-recipient meta block, the
  buttons wrap within the actions area instead of pushing the whole
  block onto its own row below From/To.
- New rule: .email-reader-more-wrap gets order:99 so the More kebab
  sits at the far right of the flattened flex row instead of in the
  middle (its source order put it ahead of the secondary row's AI
  Reply / Summary buttons after display:contents flattening).
2026-06-11 17:06:26 +09:00
pewdiepie-archdaemon 6a0a7622fd Email filter picker: nudge up 2px on desktop (3px → 1px) 2026-06-11 17:05:47 +09:00
pewdiepie-archdaemon 719867a819 Email library: nudge .email-filter-btn up 4px 2026-06-11 17:01:23 +09:00
pewdiepie-archdaemon 9dfea188bf Email filter: custom dropdown with SVG icons for each option
The All/Unread/Favorites/etc selector was a native <select>, which
can't render SVG inside <option>. Replace it with a custom picker
that:

- Keeps the existing <select id="email-lib-filter"> as the value
  store (hidden via display:none). All existing 'change' listeners
  keep working — the picker just dispatches a change event after
  updating the select's value.
- Renders a styled button + drop-out menu built from the select's
  options (preserves optgroup labels like 'Tags').
- Each option carries an SVG icon: lines for All, ringed dot for
  Unread, star for Favorites, empty checkbox for Undone, bell for
  Reminders, reply arrow for Unanswered/Reply-soon, clock for
  Pending, calendar-x for Stale, exclamation-triangle for Urgent,
  ban for Spam, newsletter and megaphone for the marketing tags.
- Icons use var(--accent) so they pick up the user's theme color.
- Click outside / Esc closes the menu (Esc handler is capture-phase
  + stopPropagation so it doesn't bubble to the modal-close listener
  and shut the whole email window).

CSS scoped under .email-filter-picker.
2026-06-11 12:53:39 +09:00
pewdiepie-archdaemon 2b1e2e9e20 Email library: center the loading whirlpool over the full grid
Old rule fixed the loading wrap at min-height:180px so the spinner
landed near the top of the email-list section. Switch to
position:absolute inset:0 over the grid (with #email-lib-grid set to
position:relative) so the whirlpool + 'Loading emails' label center
within the entire visible email area regardless of section height.
2026-06-11 08:46:34 +09:00
pewdiepie-archdaemon b5b96980e3 Email bulk bar: nudge 'Marking…' label up 2px + 'All' checkbox up 2px
- 'Marking done' / 'Marking read' / 'Marking unread' label was 2px low
  vs. the whirlpool spinner inside the Actions button. The existing
  loading-label CSS only scoped to #email-lib-bulk-delete; extend it
  to also cover #email-lib-bulk-actions and bump top from 0 to -2px.
- 'All' checkbox label was inline-styled top:2px so the box + text sat
  lower than the surrounding bulk-action items. Reset to top:0 to
  match memory + skills select-all rows.
2026-06-11 08:41:59 +09:00
pewdiepie-archdaemon 7017127a11 Email card: drop redundant header kebab; keep bottom '...' menu in expanded state
The expanded email card painted a kebab menu in its title row because
the per-card .memory-item-actions menu at the bottom was hidden while
expanded. Both pointed at _showCardMenu(em). Remove the duplicate:

- Drop the email-card-header-menu button (and its rightCluster
  wrapper) — title row now just holds the nav arrows.
- Remove the CSS rule that hid .memory-item-actions on
  .email-card-expanded so the bottom kebab stays visible.
- Unread-dot insert point retargets to .email-card-nav-arrows now
  that the rightCluster is gone.
2026-06-11 07:33:04 +09:00
pewdiepie-archdaemon 00643b5a4b Email library New (compose): envelope icon takes the accent color 2026-06-11 07:30:26 +09:00
pewdiepie-archdaemon 8ae31aeb13 Email library compose button: scope taller+lower variant to desktop only
Wrap the height:28px / top:0 rule in @media (min-width:769px) so it
can't leak into mobile, where a different touch-friendly variant
already sets min-height:36px + top:-2px.
2026-06-11 07:24:25 +09:00
pewdiepie-archdaemon cc86760a26 Email library: drop compose button another 2px (top -2→0) 2026-06-11 07:23:49 +09:00
pewdiepie-archdaemon 2e7cfbe1fa Email library: New (compose) button 4px taller + 2px lower
Base .memory-toolbar-btn is 24px tall at top:-4px. Bump the compose
button alone to 28px (4px taller) and top:-2px (moves down 2px) so
it reads as the primary action in the toolbar without affecting
Select/Refresh.
2026-06-11 07:22:38 +09:00
pewdiepie-archdaemon 0a3333b961 Edge-dock resize handle: fade accent stripe in on hover
Transparent at rest, accent gradient animates in on hover with a 0.18s
ease transition. Drag affordance + col-resize cursor still work; the
stripe just stops bothering you when not touched.

Right-side handle mirrors the gradient direction (left-to-right
gradient flipped to right-to-left).
2026-06-10 23:18:07 +09:00
pewdiepie-archdaemon 1638db9c86 Email reader: theme-aware override for Gmail drive/attachment chips
Gmail composer chips arrive with inline border:1px solid #ddd + an
assumed white background, so on dark themes they read as a barely-
visible white box with the filename invisible. Override .gmail_chip /
.gmail_drive_chip inside .email-reader-body:

- Strip inline width:386px / height:20px (use auto + max-width:100%),
- Re-flow as inline-flex with a 6px gap so icon + filename align.
- Background tinted with var(--fg) 4%, border = var(--border).
- Anchor uses var(--accent) and the filename span uses var(--fg) so
  text is always legible regardless of theme.
- Icon img clamped to 16x16.
2026-06-10 23:17:18 +09:00
pewdiepie-archdaemon 023f1ba575 Email inbox: visual flash when an email is auto-marked done after sending
When the email-answered event fires (user just sent a reply, so the
source email auto-marks as done), the row was getting the .active
class instantly with no visible cue beyond the checkbox tick. Add a
brief .email-auto-done-flash class on the row that runs two keyframe
animations:
- email-auto-done-row: tints the row background with the accent for
  ~1.2s then fades to transparent.
- email-auto-done-check: pops the done checkbox to 1.4× with an
  accent ring that expands outward over 0.6s.

Class self-removes after 1.2s so it doesn't replay on re-renders.
2026-06-10 23:06:42 +09:00
pewdiepie-archdaemon 1eca28e588 Email: revert single-row email-item; account chips single-row at all widths
- Revert the email row layout — sender/date stay above subject again,
  matching the original two-line item that the user actually wanted.
- The account filter chips (#email-lib-accounts) wrapped onto multiple
  rows on desktop. Promote the mobile-only horizontal-scroll rule to
  apply at every breakpoint so the chips always sit on one row with
  overflow scroll, regardless of screen size.
2026-06-10 22:55:10 +09:00
pewdiepie-archdaemon a80421efb6 Sessions sort dropdown: nudge all items 2px more left
Group row's auto-sort-sessions-btn padding-left 6→4, and
.sort-dropdown-item left padding 8→6 so 'Last Active', 'Newest First',
'By Folder', '↑↓ Rearrange', '● Select' all shift in by the same
amount, matching the Group nudge.
2026-06-10 22:49:53 +09:00
pewdiepie-archdaemon 89efd7d44b Email list: collapse to a single row — [sender] [subject] [date]
Subject was on its own line below sender/date. Move it inline so each
email occupies one row: sender capped at 35% width (ellipsis), subject
takes the remaining space (ellipsis), date pins to the right. Tighter
list density at the cost of dropping the spare line for snippet text
(none was being rendered anyway).
2026-06-10 22:45:19 +09:00
pewdiepie-archdaemon 41980df6f1 Sidebar/Chats manage button: parent-hover reveal + clearer 'manage' text
Two related fixes for the Chats section header:
- The 'manage' label only slid out when the button itself was hovered.
  Add section-header-flex:hover to the reveal rule so hovering the sort
  icon (or anywhere in the section header) also opens the label.
- Parent-hover opacity bumped 0.45 → 0.85 so the 'manage' text reads
  much more clearly when revealed. Direct hover on the button still
  pushes to full opacity 1.
2026-06-10 22:44:50 +09:00
pewdiepie-archdaemon baa4449a03 Sidebar/Chats manage button: drop hover background tint
The shared .section-header-btn:hover rule paints a tinted background
across all section header buttons. On the Chats manage button this
showed as a box behind the sliding 'manage' label, which the user
didn't want. Override background to transparent for that one button.
2026-06-10 22:42:06 +09:00
pewdiepie-archdaemon 94931ba59f Chats sidebar: 'manage' label sits in flex flow so its area is clickable
Email's 'new' label is absolutely positioned to the LEFT of the '+'
icon, which works there because the '+' is the visible/clickable
anchor. The chats manage button has no visible glyph at rest, so the
label was rendered outside the button's bounding box — hovering
'manage' lost the :hover state and clicking it missed.

Override list-item-plus-label inside chats-manage-btn:
  position: static (in flex flow) + max-width:0 / max-width:80px
expand-on-hover so the button's clickable rect grows alongside the
text. Hover stays sticky; click hits.
2026-06-10 22:39:05 +09:00
pewdiepie-archdaemon 4f7061fd61 Settings overhaul + UI polish pass
Two months of iteration on the Settings panel, integration forms, and
small visual nudges across the app. Highlights:

Settings restructure
- Add Models: split into separate Local + API cards (no more in-card
  tabs); each fuses Type/Provider with the URL input.
- Added Models: new dedicated sidebar tab, with Probe + Clear-offline
  pulled into its header; Local/API sub-section icons accent-tinted.
- Search: Web Search and a new Deep Research card (Model + tuning),
  with a cross-link to AI Defaults. Provider hints use real clickable
  anchors; Web Search Test button shows a whirlpool spinner.
- AI Defaults: Image Generation card returns; Research Model card
  carries only Endpoint+Model with a cross-link to Search; Vision /
  Default / Utility fallbacks unified under one numbered-row design
  matching Search's chain.
- API Permissions (was 'API Tokens'): per-row rename, inline
  Permissions toggle that expands the scope-edit panel, in-field
  copy icons (icon→check on success). Empty state accent-tinted.
- Integrations: + Add Integration drops a type-picker menu directly
  under the button (drop-up on tight viewports); each integration
  form (API, CalDAV, CardDAV, Email, Codex/Claude, Vault, MCP) uses
  the same accent-outlined Save/Test/Cancel buttons right-aligned.
- Danger Zone: Wipe→Delete with trash icons; new 'Delete everything'
  row at the bottom that loops every category.

AI Synthesis (Reminders)
- Persona dropdown sourced from PROMPT_TEMPLATES + custom preset.
- src/reminder_personas.py mirrors the five built-ins for the
  server-side synthesis path.
- dispatch_reminder() reads reminder_llm_persona and uses the
  persona's system prompt; empty/unknown falls back to warm-neutral.

Esc handling
- Kebab menus and the provider picker intercept Esc in capture phase
  so dismissing a popup no longer closes the whole Settings modal.

Accent tinting
- Scoped CSS rule across data-settings-panel=ai/services/added-models/
  search/integrations/reminders for card h2 icons + the Added Models
  sub-section icons.

Codex/Claude integration form
- No more auto-creation on form open — explicit Create token button.
- New tokens start with every scope granted; existing tokens move out
  of the integration form into the API Permissions card.
- Setup reveal: copy buttons inline inside the token + setup code
  blocks; shorter subtitle wording.

Misc visual polish
- Save/Test/Cancel uniformly accent-outlined and right-aligned on
  every integration form.
- Provider logos render inline next to the search fallback selects
  and the Deep Research Search dropdown.
- Trash icons in fallback rows bumped to 20x20 so they fill the 32px
  button.
- Image generation default flipped to off.
2026-06-10 15:15:13 +09:00
pewdiepie-archdaemon e6b1009b89 Remove non-merge-ready workspace and terminal agent hooks 2026-06-09 09:48:59 +09:00
pewdiepie-archdaemon fa8c93ec0a Cookbook UI: Ollama browser, advanced serve fold, API tokens form, diagnosis toolbar, polish
Surface a lot of accumulated cookbook + UI work as a single non-agent
commit so the agent rework lands cleanly.

Highlights:
- Ollama as a first-class backend in the Cookbook:
  * Download input accepts ollama-style names (name:tag) → backend=ollama
  * /api/cookbook/ollama/library (cached scrape of ollama.com + curated
    fallback so classic models like qwen2.5 stay reachable)
  * "Browse Ollama library" toggle below Download with size chips
  * Engine=Ollama in hwfit toolbar merges the Ollama library into the
    main scan list as per-tag rows with the same Fit/Param/Quant/VRAM
    columns; click → fills Download input
- API Tokens form added to Integrations panel (matching wired
  loadTokens()/initTokenForm() that had no HTML)
- Serve panel polish: Advanced fold tightening (-8px nudges on vLLM
  checks, Extra args, Spec row), n_cpu_moe + Split Mode controls
  pulled up 8px to align with the row's checkboxes, GGUF File dropdown
  exposed for Ollama backend, GPU re-render on Edit serve restore,
  _forceBackend flag so saved serveState wins over backend detection,
  cookbook:servers-changed CustomEvent so panels don't need refresh
- Models page redesign: Add Models row (URL + hidden API key reveal +
  Type select + Scan/Ollama/Key/Test/Add icon buttons), Probe All +
  Clear-offline buttons in Added Models toolbar, offline-pill removed
  (opacity already conveys state), Engine dropdown gains Ollama option
- _ping_endpoint probes /v1/models then base, accepts 4xx as
  reachable (vLLM returns 404 on bare /v1, fully working endpoints
  were showing offline)
- Diagnosis card: × dismiss + Copy bundle buttons restored on the
  serve error feedback card
- Orphan tmux sweep re-enabled behind a 60s rate-limit + background
  Thread (off the main event loop) so dead serves get discovered
- cookbook_routes auto-register watchdog: drops the endpoint if the
  serve session exits non-zero within the first ~3min
- ollama-rocm sidecar awareness in download wrapper (`docker exec
  ollama-rocm ollama pull` when host ollama isn't installed)
- Skill extractor sets initial_status="published" when
  auto_approve_skills pref is on (audit demotes later)
- Skill list / model list / cookbook scan misc polish
2026-06-09 09:46:19 +09:00
pewdiepie-archdaemon 646f8bd2a9 Remove remaining plan mode frontend code 2026-06-09 09:44:22 +09:00
pewdiepie-archdaemon 3b01760e95 Prepare tested main sync cleanup 2026-06-09 09:34:42 +09:00
PewDiePie fe19d072e3 Revert "fix: expose supports_tools toggle for local endpoints in UI (#3195)" (#3438)
This reverts commit 7b68413433.

Co-authored-by: pewdiepie-archdaemon <pewdiepie-archdaemon@users.noreply.github.com>
Co-authored-by: Kenny Van de Maele <kenny@kvandemaele.be>
2026-06-08 14:46:01 +02:00
PewDiePie 09565acc1e Revert "feat(model-picker): add remove-from-recent button to Recent section rows (#2894)" (#3437)
This reverts commit 2a422c00ec.

Co-authored-by: pewdiepie-archdaemon <pewdiepie-archdaemon@users.noreply.github.com>
2026-06-08 14:41:25 +02:00
michaelxer 7b68413433 fix: expose supports_tools toggle for local endpoints in UI (#3195)
* fix: expose supports_tools toggle for local endpoints in UI

Local endpoints (Ollama, vLLM, etc.) default to fenced tool blocks
when supports_tools is not set, which breaks tool calling for models
that support native function calling. The backend already supports
per-endpoint supports_tools overrides via the PATCH API, but there
was no UI to set it.

Add a 'Tools: Auto/On/Off' toggle button for local endpoints that
cycles through the three states:
- Auto (null): use the existing heuristic
- On (true): always use native function calling
- Off (false): always use fenced tool blocks

Fixes #3141

* docs: add screenshot of supports_tools toggle showing Auto/On/Off states

* Add Tools toggle screenshot for PR #3195

* refactor: convert Tools toggle to select dropdown per review feedback

Replace cycle-through button with a <select> dropdown for the
supports_tools tri-state setting. Options: Auto / On / Off with
explicit labels. Uses existing admin select styling. Fires PATCH
on change event. Same API contract (Auto=null, On=true, Off=false).

* Update Tools toggle screenshot (now dropdown select)

* fix: remove orphan screenshot and move Tools dropdown below button row

- Remove docs/screenshots/tools-toggle-three-states.png (unreferenced image causing test_no_orphan_images_in_docs to fail)
- Move Tools dropdown to its own line below Disable/Delete buttons, aligned right
- Keep Disable and Delete buttons grouped together per maintainer feedback

* fix: move Tools select onto same row left of Disable/Delete, use CSS class

Per vdmkenny feedback: move the Tools dropdown select from its own row below
the button group onto the same row, to the left of the Disable and Delete
buttons (which stay adjacent on the right). Replace inline style on the
button row with the existing .admin-ep-actions CSS class, adding
align-items:center for proper vertical alignment.

* chore: remove committed screenshots from tree

Screenshots should be in PR description/comments, not in repo history.

---------

Co-authored-by: michaelxer <michaelxer@users.noreply.github.com>
2026-06-08 00:29:06 +02:00
Zen0-99 2a422c00ec feat(model-picker): add remove-from-recent button to Recent section rows (#2894)
* feat(model-picker): add remove-from-recent button to Recent section rows

* fix(model-picker): restore original browse-mode section logic, keep remove button only
2026-06-07 17:45:59 +02:00
Kevin Fiddick 8cfc5bb28f Fix mobile markdown table layout (#3198) 2026-06-07 17:43:51 +02:00
Maruf Hasan 3c924b8dee fix: hide Select buttons in Memory/Skills tabs when list is empty (#2906)
* fix: hide Select buttons in memory/skills tabs when list is empty

* fix: disable Select buttons instead of hiding them when list is empty

* fix: dim disabled Select button and remove focus outline

* fix: reload skills after single deletion so count and toolbar stay in sync

* fix: lower minimized-dock z-index from 10020 to 100 so modals stack above it

* Revert "fix: lower minimized-dock z-index from 10020 to 100 so modals stack above it"

This reverts commit 5b092ee6cd.
2026-06-07 16:29:04 +02:00
Maruf Hasan 870ae2823f fix: lower minimized-dock z-index so modals stack above it 2026-06-06 03:35:48 -06:00
Giulio Zelante b448119919 feat(skills): import SKILL.md bundles from public GitHub URLs (#2576)
* feat(skills): import SKILL.md bundles from public GitHub URLs

Supports GitHub tree/blob/raw links and skills.sh pages that resolve to GitHub.
Installs SKILL.md plus sibling text assets under data/skills/imported/.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(skills): admin-gate URL import and validate redirect hosts

- require_admin on POST /api/skills/import-from-url (matches other skill admin routes)
- reject cross-host redirects after httpx follow_redirects
- test for redirect host validation

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(skills): match Brain Add panel import/submit button styles

- Skill URL Import: theme-io-btn + download icon (same as memory Import)
- Add Skill submit: confirm-btn confirm-btn-primary

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(skills): allow api.github.com during directory import

Real imports hit the GitHub contents API after redirects; whitelist
api.github.com and add regression tests. Shrink Import button with flex:none.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(skills): align skill Import button with URL input row

Match memory-add-input height (28px) in memory-add-row and center the
download icon with flexbox instead of vertical-align hacks.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(skills): cancel modal-body margin on skill Import button

The skill Import button sits in .memory-add-row beside an input; the
global .modal-body button { margin-top: 6px } rule only affected buttons,
pushing Import down and misaligning the download icon. Reset margin-top
and match Memory Import SVG markup at 28px row height.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(skills): surface GitHub API errors on URL import

Pass through GitHub response messages (especially 403 rate limits) as
SkillImportError instead of a generic download failure.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-05 19:48:23 +02:00
Enes Öz 977daf0643 Improve edge-docked window behavior (#2779)
* Make edge-docked windows resizable

Add draggable resize seams for left and right docked windows.

Keep the main chat area from getting too narrow and remember each window's dock width.

* Show emoji shortcodes as icons by default

Keep text-only emoji mode opt-in so model output like 😊 goes through the normal emoji renderer.

* Fix dock resize seams and left dock layout

Hide the resize seam when another floating modal is open, and keep the left-docked window from covering the chat area.

* Keep narrow modal tabs usable

* Fix split layout with both edge docks

* Fix left snap after right dock

* Enable left edge snap for all windows

* Tighten dock resize handle observers

* Use edge docking for settings window
2026-06-05 17:07:08 +02:00
Kenny Van de Maele 8ce945d338 feat: Add plan mode to the chat agent (#638)
* feat: Add plan mode to the chat agent

Adds a plan mode: the agent investigates read-only, proposes a checklist, and
waits for approval before changing anything. On approval it runs with full
tools and checks items off as it goes. Enforcement reuses the existing
disabled_tools gate.

Includes a slash command: `/plan [on|off]` (and `/toggle plan`) to flip the
plan toggle from the chat input.

- src/tool_security.py, src/mcp_manager.py: read-only allowlist (tools + MCP).
- src/agent_loop.py, routes/chat_routes.py: union the disabled set, prepend the
  plan directive, force agent mode.
- static/: plan toggle pill, Approve & Run, dockable plan window, task-list
  checkboxes, and the /plan slash command.
- tests/test_plan_mode.py.

* Plan mode: persistent re-referenceable plan + agent write-back

Three improvements so a long plan survives a weak model and stays in reach:

1. Re-reference the plan (out-of-context fix). On the execution turn the frontend
   sends the approved checklist back (`approved_plan`); the backend pins it as a
   top-of-context `## ACTIVE PLAN` system note (kept by the context trimmer), so
   the agent can always re-read the plan instead of losing the thread on a long
   run. New `build_active_plan_note()` (unit-tested).

2. Re-open / dock the plan anytime. The plan checklist is stored per-session
   (localStorage). When a plan exists, the plan-mode button opens a small menu
   ("Show plan" / "Plan mode: On/Off") that re-opens the side-dockable plan
   window — so it can stay docked while the agent works. The window live-refreshes
   as the plan changes.

3. Agent write-back: new `update_plan` tool. The agent calls it to tick steps
   `- [x]` after finishing them, or to revise steps when the user asks. Marker
   tool (no I/O) → `plan_update` SSE event → the stored plan + docked window
   update live. The ACTIVE PLAN note instructs the agent to use it.

Backend: src/agent_loop.py (param + pin + note builder + emit + prompt blurb),
src/tool_execution.py (update_plan handler), routes/chat_routes.py (parse
`approved_plan`, relay `plan_update`), registration in tool_schemas / agent_tools
/ tool_index (always-available, not admin-gated).
Frontend: static/js/chat.js (plan store, send `approved_plan`, handle
`plan_update`, capture restated checklists), static/app.js (plan-button menu),
static/js/planWindow.js (`isPlanWindowOpen`), static/js/storage.js (PLAN key).
Tests: tests/test_plan_mode.py (plan-note), tests/test_update_plan_tool.py.

* Plan mode: drop bash/python, rely on read-only discovery tools

Shell can mutate (write files, hit the network) and can't be constrained to
read-only at the tool layer, so plan mode no longer relies on a prompt to keep
it well-behaved — bash/python are removed from the read-only allowlist and added
to the fail-closed block set. Discovery is covered by the dedicated read-only
tools (read_file, grep, glob, ls) instead.

Rewrites the plan-mode directive to state shell is disabled and lists the
available read-only tools positively. Addresses review feedback on #638.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Comment: note _MCP_READONLY_VERBS are prefixes not whole words

Clarifies that entries like "summar" are intentional stems matched via
startswith (covers summarise/summarize/summary), not typos. Addresses review
feedback on #638.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Plan mode: clarify why gating inverts the allowlist into a denylist

Rename _PLAN_MODE_FALLBACK_BLOCK -> _PLAN_MODE_KNOWN_MUTATORS and rewrite the
comments. The tool gate is a denylist (disabled_tools); plan mode's policy is an
allowlist, so it returns the inverse (all known tool names minus the allowlist).
The static mutator set is a backstop for the schema-derived name list, which
misses XML-only tools and can fail to import. Addresses review feedback on #638.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Plan mode: stop hardcoding the read-only tool list in the directive

The model is already shown its available (read-only) tools by _assemble_prompt,
which removes every disabled tool. Enumerating them again in the directive only
duplicated that list and would drift as tools change. Point at the tools listed
below instead. Addresses review feedback on #638.
2026-06-05 16:32:25 +02:00
Kenny Van de Maele 0a2adc9c96 Add ask_user tool: agent-posed multiple-choice questions (#2111)
Let the agent pause and ask the user a multiple-choice question when a
task is genuinely ambiguous and the answer changes what it does next —
choosing between approaches, confirming an assumption, picking a target —
instead of guessing.

Modeled on the existing `ui_control` marker pattern: the `ask_user` tool
returns an `ask_user` payload that the agent loop emits as an SSE event
and then ends the turn. The frontend renders the question with clickable
option buttons, a free-text "Other" input, and an x to dismiss; the user's
choice is sent as the next message and the agent resumes with it in
context.

- src/tool_execution.py: `ask_user` handler — pure UI marker, no I/O.
  Validates a non-empty question + 2..6 options, normalizes string/object
  options, returns the payload.
- src/agent_loop.py: emit the `ask_user` event and break the round loop so
  the turn ends and waits for the user's selection. Stream the question as
  assistant text so it persists/replays (prevents a re-ask loop).
- Registration: TOOL_TAGS, ALWAYS_AVAILABLE, BUILTIN_TOOL_DESCRIPTIONS,
  FUNCTION_TOOL_SCHEMAS, the system-prompt blurb. Not admin-gated (any
  user can be asked); the structured args serialize via the default
  json.dumps path.
- routes/chat_routes.py: relay the `ask_user` event to the client.
- static/js/chat.js + static/style.css: render the question card (options +
  free-text Other + dismiss x; removed once answered). Reuses CSS vars and
  the .modal-close button; emoji go through the monochrome-SVG pipeline.
  Bump chat.js cache pin.
- tests/test_ask_user_tool.py: payload, multi flag, string options, option
  cap, validation errors, serializer round-trip, registration.
2026-06-05 11:49:11 +02:00
pewdiepie-archdaemon e2f449f4ef Cookbook scheduler + serve: schedule via Tasks, Stop verifies kill, Ollama auto port-pick
- Schedule cookbook serves through the existing ScheduledTask system: the
  serve preset gets a ^ button next to Launch that opens a daily/hourly/
  weekly form mirroring the admin-switch style; the schedule action runs
  action_cookbook_serve, which delegates to /api/model/serve and stamps
  the resulting task with _scheduledStopAtMs. A background
  cookbook_serve_lifecycle loop ticks every 60s and kills any serve
  whose window has ended, also dropping the auto-registered endpoint
  so the model picker doesn't keep pointing at a dead server.
- Stop and remove on a Running serve now awaits the SSH/tmux kill,
  re-checks tmux has-session, and surfaces an error toast (leaving the
  row) when the kill failed. Previously fire-and-forget, so a failed
  SSH/tmux call silently left the live serve running while the row
  vanished from the UI.
- Cookbook tasks/status orphan-adoption sweep no longer requires the
  serve-/cookbook- session-id prefix; any tmux session whose pane is
  running a known model-server process gets auto-pulled into Running.
  Without this loosening, a cookbook-launched serve whose tmux id
  fell back to a bare number was invisible — you couldn't see it,
  let alone stop it.
- Ollama serve always launches a fresh process under cookbook's tmux
  (no more monitor-mode reattach to a systemd/Docker ollama Stop can't
  reach). The handler pre-picks a free port by probing the target
  host over SSH and mutates req.cmd's OLLAMA_HOST so the runner script
  AND the auto-registered endpoint agree on the same bind port.
- Auto-register uses host.docker.internal (when running inside Docker)
  instead of localhost, matching the URL /setup adds for Ollama by
  hand. Local cookbook serves now produce a chat-reachable endpoint
  on first launch.
- Cascade-delete: removing a scheduled cookbook task also deletes any
  linked calendar event (cookbook_task_id marker in the description).
- Tasks list groups cookbook_serve under a "Cookbook" category that
  sorts above the rest, so scheduler-launched serves are easy to find.
2026-06-05 14:41:43 +09:00