mirror of
https://gh-proxy.org/https://github.com/klinsmaya/multica.git
synced 2026-11-08 01:16:45 +08:00
main
100
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
38a65f4988 |
MUL-8425 feat(sidebar): right-click quick actions on sidebar issues (#9749)
* MUL-8425 feat(issues): add a sidebar variant of the issue context menu Names the issue in a header, shows current status, priority and assignee beside their entries, and keeps only the triage and navigation actions in the full menu's order. Adds Copy identifier and, while an agent runs on the issue, a confirmed Stop run entry. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * MUL-8425 feat(sidebar): open the issue menu on right-click in the Work panel Pinned issues and issues under expanded projects and views open the sidebar variant; the right-clicked row stays lit while the menu is open. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
4bfa916450 |
MUL-8431 feat(layout): name the rail's work space Work instead of Issues (#9748)
The space holds Views, Pinned and Projects, and its id is already "work"; only the label said Issues, which made Projects read as part of Issues and repeated the word three times (rail, panel title, All issues). The Issues page and the issue noun keep their names. Other locales move from their issue word to their existing work word (工作, 作業, 작업, Travail). Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
e9ba02f6ff |
MUL-8424 fix(sidebar): light a clicked issue at once instead of All issues first (#9747)
* MUL-8424 fix(sidebar): light a clicked issue at once instead of All issues first The Work panel learned the route issue's id only from the issue detail cache, so until the issue page finished loading it no tree row matched and All issues lit up for the /issues/... path. Take the id from a UUID route or from the expanded tree lists (by id or identifier) instead, and let a clicked tree row keep the highlight over a pin without waiting for the load. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * MUL-8424 test(sidebar): mock the auth store with its callable shape plus getState Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
7c186016a5 |
feat(core): multica 1.0 part 1 (MUL-8317) (#9635)
* feat(core): add app space model for rail navigation Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(layout): replace left sidebar with app rail and space panels Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * test(e2e): drive navigation through the app rail Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(layout): finish the rail and panel shell against the mock - The sidebar toggle always works: in Inbox, Chat and Settings it collapses the page's own list column instead of being disabled. - Move create workspace from the rail into the account menu, and complete the menu: profile, theme and language submenus, shortcuts, docs, change log, Discord, desktop download, log out. - Add an explicit New issue button to the Issues and My issues headers. - Autopilot panel gets a create button and template shortcuts; Team panel gets an invite-member button for owners and admins. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(desktop): draw tabs as pills on the title bar The active tab no longer merges into the content card: with the space panel inside the card, the merged tab landed over whatever column happened to sit below it. Every tab is now a pill on the title bar; the active one uses the card's own surface, inactive ones a lighter tint. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(layout): give list columns the space panel's width Inbox and Chat defaulted to 260px with their own saved widths, Settings was a fixed 240px, and the space panel used the sidebar width. They now share one ListColumn sized by --sidebar-width with the panel's resize edge, so the divider stays in place across spaces and one drag resizes them all. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(layout): return each rail space to where you left it Rail items always linked to the space's home, so switching spaces dropped the project, squad, chat session or settings tab you had open. The shell now remembers the last page (path and query) per space and workspace, and the rail links there; the current space's item still leads home, so a second click resets it. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(layout): animate the list column when the sidebar toggles Inbox, Chat and Settings unmounted their list column on toggle, so it snapped away while the space panel slid. ListColumn now stays mounted and eases its width like the panel (200ms, off under reduced motion and while dragging), which also keeps the list's scroll position across a collapse. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(layout): one title band for every left column The space panels used PanelHeader (title-sm, no rule), Inbox and Chat used the page header (body size, bottom border) and Settings its own 64px title. PanelHeader now takes a heading level, a leading slot and a meta slot, and Inbox, Chat and Settings render their list title with it. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(layout): collapse the whole sidebar with one toggle across spaces Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(layout): switch workspaces from one rail tile Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(layout): preview Inbox, Chat and Settings lists on rail hover Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(inbox): keep the list column's own loading skeleton Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(desktop): lay out the shell for the page on screen during rail switches (MUL-8317) The tab session URL moves before the router commits the next page (it renders in a transition), so for a few frames the shell already showed the incoming space's layout around the outgoing page: switching into Inbox or Chat dropped the Work panel and the old page's header icon jumped to the top-left. The router now publishes its committed pathname from a layout effect and the shell's panel and list columns follow it; space memory keeps following the navigation URL. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(views): flatten the settings nav into one level of section headings (MUL-8317) Scope header rows, sub-group headings and dividers stacked three levels into the 240px list column. Every section is now a peer with the space panels' section label and spacing; each page already names its scope in a badge. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(views): expand projects inline in the work panel (MUL-8317) Project rows in the Issues panel get a chevron that lists the project's open issues in place, so the sidebar can move between issues without opening the project page. The issue on screen reveals its project and stays lit; expansion persists per workspace. A dedicated open-issues cache follows realtime title patches and refetches only when status or project membership moves. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(views): sidebar tree settings, load more, expandable views and project order (MUL-8317) - Expanded projects and views list issues from the server (updated date, finished statuses hidden) with Load more / Show less. - One shared issue display popover on hovered expanded projects; a project display popover on the Projects header (ordering, statuses, only mine, counts); drag to reorder; collapsible section; no project cap. - Issue rows shimmer and show agent avatars while an agent works or waits. - Settings, order and expansion persist per workspace. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(views): show sidebar status filters as checkboxes (MUL-8317) Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(ui): auto-collapse the nav only below lg (MUL-8317) The rail now stays on screen beside the space panel, so laptop-sized windows (1024-1279px, just under the 1280 desktop default) have room for the panel; they no longer open Issues with it collapsed. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(views): one Projects display popover, higher-contrast filter chips (MUL-8317) Issue settings are shared by every project, so they move from each expanded row into the Projects header popover beside the project settings. Status filters go back to chips: a solid outline and tint when on, dashed and faded when off. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(server): list views across scopes and store sidebar view order Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(views): starred views sidebar, unified view header and All views page - Sidebar Views lists only starred views (built-in and saved, user-ordered) with an All views row; order lives in a per-user sidebar preference. - Issues, My issues and project pages share one header: view name menu, folding filter chips (+N), assignee-type / relation chip, Reset and Save. - Saved-view filters are fully editable; new views are created directly and renamed inline instead of through the save dialog. - New All views directory with tabs, search and star toggles. - Project page drops the breadcrumb and hides the redundant project chip. - Remove the view bar, save/manage dialogs and the old headers. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(inbox): switch between inbox and archive with header tabs Replace the Archived row that trailed the notification list (and the back row inside the archive) with Inbox | Archived tabs pinned under the list header. The unread count moves onto the Inbox tab, and an empty archive no longer says the inbox is empty. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * Revert "feat(inbox): switch between inbox and archive with header tabs" This reverts commit e8a8e1bcea1bf5b45c4e5830d654523a0b77daff. Co-authored-by: multica-agent <[email protected]> * fix(inbox): drop the count beside the no-agents-working filter The count widened the whole filter menu for a toggle whose result is visible in the list as soon as it is applied. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(inbox): switch to the archive from the page title The Archived entry trailed the notification list and scrolled away with it. The list title is now a menu (Inbox / Archived), so the switch stays in reach without adding a row, and the archive's back row is gone. An empty archive no longer says the inbox is empty. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(sidebar): keep a pinned issue lit after its URL turns canonical The issue route replaces /issues/<uuid> with /issues/MUL-123, but a pin only matched its own UUID href, so clicking a pinned issue lit the same issue under its project instead. Issue pins now match the open issue by id, a lit pin no longer auto-expands its project, and pinned issues show the running agent the same way tree rows do. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(sidebar): line pinned agent avatars up with the tree rows The avatar sat inside the gap reserved for the unpin button, so pinned avatars landed left of the project tree's and the label lost room. A pinned issue with agents now puts the avatar in the row's right edge and hands that slot to the unpin button on hover. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(sidebar): raise the contrast of the working-agent shimmer ShimmerText now reads --shimmer-text-base, --shimmer-text-highlight and --shimmer-text-spread, defaulting to the previous values. Sidebar issue rows (tree and Pinned) rest on faint-foreground and use a 22% highlight band so the sweep is visible at sidebar size; chat, the issue page and other shimmer hosts are unchanged. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(issues): keep the view header from overlapping on narrow widths The view-name button kept the Button base shrink-0, so once the h1 hit its min width the name painted over the add-filter trigger (visible on a 390px web viewport). The button now shrinks and truncates, the add-filter label becomes screen-reader-only in a narrow header, and FoldingFilterChips re-measures its reserved width when its leading or trailing controls resize instead of only when the chips change. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(issues): one Filter dropdown and a header that adapts to its width The view header no longer lays filters out as chips with a +N overflow. A single Filter button carries the active count and opens the filter menu, which now lists the dimensions already filtering first, each showing its values, with the scope axis (assignee type, relation to me) at the top. The split is taken when the menu opens so a row never moves mid-edit. The header measures itself: when the title side runs out of room it first folds the display controls to icons, then the agents chip and New issue, before the title truncates, and only releases a step once the row is wider than the width that forced it. This fixes the overlap in saved views with table controls and after toggling agents working. FoldingFilterChips and single-row-fit had no other users and are removed. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(sidebar): keep the highlight on the row that was clicked An issue that is both pinned and listed in the tree always lit its pin, so clicking it under a project moved the highlight away from the row just clicked. The work panel now remembers which section a click on an issue link came from: a click in the tree keeps the tree row lit and the pin unlit, a click on the pin keeps the pin. Arriving any other way (search, a link, a shortcut) still lights the pin. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(sidebar): let Views and Pinned collapse like Projects Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(sidebar): keep a dragged row at its own height while reordering (MUL-8354) (#9662) Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(sidebar): create an issue in a project from its row Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(issues): put the workflow beside the title and set the panel toggle apart The project workflow now sits on the left with the title and Filter, in the same borderless style. New issue matches Display's height, and a divider separates the right-sidebar toggle from the header actions. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(issues): fold the layout switcher into the Display panel One Display button whose icon follows the layout. The panel opens with the layouts as a segmented row, then grouping, ordering and sub-issues, then the current layout's own options. The table's grouping and column pickers move in from the header. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(issues): keep hovered Display chips from looking selected Light mode's muted and accent are the same grey, so a hovered chip matched a pressed one. Hover now only darkens the text and border, and a pressed chip fills with the stronger input tone. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(sidebar): give the Projects settings the Display panel's controls Both panels now share one chip and one sort-direction button. The sidebar popover drops its dividers and dashed off-chips, takes the same section headings, and its selects match the Display panel's width. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(issues): quiet the issue view header down to its title The header carried six pieces of text, half of which said nothing: the project's workflow name, "0 agents working" and "Display". - Workflow moves into the project title menu as a submenu; the properties panel keeps its row. - Filter becomes an icon beside the title, followed by Reset / Save, so the count sits next to the actions it causes. Its tooltip names the active filter fields. - Display and New issue become ghost icon buttons named by tooltips, with New issue showing its C shortcut. - The agents chip shows only while someone is working or its filter is on, as avatars and a number. With every control already an icon, the crowding steps are gone. MUL-8361 Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(issues): is / is not per filter, Relation to me, and a hover summary (MUL-8353) (#9663) * feat(issues): is / is not per filter, a Relation to me filter, and a hover summary (MUL-8353) Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(issues): match the Relation filter's Chinese labels to My issues (MUL-8353) Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(views): advanced filter mode, menu search, and due date filter Advanced mode turns the simple filters into a rule tree (match all/any, is/is not per condition, one level of groups) edited in a panel behind the same Filter trigger. Switching back is offered when the tree is something simple mode can say. The filter menu gets a search box that matches fields and values; a value hit reads as the condition it adds. Due date joins as a dimension with relative buckets (overdue, today, this week, next 7 days, none). The issue table query accepts filters.advanced, filters.due_dates and filters.today, compiled to SQL with the same IS NOT TRUE negation. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * test(e2e): menu search, due date and advanced filter Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> Co-authored-by: Cursor <[email protected]> * test(e2e): let menus settle before filter screenshots Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(views): advanced filter keeps status columns, property filters and negated totals - Columns follow a status the rule tree requires, and a status it names un-hides its column, so switching to advanced no longer drops rows. - Status branch totals drop the excluded keys for "is not" instead of falling back to the loaded count. - The advanced panel shows property filters as editable rows with an "Add property filter" entry, and Clear all clears them too. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(views): make custom properties ordinary advanced filter conditions Properties are fields in the advanced tree: they sit in the field picker after the built-in fields, can live in groups and follow all/any, and edit their values with the property's own options. The server compiles a property:<id> condition with the existing property predicate. Entering advanced mode moves property filters into the tree, so the separate property section and its Add property filter button are gone. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(views): typed filter operators and direct condition groups - Add condition group inserts an empty group and opens its own add menu, instead of asking for a field first. The group's header carries its match ("Match any of these"); rows only show the joining word. - A row's menu can turn it into a group, and a tree with groups reads back as one sentence under the rows. - Operators follow the field's type: is / is not, includes any / none of for labels and multi-value properties, contains for text, comparisons for numbers, before / after for dates, and is empty / is not empty for anything that can be unset. Text, number and date values are typed in the row. Every operator is a reading of the stored negated + values, so saved views and the server query are unchanged. - Actor value headings sit in a menu group, which Base UI requires. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(layout): New issue and search at the far end of the desktop title bar New issue lived only as a pen in the Issues panel header, so Inbox, Team, Chat and Auto had no way to start an issue but the C shortcut. Search sat in the rail between the workspace tile and the spaces. - Desktop: New issue and search are icon buttons at the right end of the title bar, styled like Back/Forward, with search last. The tabs give way to them. The rail drops search. - Web has no title bar, so its rail keeps both under the workspace tile, New issue first. - The button does what C does: a project page files the issue into that project. Both now share one helper. - The Issues panel header loses its pen; the page header keeps New issue. MUL-8359 Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(issues): remove horizontal scrollbar from the filter menu Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(sidebar): every view expands in the sidebar Saved views preview through the table query, which expresses every view filter (is not, relation, due date, rule trees, my-any). Built-in views expand too, scoped like their page and listed with the sidebar issue settings. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(sidebar): group expanded rows by spacing, folder icon for projects Issues under an expanded row drop to 26px rows with no gap and a 12px status icon, an open group ends with 8px of space, and the expanded row's name goes full-strength. Sections sit 20px apart. Sidebar projects show a folder icon instead of their emoji. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(sidebar): expandable rows give their label the full width The hidden chevron, an empty spacer and their gaps reserved about 90px at the end of every expandable row, so names truncated with space to spare. The chevron now takes the icon's place on hover. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(sidebar): tree row chevron swaps back to the icon immediately Drop the opacity fades, and show the chevron for keyboard focus only, so a clicked row no longer keeps it until focus moves. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(issues): drop the hint beside Switch to advanced filter The grey text sat where the menu shows current values, so it read as a setting rather than an explanation. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(layout): tighten the gap under panel titles, keep selected rows at regular weight The first section kept the 20px that separates sections, so it sat far below the panel title. Selected and expanded rows, desktop tabs, the Settings nav, agent tabs and the skills file tree no longer switch to medium weight: the wider glyphs made the label grow when it was clicked. Selection reads from the background and text colour. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(sidebar): keep stars while loading, leave view state to in-place clicks, page past 100 - Star, unstar and reorder write the stored order, not the resolved items, and wait until that order is known, so views still loading are kept. - Sidebar rows switch the active view only when the click navigates this page; a new tab takes its target from the URL. - Sidebar issue lists walk 100-row pages so Load more keeps growing. - Drop a trailing blank line in advanced-filter-panel. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(views): open the clicked view in desktop tabs, prepare view state only on in-place navigation - Desktop tabs carry their own ?view=: list pages adopt it on mount and on back/forward, write view changes back with replace, and the active-view map is swapped with the active tab. A saved view is part of tab identity, so cmd+clicking view B from a tab on view A opens B in a new tab. - AppLink and useRowLink call onNavigateInPlace right before they push, so sidebar and All views rows prepare view state exactly when the page navigates in place (desktop shift-click included, web shift-click not). - Rail items and the workspace tile use named radius tokens. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(views): one page system for lists and objects Every page now follows the Issues page: one 48px header, nothing stacked under it. - Lists entered from the sidebar (agents, squads, skills, runtimes, projects, views, autopilots, issue wakeups) title themselves with an icon and a scope menu, and keep only icon tools: filter with its count and Reset, display, and "+". Counts left the header; list search is removed. - Objects (agent, squad, skill, runtime, autopilot, member) open under a breadcrumb with at most one solid action and a ⋯ menu. Their tabs became body sections with actions on the section titles, in a 760px column, with a 300px properties panel the header toggles. - Analytics keeps its tabs, now in the header; settings, chat and the create-agent flow share the same header. - Shared CollectionPage* and ObjectPage* primitives in views/layout. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(views): one CollectionList for every list page Replace the per-page tables and ListGrid with a shared CollectionList in packages/views/layout: single-line 36px rows with inline grey descriptions, a shared column/grid template, header sort, row selection with shift-range, keyboard navigation (arrows, J/K, Enter, X, Cmd+A, Esc), right-click and kebab row menus, load-more, and a shared batch bar. - createCollectionViewStore factory in core; display menus are generated from the column definitions. - Agents, Squads, Skills, Projects, Autopilots, Runtimes (page and RuntimeList), Views and Wakeups migrate to it; Wakeups pages with load-more instead of prev/next. - The Issues batch toolbar uses the shared CollectionBatchBar. - Agents hides owner and access by default so the default columns fit at 1280px; persisted v1 defaults migrate, custom choices are kept. - Remove ListGrid and the now-unused per-page locale keys. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(layout): smooth the nav panel toggle - Ease the panel and list columns with a soft-start curve (220ms ease) instead of ease-out, whose first frame jumped a quarter of the width and, when that frame dropped, nearly half of it. - End-align the panel content and clip it while it grows, so it slides in with the edge instead of spilling under the page; the resize handle moves to a zero-width sibling so the clip does not cut it. - The floating chat stays mounted while closed and re-rendered on every frame of the toggle as its container resized; it now re-renders only when the clamped window size changes. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(issues): give My agents' work its own URL My agents' work shared /my-issues with My issues and was told apart only by a persisted global scope, so it could not open in its own tab, and switching one tab flipped every other. It now lives at /my-issues?scope=agents: the page, header and sidebar read the scope from the URL, desktop tab dedupe keys on it, and the tab gets its own title and icon. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(views): preserve My agents' work in copied links Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
22a05d832b |
MUL-8423 chore(ui-lab): remove the UI Lab design workbench (#9746)
Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
893c6b9a16 |
MUL-8422 feat(attachments): page the viewer from a pager under the stage (#9745)
Prev / next lived in 64px side gutters with the position counter in the top bar: one control split across three places, its two buttons a window width apart, and a near miss in the gutter closed the viewer because the gutter is stage padding. The counter now sits between the buttons in a 48px strip under the stage, outside the backdrop. The top bar only describes the current file, the stage gutters drop back to 16px, and the buttons show their arrow-key shortcuts. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
e8ae72c9df |
MUL-8418: fix(usage): correct Cursor variant and OpenAI GPT-5.6 pricing (#9739)
* MUL-8418: fix(usage): price Cursor -fast / effort variants consistently Add vendor-published Fast rates Cursor's sheet omits (Opus 5.5/5, GPT-5.5, GPT-5.3 Codex, GPT-5.2), price gpt-5.1 and Cursor's deepseek-v41 spelling, bill Gemini 3.5/3.6 Flash at Cursor's sheet, and route provider=cursor rows in the llm_cost_usd metric through a Cursor-aware resolver that mirrors the frontend so Fast variants no longer borrow the standard rate. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * MUL-8418: fix(usage): update GPT-5.6 rates and pre-5.6 OpenAI cache writes GPT-5.6 Sol / Terra / Luna move to OpenAI's current standard rates (4/20, 2/12, 0.20/1.20) on both the dashboard and the llm_cost_usd metric. Backend pre-5.6 OpenAI rows billed cache writes at the cache-read rate; those tokens are ordinary input, matching the frontend. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * MUL-8418: fix(usage): price GPT-5.6 Sol at list rate, not promo Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
249fdf2d84 |
MUL-8417 fix(chat): open the floating chat with its messages already showing (#9737)
Cmd+J faded the floating window in on the keypress, but closing it unmounts its message list (MUL-8030), and a freshly mounted list stays invisible until it has landed on the newest message and then held still for a 120ms settle window (MUL-6879). Every open therefore showed a header and composer around an empty middle for ~175-200ms before the messages appeared. - A conversation already revealed in this page session skips the settle window and reveals as soon as it lands. Settling waits out cold content (fonts, image decodes, diagram heights); a conversation the reader has already seen has none left. - The floating window holds its fade-in until its message area reports ready (list revealed, skeleton, or empty state), bounded by a 300ms deadline so a slow list never makes the toggle look dead. Measured in Chromium against the production build, Cmd+J to frame: warm reopen went from list at ~220ms with ~175ms of visible empty panel to list at ~85ms and zero empty frames, idle or with a task streaming. Co-authored-by: multica-agent <[email protected]> Co-authored-by: Cursor <[email protected]> |
||
|
|
ac131c55cb |
MUL-8416 fix(comments): keep thread owner when root folds into a queued task (#9735)
A member reply merged into a still-queued task moves trigger_comment_id to the reply and leaves the thread root only in coalesced_comment_ids. ListConversationRootOwners matched the root against trigger_comment_id alone, so the thread lost its owner and later un-mentioned replies under the root were silently dropped. Treat a root in coalesced_comment_ids as owned, the same coverage rule taskCoversReplyParent and CancelAgentTasksByTriggerComment already use. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
16f0d307dd |
fix(realtime): announce comments folded into a queued run (#9702)
A reply posted while the agent already has a queued run in the same thread is folded into that run on the server: the reply becomes the run's trigger and the earlier comment joins its covered set. The run's status does not change, so no task event fired and open issue pages kept the run under the earlier comment, leaving the new reply with no visible queue row. Publish task:coalesced after the merge (and after a delegated-failure merge). Web and desktop already refresh the issue's runs on any task: event, which moves the queued block under the newest comment it answers; mobile now listens for it too. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
a802ce2c6f |
MUL-8377: feat(workflows): one-line project usage and named handoffs in the workflow list (#9689)
* MUL-8377: feat(workflows): one-line project usage and named handoffs in the workflow list The workflow list spelled out every project name under each row, so a workflow used by 25 projects wrapped to five lines. Rows now summarise usage as project icons plus a count (or the name, for one project) and open a filterable project list on click. Handoff chips name who takes the step instead of showing a bare avatar, steps are joined by arrows so the row chevron only means open, and the row link is the workflow name (stretched over the row) so its accessible name is no longer the whole row's text. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * MUL-8377: keep each step's arrow with the step when the chain wraps A long workflow wraps its status chain; the arrow was its own flex item, so a line could end on an arrow right beside the row's open chevron. Each arrow now travels with the step it points to, so wrapped lines start with it. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * MUL-8377: name the workflow project popover for screen readers The popover's heading was a plain span, so its dialog had no accessible name. Use PopoverTitle for the workflow name and PopoverDescription for the project count, which wires aria-labelledby and aria-describedby. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
2083970b51 |
MUL-8374: fix: keep private chat content to the session owner (realtime + REST) (#9677)
* MUL-8374: fix(realtime): deliver private chat content only to the session owner Chat events and chat-task transcript (task:message) frames were fanned out to every connection in the workspace. Route every chat:* event, and task:message for chat tasks, to the chat session creator's user scope instead. Producers stamp the owner on the bus event (from the same chat_session row they already read); an event without an owner is dropped rather than widened. Chat-task lifecycle events keep workspace fanout for agent presence. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(server): keep chat-task content private on REST task reads The transcript endpoint now 404s chat tasks for anyone but the chat session's creator, and the agent run list and workspace task snapshot keep foreign chat-task rows but blank their result and error. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(realtime): scope private chat delivery to the owner's workspace connections User-scope delivery reached the chat creator's connections to every workspace. Those are authorized against their own workspace only, so a creator removed from the chat's workspace kept receiving its transcript and reply through a socket to another workspace. Chat content now goes to a workspace_member scope each connection joins at connect time; it is re-authorized against the chat's workspace on every write. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
b2e58d0bf8 |
fix(views): move Create sub-issue below Rename issue in issue actions menu (#9661)
Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
045fcdf19a |
feat(issues): compact the sidebar execution log (MUL-8350) (#9659)
* feat(issues): compact the sidebar execution log (MUL-8350) Single-line finished runs (reason line only on failure/cancel), several queued runs fold into one expandable row, a 24px cost strip without the time axis, and the Latest label carries the Show-more link. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(issues): drop the Latest heading from the sidebar execution log (MUL-8350) Finished runs already read apart from active ones by tone and right column; the full history stays one click away from the header button and the cost strip. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(issues): cap the sidebar execution log at three rows (MUL-8350) Active runs take the rows first and are never cut; past runs fill what is left. The rest stays in the Runs dialog. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(issues): narrow the issue sidebar's outer gutter (MUL-8350) Sections already inset their bodies and rows by 16px, so the panel's own 16px put content 32px from each edge. The issue sidebar now uses an 8px gutter; the project sidebar keeps p-4. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
d5d1382b8f |
fix(ui): tint the active sidebar icon lightly instead of filling it solid (MUL-8351) (#9660)
Reverts the solid fill from 95294b1 back to the 20% body tint. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
ce565c1aa4 |
fix(ui): Linear's menu geometry across dropdown, context, select and command menus (MUL-8344) (#9657)
* fix(ui): compact menus again — 28px rows, 16px icons (MUL-8344) Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(ui): match Linear's menu geometry — 32px rows, 16px icons, 8px gaps (MUL-8344) Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(ui): same menu geometry for Select and Command lists (MUL-8344) Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
9987874547 |
fix(ui): sharp-tipped directional icons, straight checks, sized icons, 14px menus (MUL-8344) (#9655)
* fix(ui): draw checks as two straight strokes instead of a handwritten swoosh (MUL-8344) Check, CheckCircle2, CheckCheck, ListChecks, ListTodo, ShieldCheck and BookCheck share a new tick() helper with a tight vertex. CheckCircle2 and ShieldCheck mark their check as a detail so the solid state keeps it. The issue actions and member role menus use the Check icon instead of a text ✓, which fell back to the system font's calligraphic glyph. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(ui): enlarge undersized icons and stop the attach icon shrinking to 12px (MUL-8344) Paperclip spanned 11x13 of the 24 grid with rails 2 apart, so at 14px it read as a blob. It now runs corner to corner with rails 3 apart. Play, Pause, SkipForward, Pipette, Rocket and Pencil scale up to the set's usual ~18 span. FileUploadButton and the code block's reload/fullscreen buttons sized their icons with h-/w- classes, which the icon-xs button variant overrides to 12px; they now use size-* so the intended size applies. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(ui): back to 14px text in the sidebar and menus, keeping 18px icons (MUL-8344) Sidebar rows and dropdown/context menu items return to text-body. Menu items take 1px more vertical padding so rows stay 32px tall; sidebar rows keep their fixed 34px. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(ui): sharp tips on every chevron, arrow and bracket icon (MUL-8344) Chevrons, arrowheads, < > brackets, prompts, panel toggles and direction triangles turned at a soft curve or a rounded k corner. They now turn at a sharp vertex: 32 soft-curve subpaths become polylines, head() draws a straight arrowhead, the rotate/refresh and diagonal arrowheads drop their corner radius, and Play, SkipForward, FastForward and ArrowBigUp get sharp tips. Shaft bends in corner and U-turn arrows stay rounded. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(ui): stop the pencil's cap line poking out of its body (MUL-8344) Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
f0c361ebca |
feat(ui): Multica icons, roomier menus and typography pass (MUL-8334, MUL-8338) (#9640)
* refactor(ui): add @multica/ui/icons as the single icon entry point (MUL-8334) Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * refactor: import icons from @multica/ui/icons instead of lucide-react (MUL-8334) Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * chore(lint): ban direct lucide-react imports outside @multica/ui/icons (MUL-8334) Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(ui): draw Multica icons and enlarge primitive icon sizes (MUL-8334) Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(ui): roomier menu and sidebar rhythm (MUL-8334) Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(ui): mark body and detail layers in icon glyphs (MUL-8334) Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(ui): Inter optical sizing, lighter titles, CJK leading and zh-TW font stack (MUL-8338) Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(ui): 13px for in-place reading text, regular weight for descriptive labels (MUL-8338) Issue detail timeline, comment headers, properties panel, wakeup and PR rows move from 12px to 13px; sub-issue identifiers match list/board (12px regular); sidebar group labels drop to regular weight; board card titles get more leading under a CJK UI via a new cjk: variant. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(ui): tint the active sidebar icon's body with a light fill (MUL-8334) Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(ui): draw every remaining icon and drop lucide-react (MUL-8334) All 286 icon names now render Multica drawings. The drawings, their construction helpers and the generator live in packages/ui/icons/drawings; glyphs.ts and index.ts are generated and a test fails when they drift. Search loses its lens highlight and Inbox its arrow. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * chore: guard against icon libraries and document drawing new icons (MUL-8334) Lint bans the common React icon libraries, AGENTS.md points to a new multica-icons skill, route icons must mark a body for the active tint, and comments no longer describe product icons as Lucide. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(ui): fill the active sidebar icon solid with its details knocked out (MUL-8334) Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(lint): ban icon library subpaths too (MUL-8334) Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
fb49f55924 |
MUL-8340 feat(search): context-aware command bar with agent handoff (#9647)
* feat(search): rebuild the command bar around page context and agent handoff (MUL-8340) Pages register what they show (issue, selection, project, agent, autopilot, inbox, chat) and the bar leads with commands for it. Adds cmdk submenus with breadcrumbs, S/A/P on an empty input, relevance-ranked mixed results with a best match and its actions, > # @ scope prefixes, a mixed Recent group, and a Hand to agent group that turns an instruction into a quick-create. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(search): drop S/A/P single-key submenu shortcuts (MUL-8340) A plain letter on an empty input opened the issue's status, assignee or priority submenu, so a search starting with s/a/p could land in a picker; typing "alice" on an issue page could assign it instead of opening her page. Letters now always type; the issue's commands are reached from their rows or by name, where context ranking already puts them first. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(search): keep overlapping command groups apart and report writes after close (MUL-8340) With a list selection and an issue preview both open, the two groups offered rows with the same cmdk value, so Enter on the selection's row ran the single issue's command. Context group rows now carry their group in the value. The palette closes, and unmounts, before a write settles, so per-call mutate callbacks were dropped and a rejected single-issue write rolled back without a toast. Single-issue writes now go through mutateAsync behind the same run-confirm gate, and the other post-close mutations handle their outcome on the promise. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
8305976793 |
fix(views): show agent run row actions on touch devices (MUL-8341) (#9646)
Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
48df977755 |
fix(views): stop page-switch layout jumps and prefetch page data (MUL-8337) (#9643)
* fix(views): stop page-switch layout jumps from double skeletons and late toolbars (MUL-8337) Remove the dashboard-level loading.tsx again: it flashed a generic skeleton on every web route change before the page's own skeleton or content, the regression #1256 originally fixed. The NavigationProgress bar now covers click feedback. Agents, Skills, Squads and Autopilots now keep their list toolbar mounted through loading so rows no longer drop by its height when data lands, matching Projects and Issues. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(views): prefetch page data on link intent and hold skeletons for 200ms (MUL-8337) Sidebar links now warm the destination page's queries on hover/focus, and the common list pages (agents, skills, squads, autopilots, projects) are prefetched once the workspace is idle, so most navigations render from cache in one pass. Skeletons stay invisible (space reserved) for their first 200ms, so data that lands quickly swaps straight to content without a placeholder flash. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(views): draw runtimes, inbox and issue-surface skeletons in their real layout (MUL-8337) Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
c2471a9ba7 |
feat(issues): open the full log straight from the agent run row (MUL-8335) (#9641)
Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
0a83848c0d |
MUL-8284: docs(agents): require buy-in for speculative edge cases; trim duplicated rules (#9585)
* docs(agents): require buy-in before adding speculative edge-case complexity (MUL-8284) Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * docs(agents): trim duplicated rules (MUL-8284) Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
a097f592be |
MUL-8260 feat(web): fit the mobile web app to iPhone Duo (#9558)
* MUL-8260 fix(web): let the mobile nav drawer scroll as one on short screens On iPhone Duo's outer display in landscape (368px tall) the drawer's pinned header and footer left the nav list a three-row scroll window, hiding Issues, Projects, Agents and the rest. At 640px tall or less the whole drawer now scrolls as one column; taller screens keep the pinned layout. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * MUL-8260 feat(web): dock the nav and keep list/detail panes from md up On iPhone Duo's inner screen held sideways (951px) the nav could only open as an overlay sheet and the inbox and chat folded to one column, because the compact breakpoint sat at lg (MUL-5842). Move it to md: from 768px the nav is a docked column that starts collapsed (the auto-collapse band now spans md-xl) and the trigger docks it open, and inbox and chat keep both panes. Below 768px nothing changes. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * MUL-8260 test(desktop): exercise the compact shell below the new md breakpoint Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
8c3ceb3610 |
feat(issues): jump from the header agent chip to the run's block (MUL-8180) (#9451)
Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
b7d92dd514 |
feat(views): promote Create sub-issue to the top level of the issue actions menu (MUL-8181) (#9450)
Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
c57aa87a6f |
MUL-8179 fix(issues): clear sub-issue selection after a batch action applies (#9449)
* MUL-8179 fix(issues): clear sub-issue selection after a batch action applies Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * MUL-8179 fix(issues): keep selection when run-confirm batch applies partially Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
fd6fc2c600 |
MUL-8175: fix(issues): sub-issue batch toolbar ignores row selection in the side peek (#9445)
The sub-issue rows and select-all wrote the global selection store, while the inline BatchActionToolbar reads the nearest surface selection. Inside a peek the surrounding IssueSurface's provider wins, so checking sub-issues never showed the toolbar — or showed the board's selection instead. The sub-issue list now owns one selection scope shared by rows, select-all and toolbar. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
4dd6d57127 |
fix(issues): keep the sticky comment header fade off the first body line (MUL-8172) (#9442)
The sticky header draws a 4px fade just below itself. Since #8131 moved the header/body gap into the header's bottom padding, that fade overlaps the first line of the body, so a mention chip there loses its top border and reads as a drop shadow. The sticky header now reserves the fade's height as a bottom margin and takes the same 4px out of its padding; the gap at rest is unchanged. Co-authored-by: multica-agent <[email protected]> Co-authored-by: Cursor <[email protected]> |
||
|
|
b05646a452 |
fix(views): bind pills to the xs control height (MUL-8166) (#9433)
* fix(views): keep toolbar pills a fixed height (MUL-8166) The assignee pill grew to 30px around its 20px avatar while text pills stayed 26px. Pin the pill chrome height and use the 16px avatar tier inside pills. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(views): bind pills to the xs control height and let them size their contents (MUL-8166) Pills now take --button-height-xs instead of padding, and set avatar and label-chip sizes for their contents via --avatar-slot-size and a label-chip slot. Reverts the per-call-site avatar sizes. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
5f6cd749ae |
feat(issues): move hidden columns into Display, keep boards to their workflow (MUL-8160) (#9429)
* fix(issues): keep project boards to their workflow's statuses (MUL-8160) Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(issues): move hidden columns into Display and drop the panel (MUL-8160) Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(issues): lock Display columns while a status filter is on (MUL-8160) Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
23c8fc4dba |
refactor(ui): remove copy that restates titles, labels and buttons (MUL-8162) (#9432)
* refactor(ui): remove copy that restates titles, labels and buttons (MUL-8162) Drop collection page taglines, redundant Settings descriptions, agent creation filler, triplicated Qoder credential notes and the workflow card caption. Compress the handoff next_hint to its two constraints. Update all five locales. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(settings): keep the background condition in the system notification label (MUL-8162) Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
029466efb3 |
feat(agents): move conversation starters to the agent profile (MUL-8151) (#9419)
* feat(agents): move conversation starters to the agent profile (MUL-8151) Starters are what people see in a new chat, not part of the system prompt, so they now sit in Settings > General > Profile beside avatar, name and description, autosaved, with a live new-chat preview. The Instructions tab holds only the prompt in a Write/Preview editor with a pinned save bar. In the create flow starters are an optional row under Identity. The chat's Customize link now lands on General; its focus flash no longer sticks under StrictMode. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * docs(agents): say where conversation starters are edited (MUL-8151) Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(agents): keep an incomplete conversation starter open until filled in Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
c9b6de8567 |
MUL-8142: docs(runtimes): step-by-step Qoder Cloud Agent setup and correct entry path (#9408)
Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
6a70ec5352 |
feat(ui): give tooltips a dark surface in both themes (MUL-8140) (#9407)
Tooltips shared the popover surface: white, a faint border and no shadow in light mode, so they blended into white cards and looked like the interactive menus and hover cards around them. They now use a dedicated --tooltip surface: near-black in light mode, one step above every surface with a 1px ring in dark mode. The popup is a .dark scope so muted, status, and keycap colors inside it stay readable in both themes. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
0fe2ebf02e |
MUL-8045: feat(runtimes): Qoder Cloud Agent as a managed cloud runtime (#9402)
* feat(runtimes): add Qoder Cloud Agent managed remote execution * fix(qoder): satisfy migration and localization CI contracts * fix(qoder): bound execution and scope managed credentials * fix(qoder): avoid upstream migration number collisions * fix(qoder): gate issue creation and correlate tool results * fix(qoder): synchronize guarded issue lifecycle transitions * test(agent): publish Hermes holder identity atomically * feat(agents): runtime-first create flow and cloud runtimes section for Qoder Cloud Agent - Three-step create-agent flow (runtime -> configure -> done) with local, remote and cloud sections; Qoder connect form inline in the runtime step - Runtimes page regrouped into remote and cloud sections with Qoder card - Generalize Qoder storage to cloud_agent_connection (migrations 586/587) - Locales for en, zh-Hans, ja, ko, fr; desktop and web routes for done step - Fix status-picker fixture owner_id and diagnostics route coverage after main merge Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(runtimes): unify runtimes page into machines and cloud services - One Add menu replaces Add remote runtime, the duplicated Add a computer and the web-only Cloud Runtime header button - Group by machines / cloud services instead of local / remote / cloud, so web and desktop share one structure; this device is pinned with a badge - Cloud services use the machine row anatomy in a single ListGrid table; unconnected Qoder is a row with Connect, coming-soon providers are rows - Empty groups show the next step inline; search and online/offline filter - Rename computer to machine across runtimes copy in all locales Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * test(runtimes): cover unified runtimes page; pin status and action tracks Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * refactor(runtimes): trim redundant descriptive copy on runtimes page Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(runtimes): keep row actions visible at narrow widths Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * refactor(runtimes): align Qoder add-menu item with other cloud services Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(runtimes): close the Qoder dialog after a first-time connection Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(agents): pick the runtime from one grouped list The runtime step showed four kinds of cards, a comparison panel and per-section descriptions. It is now one list in the runtimes-page layout: machines (this one open, others folded to a row) and cloud services. An unconnected Qoder opens the runtimes-page connect dialog in place and is selected once it comes online. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(agents): show owners as 'you' and bare version numbers in the runtime list Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(qoder): disconnect action and dedicated Qoder runtime page Disconnect removes the encrypted connection and the managed runtime, unbinding its agents after the admin confirms them. The Qoder row now opens its own page (status, agents, usage, configuration, pause/resume, disconnect) instead of the machine layout; generic runtime delete and visibility refuse a managed runtime. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(agents): land on the done page after creating from step 2 on desktop Desktop's location is the tab URL, which moves to /agents/new/done/<id> while the configure page is still mounted. Its missing ?runtime= tripped the skipped-step-1 redirect and replaced the tab back to /agents/new, so Create looked like it did nothing. Only redirect on the manual route. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(agents): show only settings a Qoder agent can run with The Qoder bridge fails every task whose agent carries a model, thinking or speed override, env, custom args, custom skills, MCP config or connected apps, and it runs issues only. The agent detail page still offered all of those editors, so one save could break every later run. For a qoder_cloud agent the page now keeps Instructions under Capabilities, General / Access / QCA Agent under Settings, drops the model rows and the header model chip, shows the QCA agent in the summary, and locks the runtime. Other agents no longer see the Qoder runtime in their picker, since moving onto it needs a QCA agent the server would otherwise reject. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(agents): hide conversation starters for Qoder agents Starters only appear in a chat, and the Qoder bridge runs issues only. The create flow already leaves them out for this runtime. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(runtimes): show the Qoder connection as cards with per-section editing The Qoder runtime page rendered the whole connection as one always-editable form. It now summarizes the connection, repositories and limits as read-only cards; each section opens its own dialog and saves only that section. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(qoder): reuse a follow-up session only with the same repository and credential Resolve repository credentials before deciding to continue a prior session, and stamp each session with a fingerprint of its repositories, branches and tokens. A follow-up continues only when the fingerprint still matches, so a changed repository, branch or rotated/revoked token never rides into an old session. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(qoder): keep a paused connection paused when its settings are saved Saving repositories, limits or the connection no longer re-enables a paused runtime. Resume goes through a new POST /qoder/resume. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(agents): drop settings a Qoder agent cannot run when creating one A draft started on another runtime could carry hidden skills, model overrides and starters into a Qoder agent that then failed every task. The create request now drops them for Qoder, and the API rejects skills and execution overrides on Qoder agents at save time. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * chore(db): regenerate sqlc models for cloud_agent_connection Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(runtimes): never list the Qoder runtime under Machines When the server could not run Qoder (no MULTICA_VCS_SECRET_KEY / MULTICA_QODER_STATE_DIR), the managed Qoder runtime fell back into the Machines group as if it were a computer. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * refactor(qoder): drop MULTICA_QODER_STATE_DIR The managed bridge keeps its run journal encrypted in cloud_agent_connection and a database advisory lock already elects one supervisor, so the state directory only held a redundant file lock and acted as a feature switch. Qoder is now available whenever MULTICA_VCS_SECRET_KEY is set. The standalone qoder-runtime command still uses its on-disk state_dir. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(qoder): keep the branch in the session fingerprint after a journal restore Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(agents): validate Qoder agents' effective settings on every write Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: 安辰 <[email protected]> Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
e720fe2219 |
MUL-8135: feat(wakeups): wake on linked PR merge conflicts (--until-pr conflicts) (#9406)
* MUL-8135: feat(wakeups): wake on linked PR merge conflicts (--until-pr conflicts) Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * MUL-8135: fix(wakeups): conflict wakes per PR identity, rotate the watch sweep - A linked-PR condition only fires for a PR key the rule has not seen; a PR leaving the satisfying set no longer re-wakes the agent for the others. - Conflict keys use the PR id, so same-numbered fork PRs on one head stay distinct. - The conflict-watch sweep rotates an address cursor so failing fetches cannot starve the rest. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * MUL-8135: fix(wakeups): count repeated linked-PR keys when deduping Checks and merged keys carry only the PR number, so same-numbered PRs from two repositories share a key. Compare occurrence counts so the second one satisfying still wakes the agent. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
e0e9efc5f1 |
MUL-8131: feat(ui): tooltips with shortcut hints and disabled reasons for icon buttons (#9398)
* MUL-8131: feat(ui): tooltips with shortcut hints and disabled reasons for icon buttons Add IconButton (label + optional shortcut keycaps + disabledReason) and let SubmitButton keep a disabled send button hoverable when it has a reason, so blocked composers explain themselves instead of greying out. Surface registered shortcuts (⌘B, ⌘/, ⌘J, E, ⌘[ ⌘], ⌘↵) in tooltips, name the unlabeled More menus, translate the desktop back/forward controls, and drop the global tooltip delay from 500ms to 200ms. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * MUL-8131: migrate icon-only buttons to real tooltips Add TooltipHint for icon controls that keep their own element, and move icon-only buttons across agents, autopilots, skills, issues, editor, chat, settings, projects, runtimes, modals, onboarding and the desktop shell onto IconButton / TooltipHint / DeferredTooltip, replacing native title attributes. Dense per-row actions use DeferredTooltip. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * MUL-8131: tooltips for create-issue pills, attach/reaction/help/avatar buttons, row menus, and remaining native titles Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * MUL-8131: fix(test): add owner_id to Default workflow fixture in status-picker test Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * MUL-8131: keep tooltips on expanded disclosure toggles; keep version-blocked Create aria-disabled Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * MUL-8131: move icon-button test out of the wildcard-exported ui directory Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
1961464067 |
MUL-8092: fix(views): even spacing above and below markdown tables (#9338)
Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
f896cc4833 |
MUL-8074: feat(issues): fold resolved threads in the comment outline by default (#9325)
* MUL-8074: feat(issues): fold resolved threads in the comment outline by default Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * test(issues): expand the folded resolved thread before jumping to its reply Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
9b43430438 |
MUL-8067: feat(views): readable, resizable and expandable markdown tables (#9321)
* MUL-8067: feat(views): table model, source markdown and column width storage Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * MUL-8067: feat(views): readable, resizable and expandable markdown tables Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * MUL-8067: refactor(views): table frame with overlay resize handles, shared by both renderers Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * MUL-8067: feat(views): resize, expand and copy tables in the editor Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * MUL-8067: fix(views): copy a table's Markdown from the content as written Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * MUL-8067: fix(views): table toolbar in its own row; keep handle height after a click Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * MUL-8067: fix(views): keep mentions in the editor table's filter, sort and CSV text Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
050f8b946e |
feat(views): richer issue mention hover card + shift+click peek (MUL-8071) (#9323)
* feat(issues): richer issue mention hover card (MUL-8071) Name the status and priority in words, add a property list (assignee with live agent activity, project, parent, labels, due date, sub-issues, lead PR) and a creator/updated footer, so even a freshly filed issue gets a card that says more than its chip. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> Co-authored-by: Cursor <[email protected]> * feat(views): shift+click an issue mention to open it in the side peek Mount an IssuePeekHost on the issue page and the inbox detail pane so mentions there can peek, alongside the existing list surfaces. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(views): only show the assignee's own runs as hover card activity Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
dfa8bdaa53 |
MUL-8070: feat(cursor): support live-run steering via Cursor hooks (#9322)
* MUL-8070: feat(cursor): support live-run steering via Cursor hooks Cursor's headless --print mode has no mid-turn input channel, but its postToolUse/postToolUseFailure hooks can return additional_context that reaches the model in the same turn. A steerable Cursor run now writes a managed .cursor/hooks.json whose command is the multica binary in a hidden relay mode; the relay forwards the hook event to a token-protected loopback endpoint owned by the run, which hands back pending guidance tagged with a per-run nonce. The prompt declares that tag so the model treats the context as genuine user guidance instead of a prompt injection. Steering is offered only for daemon-managed workdirs on Unix with cursor-agent 2026.10.14+, and the server allowlists cursor for capability negotiation, supplement creation and composer binding. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * MUL-8070: fix(cursor): confirm steering only on Cursor's receipt and gate on installable hooks - Count hook-delivered guidance as delivered only when the tool call's completed stream event echoes it in hookAdditionalContexts. Guidance Cursor dropped for the same call is retried at the next tool boundary; guidance without a receipt fails when the turn ends. - Offer steering only when the workdir can carry the managed hooks.json, and fail supplements immediately if installation still fails after negotiation. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
18fa9f728a |
MUL-8050: price Cursor runtime catalog variants (#9295)
Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
700d25eef5 |
MUL-7420: render the workflow brief once on the server, for the assignee or an observer (#9293)
- issueworkflow.Brief is the only renderer: the claim carries it into every run's per-turn prompt; the editor preview and timeline show the same text. - Workflow handoffs stop writing the brief into handoff_note, so a person's note no longer drops the brief and the handoff framing fits again. - Agents that are not the issue's assignee get an observer brief without the step's commands. - Clearer rule override and narrower wakeup guidance; user text is stripped of control characters. - multica-platform skill documents project workflows. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
ec1e931742 |
MUL-8049: fix(workflows): validate the handler in the brief preview (#9294)
Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
da1671ca20 |
MUL-7420: Project workflows — columns and handoffs on the workflow (#8814)
* feat(workflows): workspace workflows with step handoffs (MUL-7420)
A workflow is a named, workspace-level selection of statuses from the
shared status catalog, in board order, with an optional handoff on each
step. Projects opt in through project.workflow_id; a project without one
keeps the whole catalog (the implicit Default workflow), so existing
workspaces see no change.
- issue_workflow table + project.workflow_id, CRUD API under
/api/issue-workflows, POST /api/projects/{id}/workflow with a dry-run
status mapping plan. Only issues on statuses the target workflow does
not list are remapped, and remapping never hands issues off.
- Issue writes keep the status inside the project's workflow. Entering a
step with a handler through a status change assigns the issue to that
handler and starts its run with the step's brief as the handoff note;
an explicit assignee in the same write wins. Creating an issue starts
at the workflow's starting step.
- Task claims carry the issue's project workflow, and the brief renders
a Project Workflow section so agents move along this project's
statuses instead of the built-in ones.
- Statuses a workflow lists cannot be archived.
- Adoption is gated by the project_workflows_v1 flag; existing
workflows keep working and projects can always switch back to Default.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* feat(workflows): workflow settings, project picker and workflow-aware boards (MUL-7420)
- Settings → Workflows (behind project_workflows_v1): the Default
workflow plus named workflows, each shown as its step chain with
handlers and the projects using it; an editor to pick statuses from the
library, order them, mark the starting step, and set each step's
handoff, instructions and next/back statuses.
- Project Workflow property: switching dry-runs first and asks where
issues on unlisted statuses go; nothing else moves and nothing is
handed off.
- A project board's columns are its workflow's steps, and each column
head names who entering it hands the issue to.
- Status pickers offer only the issue's workflow steps and say who each
hands off to; boards refuse drops onto statuses the dragged card's
workflow does not list.
- New issues in a workflow project start on its starting step, with a
hint naming who they will be handed to.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* fix(workflows): name built-in steps once in the brief; roomier picker hints (MUL-7420)
Built-in statuses have no stored name, so the handoff brief printed
`todo` todo. Print the key alone when the name adds nothing.
The status picker widens for workflow projects and shows the handoff as
an arrow and name, so step names no longer truncate to one letter.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* feat(workflows): handoff previews and a single timeline entry per handoff (MUL-7420)
- GET /api/issues/{id}/workflow-handoff?status= says what moving an issue
would do: who it goes to, which runs of its current agent are still
active, and the brief the handler receives. Backs the confirmation.
- POST /api/issue-workflows/preview-brief renders a step's brief from an
unsaved workflow, for the editor's preview.
- Mapping plans list the statuses that stay, so the switch dialog can say
which issues are untouched.
- A handoff is recorded on the status_changed activity (workflow, handler,
whether a run started, the brief) instead of a separate assignee row.
- The brief now reads like the one shown in the design: the workflow, the
current step, its instructions, the statuses, and the commands to hand
off.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* feat(workflows): rebuild the workflow UI to the reviewed design (MUL-7420)
The first cut used generic controls where the design had purpose-built
ones. This brings every surface up to the mockup:
- Settings → Workflows is one page: the workflows (step chain with
handler avatars, handoff count, projects using it; Default first) and,
below, the shared status library with each status's workflow usage.
- The workflow editor is a full page instead of a dialog: draggable step
cards summarising each handoff, and a panel for the selected step —
swap its status, pick the handler with a segmented control and a
searchable target, handoff instructions, next/back statuses, a preview
of the brief the handler receives, duplicate and delete.
- The project Workflow picker lists each workflow's statuses, handoffs and
projects, links to settings, and always confirms the switch with what
moves and what stays.
- Moving an issue into a handoff step (status picker, table, board drop)
asks first: who it goes from and to, a default-on option to stop the
previous agent's run, and the brief.
- Status pickers name the workflow and project, show each step's handler
with an avatar or that the assignee stays, and explain themselves.
- Boards: the handler chip in project column heads, hatched columns a
dragged card cannot enter with the reason, and a drop hint naming who
the card will go to.
- The timeline records a handoff under its status change, with the brief
the run received; the issue sidebar shows the workflow it follows.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* fix(workflows): word a queued previous run as queued in the handoff confirm
The confirm dialog said the previous agent was "still running (for N
minutes)" even when its task had only been queued. Queued runs now read
as queued, and the checkbox cancels them instead of stopping them.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* feat(workflows): refuse a run's status change once the issue left its step
A run decides where the issue goes next from the step it was queued for.
When someone else moved the issue while the run worked, applying that
decision undid their move: in the live Grok run, a PM parked NW-1 as
blocked and the still-running agent moved it straight back to code
review.
Tasks now record the issue's status when they are queued
(agent_task_queue.workflow_step, written by the task INSERTs; automatic
retries keep their parent's step), and a run's own status changes move
it along. In a workflow project, an agent status change from a run whose
step no longer matches the issue is refused with 409
workflow_step_moved, naming where the issue is now and who moved it, so
the agent stops instead of retrying.
A handoff away from a squad now also stops the runs made on the squad's
behalf, and stopped runs record who stopped them.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* fix(workflows): keep every status entry point inside the issue's workflow
The issue context menu listed every catalog status and applied handoff
steps without the confirmation the status picker and board show, so a
right-click could pick a status the workflow refuses or start an agent
unasked. It now offers the workflow's steps and opens the handoff
confirmation through a shared modal.
One-click status actions no longer assume built-in statuses a workflow
may not list: "mark done" lands on the workflow's done step (hidden when
it has none), un-marking a duplicate returns to the workflow's start,
and "mark duplicate" is offered only when the workflow lists cancelled.
The batch toolbar offers a single project's workflow statuses when the
selection sits in one project.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* fix(workflows): keep issue wakeups consistent with workflow steps
Three places where project workflows and issue wakeups met:
- A wakeup run is queued when it fires, so it took the issue's status at
that moment as its workflow step. A wakeup an agent registered then
bypassed the stale-step refusal: parked by a PM, the issue could be
moved on by the agent's "check CI, then hand to review" wakeup. It now
keeps the registering run's step; a member's wakeup still starts from
the issue's status.
- Retries carried handoff_note only for wakeup runs, so a retried
workflow handoff lost its brief. Rows with a workflow step keep it.
- Switching or editing a workflow remaps statuses in bulk without the
close rule, so an issue remapped into a done status kept its wakeups
and pending wakeup runs. The remap now ends them like any status write.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* fix(wakeups): don't also wake the agent a write hands the issue to
A workflow handoff or an assignment already starts the receiving agent's
run. If that agent also subscribed an event wakeup to the issue's status
or assignee, the same write queued a second run for one fact, and
workflows made such writes frequent.
The write now names the agent it hands the issue to in the
transaction-local multica.handed_to_agent (the new agent assignee, a
squad's leader, or a step's handler even when it already owned the
issue), and wakeup capture skips that agent's subscriptions for the
write's issue.* events. Other agents' wakeups, and task, comment and
reaction events, are captured as before.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* feat(workflows): tell agents not to watch workflow issues with wakeups
The handoff brief and the runtime's project workflow section now say
that each step's handler gets a run when the issue enters the step, so
wakeups on a workflow issue are for waiting on time or on something
outside it, not on its status, assignee or runs.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* fix(workflows): refresh project usage after project changes
Co-authored-by: multica-agent <[email protected]>
* feat(workflows): MUL-7420 split columns from per-project handoffs
Workflows now only define a board's columns between a fixed head
(backlog, todo) and tail (blocked, done, cancelled). Handoffs move to
project.workflow_handoffs, so projects can share columns and still hand
off to different people. Default becomes a real, editable row that every
project without a named workflow follows. Adds project handoff, add-column
(project fork or shared) and project brief preview endpoints; same-agent
adjacent columns re-run the agent.
Co-authored-by: Cursor <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* feat(core): MUL-7420 project handoffs and Default workflow client model
Co-authored-by: Cursor <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* feat(views): MUL-7420 column-header handoffs and project workflow menu
Board column headers set the project's handoff for that column; the
project toolbar gets a workflow menu (full flow, switch, templates) and an
add-column action. Views outside a project show Default's columns, with
other statuses reachable through a status filter. Adds the issue flow card,
create-project workflow choice, a columns-only workflow editor and a
lighter status picker.
Co-authored-by: Cursor <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* fix(views): MUL-7420 wrap create-project workflow label in a menu group
Co-authored-by: Cursor <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* feat(workflows): MUL-7420 keep workflow structure in settings; no squad handoffs
Projects no longer add columns or create workflows: the add-column
endpoint is removed and creating a workflow is admin-only. Handoffs go
to one agent, a member or the project lead; squads route work themselves,
so a handoff to one is rejected, as is the issue-creator handler.
Co-authored-by: Cursor <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* refactor(core): MUL-7420 drop the project add-column client
Co-authored-by: Cursor <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* feat(views): MUL-7420 simpler handoff picker and workflow editor form
The handoff form is one searchable "Hand to" picker (no handoff, the
project lead, an agent or a member); the next status defaults to the next
column and next/back overrides sit under "More options". The workflow
editor gets labelled name and description fields and shows the fixed
statuses as one start and one end row. Templates move from the project
menu to Settings → Workflows → New, and the project board loses its
add-column action.
Co-authored-by: Cursor <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* refactor(server): MUL-7420 keep handoffs on the workflow, make backlog and blocked optional
Handoffs move back onto workflow steps: a workflow is the whole pipeline,
and a project only picks one. The project lead stays a relative handler, so
projects can still share a workflow. Handoff edits are admin-only, through
the workflow write or PUT /api/issue-workflows/{id}/handoffs/{status}; the
brief preview moves to the workflow too. Drops the unreleased
project.workflow_handoffs migration.
Todo, done and cancelled are required; backlog and blocked are optional and
keep their fixed places. Without blocked, the brief points agents at the
step's back status.
Co-authored-by: Cursor <[email protected]>
Co-authored-by: multica-agent <[email protected]>
Co-authored-by: Cursor <[email protected]>
* feat(views): MUL-7420 edit handoffs on the workflow, optional backlog and blocked
The workflow editor sets each column's handoff in its side panel, and
Backlog and Blocked switch on and off. The board's column popover and the
flow panel edit the workflow's handoff, say how many projects it reaches,
and are read-only for non-admins. Drops the per-project handoff client
code.
Co-authored-by: Cursor <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* fix(wakeups): MUL-7420 keep platform rules on writes that hand off nobody
Migration 579 skips an issue.* event for the agent a write hands the issue
to. Its filter compared agent_id with the transaction's handed_to_agent
setting using IS DISTINCT FROM, which is false when both are NULL. Main's
platform rules (child_done) have no agent_id, so every issue.* event that
handed the issue to nobody was dropped for them: a parent leaving backlog
never woke its agent for sub-issues that closed meanwhile
(TestChildDoneHeldWhileParentInBacklog).
Rules without an agent are never the handoff target, so they always
capture. Extends TestHandoffDoesNotAlsoWakeTheHandler with a platform rule
on a handoff and on a plain status change; the latter fails on the old
filter.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* feat(views): MUL-7420 three-way handoff choice; quieter move confirm
The handoff form picks one of three directions, as in the mockup: no
handoff, hand to an agent (starts a run), or hand to a member, project lead
included (assignee only). What the step does, where it goes next and the
back status only reach an agent's brief, so they show and save for agent
handoffs alone.
The board's move confirmation keeps the agent's brief collapsed. Create
project shows the workflow picker even when Default is the only workflow,
with a note on where to make more. The hidden-columns panel says a board's
columns come from its workflow, with a link to manage workflows for admins.
Co-authored-by: Cursor <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* feat(workflows): confirm handoff on project move, per-project handoff copy, two-pane editor (MUL-7420)
- A single issue moved into a workflow project from issue detail confirms
the handoff of the column it lands on; the write opts in with
enter_workflow_step. Batch, API and CLI moves stay administrative.
- The handoff preview takes project_id to preview such a move.
- Saving a shared workflow's handoff from a board can keep the change to
that project: the server copies the workflow for it and switches the
project in one transaction (copy_for_project_id).
- The column popover says which workflow it edits and who else uses it.
- The workflow editor is a step list with a detail panel for the
selected step.
Co-authored-by: Cursor <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* style: gofmt workflow tests
Co-authored-by: Cursor <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* feat(views): MUL-7420 show next/back always; edit workflow name and description in place
Co-authored-by: Cursor <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* feat(views): MUL-7420 trim copy on the workflows settings page
Co-authored-by: Cursor <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* fix: MUL-7420 keep pre-workflow behavior for workspaces that never adopt workflows
The run step guard now applies only to workflows that hand off, and the
standalone Statuses settings page keeps its original header.
Co-authored-by: Cursor <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* fix(views): MUL-7420 use a solid placeholder tone on the workflow header
Co-authored-by: Cursor <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* fix(workflows): keep the runtime brief cache-stable; fix project board and batch status gaps (MUL-7420)
- Move the project workflow out of the runtime brief into the per-turn
prompt so CLAUDE.md stays byte-identical across steps and issues.
- An explicit status filter overrides the project workflow's columns; the
hidden-columns panel lists statuses outside the workflow.
- Batch status offers only statuses every selected workflow allows; a
partial batch rolls back, refetches and warns.
- setProjectWorkflow returns void instead of an unparsed body.
Co-authored-by: Cursor <[email protected]>
Co-authored-by: multica-agent <[email protected]>
---------
Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: multica-agent <[email protected]>
Co-authored-by: Lambda <[email protected]>
Co-authored-by: Cursor <[email protected]>
|
||
|
|
130aaa5302 |
MUL-8047: feat(onboarding): open the runtime guide issue directly instead of a welcome modal (#9289)
* MUL-8047: feat(onboarding): open the runtime guide issue directly instead of a welcome modal Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * MUL-8047: chore(onboarding): drop dead option cards, copy, and completion animations Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * MUL-8047: fix(onboarding): reopen the existing guide issue on duplicate A reload, or a create whose response was lost, leaves the guide issue from an earlier Skip in place while onboarding is still incomplete; the retry then hits the server's active-duplicate guard and the step was stuck toasting forever. Recover the existing issue from the validated 409 body and continue to completion. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
86020b88a4 |
MUL-8047: chore(server): remove the pre-v3 desktop onboarding shim (#9291)
Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
e6031902e6 |
MUL-8046: feat(issues): per-run cost bars and token detail in the run log (#9288)
* MUL-8046: feat(issues): per-run cost bars and token detail in the run log The sidebar's cumulative spend curve becomes one bar per run with spend, token and agent-time totals, and each past run gains a second line with agent, duration or failure reason, tokens and model. The Runs dialog replaces the step curve with a bucketed bar chart (cost, tokens or agent time, stacked by agent or token type), adds a cost split by agent and model, model and token columns, and an expandable per-run breakdown. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * MUL-8046: feat(issues): one bar per run in the Runs dialog chart Time buckets spent most of the chart on hours where nothing ran and made each bar roughly one run anyway. The dialog chart now draws one bar per run like the sidebar strip: height is cost, tokens or agent time, colour is the agent or token type, a tick marks failed and cancelled runs, and day dividers replace the time axis. Drops the bucket, lane hit-testing and time-tick helpers. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * MUL-8046: fix(issues): split run bars by share so sub-dollar costs fill them Segments used dollar amounts as flex-grow; factors summing below 1 fill only that fraction of the free space, so bars and share bands under $1 drew short. Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> * MUL-8046: feat(issues): keep the cumulative cost chart as a second Runs dialog view Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Cursor <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
231dedb552 |
MUL-8034: chore: clean historical comments across the codebase (#9274)
* chore: clean historical comments (MUL-8034) Co-authored-by: multica-agent <[email protected]> * docs: preserve pending Composio expiry contract Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: multica-agent <[email protected]> |
||
|
|
8db6cfe19a |
fix(desktop): align navigation and tab toolbar content (#9127)
Co-authored-by: multica-agent <[email protected]> |
||
|
|
67d61a2073 |
MUL-7780 feat(issues): run charts follow the pointer; a cost sparkline replaces the sidebar strip (#8912)
The Runs dialog's crosshair snapped to the end of whichever run was nearest,
so it moved in jumps: a pointer 57px further right could send it 250px across
the chart, and inside a long run it sat at the run's far end rather than under
the pointer. It now follows the pointer, clamped to the stretch that holds
runs. The run whose bar spans that moment (give or take 8px) answers; between
runs the card says there was no run, how long the quiet lasted, and what had
been spent by then. The card sits in the half of the plot its dot is not in.
Three smaller breaks in the hover are fixed too:
- it covered only the plot column, so drifting onto the lane labels or the
y scale dropped it; the whole chart row tracks now
- the gaps between lanes belonged to no lane and briefly handed the hover to
every agent's runs; lane rows now touch
- the peak label unmounted on enter and leave; it fades instead
The sidebar's spend strip drew one bar per run, 12px wide and left-aligned, so
an issue with three runs showed three bars in the corner of an empty strip. It
is replaced by the dialog's chart in miniature: the cumulative cost as a step
curve over a track of the runs. It spans the column whatever the run count,
appears from the first priced run, and hovers the same way the dialog does.
nearestRunIndex becomes runIndexAt (with a slop, -1 between runs), and the
timeline gains cumulativeCostAt, idleSpanAround, stepCurvePath and extent so
both charts share one hover model.
Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: multica-agent <[email protected]>
|
||
|
|
f76cde8e60 |
MUL-7766: feat(editor): fit Mermaid previews to show the whole diagram, with inline zoom (#8898)
The inline Mermaid preview now opens fitted: the whole diagram within the column's width and at most 448px tall (the frame's collapse threshold less padding), never upscaled past natural size. Zoom out / percent / zoom in / fit buttons step from there; a zoomed diagram scrolls inside the same box and can be drag-panned both ways. Tap still opens the full viewer. - New useInlineZoom hook: measures the column, keeps a fitted preview fitted on resize, snaps through 100%, and zooms about the visible center. - The SVG fills its iframe, so zoom resizes the iframe and redraws vectors instead of scaling a bitmap. - Framed blocks get a floating pill bottom-right; the standalone editor preview puts the controls in its existing toolbar. - The layout cache records the fitted height so the lazy shell reserves the space the preview actually takes. Co-authored-by: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
54987006b5 |
fix(views): keep the PR row diff whole and spin the running-checks icon (MUL-7767) (#8900)
* fix(views): keep the PR row diff whole instead of cutting it mid-number When the verdict pill needed the room, the diff after `repo#number` was clipped by `overflow-hidden`, so `−486` showed as a bare `−` and `+312` could read as `+31`. Everything after the dot is now one unit that wraps onto a clipped second line when it doesn't fit, and the repo name is only shown when the linked PRs span repos, so the diff fits at the narrowest sidebar width in the common case. The tooltip keeps owner/repo#number. MUL-7767 Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(views): spin the running-checks icon in the PR verdict pill The loader icon on a PR whose checks are running stood still. It now spins (motion-safe), and stops when the snapshot is stale, since a stale snapshot can't vouch that the checks are still running. MUL-7767 Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
decd602a57 |
fix(views): stack wakeup condition hints under their labels (MUL-7769) (#8899)
The condition menu put each label and its hint side by side in a 22rem popup. English and French strings are too long for that row, so labels and hints both wrapped and misaligned. Stack the hint under the label, top-align the icon with the first line, and narrow the menu to w-72 so every locale lays out the same way. Co-authored-by: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
13094caf7a |
MUL-7758: lay an issue's runs out in time (#8890)
* fix(issues): render run trigger snapshots as plain text (MUL-7758) A run's trigger snapshot is the comment's raw Markdown cut at ~200 runes, and the execution log printed it verbatim: an escaped ampersand read "&", and a comment that opens with a screenshot read "![CleanShot 2026-…" because the cut lands inside the image URL. Decode the entities in one pass, turn whole or cut images into a localized "[Image]" label, and keep links' text, so every surface that lists runs shows what the person actually wrote. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(issues): lay an issue's runs out in time (MUL-7758) The usage breakdown was a nine-column table of raw token counters headed by a token total that is 99% cache re-reads and a "cache savings" figure larger than the spend itself, with no way to tell when a run happened or to open it. The execution log showed tokens where the question is cost, and kept every past run behind a "Show past runs" toggle. Execution log (sidebar): - the header reads "21 runs · $166" and opens the new Runs dialog; narrow panels drop the count, never the cost's digits - a spend strip draws one bar per past run, oldest to newest, height = cost, with a baseline dot for runs that recorded no usage - agent time and elapsed time sit under it, active runs stay on top, the latest three past runs are listed with their cost, and "Open timeline" hands the rest to the dialog Runs dialog (replaces the usage breakdown): - spent / agent time / elapsed / runs, with failed and cancelled counts - a cumulative cost curve over per-agent run lanes on one time axis, the run that moved the total most labelled, hover summaries on every bar - runs grouped by day, newest first: who asked (quoted), which agent ran it, how long, a cost bar split by what was billed with the exact split on hover, and transcript / retry actions - runs without usage are listed with "—" instead of being left to a footnote, so the run count no longer disagrees with itself The timeline arithmetic lives in issue-run-timeline.ts with its own tests; retry moves to a shared RetryRunButton so both surfaces retry the same way. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(issues): open a run's transcript from its row (MUL-7758) A Runs row cut its trigger to one line and opened the transcript only from a small icon at the row's end, so a long ask could not be read anywhere and the obvious click did nothing. The whole row now opens that run's transcript; the trigger text is the row's real button for keyboard and screen readers, and retry stays its own action. The transcript dialog gains a "Trigger" line under its header that shows the ask whole and wrapped, for every surface that opens it. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * revert(issues): open Runs rows' transcripts from the hover action again (MUL-7758) Row-wide clicks were a response to the transcript icon looking permanent; it only appears on hover, which reviewers found enough. Restore the per-row icon and retry actions. The trigger keeps its full-text native tooltip, and the transcript dialog keeps its Trigger line, so a truncated ask is still readable in full. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(issues): make the Runs chart answer the pointer anywhere (MUL-7758) Only the lane bars carried hover summaries, and most are a few pixels wide, so the chart read as static: hovering the curve did nothing. The plot column now snaps the pointer to the nearest run and shows a crosshair at its completion, the curve's reading there, and a card with the ask, agent, time, duration, the run's cost and the total so far; the other lane bars dim. Each run carries `costSoFar`, and `nearestRunIndex` does the snapping, both with helper tests. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(issues): reach nested runs and open cost splits without hover (MUL-7758) Addresses the two review findings on the Runs dialog: - Overlapping runs: the chart snapped by time alone and broke distance ties by start order, so a run fully inside a longer one could never be picked, even with the pointer on its bar. The innermost bar now wins a tie, and a pointer over a lane only considers that agent's runs. - Cost split: the input / output / cache breakdown lived in a tooltip on a non-focusable span, out of reach for keyboard and touch. The cost cell is now a button that opens a popover on hover, click, tap or Enter. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(issues): use radius tokens for the Runs chart marks (MUL-7758) CI's radius check rejects fixed arbitrary radii outside its allowlist. The lane bars, legend swatches and spend-strip bars used rounded-[2px]; they now use rounded-xs (3px), the same step the transcript's run timeline marks already sit on, rather than widening the allowlist. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
3d2592a9a2 |
MUL-7754: feat: local search index for web and desktop (#8891)
* feat(server): add a change log and sync endpoints for local search (MUL-7754) Web and Desktop will keep a per-workspace copy of issue, comment, and project text for instant search. Triggers on issue/comment/project record the xid of each entity's latest write in search_index_change, covering every write path including hard and cascaded deletes. Clients bootstrap with GET /api/search-index/manifest + /snapshot pages and catch up with POST /api/search-index/changes, whose cursor is a pg_snapshot: a change is returned once it is visible in the target snapshot but not in the one the client holds, so late commits are never skipped and long transactions do not stall catch-up. Workspace teardown skips the triggers and clears the table, and an hourly scheduler job prunes rows older than 30 days; a cursor older than the prune mark gets 410 and rebuilds. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(core): add a synced local search index for web and desktop (MUL-7754) Each (user, workspace) gets an IndexedDB copy of its issue, comment, and project text, kept in a worker (SharedWorker when available, otherwise a dedicated worker per tab) and searched in memory. Matching, ranking, and snippets port the server's issue/project search, so local rows have the server's shape and order. The worker bootstraps from /api/search-index/manifest + snapshot pages, catches up through /changes after realtime events, reconnects, focus, and every five minutes, and resumes an interrupted bootstrap. It has no credentials of its own: tabs run its requests through their API client. Local results are served only while the copy is complete and recently confirmed; otherwise searchIssues/searchProjects fall back to the server. Workspaces over 500 MB of text, lost access, and expired cursors are handled by declining, wiping, and rebuilding respectively. Session cleanup deletes every local index. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(views): search through the local index first (MUL-7754) The command palette, @mention suggestions, the issue picker, and duplicate suggestions now call the core local-first search. The palette drops its 300 ms debounce while the local index is serving, since no request leaves the tab. An E2E spec checks that palette results match server ranking without any server search request, follow issues created and deleted through the API, and that logging out deletes the local copy. .env.example documents the FF_LOCAL_SEARCH_INDEX kill switch. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(core): close local search gaps found in review (MUL-7754) - Access loss: deleting, leaving, or being removed from a workspace now destroys its local copies right away (worker and tab both delete the database, since a full-page relocate may end the worker first). The sync hook also prunes every copy outside the user's current workspace list, which covers access lost while offline or on another device; copies a tab is showing are kept in case the list is stale. - Memory budget: the engine counts UTF-8 bytes the way the manifest does, and the budget is checked on every load, snapshot page, and catch-up batch, not only at bootstrap. An over-budget copy is dropped and search falls back to the server until the workspace is measured again. - Frozen tabs: a port the sweep dropped is restored with its workspace the next time the tab sends anything, a page restored from the bfcache attaches again, and a null local answer clears the tab's "serving" flag so the palette goes back to debounced server search. E2E now also covers being removed from a shared workspace. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
5ed09342af |
MUL-7680: issue wakeup v2 — conditions, runaway protection, check-ins and visibility (#8807)
* feat(wakeups): add rule deadlines and expose the child-done system rule (MUL-7680)
Wakeups can now end: an absolute deadline (expires_at) or a relative wait
(expires_in_seconds) that restarts when the rule is re-enabled. When the
deadline passes first, the scheduler ends the rule; event rules with
on_timeout=wake run the target once with a wakeup.timeout fact. A timed-out
rule keeps disabled_at NULL so its timeout run stays claimable.
The implicit "wake the parent's assignee when a stage of sub-issues
finishes" behavior is now described by GET /api/issues/{id}/system-wakeups
and can be turned off or given a supplementary instruction per issue via
PUT /api/issues/{id}/system-wakeups/child_done. Rule reads fail open to the
previous behavior.
List responses add the creator (member or agent) and the new expiry fields.
The CLI gains --expires-in, --expires-at and --on-timeout.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* feat(issues): let members create wakeups and show the child-done system rule (MUL-7680)
The issue sidebar's Wakeups section is always available on open issues and
gains a New wakeup popover. Members pick a condition (a time, a recurring
check with an end date, someone's reply, an agent's run ending, or raw
events), the agent to wake, the instruction, how often it fires, how long
to wait and what happens on timeout. It posts the same configuration agents
create with the CLI.
The parent's child-done wake appears as a System rule with its stage,
remaining sub-issues and target, a per-issue toggle and a supplementary
instruction. Rows show when a rule ends, timed-out rules read as such, and
details name who created the rule. Rule titles wrap to two lines instead of
truncating.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* docs(wakeups): document deadlines, member-created rules and the system rule (MUL-7680)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* feat(wakeups): platform conditions, runaway protection and check-ins (MUL-7680)
Conditions: a wakeup can now wait for a fact the platform checks itself
(a status, assignee, label or property value; sub-issues or one stage
finishing; a linked PR's checks finishing or merging; another issue's
status). Related events only prompt an early evaluation; the rule wakes
its agent when the predicate becomes true, and a repeating rule fires
again only after it turned false or its facts changed. Finished PR checks
from before registration are ignored.
Runaway protection: repeating event rules stop after max_fires runs
(default 20), a rule pauses when its causal chain passes through it a
third time without a person in between, or when it starts 12 runs in an
hour. The reason is stored and shown.
Also: silent check-ins for every/cron checks (the run then posts no
fallback comment), wake now, delete, a per-rule run history, paused-rule
lists, timeline entries for created/triggered/timed-out/paused/check-in,
and source, paused scope, 7-day runs and child-done system rows in the
workspace list. The CLI gains --until-* conditions, --max-fires and the
trigger/delete/checkin/runs commands; the brief and wakeup prompt state
the check-in exception.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* feat(issues): record child-done transitions in the status write (MUL-7680)
The child-done system rule ran after the status write committed and gave
up on any error, so a crash, deploy or transient failure lost the
parent's wake. A trigger now records each child's move into a closed
status in the writing transaction, for every writer. The request that
wrote it processes the rows right away and a scheduler sweep retries
anything left over; claims make the two paths process a transition
once.
The rule also follows a workspace default (settings key
system_wakeup_child_done) until an issue sets its own, the per-issue
update accepts partial bodies, and each trigger adds a timeline entry
that names its system comment.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* feat(views): wakeup conditions, history, timeline and workspace list (MUL-7680)
Issue sidebar: members can create the platform-checked conditions (a field
reaching a value, sub-issues or a stage finishing, a linked PR's CI or merge,
another issue's status) and cap how often a repeating wait fires. Rule
details show the fire count, why the platform paused a rule, the latest runs
with silent-check notes, and offer wake now and delete.
The issue header says what the issue is waiting for ("Emacs 在等 Jiayuan 回复
+2") and opens the Wakeups section. Board and list cards use the same short
sentence, or flag a paused rule. Wakeup runs read as "由唤醒触发 · <condition>"
in the execution log, transcript and on the comments they post.
The timeline shows created, triggered, timed-out, paused and check-in entries
with the rule they came from; consecutive check-ins merge, and the child-done
entry stands in for its system comment, which it can reveal.
Automation → Issue wakeups adds a source column and filter, 7-day runs, a
paused scope with a banner, the child-done system rule on each waiting parent,
and "New wakeup" with an issue picker. Settings → Issue statuses sets the
system rule's workspace default. Copy in all five languages.
The server records the watched issue's identifier in other-issue conditions
and the rule's creator in timeline snapshots, and returns board summaries with
their condition.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* docs(wakeups): document conditions, runaway protection and check-ins (MUL-7680)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* fix(wakeups): list system rules without a revision and localize statuses (MUL-7680)
System rule rows returned revision 0, which clients reject as a rule
revision; they now return null, and a list row with an invalid revision no
longer fails the whole page. Built-in statuses in conditions and the status
picker read in the viewer's language. Adds a browser test for a condition
created from the form, the header summary, the scheduler waking the agent
and the workspace list.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* fix(views): say why a rule paused without repeating "paused" (MUL-7680)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* fix(i18n): use the product's task terms in wakeup copy (MUL-7680)
ja, ko and fr wakeup strings said イシュー / 이슈 / ticket; the product term
for an issue in those languages is タスク / 태스크 / tâche (and sub-tasks
accordingly), per the conventions page. French strings are rewritten for
the feminine noun.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* test(views): pin the shortcut platform in the wakeup form test (MUL-7680)
The send shortcut is primary+Enter, which is Ctrl on Linux CI runners, so
pressing Cmd+Enter only submitted on macOS.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* fix(views): simplify the workspace wakeup list
Put the filters on one row: scope as a segmented control on the left,
source/trigger/agent and a search-as-you-type box on the right. "New
wakeup" moves to the page header, which drops the separate Search button.
Rows are single-line: the identifier sits before the title, frequency and
timezone move into the trigger tooltip, and selection, prompt edit and
the last run's transcript show on row hover or focus. The issue column
takes the remaining width and truncates, so the table fits the page.
Also fix creating from the list: the issue picker closes itself right
after reporting the selection, and that close cancelled the flow before
the form could open.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* refactor(server): run the child_done rule as a system issue wakeup
The parent-assignee wake on closed sub-issue stages was its own code path:
a system comment, a mention-style run, an override table and endpoints.
It is now an ordinary issue_wakeup row with system_rule set, sharing the
condition, receipts, runaway protection, timeline entries and run model of
people's rules.
- One children_done evaluator: a stage wakes the assignee when it closes
while a later stage waits; the wrap-up waits for every sub-issue,
unstaged ones included. People's sub-issue conditions read the same set.
- issue_child_event records closing, reopening, re-parenting and restaging
for every writer; the request processes it right after commit and the
sweep retries. User sub-issue rules become immediate too.
- The target is resolved when it fires: an agent run, a squad leader run,
an inbox notification for a member, or only the timeline entry.
- A parked (backlog) parent catches up when it leaves backlog; a waiting
run of the same agent is joined instead of queuing a second one; the
hourly limit pauses a runaway rule. No system comment is posted.
- The run gets the issue's instruction, else the workspace's, else the
built-in one, plus each stage's counts and the next stage.
- Workspace defaults move to GET/PUT /api/system-wakeups (owners and
admins) and apply to every rule nobody customized; turning a rule on
records what already holds so old facts do not fire.
- Existing open parents get their rule from a one-time backfill.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* feat(views): workspace wakeup settings and sub-issue notifications
- Settings → Wakeups holds the sub-issue rule's workspace default and
default instruction; the toggle leaves Issue statuses.
- The issue's system rule shows who it reaches (a member is notified),
a platform pause, and the instruction it will use.
- Timeline entries say whether the assignee was woken, notified or joined
a waiting run. The folding of the old system comment is gone.
- Inbox renders the new children_done notification on web, desktop and
mobile.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* fix(server): stop wakeups from repeating their agent's runs
Runs are serialized per issue and agent, so a wakeup never ran beside
another run of its agent, but it queued behind one and repeated it. Each
rule now checks two things before it starts a run:
- Acknowledged: every input came from the agent itself. Its own comments
and issue changes never wake it, and a condition its own unfinished run
on the issue satisfied does not wake it when the platform or the agent
set the rule up. This fixes #8849: a coordinator closing its own stage is
not woken again while that run is going. A person's condition rule still
runs afterwards, since the running agent lacks its instruction.
- Merged: when a run of the agent is already waiting to start on the issue
(assignment, comment, another rule), the rule's instruction and facts
join that run (context.wakeup_joined, sent to the daemon as
wakeup_joined and rendered for every prompt kind) instead of queuing
another. Turning the rule off or replacing it withdraws what it joined.
Sub-issue changes now record the run that made them, and hints and
condition.met inputs carry those runs so a satisfied condition knows
whether the agent caused it. A rule that names the agent itself as the
actor keeps waking it on its own changes.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* feat(views): show merged and acknowledged wakeups, hint assignee comment rules
- Timeline entries say when a wakeup joined the agent's waiting run or was
the agent's own doing, for people's rules and the sub-issue rule.
- The create form tells a member that a reply or comment rule for the
issue's agent assignee joins the run a comment already starts.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* fix(server): hand waiting wakeups to a run when it is claimed
A rule that fired while its agent had a run waiting used to write its
instruction into that run right away and consume its inputs. That let a
member's rule run under another member's identity, kept deleted rules'
instructions in the run, lost the inputs when the run was cancelled or
claimed by an older daemon, and skipped the fire cap and loop check.
Now the rule only waits for a run that runs as the same person its own
run would, keeping its inputs. When a daemon advertising
joined-wakeups-v1 claims that run, JoinWaitingWakeups rechecks each rule
(on, same agent and person, creator still allowed, not the agent's own
input, no loop), consumes its inputs, counts the fire toward max_fires,
adds its chain and records the merge. A re-claim drops entries of rules
turned off or changed since. Anything else leaves the rule its inputs to
start its own run.
A child_done rule created by the backfill or by processing a change now
treats sub-issues with unprocessed close events as still open, so the
backfill no longer swallows a close waiting for the sweep.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-authored-by: multica-agent <[email protected]>
* fix(server): consume joined wakeup inputs only once the run starts
A claim used to consume the inputs of the rules that joined the run. If
that claim did not go through, the run went back to the queue carrying
inputs the rules no longer had: turning the sub-issue rule off on the
issue or for the workspace (which only changes enabled) did not remove
them from the next claim, and cancelling the run lost a once rule that
had already ended.
A claim now reserves the inputs for the run (receipt task_id, still
unprocessed). The rule's next dispatch settles them: a run that started
consumes them as a merged firing (once ends, max_fires counts and can
pause, timeline entry); a run that ended without starting gives them
back; one that has not started keeps them. Turning a rule off or
changing it discards its pending inputs, reserved ones included, and a
later claim of the same run rechecks every entry and drops the ones
without reserved inputs or no longer allowed to reach the run.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-authored-by: multica-agent <[email protected]>
---------
Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: multica-agent <[email protected]>
|
||
|
|
4054d57802 |
MUL-7755: feat(issues): configurable side peek in every issue view (#8886)
* feat(issues): add a peek variant to IssueDetail A single-column layout for the board's side peek: the core properties render as a row of pills under the title (the create dialog's PillButton with the sidebar's pickers), the properties sidebar and its toggle are dropped, and the host supplies the header's leading and trailing controls. The peek keeps its own scroll key and always opens at the top. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(issues): open board cards in a side peek on Shift+Click (MUL-7755) Shift+Click (or Space on a focused card) opens the issue in a floating panel over the board, so it can be triaged without leaving the board. Shift+Click another card switches the panel; on the same card, or Esc, it closes. J / K step through the card's column, the peeked card keeps a brand ring, and the board scrolls it clear of the panel. The page header and toolbar stay usable, and the panel stops above the chat launcher. On web, Shift+Click on a board card no longer opens a browser window; Cmd/Ctrl(+Shift)+Click still open tabs. Board and swimlane only. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(issues): animate the side peek and peek the hovered card on Space The panel now enters and exits through motion/react with the shared UI easing: a 200ms fade and 16px slide in, a shorter 150ms fade and 8px slide out, fade-only under reduced motion. The key is stable, so switching issues (J / K, Shift+Click another card) swaps content without replaying it, and the exiting panel stops taking clicks and keys at once. The sideways board scroll that keeps the peeked card in view also respects reduced motion. Space now peeks the card under the pointer as well as a focused card, unless a control has focus and owns Space itself. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(issues): side peek in every issue view, with H / L and arrow keys Shift+Click (and Space on the hovered issue) now opens the side peek from list rows, table rows, gantt rows and swimlane cards as well as the board. The host wraps every view and its loading states, so an open peek survives a view switch; each view publishes its own order: - board: its columns; swimlane: one column per status, running down through the expanded lanes; list, table, gantt: one column in display order, skipping collapsed groups. H / L step to the nearest non-empty column at the same row (clamped), J / K within it. The arrow keys mirror them unless the reader last clicked into the panel, where they scroll it as usual; tabs, radios and sliders keep their own arrows. Peeked rows get a brand tint and leading bar; table cells carry it because pinned cells paint over the row. DataTable gains a generic getRowProps for that. The swimlane scroller reserves room for the panel like the board's. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(issues): keep the peek closable in every state, and follow moved cards Review of #8886: - The peek's close button lives in IssueDetail's trailing controls, which the loading and not-found early returns dropped, leaving only Esc. Both states now render the host's trailing controls, and the panel's error boundary gets a fallback with its own close button. - Keep-in-view keyed on the peeked card's neighbours, so a card alone in its column that moved to an empty column never scrolled back into view. It now acts whenever the element standing for the issue is a new one (another issue, a column move, a view switch) and still ignores reorders that leave it in place. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(issues): make default card opening configurable (MUL-7755) Co-authored-by: multica-agent <[email protected]> * feat(settings): move the issue-opening preference into the new Preferences page Main folded the Preferences tabs into one page (MUL-7732), deleting the issue tab the preference had been added to. It now lives there as its own "Opening issues" section, in the page's own terms: - device scope badge, like Appearance, since the choice is stored per device - the either/or SegmentedToggle Theme uses, instead of a two-item dropdown - no success toast: the new page announces only failures - a settings-search entry, also matched by its option names Clicks now mean "the other one" with Shift: a plain click opens the preferred target, Shift+Click the other. In side-preview mode that makes the full page one click away again (before, Shift also peeked, leaving only the panel's button or a new tab); a link would otherwise hand Shift to the browser, so the hook navigates in place itself. The row's hint says so. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
32a396fd52 |
fix(views): stop dialog scroll lock from re-rendering Mermaid diagrams (MUL-7760) (#8889)
useThemeVersion bumped on any class/style/data-theme mutation on <html>/<body>. Base UI's scroll lock writes `overflow` into that style on every dialog open and close, so each close re-rendered every Mermaid diagram on the page: a 140-200ms long task (dev build, three diagrams) starting ~30ms into the 100ms exit animation, which stalled the dialog's unmount and made the page flash. The hook now keeps a theme signature (theme-selecting attributes plus the resolved tokens, color-scheme and font) and only bumps when it changes. Tokens written straight into the root style still count as a theme change. Co-authored-by: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
0a51a6cc43 |
MUL-7759: copy image from the desktop attachment viewer (#8888)
* fix(desktop): add Copy Image to the right-click menu (MUL-7759) Electron ships no default context menu, so right-clicking an image in the attachment viewer (or anywhere in the app) offered nothing. Add a Copy Image item for loaded <img> targets that copies the decoded bitmap via webContents.copyImageAt — works for any format and origin without a refetch. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(views): copy-image button in the desktop attachment viewer (MUL-7759) Adds a copyImage clipboard helper (fetch, re-encode non-PNG through a canvas, write via the async Clipboard API) and a Copy image button next to Download for image previews. Shown only in the desktop shell: web script can't read the storage CDN's bytes (no CORS), and browsers already offer Copy image in their own context menu. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(views): gentler copy-image failure copy per conventions (MUL-7759) Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
104bf7be35 |
MUL-7732: regroup settings by scope and consolidate scattered pages (#8874)
* feat(mcp): report how many agents use each workspace MCP server The workspace MCP library listing now carries agent_count: the number of live (non-archived) agents each entry is assigned to. Settings shows it so an admin can tell whether replacing or removing a server affects anyone. The field is optional in the client schema, so an older server that omits it simply shows no count. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(settings): regroup settings by scope and consolidate scattered pages Implements the MUL-7732 settings redesign: - Navigation is grouped by who a setting affects: Personal, the current workspace (with Issues & workflow and Connections & extensions sub-groups), and This device on desktop. Pages and sections carry a scope badge (account, this device, workspace), and members see a lock on pages only owners and admins can change plus a shared read-only notice. - Settings search in the nav indexes page and row titles and descriptions; opening a result scrolls to and highlights the row. - Preferences is one page instead of three tabs, with a searchable time zone picker, a segmented theme control and a field grid for the create-issue dialogs. - Code merges Repositories, GitHub and self-hosted Git. Repositories are read-only rows edited through dialogs; self-hosted Git connects in a dialog that ends on the one-time webhook secret. - The PR merge rule moves to Statuses & transitions as an automatic transition; Code only shows its current value. Built-in statuses show edit and archive as unavailable instead of refusing after a click. - Integrations becomes Messaging (IM channels only) with a breadcrumb on detail pages; Composio moves to Personal as Connected apps. - Members gets tabs, search, invite and share-link dialogs and a seat summary. MCP servers show assignment counts and explain how MCP, connected apps and plugins differ. Workspace General shows members plain values and changes the issue prefix through an explicit dialog. - Skill labels are managed from the Skills page; Settings > Labels keeps the issue catalog. - Successful saves no longer toast; failures still do. Old ?tab= values (github, repositories, integrations, issue, chat, labs, and the Composio OAuth callback) resolve to the new pages, since server redirects still use them. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * docs: point settings paths at the regrouped settings pages GitHub, repositories and self-hosted Git now live under Settings > Code, IM bots under Settings > Messaging, and the PR merge rule under Settings > Statuses & transitions. The GitHub guide also drops the old master switch step in favor of pausing from the GitHub row. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(settings): edit the PR merge rule on the Code page The "After PRs merge, move the issue to" rule sits with the other pull request rules on Code again instead of a separate Automatic transitions section. It applies to every code host, so pausing GitHub features does not lock it. The statuses page goes back to Issue Statuses, and its merge badge links to the rule on Code. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(settings): manage skill labels under Settings → Labels again The Skills page entry was buried at the bottom of the filter menu's Labels submenu. Settings → Labels switches between the issue and skill catalogs again, using the members page's segmented switch (now SettingsViewTabs), and the Skills page keeps its shortcut. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(settings): keep GitHub resume reachable after a disconnect Pausing GitHub features is a workspace setting, but the pause and resume item lived in a menu that only rendered with an installation. A workspace paused before disconnecting, or with github_enabled=false and no installation, lost the way back, and every PR switch stayed disabled. On deployments without a GitHub App it could not even reconnect, though Co-authored-by works without one. The menu now shows whenever GitHub is connected or paused, and only Disconnect requires an installation. The paused note shows in either state. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(settings): let the URL choose the open members list The members page read `section` only to initialize its list tab, so a search result for invitations or share links opened while already on the page changed the URL but not the list, and back/forward did nothing. With a router the open list is now derived from the URL, and switching lists replaces `section`. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(settings): tell repositories on different ports apart The manual repository dialog reused the GitHub import's identity, which drops the port, so https://git.example.com:9443/acme/api.git read as a duplicate of the same path on :8443 and could not be saved. Non-default ports now stay in the identity; default ports, including 22 for ssh://, still compare equal to the scp-like form. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * test(comments): stop the recipient-menu tests flaking under CI load The steering tests opened a recipient chip menu while the composer could still re-render its chips, from the previous send settling or the preview catching up. That closed the menu, and the menu steps also used the 1s default wait inside the 5s default test timeout. Under parallel load locally, about 1 in 20 runs failed the same way as CI. Menu choices now go through a helper that reopens the menu until the item shows. The remaining waits get the 5s the first steps already had, and each test gets 15s. 140 of 140 loaded runs pass. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
e427ed7dfb |
fix(views): keep the Save as view name while the host re-renders (MUL-7756) (#8885)
SaveViewDialog re-seeded its draft (name, filters, display) whenever the `scope` / `editView` prop identity changed. The My Issues header builds `scope` inline, so any background refetch re-rendered it and wiped the half-typed name. Seed once per open instead, so every host is safe. Co-authored-by: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
e8a16d334f |
MUL-7753: one verdict per PR in the issue sidebar (#8884)
* feat(core): derive one verdict per pull request (MUL-7753) Fold CI status and mergeability into a single prioritized verdict for the issue sidebar, keeping a conflict alongside a failure so neither is lost. Add helpers to drop the issue's own key from a PR title and to shorten diff counts for the narrow sidebar. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(views): lead each sidebar PR row with one verdict (MUL-7753) Each PR now reads title, then repo#number with the diff size and a verdict pill aligned right, so several PRs scan as a column. Failed PRs list what failed underneath, one line per check. Owner, author, the full title and exact counts move to the row tooltip; the section header shows a count. Drop the Open / Unstable / Has hooks labels and the failed-names sentence. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
344ffaf1be |
MUL-7737: feat(views): address bar for HTML attachment previews (#8873)
* MUL-7737: feat(views): address bar for HTML attachment previews HTML attachments render in a sandboxed srcdoc iframe, so the document's URL is about:srcdoc and location.search is always empty. A self-contained mock that picks its screen with `?s=overview` could only show its default screen. A one-line bridge script placed in front of the author's markup gives the document a real query and fragment through history.replaceState (Chromium and WebKit allow an opaque-origin document to rewrite them), resolves relative pushState/replaceState URLs against the document, reports address changes to the parent, and turns `?…` link clicks into navigate requests. The viewer and the full-page preview get a reload button and an address field after the file name. A new query reloads the document; a fragment-only change navigates in place. "Open in new tab" carries the address as `loc`, and the full page keeps it in the desktop tab's view state across tab switches. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * MUL-7737: feat(views): put the HTML address in the viewer's top bar The address bar took a row of its own above the document. The file name in the top bar is the fixed part of the address anyway, so it now is the address: the query and fragment follow the file name and are edited in place. A document at its bare address reads as just the file name, so files that never use an address look as before; hovering or focusing shows the field and a hint of where to type. Reload joins the HTML view controls, disabled with them in the source view. The address state moves from the stage to PreviewPanel, which owns both the bar and the stage, and resets per file since the viewer pages to the next file without remounting. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
3125bd2ea2 |
feat(comments): show every attached image at full size (MUL-7736) (#8870)
Several images under a comment (or a chat message) were packed into justified rows between 100 and 240px tall, so a screenshot shrank to a thumbnail and reading it took a click into the viewer; tall screenshots were also cropped to fit the row. Each image now shows at its full size, one under another, the way a lone image already did: a wide screenshot fills the column, and every image is capped at 36rem tall so a phone screenshot keeps its shape instead of running the length of the page. Files other than images stay cards in a grid below. JustifiedImageRow and its layout helper have no other caller and are removed, along with the .image-tile styles. Co-authored-by: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
9c6622787d |
MUL-7735: docs(readme): fix stale facts, sync the Chinese README, retake the hero screenshot (#8869)
* MUL-7735: docs(readme): fix stale facts and bring the Chinese README in line Facts that had drifted from the code: - Runtimes table was missing ZeroClaw (25 rows against the 26 CLIs in scripts/agent-cli-command-names.txt). - Architecture diagram routed Desktop and iOS through Next.js; only Web does. Desktop and iOS talk to the Go backend directly. - A single execution is a Run, not a Task (conventions glossary; the docs page is already titled Runs / 运行). - Mobile runs natively on iPad too; link the mobile-app docs page. - New Feishu/Lark connections are mainland-China Feishu only. - "Any Git host" overclaimed; it is GitHub, GitLab, Gitea, and Forgejo. Chinese README: channel list now matches English (adds WeCom and Telegram and the community-maintained note), docs links point at /docs/zh/ with Chinese heading anchors, adds the missing CLI-skill row and Star History badges, and uses the UI's terms (聊天, 自托管). Structure: the CLI count now appears once, in the Runtimes section, instead of four places per file; Get started and the five-minute walkthrough are merged; the self-host block states the anonymous telemetry default and the DO_NOT_TRACK opt-out; Stay in the loop gains steering a running agent. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * MUL-7735: docs(assets): retake the workspace overview screenshot The hero image predated the sidebar regrouping (Work / AI Team) and the Usage -> Analytics rename. Retaken from a seeded local environment at the same 1600x900 size and WebP q80 (85 KB -> 82 KB). The README and docs index pages share this file. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
bb40537c59 |
fix(issues): keep the run spinner turning after a steer moves it (MUL-7729) (#8871)
Sending a steer reply moves the running agent's block below the new message. That keyed move detaches and reinserts the row, and Electron reports both changes in one IntersectionObserver callback: first the detached row (not intersecting), then its new place (intersecting). useRunAnimationVisibility read only the first entry, so it paused the spinner as if the row had left the viewport. Nothing changed afterwards, so the spinner stayed frozen at its start angle for the rest of the run. Read the last entry, which is the current state. Co-authored-by: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
6dc6a0b9a2 |
MUL-7650: attachment viewer — CSV tables, JSON/YAML tree, numbered code, HTML viewports, every kind in a new tab (#8868)
* feat(server): accept JSON Lines in the attachment text preview proxy The viewer now shows .jsonl / .ndjson files as a tree, so the text proxy's whitelist takes them too (extension and application/x-ndjson). The whitelist test gains the CSV / TSV / log / JSON Lines cases and says it is mirrored by the client-side table in packages/views/editor/utils/preview.test.ts. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(views): table, tree, numbered-line and viewport views in the attachment viewer MUL-7650, step 3 of MUL-7642. Fills in how the full-window viewer shows the file types agents produce most. - CSV / TSV (`table` kind): parsed to a table on the shared DataTable — pinned header, virtualized rows, resizable columns, a frozen row-number column. Clicking a header sorts ascending / descending / file order; numbers sort numerically, empty cells stay last, all-number columns align right. `;`-separated exports are sniffed. DataTable headers now carry aria-sort when the table sorts through TanStack's own state. - JSON / JSON Lines / YAML (`structured` kind): a collapsible tree with inline previews of collapsed records and paged long lists; Tree / Raw in the top bar. A file that does not parse falls back to the source and says why. YAML alias expansion stays capped by the parser. - Code, text and logs: numbered lines (the number is a pseudo-element, so copying skips it) with a sticky gutter, and a wrap toggle. Logs and plain text wrap by default, code does not; the reader's choice carries across the sequence. - HTML: Fit / Desktop 1440 / Tablet 768 / Phone 390. A device width lays the document out at that width and scales it down when the stage is narrower, with the size and scale shown under it; switching never remounts the iframe. A source toggle shows the HTML with line numbers. - Open in new tab works for every previewable kind: /{slug}/attachments/{id} /preview loads the record by id and renders the viewer's own top bar and stage (AttachmentPreviewStandalone), keeping the desktop scroll restore for HTML. - Whitelist: .jsonl / .ndjson join the text types on both sides, and the client test mirrors the server's case table. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
4f2fdc0b15 |
MUL-7733: more room around dynamic blocks, actions on hover (#8867)
* fix(comments): more room around dynamic blocks, actions on hover (MUL-7733) A ```html or ```mermaid block sat 12px from the prose around it, barely more than a paragraph break (10px), so a bordered card with a title bar read as crowded against the text. It now gets 20px above and below. The margin moves from the block to the lazy shell that wraps it. A child's bottom margin cannot collapse through a box with a min-height, so on the block it sat inside the reservation; on the shell it collapses with the paragraphs on both sides and the prose first/last-child reset still applies. The title bar keeps the icon, title and kind chip, but Preview | Source, fullscreen and copy now fade in while the block is hovered or holds focus. They use opacity, so the bar does not reflow and the controls stay in the tab order. They stay up in the source view (Preview is the way back) and while the copy confirmation shows, and always show where there is no hover. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(mermaid): keep a wide diagram's left edge reachable (MUL-7733) The diagram scroller centered its iframe with justify-content: center. When the diagram is wider than the column, that pushes its left part past the scroll origin, where it is cut off and cannot be scrolled to: a four-step LR flowchart in a comment lost its first node. The iframe is now centered with auto margins, which never go negative, so a small diagram stays centered and a wide one starts at its left edge and scrolls to the right. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
7dac88a6a8 |
MUL-7649: issue deliverables and dynamic blocks — sidebar section, overview grid, viewer info panel, html/mermaid block frame (#8779)
* feat(attachments): issue deliverables model and sequence block ids (MUL-7649) collectDeliverableFiles groups every comment upload into deliverables, merging same-name, same-type re-uploads into versions (newest version first). Description attachments are inputs and never enter the model. Sequence items now carry the id of the block they came from, so a viewer can say which comment (or the description) a file was posted in. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(viewer): host details, overview and info panel slots (MUL-7649) PreviewSequenceProvider takes an optional describeItem (title accessory, info panel, locate action) and onOpenOverview. The viewer renders only the slots it is handed: a locate button, a grid button (G) and an info toggle (I) whose panel sits beside the stage. Letter keys stand down in fields, and any key pressed inside an open menu stays with the menu. A zoom canvas still at fit now follows a viewport resize (the info panel opening), while a zoom the reader chose is only clamped, as before. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(issues): deliverables section, overview grid and info panel (MUL-7649) The sidebar's "Deliverables" section shows what the issue delivered as a whole: its pull requests and the files its comments uploaded, re-uploads merged into one entry marked v2. It lists the three newest images and four newest files, plus "View all N deliverables". The former Pull requests section becomes the code group, keeping its MUL-7429 actions (link a PR by URL, the auto-complete menu) beside the group label. While the workspace shows PRs, the section stays up even with nothing delivered, since that is where a PR gets linked by hand. The overview (from "view all" or G in the viewer) shows code first, then files grouped by posting comment, filterable by kind, each group one click from its comment. Its count always equals the sidebar's. In the viewer, deliverables get a version switcher, and every file gets an info panel (source excerpt, sibling files, uploader, time, size) and "Show in comments", which unfolds a resolved thread if needed and reuses the timeline's jump-and-flash highlight. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(comments): standalone attachments as cards and an image row (MUL-7649) The files under a comment (and a chat message) no longer stack as one full-width row each. Other files become cards in a grid: type glyph, name, "TYPE · size", download / remove on hover, and the whole card opens the file. Several images sit in one row at a shared height; a lone image keeps its full size. HTML keeps its embedded preview (MUL-2330). On the issue page a re-uploaded file's card carries its version (v1, v2) from the deliverables model, through a small context. Standalone attachments are grouped images, then HTML, then files, and the preview sequence walks them in that same order, so paging follows the screen. The file-type glyph moves to editor/utils/file-icon so comment cards and the deliverables surfaces share one mapping. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * refactor(issues): pull requests keep their own section (MUL-7649) Since MUL-7429 the PR block is issue workflow — linking a PR by hand, the auto-complete switch, "won't auto-complete: missing Closes" — rather than output, so it goes back to main's own Pull requests section, unchanged, directly above Deliverables. Deliverables is now the delivered files only: hidden until a comment delivers one, and the sidebar number, "View all N" and the overview's "All N" all count files. The overview drops its code group. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(comments): lay several images out as justified rows (MUL-7649) Fixed-height tiles wrapped as soon as the column narrowed — three screenshots became two plus an orphan, with a ragged right edge. Rows are now justified from each image's real aspect ratio: every row shares one height and a full row runs edge to edge. A row takes as many images as fit above a minimum height, never grows past a maximum, and a last row that does not fill keeps the height of the row above it. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(rich-content): dynamic block frame for html and mermaid fences (MUL-7649) A fenced ```html or ```mermaid block is part of the message body, so it now renders in one shared frame instead of two unrelated widgets: - Always-visible title bar: kind icon, the fence's title="..." (or the kind name), a kind chip, Preview | Source, fullscreen and copy. Previously the controls only appeared on hover and floated over the content. - The body takes its content's height (at least 120px) and collapses past 480px behind a fade and "Show all". An HTML block used to be a fixed 480px. - Loading keeps the height this block had earlier in the session; a script error or a Mermaid parse error is explained inside the frame with "View source" and "Copy error". - HTML gets the app's theme tokens (--foreground, --chart-1 ...); HTML that uses one also gets the app's color-scheme, so it follows dark mode. HTML that uses none keeps its own look. The sandboxed document reports its height and first uncaught error through a one-line postMessage bridge; the page checks the message source and clamps every value, and stops a document whose height follows the frame. rehype-raw drops the fence meta, so the title is read in the closed-fence parse. The Mermaid sandbox now also declares the app's color-scheme and font: in dark mode it was painted on an opaque white canvas, and its labels were drawn in a serif font that did not match the layout Mermaid measured. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(attachments): HTML files show as cards, not inline previews (MUL-7649) Reverses the MUL-2330 pin. An uploaded HTML file is a deliverable to open, not part of the text: like every other non-image file it shows as a card (a row inline in the body, a grid card under it) that opens in the viewer, and its contents are no longer fetched to embed a 480px iframe. HTML meant to be read in place is written as a ```html block, which renders as a dynamic block. - Attachment drops its html branch; HtmlAttachmentPreview is deleted and HtmlPreviewBody keeps only the inline source the viewer uses. - orderStandaloneAttachments groups images, then files (HTML included), so AttachmentList and the viewer sequence still walk the same order. - The MUL-2330 regression pins now assert the card and that no text fetch happens. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * docs: charts go in html/mermaid blocks, files show as cards (MUL-7649) Agents that uploaded an HTML chart expecting it to render in the comment now get a file card instead. Tell them where each kind of content goes: - multica-platform skill (issues reference, routed from the table): a fenced ```html / ```mermaid block renders in place with a title bar and content height; an attached file, HTML included, is a card that opens the viewer. Covers title="...", the sandbox, the theme variables and their opt-in color scheme, and sizing to content rather than the viewport. - `multica issue comment add --attachment` help says the same in one line. - Comments docs (all five languages) describe both. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(daemon): runtime brief says where charts and diagrams go (MUL-7649) The chart/file rule lived only in the multica-platform skill's issues reference, which an agent opens on demand, and the skill's description did not mention comment formatting, so an agent that just wanted a chart in its result had no reason to read it. Agents that uploaded report.html expecting an inline chart now get a card. - The brief's Output section carries one line, beside the file-delivery line, on the surfaces the web renders (issue comments and web/mobile chat): put charts and diagrams in the text as a fenced html or mermaid block, name it with title="...", and an attached file, HTML included, shows as a card. Theming and sizing stay in the reference. - Channel chats, autopilot run results and quick-create stdout do not render these blocks and do not get the line; the delivery tests pin both sides. - The skill description names "charts and files in comments" so the reference is picked for that task. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(issues): locate a file in a collapsed thread (MUL-7649) "Show in comments" for a file posted in a reply only unfolded resolved threads and gave up after 30 frames, so a thread the reader had collapsed stayed shut and the reply never mounted. A reply now goes through the quick-jump rail's jumpToReply, which already undoes every kind of folding and waits for the reply to land. A root comment gets the same treatment for its own thread (the reader's collapse, or a resolved bar), then the jump. Found in review by Emacs. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(viewer): the info panel's "Show in comments" closes the viewer (MUL-7649) The top bar's locate went through the viewer, which closes itself first; the same button in the info panel called the host's callback directly, so the page scrolled underneath a viewer that still covered it. Controls handed to describeItem gain close(), and the issue page builds one close-then-locate action for both entry points. Found in review by Emacs. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(issues): the deliverables overview is a real modal dialog (MUL-7649) The overview was a portaled layer with role="dialog" and nothing else: focus stayed on the opener, Tab walked into the page underneath, and closing left focus wherever it was. It now renders through the shared Dialog, restyled to cover the window, so the primitive moves focus in, keeps it inside, returns it to the opener, and handles Escape. `G` back to the viewer's file stays. The dialog is named by its title ("MUL-123 deliverables"). Found in review by Emacs. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
fc4a615700 |
MUL-7726: let the workspace choose the status merged PRs move an issue to (#8862)
* feat(pr): move issues to a workspace-chosen status when their PRs merge (MUL-7726) The merge automation completed an issue only when a PR said "Closes MUL-1", so the workspace switch mostly did nothing: most PRs are linked by title or branch and never completed anything. The workspace now picks what a merge does, in settings.pr_merge_status: "none", or the key of a started or done status (custom ones included, Blocked excluded). Absent means Done. When every linked PR is merged, the issue moves to that status. A closing keyword only links. - Decision: terminal, triage, "none", the per-issue switch and a new at_target state (the issue already has the target) come before the PR states, so the issue page only speaks when a merge would move the issue. The response adds target_status. - MoveIssueFromPullRequests replaces CompleteIssueFromPullRequests and writes the target status. The target is resolved through the delivery's shared catalog read (Resolver.WritableCategory). An archived or unknown choice, or a failed read, fails closed to no write. - Close intent is no longer synced or read. The column stays. - Migration 551 pins "none" on existing workspaces whose history shows a merge never moved every issue: auto-complete switched off, or a linked PR whose merges were not all keyword merges. Workspaces with no links, or with only keyword merges, keep the Done default. Replays are harmless. - CLI: `multica issue pr-automation <id> on|off` lets an agent keep one issue where it is. The multica-platform skill describes the new rule. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(views): choose the status merged PRs move an issue to on the GitHub page (MUL-7726) - Settings → Integrations → GitHub → Features: "After PRs merge, move the issue to" picks Don't change, or a started or done status, custom ones included and Blocked excluded. It replaces the read-only auto-complete row. The self-hosted Git page shows the same setting. The statuses page drops its switch, and a badge on the target status now links to the setting. - Issue sidebar: the line under the PR list names the target status ("Moves to In Review when #19 merges"). It says nothing when the workspace leaves status alone, when the issue already has the target, or on an older backend's no_close_intent. The per-issue switch reads "Keep status when PRs merge" and is hidden when it would change nothing. The menu opens the GitHub setting. The link hint only shows while auto-link is on. - core: derivePRMergeStatus replaces derivePRAutoCompleteEnabled; the auto_complete schema adds target_status and the at_target state. - Copy in 5 languages. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * docs: describe the workspace-chosen status for merged PRs (MUL-7726) GitHub integration, self-hosted Git, issues and environment variable pages (4-5 languages) now say that the workspace picks what a merge does: Done by default, another started or done status, or no change. They also say that a closing keyword only links, and how to keep one issue's status. The troubleshooting entries explain what a missing line under the PR list means. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * refactor(pr): keep the merge automation out of agents' instructions (MUL-7726) Agents don't act on what a merge does to an issue, so they don't need a command for it or a rule to learn. Drop `multica issue pr-automation`, and cut the multica-platform skill down to how PRs get linked: no merge rule, no auto_complete field guide, no "the server moves it to done" note. People still keep one issue's status from its Pull requests menu, and the docs now point there. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(pr): keep the retired auto-complete switch working for old desktop clients (MUL-7726) Review of #8862: an admin on a desktop client from before this change can still flip "Complete issues when their PRs merge". The client saved pr_auto_complete_enabled = false, and the save looked successful, but the server only read pr_merge_status, so merges kept moving issues to Done. - Settings writes: a flip of the retired switch becomes a choice (off → none, on → Done). An old client that echoes a chosen target without flipping the switch leaves the target alone. Every write mirrors the switch from the effective choice (false for none, absent otherwise), so old clients show the right state. - Reads: without pr_merge_status, the retired switch decides (off → none, else Done), on the server and in derivePRMergeStatus. This also covers settings written by a pod that predates the change during rollout. - Migration 551 sets the switch off on the workspaces it pins to none. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
400791262f |
build(views): upgrade Tiptap to 3.31.3, fixing select-all + delete (MUL-7725) (#8860)
* build(views): upgrade Tiptap to 3.31.3 (MUL-7725) Move all @tiptap/* packages from 3.27.1 to 3.31.3. Beyond the select-all + delete fix (MUL-7725, @tiptap/core 3.29.0), this picks up: - security fixes: prototype pollution through mergeAttributes (3.30.4), a Markdown attribute parsing DoS (3.30.5), and prosemirror-view >= 1.42.3 for a paste XSS (3.31.2) - deleteSelection over multi-range selections such as table cells, input rules crashing next to mention atoms, and the blockquote Backspace crash at a leading image - Markdown parsing fixes for lists followed by headings, rules, code fences, or bullets, and for `||` inside table code spans Stop at 3.31.x rather than 3.29.x: StarterKit only pins its bundled @tiptap/* dependencies to exact versions from 3.30.0, so a 3.29 pin still resolves most of them to the newest release. @tiptap/markdown still parses an empty list item into a childless listItem, so repairEmptyListItems stays. Only the pre-repair selection changed: the caret now lands on the following block rather than in an AllSelection. Update the test precondition and comments to match. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * test(editor): pin the caret after select-all + delete (MUL-7725) Cmd+A then Backspace/Delete used to leave the emptied document under an AllSelection, painted as a lone selected space with no caret. Tiptap 3.29 fixed deleteSelection upstream; guard it through our production keymaps for both the content and the single-line title schemas. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(editor): park the caret when a composer clears after send (MUL-7725) Composers clear through ContentEditorRef.clearContent after a send. Tiptap's clearContent maps the selection across the replace, and an AllSelection maps onto itself, so a send right after Cmd+A left the emptied composer "all selected". Surfaces that refocus after sending (thread replies, chat, quick create) then painted that selection over the empty line as a lone selected space: the MUL-7725 symptom through a path the upstream deleteSelection fix does not cover. Set the selection to the start after clearing. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
57fabfc078 |
MUL-7724 feat(desktop): left-align window toolbar as Back / Forward / sidebar toggle (#8859)
Left-align the title-bar controls just past the macOS traffic lights and order them Back, Forward, then the sidebar toggle, with arrow icons in place of chevrons. Drop the standalone History button: long-pressing, right-clicking, or pressing ArrowDown on Back / Forward already opens the directional history menu. With the History button gone and the controls left-aligned, the toolbar clearance shrinks from 256px to 200px (88px traffic-light inset + three 28px buttons + two 8px gaps + 12px trailing pad), matching the sidebar's minimum width so the controls always fit inside the expanded sidebar. Co-authored-by: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
e2f4a22030 |
feat: steer a running agent from the normal composer, per recipient (MUL-7631) (#8760)
* feat(server): steer running turns from ordinary comments (MUL-7631) A comment can now name recipients whose running turn should receive it (`steer_agent_ids` on POST /issues/:id/comments). Each named recipient with a running, steer-capable turn gets the comment bound to that turn instead of a follow-up run; any other recipient keeps its normal queued / coalesced / deferred trigger, so losing a race never drops input. - One comment can steer several turns: receipts are keyed by (comment_id, task_id) and returned as `supplements` on comments and timeline entries. The single supplement_* fields mirror the first receipt for older clients. - Completion reconciliation skips a steered comment only for the agent it steered, so the same comment still reaches recipients that were addressed without steering. - Delivery claims match the (comment, run) pair. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(issues): choose per recipient how a message reaches a running agent (MUL-7631) Steering moves from a separate "Add message" box on the run row into the normal reply and comment composers. Recipients keep the existing trigger rules; each recipient's current run on the issue decides what the message can do: - running (and steer-capable): add to the current run (default in that run's own thread), start after this run, stop and start over, or skip - queued: include when it starts, or skip - idle: start on send, or skip Receipts follow the message ("Waiting for Lambda to read it" → "Read by Lambda · after step N"), a failed delivery offers retry or sending it as a new run, and the run's step list marks where it read the message. A draft whose recipient finished meanwhile stays in place and says it will start a new run; a message with files is handled after the run. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(server): steer only the chosen turn, and make a retried steer idempotent (MUL-7631) - Steering names the exact running turns the author chose (`steer_task_ids`). A chosen turn that ended before the send arrives is never swapped for a later turn of the same agent; that recipient keeps its normal trigger. - A steering send carries `client_request_id`. A retry after a lost response returns the original comment (200) instead of creating a second comment and a second delivery; a concurrent twin binding the same request is treated as already steered. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(issues): guard steering sends against stale previews and broad resends (MUL-7631) - "Stop and start over" never stops a run while the trigger preview is still catching up with an edited @mention: the stop is dropped unless the preview answers the submitted text. - Steering sends the chosen turns' task ids and one request id per draft text, reused on retries of the same text. - "Send as a new run" on a failed receipt reaches only that receipt's agent: every other current recipient is suppressed. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(issues): keep the reply box placeholder neutral (MUL-7631) The empty reply box cannot know who a reply goes to: the author may @ someone else or only talk to a teammate. The recipient chip already says what Send will do once there is text. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * test(issues): give steering composer tests room for the preview debounce (MUL-7631) Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(issues): choose the default reply to a running agent (MUL-7631) Preferences > Comments gains "When replying to a running agent": "Add to current run" (default) or "Start after this run". It only changes what a reply does without a per-message choice; the recipient chip still offers both, and replies that never steered by default (another thread, an idle or queued agent) are unaffected. Saved on this device next to the sticky comment bar. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(server): save one comment per send and honor "don't start" on replay (MUL-7631) Idempotency now lives on the comment, not the delivery receipt. A send's client_request_id is stored on the comment behind a partial unique index (migrations 550/551), so a retry, or a concurrent twin, returns the saved comment (200) whether the send steered a running turn or fell back to a normal trigger. Before, a twin could save a second comment, and a send whose turn had ended kept no receipt to find. The agents an author chose not to start are stored on the comment too, and completion replay skips them. "Send as a new run" for one missed recipient, and "Won't start this time", no longer wake the other agent once its current run completes. An edit re-records the choice. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(issues): repeat the original steering request on retry (MUL-7631) Until a send is settled, retrying the same text sends its first steering request unchanged, even after the chosen turn ended. The server then returns the comment the first attempt saved instead of posting it again as new input. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(migrations): fail fast on locks in 549 and 550 (MUL-7631) Both take an ACCESS EXCLUSIVE lock on a table the product touches continuously: comment for every read and write, task_supplement for every daemon claim. Bound lock acquisition and execution, as 483 does for issue, so a long transaction makes the migration fail and retry on the next run instead of queueing all traffic behind it. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(server): steer at most one turn per comment during rollout (MUL-7631) Steering is live, and servers from before per-run receipts claim every receipt of a comment at once. While they still serve daemons during a rollout, a comment bound to two turns could have the second copy marked in flight and never delivered. Until every server claims per (comment, run), a comment steers the first chosen turn only; later recipients keep their normal trigger. A follow-up lifts the limit after this ships. Also covers a steer_task_ids entry that names another issue's turn. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(server): finish a saved send on retry; keep an edit's choices with its text (MUL-7631) A send's comment was saved before its agents were started or steered, and deduplication treated the saved comment as the whole send. A dropped connection cancelled the request between the two, and the retry only returned the comment, so no agent ever received it. - Attempts of one logical send now run one at a time under a transaction advisory lock, held on its own connection: a twin waits for the attempt in progress (up to 30s, then 409) instead of racing it, and a process that dies releases it. - After the comment is saved, dispatch runs on a non-cancelable context, and comment.client_request_dispatched_at (migration 552) records that it finished. A retry that finds a saved but undispatched comment finishes the dispatch with the comment's recorded choices. An edit's "don't start" choices were written by a separate statement after the text, so interleaved edits could leave an older edit's choice. They are now part of UpdateComment, under the same revision check as the text. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(issues): offer one steered recipient per message during rollout (MUL-7631) The server steers at most one turn per comment until #8800, but the composer showed "Add to current run" for every running recipient and the server quietly queued the rest. Now only one recipient steers: the one the author picked, otherwise the first that would by default. The others show "Start after this run", and picking "Add to current run" on one of them moves the steer there. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(server): claim a send before dispatching it; drop the request lock (MUL-7631) The previous recovery marked a send dispatched only after reaching its agents, so a failure after dispatch made a retry reach them all again. It also held a pooled connection per send for an advisory lock while the send needed more from the same pool, which could wait on itself until timeout. A send's comment now holds a dispatch claim instead (comment.client_request_dispatched_at, one conditional update): only the attempt whose claim takes effect publishes the comment and reaches its agents. A failed claim writes nothing else and returns 500 for the client to retry; a retry that finds an unclaimed comment claims and dispatches it; a claimed one is only returned. Concurrent attempts no longer wait on each other, and post-save dispatch keeps a 30s bound of its own. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(server): let one comment steer several running turns (MUL-7631) Lifts the rollout limit from #8760. Every server now claims receipts per (comment, run), so a comment can be bound to each running turn its author chose, and each recipient receives it in its own run. Merge only after #8760 is deployed everywhere. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(issues): steer every running recipient a message addresses (MUL-7631) The client side of lifting the rollout limit: each running recipient can take the message in its current turn again, instead of only one per message. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * refactor(issues): drop send-retry idempotency and two display extras (MUL-7631) A steering send now behaves like any other comment when its response is lost: a retry posts it again. The machinery that tried to make that retry return the saved comment grew with every edge it met, and ordinary comments never had it: - Remove comment.client_request_id, its unique index, and the dispatch claim (migrations 551/552, and 550 reduced to suppressed_agent_ids). - Remove the replay/resume path in CreateComment, the post-save non-cancelable dispatch context, and the client's sticky request id. Steering sends only `steer_task_ids`; each binding uses the comment id as its receipt request id. Two display extras go too, since the UI already shows the same thing: - The "run ended while you were writing" notice: the recipient chip already switches from "Add to current run" to its new action. - "after step N" on a read receipt: the run trace already places the message at the step where it was read. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(issues): space agent names in Chinese copy; neutral recipients header (MUL-7631) - The steer badge joined names with Intl.ListFormat, which gives "Lambda和Orion" in Chinese. Latin names are now spaced from the Chinese joiner ("Lambda 和 Orion"), per the zh copy conventions; the enumeration comma stays unspaced. - The multi-recipient popover was still titled "Will start when sent" and its tooltip said "choose who runs", though each row now picks how that agent handles the message. Title it "Recipients" and reword the tooltip. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(issues): translate the recipient source labels in Chinese (MUL-7631) "assignee" and "@mention" were left in English in zh-Hans; the recipient menu header shows them. Use 负责人 (per the zh conventions) and @提及. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
1c908ea52c |
feat(issues): state a failed or cancelled run once in the thread (MUL-7692) (#8813)
* feat(issues): state a failed or cancelled run once in the thread (MUL-7692) A run that ended in failure rendered as two stacked components: the platform's system comment (the raw daemon error, shown as if the agent had said it) with its own "Retry run" button, then the run line with "Failed", the duration, and a red reason. One outcome was stated three ways, and a failed row with failure_reason=cancelled read as both failed and cancelled. - The run's own failure notice no longer renders as a comment. The run block takes its slot (keeping the notice's deep-link id and highlight), in a thread and at the top level. A top-level notice that people replied to keeps its thread header and drops only the raw body and its button. - The run line states the outcome once: icon + reason (or who cancelled), then View activity, duration, and a single Retry run in the slot the running row's Stop occupies. The raw error moves to a tooltip on the reason. - Cancellation reasons (cancelled, manual, user_cancelled) read as cancelled with the neutral Ban icon; red is reserved for real failures. - Failures that need a configuration change (auth, quota, missing config or CLI, unavailable model, private runtime) keep the raw error in view under the row. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(issues): keep a retry below the attempt it retries (MUL-7692) A working run in a thread was spliced directly after the input it answers. A retry answers the same input as the failed attempt, so while it ran it sat above that attempt's failure row, out of order. Place a working run after its input, after earlier runs on that input, and after any row that happened before the run was enqueued. Later comments still go below it, as MUL-7632 requires. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
07059303f4 |
MUL-7682 feat(issues): give every reply a tick on the thread rail (#8809)
The quick-jump rail only reached thread roots, so a long agent thread could not be entered at the reply that mattered. Each reply now gets a short tick under its thread's long tick, and the hover outline lists every reply (avatar, first line, time, resolution mark) under its thread. Jumping to a reply first undoes whatever hides it: the reader's own collapse, a root resolution that folds the thread into a bar, or a reply resolution that folds the other replies. The thread is mounted through Virtuoso, the reply is aligned 16px below the top of the viewport (clear of a pinned resolve-collapse bar), and it flashes like other jumps. Past 80 comments the rail keeps one tick per thread, while the outline still lists every reply. The rail layer moves to z-30 so the outline paints over the sticky collapse bars that these jumps now pin. Co-authored-by: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
f721ce5c32 |
MUL-7679 feat(issues): group comment actions by intent, Edit and Resolve first (#8801)
* MUL-7679 feat(issues): lead the comment actions menu with Resolve Resolve is the most used comment action, but it sat in the middle of the menu below copy/derive actions. Reorder both the thread-root and reply menus into three groups, most used first: 1. Resolve thread / Resolve thread with comment (or Unresolve) 2. Copy, Copy link, Create sub-issue from here 3. Edit, Delete Edit and Delete now share one group; Delete stays last, destructive-styled, and behind its confirmation dialog. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * MUL-7679 feat(issues): group comment actions by intent, Edit first Regroup the comment actions menu by what the viewer wants to do: 1. Act on it: Edit, then Resolve thread / Resolve thread with comment 2. Take it elsewhere: Copy, Copy link, Create sub-issue from here 3. Delete, alone at the bottom Edit only renders on comments the viewer may edit, so on anyone else's comment Resolve leads the menu. The first group's separator only renders when that group has items. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
1d94166dc2 |
MUL-7642: full-window attachment viewer that pages through every file (#8763)
* feat(attachments): full-window viewer that pages through every file (MUL-7642) The preview was a centered card capped at max-w-6xl, so a screenshot never showed larger than 1152px wide whatever the screen, and prev / next only walked images. - The viewer takes the whole window: no card, a near-black stage, a top bar in the dark token set, prev / next in 64px side gutters, type / pixel size / file size instead of the MIME type. Markdown and text read on a centered sheet in the app theme; PDF and HTML fill the stage. - The surface sequence now covers every previewable kind, so an issue pages through its screenshots, PDFs, reports and HTML in render order. `collectAttachmentSequence` takes the inclusion rule; mobile keeps the images-only `collectImageSequence`. - The issue description block no longer lists every issue attachment as its own: comment uploads keep issue_id, so they were counted at the description's position. - A focused video / field keeps its arrow keys. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(attachments): viewer image swap and desktop window chrome (MUL-7642) Review of #8763: - Paging from a PDF (or any non-image) onto an image that had not decoded yet handed the PDF's URL to <img>; its load error was blamed on the image being opened, which got marked broken and skipped. The settled-URL hook now only ever holds a URL that decoded as an image, and the <img> reports errors only when it shows the current file. - On desktop the full-window top bar sat under the macOS traffic lights and over the app's top-bar drag region. The viewer now enters immersive mode while open, marks itself no-drag, lets its top bar drag the window, and opts the bar's controls back out. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(attachments): viewer waits for the media re-sign before loading (MUL-7642) On clients that cannot load `/api/attachments/{id}/download` natively (desktop, split-origin web, self-host proxy mode) the viewer handed that endpoint to <img> while the re-sign / authenticated byte fetch was still in flight. The native load failed, and in a sequence the failure read as a broken image: it was marked unavailable and skipped before the loadable URL arrived. `useResignedInlineMedia` now also reports whether the upgrade is pending. The viewer holds the previous frame (or shows loading) until it settles, and the neighbour prefetch waits too. The inline figure keeps its behaviour. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(attachments): no focus ring around the viewer stage on open (MUL-7642) The viewer focuses its zoom canvas on open so +/-/0 and the arrows work without a click. That programmatic focus can match :focus-visible, and on the full-window viewer the canvas ring drew a light frame around the whole stage. The canvas now marks focus it placed itself; the stylesheet drops the ring for it until focus leaves, so tabbing back in still shows one. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
9df0cae78a |
MUL-7429: complete issues when every linked PR merges (#8758)
* feat(pr): complete issues when every linked PR merges (MUL-7429) Title/branch identifiers link a PR; keywords and the body no longer matter. Completion is evaluated only on a PR event for the issue (merge, link, unlink), so settings changes and reopening never complete an issue. Adds manual link/unlink with remembered exclusions and a per-issue auto-complete switch. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(pr): issue-page PR automation and single auto-complete setting (MUL-7429) The issue's Pull requests section says what the merge rule will do next, links a PR by URL, removes one per row, and turns auto-complete off for that issue. The workspace switch lives under Issue statuses; the GitHub page reports it. Agent skill and docs describe the title/branch rule. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(pr): accept PR links pasted without a scheme (MUL-7429) Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * test(skills): pin the PR auto-complete contract in the platform skill (MUL-7429) Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix(pr): re-check linked PRs at the completion write; skip stale GitHub events (MUL-7429) The status write now requires every linked PR to still be merged when it runs, so a PR linked between the decision and the write keeps the issue open. GitHub PR upserts ignore events older than the stored row, like the self-hosted path, so a late delivery cannot roll a merged PR back to open and turn a redelivered merge into a new one. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Claude Opus 5.5 <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
3ec96f6860 |
fix(issues): preserve active run order before later comments (MUL-7632) (#8748)
Co-authored-by: multica-agent <[email protected]> |
||
|
|
c375f83c2e |
MUL-7418: add issue event and time wakeups (#8467)
* feat: add issue event and time wakeups (MUL-7418) Co-authored-by: multica-agent <[email protected]> * feat(wakeups): capture issue collaboration event lifecycle Co-authored-by: multica-agent <[email protected]> * fix(wakeups): preserve reply source when reopening threads Co-authored-by: multica-agent <[email protected]> * feat(wakeups): summarize sidebar and issue activity cues Co-authored-by: multica-agent <[email protected]> * fix(wakeups): restore disabled configurations with a two-way toggle Co-authored-by: multica-agent <[email protected]> * feat(wakeups): manage workspace wakeups in Autopilot Co-authored-by: multica-agent <[email protected]> * chore(wakeups): reserve migrations after current main Co-authored-by: multica-agent <[email protected]> * test(wakeups): align inventory fixtures with shared contracts Co-authored-by: multica-agent <[email protected]> * fix(wakeups): distinguish trigger conditions and execution results Co-authored-by: multica-agent <[email protected]> * fix(wakeups): suppress registration feedback and drain bounded evidence Co-authored-by: multica-agent <[email protected]> * fix(wakeups): align sidebar actions with titles Co-authored-by: multica-agent <[email protected]> * fix(wakeups): bound database work and unify shared issue visibility Co-authored-by: multica-agent <[email protected]> * feat(wakeups): filter mutation events by member or agent actor Co-authored-by: multica-agent <[email protected]> * refactor(wakeups): merge structured evidence and narrow receipt locks Co-authored-by: multica-agent <[email protected]> * feat(wakeups): let people edit wakeup instructions Co-authored-by: multica-agent <[email protected]> * fix(wakeups): align inventory controls and compact prompt editing Co-authored-by: multica-agent <[email protected]> * fix(mobile): handle deferred agent run status Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Lambda <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
a6d2a5ca83 |
fix(chat): match default list width to inbox (#8537)
Co-authored-by: multica-agent <[email protected]> |
||
|
|
0cb64a77aa |
feat(ui-lab): add design system workbench (MUL-7425) (#8388)
* feat(ui-lab): add shared component design workbench * feat(ui-lab): support English and Chinese * feat(ui-lab): scaffold design system catalog * fix(ui-lab): cover narrow headers and CI path filtering * feat(ui-lab): add dialog motion and component usage rules * feat(ui-lab): add semantic color workbench * fix(ui): update brand color to #0070E3 * feat(ui-lab): add color usage and live contrast checks * feat(ui-lab): support collapsible sidebars * fix(ui-lab): place collapse controls in sidebar headers * fix(ui-lab): avoid repeating page titles in breadcrumbs * test(agent): synchronize Cursor background finalization fixture * fix(ui-lab): preserve contrast and list scroll restoration (MUL-7425) Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Lambda <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
30831b70d3 |
fix(landing): include t in Multica acronym emphasis (#8477)
Co-authored-by: Lambda <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
d95c20aab2 |
feat: complete issue status category upgrade (MUL-7365 PR3) (#8466)
* feat: converge issue status categories on upgrade (MUL-7365) Co-authored-by: multica-agent <[email protected]> * refactor(status): remove redundant stored-category normalization (MUL-7365) Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Lambda <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
3fe16b8fcb |
MUL-7422: paginate archived inbox and load it on demand (#8471)
* fix(inbox): paginate archived notifications on demand Co-authored-by: multica-agent <[email protected]> * fix(inbox): isolate archived deep-link lookup states Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Lambda <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
080b118f07 |
fix(daemon): isolate cached worktree Git identities (MUL-7423) (#8470)
* fix(daemon): isolate Git identities in cached worktrees (MUL-7423) Co-authored-by: multica-agent <[email protected]> * fix(repocache): preserve config lock ownership on handoff Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: multica-agent <[email protected]> |
||
|
|
e6fac5feff |
docs: add Star History badges to README (#8474)
Co-authored-by: Lambda <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
9663b4a87b |
fix(issues): remove sidebar PR linking help (#8469)
Co-authored-by: Lambda <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
96aa80ff9e |
MUL-7348: simplify redundant UI descriptions across product surfaces (#8393)
* refactor(ui): remove redundant descriptions across product surfaces Implement MUL-7348 copy audit across shared views, Desktop, Mobile, and contact sales. Keep actionable constraints visible and move advanced explanations into explicit help. Update all four locales and document default-omit copy rules. Co-authored-by: multica-agent <[email protected]> * fix(ui): preserve constraints and improve contextual copy help Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Lambda <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
d7f8c3f2b6 |
MUL-7404: ci: scope validation and remove duplicate lifecycle runs (#8451)
* ci: scope validation and remove duplicate lifecycle runs Co-authored-by: multica-agent <[email protected]> * fix(migrations): renumber the Triage validate migration to 489 #8449 and #8436 merged minutes apart and both took 485, so TestMigrationNumericPrefixesAreUnique fails on main and every PR branched from it. #8436 owns 485-488, so the single validate file moves to 489. Renaming an applied migration makes databases that already recorded 485_issue_triage_state_validate run it once more under the new version string. That is safe here: VALIDATE CONSTRAINT on an already-validated constraint is a no-op, verified against PostgreSQL 17. Co-authored-by: multica-agent <[email protected]> (cherry picked from commit 09140a04aea06e8ca1cf008433cad3600d851cef) * fix(ci): gate installers and reuse frontend quality setup Co-authored-by: multica-agent <[email protected]> * docs(ci): remove redundant CI overview Co-authored-by: multica-agent <[email protected]> * refactor(ci): remove unused output and duplicate test fixtures Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Lambda <[email protected]> Co-authored-by: multica-agent <[email protected]> Co-authored-by: J <[email protected]> |
||
|
|
02a8ff3e95 |
feat(maintenance): add resumable internal backfill API (MUL-7365) (#8436)
* feat(maintenance): add resumable internal API backfills (MUL-7365) Co-authored-by: multica-agent <[email protected]> * fix(maintenance): ship bounded container operations driver Co-authored-by: multica-agent <[email protected]> * test(cursor): synchronize ownership before finalization Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Lambda <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
95629c6d5b |
fix(sidebar): align help after dismissing Discord link (#8437)
Co-authored-by: Lambda <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
a3318b68de |
fix(views): move issue refresh feedback into page title icons (#8430)
Co-authored-by: Lambda <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
7d9613bd2c | fix(issues): show content previews in inline agent logs (#8408) | ||
|
|
9d18186e6e |
fix(status): MUL-7365 expand category compatibility before backfill (#8407)
* fix(status): stage category expansion and preserve installed client groups (MUL-7365) Co-authored-by: multica-agent <[email protected]> * fix(status): validate mixed storage with GC and recovery compatibility Co-authored-by: multica-agent <[email protected]> * docs(status): align phase one rollout with merged main dependency Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Lambda <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
47054a7b6f | docs: unify and simplify coding agent instructions (#8404) | ||
|
|
d77a1c5ea7 |
fix(prompts): remove status wire details from operational guidance (#8401)
Co-authored-by: Lambda <[email protected]> Co-authored-by: multica-agent <[email protected]> |