mirror of
https://gh-proxy.org/https://github.com/klinsmaya/multica.git
synced 2026-11-08 17:36:45 +08:00
main
991
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
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]> |
||
|
|
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]> |
||
|
|
53c4bbe5cd |
MUL-8395 fix(lark): distinguish bound bots from verified message reception (#9709)
* fix(lark): verify message reception separately from binding * fix(lark): preserve verification evidence during rollout * fix(lark): remove stray space in Chinese verification hint Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Multica Eve <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
3191de1930 |
MUL-8385 feat(wecom): show the run's steps and reasoning in the bubble while it works (#9696)
* feat(wecom): show the run's steps and reasoning in the bubble while it works The bubble used to open, spin for the whole run and close with the answer. It now fills in while the run is going: each tool call as a sentence in the reader's language, the agent's own reasoning under it, and how long it has been. Only the bot's principal sees any of it, and only in their own 1:1 — a group or anyone else gets the plain spinner, decided again for every round. - Steps come from task:message (the transcript), plus the daemon's first task:progress milestone, which is said as "starting the agent" in the bubble's language rather than the daemon's English. Only runs asked over WeCom (a WeCom channel_task_delivery row) show steps. - Progress reaches the replica that holds the round, whichever replica served the daemon's request. The bus subscriber only classifies the event and queues it on a per-run lane, so the daemon's request does no database read and no socket write. The holder reads the run's new transcript rows past a per-run watermark (ListTaskProgressSince), redacts, throttles and writes the frame. A replica without the round publishes a progress relay frame that carries ids and a seq, no text; it takes no claim and never enters the dispatcher's queues, so it cannot delay or crowd out an answer. Duplicates, replays and out-of-order frames read nothing new, and do not count as a sign of life for the rotation guard. - Credentials are redacted from steps and reasoning: labelled values, known key prefixes, long high-entropy runs, and the same checks on each part of a URL or of a word glued to shell punctuation, plus webhook URLs whose path is the secret. Nothing the renderer strips afterwards can join two pieces into a key the redactor never saw. Reasoning arrives in 500ms increments, so redaction and the </think> defence run over the joined buffer, where a key and its value are seen together, and a run that may still be the start of a key is held back until it has finished. - A bubble near the server's ten-minute window is handed over to a fresh stream; a hand-over the server refuses stops rotation, and any stream the server has disowned takes no further frame — every closer falls back to a plain message instead of spending another refusal. Every frame a step writes, and both frames of a hand-over, take the reply write guard. - The identity lookup is wired on the real boot path, and its absence logs a warning, since without it no bubble ever shows a step. A relay with no typing indicator attached warns once when progress frames arrive. * fix(wecom): show a step the throttle held back without waiting for the next report A step that landed inside the 1.5s refresh window was only shown when the run reported again. The step most worth showing is often the last before a long silence (a file read, then a test suite that runs for minutes), so the bubble sat on the earlier step for the whole wait. A held step now schedules one trailing refresh per feed for when the window ends. It goes through the run's lane like any report, is not counted as a sign of life for the rotation guard, is never published to other replicas, and finds nothing once the round has ended. Co-authored-by: multica-agent <[email protected]> * fix(wecom): keep the reasoning buffer across a bubble hand-over Redaction runs over the joined reasoning buffer so a label and its value split across two increments are seen together. A rotation started that buffer over, so `password=` at the end of the old bubble and `hunter2` at the start of the new one were judged apart and the value went out in the clear. The new bubble now starts with no step lines and a fresh throttle but the same raw reasoning buffer. The old bubble is sealed with the hand-over line, so the reasoning is not shown twice. Also gofmt the two-replica test. Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: multica-eve <[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]> |
||
|
|
374b6f3db4 |
fix: respect omp profiles when discovering runtime skills (#9711)
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]> |
||
|
|
f2a6398d6e |
MUL-7257: refactor(server): remove unused compatibility queries and capabilities (#9671)
* refactor(comments): drop redundant RFC3339 fallback parse RFC3339Nano parsing already accepts timestamps without fractional seconds, so the second time.Parse(time.RFC3339) attempt can never succeed where the first failed. Keep the existing 400 responses and add a test pinning second-precision since and the invalid since/before cases. Co-authored-by: multica-agent <[email protected]> * refactor(daemon): stop advertising unread plugin capabilities execution-manifest-v1, agent-skill-v1 and remote-mcp-v1 have had no server-side reader since the Plugin V1 gates were removed in #7144. Drop the constants and the daemon advertisement. Co-authored-by: multica-agent <[email protected]> * refactor(autopilot): remove legacy no-reservation terminal queries UpdateAutopilotRunCompleted, UpdateAutopilotRunFailed and UpdateAutopilotRunSkippedWithResult have no production callers; terminal transitions go through UpdateAutopilotRunTerminalWithQuota. Their generated Params structs were still used as service argument types, so replace them with service-local structs. The reconciler test now seeds its crash window with an explicit fixture UPDATE. Co-authored-by: multica-agent <[email protected]> * refactor(tasks): remove unused StartAgentTask query Production start paths use StartAgentTaskWithSupplement. Move the seven test fixtures to the same query with both capability flags off, which performs the same running transition. The empty-body start handler branch is unchanged. Co-authored-by: multica-agent <[email protected]> * refactor(channels): remove unused pending_fresh queries MarkChannelChatSessionPendingFresh, LockChannelChatSessionPendingFresh and ClearChannelChatSessionPendingFresh have no callers. The context generation path and ClearChannelChatSessionPendingFreshForRevision remain. Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: multica-agent <[email protected]> |
||
|
|
e7dfbe83bd |
MUL-7995: fix(openclaw): report actionable state ownership lock error (#9222)
* fix(daemon): give OpenClaw tasks a private per-agent state dir (INFRA-70) Co-authored-by: multica-agent <[email protected]> * fix(openclaw): report actionable state ownership lock error (INFRA-70) * fix(openclaw): handle resident gateway local refusal (INFRA-70) --------- Co-authored-by: multica-agent <[email protected]> |
||
|
|
46d4e26712 |
MUL-8347: fix Hermes compatibility with gateway-backed and older ACP (#9666)
* fix(hermes): support gateway-backed and in-process ACP Co-authored-by: multica-agent <[email protected]> * fix(hermes): interrupt active task gateways during cleanup Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: multica-agent <[email protected]> |
||
|
|
375b23247b |
fix(codex): price GPT-6.1 Terra and add it to the fallback catalog (#9668)
gpt-6.1-terra runs through Codex but has no row in either price table, so its usage estimates at $0 and shows up as an unmapped model. Add OpenAI's standard short-context rates ($1 input, $0.05 cached input, $1.25 cache write, $5 output per 1M) to the backend metrics table and the frontend estimate table. The model is live-only on codex-cli 0.164.0-alpha.11.1 (absent from `codex debug models --bundled`), so also add it to the static fallback catalog with the observed `low` default and low..ultra efforts, and normalize its label alongside the rest of the GPT-6 family. Co-authored-by: Claude Opus 5.5 <[email protected]> Co-authored-by: Multica Eve <[email protected]> |
||
|
|
828e0c927e |
MUL-8346: fix(agent): handle Claude Code session and weekly limits (#9652)
* fix(taskfailure): classify Claude Code session and weekly limits as provider quota Claude Code reports a spent subscription window as "You've hit your session limit · resets 2pm (UTC)" or "You've hit your weekly limit · resets <date>". Neither matched the quota patterns, so these runs were classified as agent_error.unknown and quota-aware handling never saw them. * fix(agent): stop waiting for claude after an error result With stdin closed, the Claude Code CLI stays alive while any background task it started is running, then opens a new turn when the task ends. After an error result (a spent session limit, an API failure) that turn cannot change the outcome, yet the daemon kept the run open for the background task's lifetime. Terminate the process group 10s after an error result, the same way cancellation does, so the run fails with the result's error. --------- Co-authored-by: Evgeniy Yakutov <[email protected]> |
||
|
|
bb3747186e |
feat: let agents steer running turns they could start (MUL-8285) (#9630)
* feat(server): let agents steer running turns they could start (MUL-8285) An agent comment can now be added to another agent's running turn, the way a member steers from the composer: exactly when the comment could start that agent (canInvokeAgent, judged on the human at the top of the chain), never its own turn. - steer_task_ids now work for agent authors; steer: true asks the server to add the comment to the current running turn of every recipient without a named turn. - Agent-authored bindings are capped per turn (10) and per authoring agent (3). The task row is locked in its own statement before the bind, so the cap count sees what an earlier lock holder committed. - An agent comment that steered a turn but was never read is replayed on completion like the mention it replaced. Member receipts keep today's behaviour (the member sees the failure and can retry or resend). - The supplement claim returns author_type and the agent's name. A daemon that does not send task-supplement-author-v1 gets the attribution in the content, so an agent message never reads as a human's. - can_supplement on task-runs is computed for an agent caller by the same rule. Co-authored-by: Tim Smart <[email protected]> Co-authored-by: WitMiao <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(daemon): present an agent's added message as an agent's (MUL-8285) Claims send the task-supplement-author-v1 capability and render agent messages as peer input that cannot replace the objective or override humans. Co-authored-by: Tim Smart <[email protected]> Co-authored-by: multica-agent <[email protected]> * feat(cli): add --steer and --steer-active to issue comment add (MUL-8285) Docs: CLI help, CLI_AND_DAEMON.md, the CLI docs in every locale, the squad leader briefing, and a steering section in the multica-platform mentions reference. Co-authored-by: Tim Smart <[email protected]> Co-authored-by: multica-agent <[email protected]> * fix: close the review gaps in agent steering (MUL-8285) - Replay an unread agent steer even when it reached the turn through an implicit route (a worker's reply to its leader): a comment bound to the completing run counts as planned input for the replay filter. - Drop the receipt of an agent steer once completion has replayed it, so no client (old or new) offers to resend what the follow-up already handles. - Never hand an agent's message to a daemon without task-supplement-author-v1: it would frame it as a human's. The message stays pending, settles when the turn ends, and is replayed as a mention. - Tell a squad leader about --steer only when its daemon advertises cli-comment-steer-v1, since an older CLI rejects the flag; the skill reference says to drop the flag on 'unknown flag'. Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Tim Smart <[email protected]> Co-authored-by: WitMiao <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
7d02596fc3 |
fix(agent): MUL-8307 drive OpenCode over ACP so long tools and subagents are not force-stopped (#9619)
* fix(agent): drive OpenCode over ACP so long tools and subagents are not force-stopped `opencode run --format json` reports a tool only when it finishes, with the call and its result in one event. The daemon never saw a tool in flight, so a long silent tool or a delegated subagent was judged by the 10-minute OpenCode idle window instead of the tool budget and force-stopped (GH #9614). Built-in OpenCode 1.15+ and 2.x runtimes now run `opencode acp`, which on both majors announces a tool when it starts executing. MessageToolUse is emitted from that in_progress frame, so the daemon applies AgentToolWatchdog for the whole tool. One code path covers both majors: - model via session/set_config_option (2.x has no session/set_model); effort via the advertised `effort` option, splitting 2.x `model#variant` - resume via session/load; a missing session is reported as ResumeRejected - cancel via session/cancel, which aborts the running tool on both majors - MCP: 1.x keeps OPENCODE_CONFIG_CONTENT; 2.x gets servers in session/new, which lifts the 2.x MCP refusal on this transport - 2.x subagent text (`_meta["opencode/child-session"]`) stays out of the parent's output; its tool calls are kept - usage summed from the session export over this turn's assistant messages, since the prompt result's usage is not per-turn on either major The run transport stays as the fallback for custom profiles, older or unknown versions, agents with custom_args, and MULTICA_OPENCODE_TRANSPORT=run. Also fix the run transport on 2.x: tool_use parts carry the call id as `id` (1.x: `callID`), so every 2.x tool message had an empty CallID. Co-authored-by: multica-agent <[email protected]> * fix(agent): bound OpenCode ACP teardown when the runtime stops reading A runtime that stops reading stdin mid-prompt left the prompt write blocked holding the client's write lock. The cancel path then waited on that lock to send session/cancel, and the cancel grace and the process-group kill only ran after the write, so the process could outlive the task indefinitely. - session/cancel is sent only once the prompt is fully delivered, from its own goroutine, so the grace starts immediately and a stalled pipe cannot hold it - a turn OpenCode never answered (or a cancelled/timed-out setup) is torn down forcibly: stdin closed first to release a blocked write, then SIGTERM to the group and SIGKILL after the grace; an answered turn still exits on EOF Regression tests cover a stalled prompt write under a 1s timeout and a runtime that ignores session/cancel. Co-authored-by: multica-agent <[email protected]> * fix(agent): bound OpenCode ACP teardown when a setup write stalls Setup requests (initialize, session/new, session/load, set_config_option) are synchronous stdin writes that check their context only after the write returns. A runtime that stops reading after initialize, with a large MCP payload in session/new, left the run goroutine blocked in that write, so the deferred teardown never ran and the process outlived the timeout. A watcher now force-stops the process as soon as the run ends before the prompt is fully delivered; closing stdin releases the blocked write. Once the prompt is delivered the existing session/cancel path owns shutdown. Regression test: 256 KiB MCP env, runtime stalls after initialize, 1s timeout; returns in ~1s (60s before the fix). Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Multica Eve <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
55be334864 |
fix(taskfailure): classify Kiro dispatch failure as retryable provider_network (MUL-8314) (#9621)
Co-authored-by: multica-agent <[email protected]> |
||
|
|
84e56b6b00 |
MUL-8256 fix(runtime): recover stalled HTTP/2 connections (#9551)
* fix(daemon): recover stalled HTTP/2 control-plane connections * fix(daemon): recover stalled skill bundle connections * fix(runtime): share HTTP/2 recovery across persistent clients |
||
|
|
d7d1831fcf |
feat(cli): add run-targeted retries with a fresh option (#9592)
Co-authored-by: multica-agent <[email protected]> |
||
|
|
16a067f30a |
MUL-8270: fix(db): keep lease claims within query limits (#9563)
* fix(storage): claim one cleanup object per statement * fix(tasks): bound stale dispatch recovery candidates * fix(db): restore English lease claim documentation Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Sol-Boy <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
73f5664ca4 |
MUL-8263 fix(agents): reject reserved custom arguments on save (#9560)
* fix(agents): reject reserved custom arguments on save * fix(agents): validate OMP session arguments before saving Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Sol-Boy <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
bcf40040e0 |
MUL-8233: fix Pi cancellation and guard unconfirmed cleanup (#9557)
* fix(agent): join Pi cancellation cleanup and guard continuation Co-authored-by: multica-agent <[email protected]> * fix(agent): preserve Pi completion and negotiate cleanup Co-authored-by: multica-agent <[email protected]> * perf(agent): avoid Pi exit delay and index cleanup guards Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Multica Eve <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
ff6d3207c8 |
fix(agent): keep per-run usage when Claude resume baseline capture fails (#9567)
When a resume's baseline capture fails, the result event's modelUsage was stored as the task's usage as-is. On newer Claude Code a resumed session restores its cumulative counters, so that reported total spans every prior task in the session: the #8781 inflation returned for every baseline-unavailable mode. The reported trigger is a custom runtime profile whose command is a wrapper script that sets CLAUDE_CONFIG_DIR internally - the daemon resolves the transcript from its own env (os.Environ() + agent custom_env) and never sees it, so every resume logged 'claude usage baseline unavailable' and stored the running session total (observed ~10x on a session's 7th task). The code already distinguishes a transcript that exists but has no cost-state (older Claude Code reports per-run totals there; behavior preserved, pinned by existing tests) from one that cannot be found at all. For the latter the reported modelUsage is now treated as non-authoritative: usage keeps the stream-derived per-run totals, and the reported totals are only recorded for the resume-rejected recapture where the run is known to have started a fresh session of its own. Affected modes now degrade to a conservative per-run approximation instead of silently storing a cumulative total; the WRN stays, reworded to say what actually happens. Out of scope, per the adjudication on the issue: per-profile env vars (schema/feature) and expanding $HOME/~ in custom_env values (makes the manual workaround portable but leaves the default inflation path live). Ablation: reverting only server/pkg/agent/claude.go on this branch makes both new tests fail again with the cumulative total stored (700/30/800/80 instead of the per-run 70/0/80/8). Fixes #9564 Generated-by: GLM-5.3-Flash (ZCode) |
||
|
|
2de89ff46e |
MUL-8244: fix(agent): preserve recovered Antigravity stream responses (#9534)
* fix(agent): tolerate recovered Antigravity stream interruptions * fix(agent): preserve failed Antigravity interruptions |
||
|
|
f9b3065ae1 |
fix(handler): serialize project resource read-modify-write with a row lock (#9240)
UpdateProjectResource derives every column it writes back from the row read at the top of the request, but the read and the write ran outside any transaction. Two concurrent partial updates could interleave as read-read-write-write, and the second writer's stale snapshot silently reverted the first writer's change: a label-only PUT reverted a racing ref update to an old Git ref, and a label-only PUT on a local_directory restored a stale execution mode (reported in #9238 with a deterministic interleaving that fails 15/15 under -race -count=3). Serialize the flow with SELECT ... FOR UPDATE inside a short transaction (GetProjectResourceInWorkspaceForUpdate + Begin/WithTx, same shape as CreateAgent). Competing updates block on the row until the write lands, then re-read fresh. This keeps the local_directory legacy label-mirror writeback intact, which a presence-aware column rewrite alone would have broken for mirror-triggered ref updates. Review follow-ups: - The regression test no longer leaves the race to the scheduler. Before resuming the paused label request, it waits until the ref request has either completed outright (the only exit on the pre-fix code, which never blocks) or is blocked waiting for the label request's row lock (the only exit with the fix, seen as wait_event_type='Lock' on the backend running the FOR UPDATE query, checked via pg_stat_activity). The two signals are mutually exclusive, so the test fails deterministically without the lock and passes with it. - findLocalDirectoryConflict and requireWorktreeCapableDaemon now read through caller-provided queries instead of the handler's pool: on the update path they run inside the transaction, so a locked request no longer borrows a second pooled connection per request. - Added a local_directory concurrency case: a label-only update racing an execution_mode update through the label-mirror ref rewrite. The regression tests fail on the pre-fix code ("stored ref = main, want the concurrent ref update (release)" / "stored execution_mode = worktree, want the concurrent mode update (cleared = in_place)") and pass with the lock, 20/20 runs each way. Fixes #9238 Generated-by: GLM-5.3-Flash (ZCode) |
||
|
|
e8fdcfd226 |
MUL-6623 feat(agent): add host-local Devin CLI over ACP (#7485)
* feat(agent): add host-local Devin CLI over ACP Spawn `devin acp` via the shared ACP client. Local CLI only — not cloud Devin VMs/Playbooks/Secrets. Model via `devin acp --model`. Catalog from `devin models list --format json` (families/variants). * fix: skip Devin ACP handshake when browser auth is also offered * fix: close dim case string so Devin compiles Missing quote after dim broke runtime_config.go and every Go CI job. * fix: stop runtimeConfigPath recursion on Devin Devin is a builtin whose ProtocolFamily is itself. Recursing on that overflowed the stack and killed backend-tests. * test(agent): cover Devin model failures and final-answer delivery Co-authored-by: multica-agent <[email protected]> * fix(agent): honor Devin model aliases and stored login (MUL-6623) Co-authored-by: multica-agent <[email protected]> * fix(agent): drain Kiro panic details before terminating runtime (MUL-6623) Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Sol-Boy <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
90a88519df |
fix(daemon): defer issue status rules to project workflow (MUL-8145) (#9415)
* fix(daemon): defer issue status rules to the project workflow (MUL-8145) When the claim carries a project workflow, the runtime brief no longer tells the agent to set in_progress first and in_review on delivery. Those statuses may be outside the workflow (the server rejects them), and entering a handoff step reassigns the issue. The brief now points at the per-turn [Project workflow] block, and the workflow brief carries the entry/exit checks in workflow terms. Briefs without a workflow are byte-identical to before. Co-authored-by: multica-agent <[email protected]> * fix(squad): word the owning leader's status moves by the project workflow (MUL-8145) The squad protocol (Agent Identity, which outranks the runtime brief) still told an owning leader to move the parent to in_progress and then in_review, which a workflow may not list and which can hand the parent to another step's handler. When the claim carries a project workflow, responsibility 6 now keeps the ownership grant but moves the parent only through the [Project workflow] commands. The claim resolves the workflow before the briefing to choose the wording. Guest leaders and issues without a workflow are unchanged. Co-authored-by: multica-agent <[email protected]> * refactor(daemon): list no status keys in the brief for a workflow issue (MUL-8145) With a project workflow, [Project workflow] already lists the issue's statuses and the commands that move it, and the built-in keys may not be accepted there. The status command line now keeps only the command and points at that block; other issues learn valid statuses from the error. Co-authored-by: multica-agent <[email protected]> * refactor(workflow): stop forbidding status moves nothing asks for (MUL-8145) Under a project workflow the current runtime brief no longer states the built-in in_progress / in_review moves, so the lines that forbade them (in [Project workflow], the runtime brief and the squad protocol) only named statuses the agent had no reason to use. Drop them, and the exit check the runtime brief already states. Older daemons still state the built-in rules, so the daemon now advertises workflow-status-rules-v1; without it the claim keeps the override lines in [Project workflow] and the squad protocol. The multica-platform skill notes that [Project workflow] supersedes its built-in status arc. Co-authored-by: multica-agent <[email protected]> * refactor(workflow): shorten the step's moves in the workflow brief (MUL-8145) Replace the handoff preamble with a plain "Your moves:" heading, name who each move hands off to on its own line, and drop the "this workflow has no blocked status" explanations from Can't proceed. Co-authored-by: multica-agent <[email protected]> * refactor(workflow): state each step outcome as the status to set (MUL-8145) The moves block read like raw CLI ('Step done → multica issue status MUL-7 x'). Each outcome now says which status to set and that the server assigns the next handler; the CLI form is given once. Co-authored-by: multica-agent <[email protected]> * Revert "refactor(workflow): state each step outcome as the status to set (MUL-8145)" This reverts commit 2d82d2d342a99afe88cc40c48516b7ea8e860d1e. Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: multica-eve <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
b5477490e4 |
MUL-7376: fix(openclaw): preserve agent identity with persistent model overrides (#9223)
* fix(openclaw): carry per-run model override on the run input (INFRA-71) Reimplement MUL-7376 (#8419) on this fork and address the review points. Resolve runtime_config.model_override once, at claim time, and carry it on the run input (model_override); the daemon no longer decodes it from mutable agent config. OpenClaw keeps agent.model as the registered agent id (--agent) and the override as the underlying model (--model); arbitrary --model from custom_args stays blocked. Usage attribution falls back runtime model -> per-run override -> unknown, never the agent id. Round-trip model_override through the runtime-config schema, serializer, equality check and the runtime-config tab (i18n in all locales). Docs updated. Co-authored-by: multica-agent <[email protected]> * docs(openclaw): clarify persistent agent model overrides Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: multica-agent <[email protected]> Co-authored-by: Multica Eve <[email protected]> |
||
|
|
a47a1ced0c |
MUL-8240: fix(agent): keep Codex commentary out of output on empty final answer (#9521)
* fix(agent): keep Codex commentary out of output on empty final answer * test: pin empty-output completion and single result delivery |
||
|
|
b51f42c54b |
MUL-8200: fix(autopilot): don't fail create_issue runs on issue blocked (#9472)
* fix(autopilot): settle create_issue runs by first task outcome, not issue blocked (MUL-8200) Co-authored-by: multica-agent <[email protected]> * fix(autopilot): settle create_issue runs only from their own dispatch chain (MUL-8200 review) Co-authored-by: multica-agent <[email protected]> * fix(autopilot): root create_issue dispatch chain at the recorded task and let its outcome win (MUL-8200 re-review) Co-authored-by: multica-agent <[email protected]> * fix(autopilot): resolve unlinked create_issue dispatch by agent and wait for pending enqueue (MUL-8200 review) Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: multica-agent <[email protected]> |
||
|
|
4dc39434ef |
MUL-8198: fix(daemon): keep pre-588 Remote MCP tokens working for their issuing owner (#9469)
Co-authored-by: multica-agent <[email protected]> |
||
|
|
76dfd4a58b |
MUL-8186: treat process exit as terminal signal on OpenCode 2.x (#9463)
* fix(opencode): treat process exit as the terminal signal on 2.x
OpenCode 2.x stops consuming step events once the session settles, so the
final step_finish is routinely never written. The daemon failed those
completed runs as 'step still open at EOF' / 'continuation never started',
classified them provider_network and auto-retried, repeating side effects.
On built-in 2.x runtimes, waive the two step-bracketing guards and let the
process outcome decide: exit code, error events, prompt write, cancel /
timeout and scanner errors still fail the run. The void-step guard stays.
1.x and custom runtimes are unchanged.
Also decode the 2.x error payload ({type, message}) so failures surface
their real cause instead of 'unknown opencode error'.
Refs #8892, #9456
Co-authored-by: multica-agent <[email protected]>
* fix(opencode): address review on 2.x terminal-signal relaxation
- Clear the void-step flag on 2.x once later text or a tool call shows the
run recovered, since the recovering step may never report step_finish.
1.x still requires that step to close.
- Never report stream-level completion (sawTerminalSignal) on 2.x: an
intermediate step_finish is not proof the run finished, so a failed
prompt write keeps failing the run.
Refs #9463
Co-authored-by: multica-agent <[email protected]>
---------
Co-authored-by: Multica Eve <[email protected]>
Co-authored-by: multica-agent <[email protected]>
|
||
|
|
04931df162 |
MUL-8174: fix OpenCode resume after host clock rollback (#9460)
* fix(opencode): retire future-dated resume sessions (MUL-8174) Co-authored-by: multica-agent <[email protected]> * fix(opencode): check resume clocks across CLI versions Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: Sol-Boy <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
79d801f45c |
MUL-8188: fail fast on Kiro panic and stop resuming undrivable sessions (#9458)
* fix(kiro): fail fast when the runtime panics mid-turn (MUL-8188) Kiro can panic inside its agent loop while the ACP process stays alive, so session/prompt never answered and the task hung until the 2h idle watchdog or a manual cancel. Watch stderr live for a panic header, abort the prompt, and surface the panic text. A resumed session that panics before its first message signals ResumeRejected so the daemon retries once on a fresh session. Co-authored-by: multica-agent <[email protected]> * fix(resume): stop re-resuming sessions the runtime cannot drive (MUL-8188) - taskfailure.UnresumableHistory matches "invalid conversation history", so the daemon's fresh-session retry, classifyPoisonedError and ResumeUnsafeFailure all treat Kiro's panic as resume-unsafe; the GetLastTaskSession / GetLastChatTaskSession text guards mirror it for rows written by older daemons. - A resumed run cancelled after >=5 minutes with zero agent output now retires its session: the daemon sends retired_session_id on cancel-ack and the server records it on the cancelled row (status CAS, never overwrites) and clears a chat pointer still naming it. Co-authored-by: multica-agent <[email protected]> * fix(resume): address review on retired sessions (MUL-8188) - Manual retry no longer revives a retired session: the exact-source rerun claim path now checks IsTaskSessionRetired (fails closed), still reuses the source workdir, and sets PriorSessionResumeUnavailable. - Silent-resume retirement measures awakeclock time, so host suspend (Windows monotonic clock counts through sleep) cannot retire a healthy session; adds a suspend regression test. - Handler tests use dbfx.Issue/Task and testutil.Call per AGENTS.md. Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: multica-agent <[email protected]> |
||
|
|
ebc7c4696b |
fix(taskfailure): exclude letters in HTTP status code boundaries (#9150)
The failure classifier's status-code regexes guarded against longer numbers only: `(^|[^0-9])(429|529)([^0-9]|$)` and friends. Workspace and task IDs are hex, so a path like ~/multica_workspaces_x/<slug>-0000c429f4b/<task>/worktree embeds "429" between letters, which passed the digit-only guard — and the capacity rule runs before the process-failure and unknown rules. Every failed task quoting such a path was labeled agent_error.provider_capacity_or_rate_limit, sending users to check their provider accounts for a 429 no provider ever returned. The same gap misfiled paths containing hex "401"/"402"/"403"/"5xx" into the auth, quota and server-error buckets. Widen all five boundary guards (capacity, auth, quota, 5xx, and the 403 usage-limit regex shared with NormalizeDaemonReason) from `[^0-9]` to `[^0-9a-z]`. The classifier lowercases its input before matching, so letters are the only remaining embedded context to exclude. Genuine status codes (space/punctuation-delimited, or bare) still match. The MUL-1949 offline backfill SQL these patterns mirror is not in this repo; regenerating it needs the same widened boundary to stay in lock-step (noted in the pattern comments). Fixes #9146 Generated-by: GLM-5.3-Flash (ZCode) |
||
|
|
ff674c4e1d |
MUL-8185: Support sharing runtimes with specific members (#9455)
* feat: share runtimes with selected workspace members Co-authored-by: multica-agent <[email protected]> * refactor(runtimes): one-click private/public and popover member picker Private and Public apply immediately again (restrictions still go through the reviewed revocation dialog). Specific members opens a draft popover with search, Cancel and Save; selected recipients are summarized under the scope control with an Edit entry point. The editor moves to its own runtime-access-editor component. Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: multica-agent <[email protected]> |
||
|
|
f9036be46a |
MUL-8184 Fix Hermes reasoning options for non-default models (#9452)
* fix(agent): discover Hermes reasoning options per model * refactor(agent): extract per-model ACP effort probe Move the discovery loop out of discoverACPModels into probeACPModelEffort beside the other ACP effort helpers, and have acpOptionsAfterModelSwitch return nil when the runtime exposes no post-switch state so callers no longer re-check the response. Hermes execution only refreshes options when a thinking level is set, which is the only consumer of the result. * test(agent): trim Hermes effort regression tests |
||
|
|
72d9058cc6 |
feat(telemetry): add visiting and delegating member counts (MUL-8161) (#9435)
* feat(telemetry): report visiting and delegating member counts in self-host snapshot v2 (MUL-8161) Co-authored-by: multica-agent <[email protected]> * fix(telemetry): count delegating members from a human-action ledger, drop v1 fallback (MUL-8161) - member_delegation_day records (member, UTC day) at the human action itself, so retries, system wakeups and creator-fallback runs never count, and a comment folded into a queued run keeps both humans and their own days. - Activity read failures now fail collection and use the existing retry instead of silently sending a v1 snapshot. Co-authored-by: multica-agent <[email protected]> * fix(telemetry): record create-with-assignee, honor DO_NOT_TRACK, build ledger PK concurrently (MUL-8161) - A member creating an issue assigned to an agent or squad now records a delegation day, on both the immediate and deferred create paths. - TaskService.RecordMemberActivity gates the ledger and is set from the startup telemetry config, so DO_NOT_TRACK stops collection too. - member_delegation_day's primary key is built with CREATE UNIQUE INDEX CONCURRENTLY + PRIMARY KEY USING INDEX (589-591), with cleanup registered. Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: multica-agent <[email protected]> |
||
|
|
88de9d3713 |
feat(agent): surface Hermes dependency reinstall at launch (MUL-8124) (#9434)
* feat(agent): surface Hermes dependency reinstall at launch (MUL-8124, GH #9390) Hermes prints its launch-time dependency sync only to stderr, which the daemon forwards at Debug, so the 30-60s rebuild that the per-task Hermes home triggers when the user's home enables a memory plugin with Python deps was invisible. Log one Warn when Hermes starts reinstalling (with HERMES_HOME and a hint) and one when the ACP handshake returns, with the measured startup delay. Task outcome is unchanged. Document the cause and the memory.provider workaround in troubleshooting. Co-authored-by: multica-agent <[email protected]> * fix(agent): log Hermes reinstall finish when stderr lags the handshake (MUL-8124) stdout and stderr are drained independently, so initialize can return before the stderr copier reaches the reinstall marker Hermes wrote first. Finish then saw no detection and the finish log was lost. Record the handshake result and time in Finish, and emit the finish log when the second of (marker, handshake) arrives. Measure the delay from launch to handshake so it no longer depends on pipe ordering. Adds the reviewer's repro as an Execute-level regression test plus a unit test. Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: multica-agent <[email protected]> |
||
|
|
13eb4bda93 |
MUL-8154 fix(daemon): enforce runtime ownership on daemon routes (#9423)
* fix(daemon): enforce runtime ownership on daemon routes (MUL-8154) /api/daemon/* accepts any workspace member's PAT/JWT, and authorization only checked workspace membership. Any member could claim another member's tasks (receiving the agent's custom_env, MCP config and an owner-scoped task token), write task results/messages, and take a runtime over by re-registering its daemon_id. - Runtime-level check on every runtime/task daemon route, HTTP heartbeat, deregister, batch claim (and so the WS claim RPC) and the WS handshake: user credentials must own the runtime (NULL owner fails closed); daemon tokens must match a non-empty runtime daemon_id. - Register: pre-check that every existing row on the daemon_id belongs to the caller, plus a required_owner_id fence in both upserts (incl. the failed-profile path) so a concurrent registration cannot win the row. Daemon-token registration keeps the existing owner. - Legacy merge: only for user-credential registrations, and only when the caller owns both rows, verified on the FOR UPDATE-locked rows. - Tasks without a runtime are not writable through daemon routes; status stays readable. - GetTaskStatus / WS lease queries carry runtime owner/daemon so the hot paths keep one round trip. Co-authored-by: multica-agent <[email protected]> * test(daemon): authenticate fixtures as the runtime owner (MUL-8154) Most handler tests drove daemon routes with a daemon token whose daemon_id did not match the fixture runtime, relying on the workspace-wide token scope this fix removes. They now authenticate the way real daemons do, with the runtime owner's user credential (newOwnerDaemonRequest). Tests about daemon token scoping keep mdt_ and get fixtures with a matching daemon_id; the ownerless-runtime tests also assert that a user credential is refused. Co-authored-by: multica-agent <[email protected]> * fix(daemon): serialize registration per daemon and keep Qoder WS claims working (MUL-8154) Review of #9423: - P1: the owner pre-check and the per-provider/profile upserts hit different conflict keys, so two members registering different providers of the same daemon could both pass the pre-check and both insert, leaving one daemon with two owners (and a daemon token for either runtime reaching the other's). Registration now runs the pre-check and every runtime write in one transaction under a pg_advisory_xact_lock on (workspace_id, daemon_id), on a single connection so queued registrations cannot starve the holder. Legacy merges, analytics and the register event run after commit; failed-profile records use savepoints so they stay best-effort. - P2: the Qoder revocation check read the Authorization header, which the WS RPC bridge's in-process request does not carry, so valid Qoder WS claims silently returned nothing. DaemonAuth now records the mdt_ token hash in the request context, the WS identity keeps it, the RPC bridge re-attaches it, and the check validates that hash on every call (revocation still applies to an open connection). - Regression tests for cross-provider and provider+profile concurrent registration, and for valid/revoked Qoder credentials over WS RPC. Co-authored-by: multica-agent <[email protected]> * fix(daemon): bind daemon tokens to the runtime owner they were issued for (MUL-8154) Second review of #9423: a daemon_id can be re-registered by another member after its runtimes are deleted, and a daemon token was bound only to (workspace, daemon_id), so the previous owner's Remote MCP token reached the new owner's runtime (heartbeat, claim, owner-scoped task token). - daemon_token.owner_id (migration 588). Remote MCP tokens are bound to the locked runtime owner inside FinalizeTaskClaim; live tokens are backfilled only where their daemon has exactly one owner. - DaemonAuth carries the owner binding (DB and cache; cache key bumped to v2 so pre-upgrade entries are never read), the WS identity keeps it and the RPC bridge replays it. - Daemon-token authorization now also requires token owner == runtime owner. Qoder-managed tokens stay unbound (governed by cloud_agent_connection), and user credentials can no longer register the reserved qoder-managed-* ids. - Tests: the reuse lifecycle over HTTP, a new WS handshake and an already open WS connection; the reserved daemon_id; the concurrency barrier now hooks the registration transaction (TxStarter) so the interleaving is real. Co-authored-by: multica-agent <[email protected]> * fix(daemon): owner-bind daemon-token registration; drop unsafe token backfill (MUL-8154) Third review of #9423: - Migration 588 no longer backfills daemon_token.owner_id from the daemon's current owner: that owner may be a later re-registrant, which re-bound the previous owner's live token to them. Existing non-Qoder tokens stay NULL and are refused (24h Remote MCP credentials, re-issued on the next claim). - owner_id is a plain UUID column, no foreign key / cascade (AGENTS.md). - Register via a non-Qoder daemon token now uses the token's owner for the in-transaction pre-check and the SQL owner fence, and refuses unbound tokens. Qoder keeps its connection-based check; daemon tokens still never trigger legacy merges. - Tests: an old owner's bound token and an unbound legacy token can neither register over nor heartbeat the replacement owner's runtime. Co-authored-by: multica-agent <[email protected]> * fix(daemon): grant the Qoder registration exemption only with a live connection (MUL-8154) Fourth review of #9423: register skipped the token owner binding for any qoder-managed-* daemon token, but checked the Qoder connection only when the body declared a qoder_cloud runtime. A pre-upgrade Remote MCP token under that prefix (no owner, no connection) could register type=claude and rewrite another member's runtime. Register now verifies the token against a live cloud_agent_connection before anything else whenever the token is in the Qoder namespace, regardless of the declared runtimes, and restricts that namespace to the bridge's own shape: a built-in qoder_cloud runtime, no custom profiles, no failed_profiles. Test covers built-in, custom-profile, failed-profiles-only and qoder_cloud bodies with an unconnected token, plus the connected token's allowed and refused shapes. Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: multica-eve <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
4b645a354c |
fix(agent): clarify opaque Kimi turn failures (MUL-8157) (#9431)
Co-authored-by: Yushen <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
2b6db0d2b8 |
fix(cursor): resume stalled provider connections with bounded retries (MUL-7968) (#9180)
* fix(cursor): recover stalled provider connections with session resume * fix(cursor): exclude diagnostic counts from provider error classification * fix(cursor): ignore stack locations when classifying transport errors |
||
|
|
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]> |
||
|
|
2b64569138 |
MUL-8126: feat(agent): steer running Kiro turns via _session/steer (#9396)
* feat(agent): support steering running Kiro turns via _session/steer Kiro CLI 2.33.0 exposes an undocumented ACP extension, _session/steer, that queues a message and injects it into the in-flight session/prompt at the next tool or message boundary. Wire it up as the kiro backend's Session.Supplement (active only while the prompt is in flight, and only when the daemon negotiated task supplements), and gate kiro >= 2.33.0 in SupportsTaskSupplement. MUL-8126 Co-authored-by: multica-agent <[email protected]> * fix(supplement): allow kiro in server-side steering whitelists The capability handshake (StartAgentTaskWithSupplement), direct steering (CreateTaskSupplement) and composer reply binding (BindCommentTaskSupplement) each whitelist providers, and none included kiro, so a negotiated Kiro run never got a capability row and steering stayed unreachable. Add kiro to all three, regenerate sqlc, and cover kiro in the negotiation and both delivery path tests. Also widen the kiro supplement test's readiness wait, which was flaky under full-package parallel load. MUL-8126 Co-authored-by: multica-agent <[email protected]> * fix(supplement): allow grok in composer reply binding BindCommentTaskSupplement was the only steering whitelist without grok, so a reply from the normal composer to a running Grok turn fell back to the next run even though direct steering worked. Add grok and cover it in the composer binding test. MUL-8126 Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: multica-agent <[email protected]> |
||
|
|
0beaeddc0e |
MUL-8120 feat(workflows): owner-based workflow edit/delete permissions (#9388)
* MUL-8120 feat(workflows): record workflow owner and let owners edit their workflows Any workspace member may now create a workflow and becomes its owner. Editing, deleting and changing handoffs is open to the owner and to workspace owners/admins. Default has no owner and stays admin-only. Copying a workflow for one project now also requires managing that project. Migration 585 adds issue_workflow.owner_id and backfills existing named workflows with the workspace's earliest owner. Co-authored-by: multica-agent <[email protected]> * MUL-8120 feat(workflows): mirror owner-based workflow permissions in the UI Members can create and duplicate workflows; the editor, column handoff and flow panel are editable by the workflow's owner and admins. The save-for-this-project option only shows to admins and the project lead. Co-authored-by: multica-agent <[email protected]> * MUL-8120 fix(workflows): only admins add statuses through workflow writes Workflow create/update could add statuses to the shared workspace catalog without a role check. Non-admins now get 403 status_create_forbidden when a step names a status that does not exist; reusing a status by key or by name stays open. Co-authored-by: multica-agent <[email protected]> * MUL-8120 fix(workflows): hide new-status for members in the workflow editor Members pick from existing statuses only. A template that needs statuses the workspace lacks shows which ones and keeps Save disabled until they are removed or an admin adds them. Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: multica-agent <[email protected]> |
||
|
|
984d8192ad |
fix(daemon): preserve Claude effort for unlisted models (MUL-8112) (#9392)
Co-authored-by: Sol-Boy <[email protected]> Co-authored-by: multica-agent <[email protected]> |
||
|
|
4152fed89f |
fix(opencode): discover v2 model thinking variants (ZIC-351) (#9365)
Co-authored-by: multica-agent <[email protected]> |
||
|
|
74281e313d |
fix(agent): deliver the copilot prompt on stdin (MUL-8105) (#9380)
* fix(agent): deliver the copilot prompt on stdin; name E2BIG start failures (MUL-8105) Copilot inlined the whole task prompt as -p <prompt>, so a thread above Linux's 131,072-byte MAX_ARG_STRLEN died at fork/exec with E2BIG (#9362). The prompt now rides stdin, mirroring the OpenCode move in #6552. startOwnedProcessTree also wraps oversized-command-line failures in ErrArgvLimitExceeded with an actionable remedy. Co-authored-by: multica-agent <[email protected]> * docs(agent): update copilotBackend comment for stdin prompt delivery (MUL-8105) Co-authored-by: multica-agent <[email protected]> --------- Co-authored-by: multica-agent <[email protected]> |
||
|
|
5b21b63fa8 |
fix(codex): attribute default-model usage (#9360)
Co-authored-by: multica-agent <[email protected]> |
||
|
|
d908e4882d |
MUL-6710: fix(runtimes): revoke access when making runtime private (#7580)
* fix(runtimes): revoke access when making runtime private * fix(runtimes): regenerate queries for workflow step --------- Co-authored-by: m2keloop <[email protected]> |
||
|
|
a790bc8c08 | fix(comments): retain delivered supplement root owners (#9061) |