@runfusion/fusion 0.33.0 → 0.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.js +1522 -996
- package/dist/client/.vite/manifest.json +63 -62
- package/dist/client/assets/{AgentDetailView-BACu9GYE.js → AgentDetailView-CFX3jxfA.js} +1 -1
- package/dist/client/assets/{AgentPermissionPolicyEditor-tNNlcCDk.js → AgentPermissionPolicyEditor-4tnYHS0-.js} +1 -1
- package/dist/client/assets/{AgentsView-CPpHwjn3.js → AgentsView-DnNWfwiY.js} +5 -5
- package/dist/client/assets/ChatView-rwl2O-s0.js +6 -0
- package/dist/client/assets/{DevServerView-BlxSS8Uu.js → DevServerView-C9fEzcFQ.js} +1 -1
- package/dist/client/assets/{DirectoryPicker-ioTzF36r.js → DirectoryPicker-Cwyr0Sl4.js} +1 -1
- package/dist/client/assets/{DocumentsView-CsDb8dPw.js → DocumentsView-gDWTMU2w.js} +1 -1
- package/dist/client/assets/{EvalsView-I0GhxVhm.js → EvalsView-Cw7D1x0W.js} +1 -1
- package/dist/client/assets/{ExperimentalAgentOnboardingModal-Cr6g_jok.js → ExperimentalAgentOnboardingModal-8yeOcqbX.js} +1 -1
- package/dist/client/assets/{GoalsView-DXJxe6D4.js → GoalsView-kRIhgAA6.js} +1 -1
- package/dist/client/assets/{InsightsView-BaIhzpvX.js → InsightsView-IHHikd5n.js} +1 -1
- package/dist/client/assets/{MemoryView-DlmcI0ca.js → MemoryView-pii3HOba.js} +1 -1
- package/dist/client/assets/{NodesView-vc4T0uCy.js → NodesView-CoDK14B3.js} +1 -1
- package/dist/client/assets/{PiExtensionsManager-C0ljxGbt.js → PiExtensionsManager-vH7EJ5JD.js} +1 -1
- package/dist/client/assets/{PluginManager-D27abRF-.js → PluginManager-PbkFQ0Nu.js} +1 -1
- package/dist/client/assets/{ResearchView-BSpDz8YN.js → ResearchView-Dp4g_BWq.js} +1 -1
- package/dist/client/assets/{SecretsView-BmCemEu8.js → SecretsView-Q8wES8_N.js} +1 -1
- package/dist/client/assets/SettingsModal-127YAB8c.js +31 -0
- package/dist/client/assets/{SettingsModal-DvmwpEUE.js → SettingsModal-DdUztATB.js} +1 -1
- package/dist/client/assets/{SetupWizardModal-CDfZpkB7.js → SetupWizardModal-BSAFiQpJ.js} +1 -1
- package/dist/client/assets/{SkillsView-BCpa_vud.js → SkillsView-Bj8KQQXB.js} +1 -1
- package/dist/client/assets/{StashRecoveryView-BYLja93K.js → StashRecoveryView-DvKN_b_k.js} +1 -1
- package/dist/client/assets/{TodoView-lbnG-8cZ.js → TodoView-C-cabt2D.js} +1 -1
- package/dist/client/assets/{dashboard-view-CY6MGQbI.js → dashboard-view-DrHb8VOl.js} +1 -1
- package/dist/client/assets/{folder-open-CZghG0dv.js → folder-open-CYVKFKAx.js} +1 -1
- package/dist/client/assets/index-Cuh_Pqv0.css +1 -0
- package/dist/client/assets/index-Cze5qbME.js +742 -0
- package/dist/client/assets/{upload-L7aDk8Xn.js → upload-eQh-mH3-.js} +1 -1
- package/dist/client/assets/{users-DoWKt94F.js → users-B5upejXg.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/client/version.json +1 -1
- package/dist/droid-cli/package.json +1 -1
- package/dist/extension.js +1078 -644
- package/dist/pi-claude-cli/package.json +1 -1
- package/dist/plugins/fusion-plugin-cli-printing-press/package.json +1 -1
- package/dist/plugins/fusion-plugin-cursor-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-dependency-graph/package.json +1 -1
- package/dist/plugins/fusion-plugin-droid-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-hermes-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-openclaw-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-paperclip-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-reports/package.json +1 -1
- package/dist/plugins/fusion-plugin-reports/src/dashboard/__tests__/ReportsView.test.tsx +15 -0
- package/dist/plugins/fusion-plugin-reports/src/dashboard/test-setup.ts +9 -1
- package/dist/plugins/fusion-plugin-roadmap/package.json +1 -1
- package/dist/plugins/fusion-plugin-whatsapp-chat/package.json +1 -1
- package/package.json +1 -1
- package/skill/fusion/references/extension-tools.md +2 -0
- package/dist/client/assets/ChatView-CCAUA7HB.js +0 -6
- package/dist/client/assets/SettingsModal-m3KMs_uS.js +0 -31
- package/dist/client/assets/index-lDPXOH7J.css +0 -1
- package/dist/client/assets/index-tJzhtiGM.js +0 -742
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fusion/pi-claude-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.35.0",
|
|
4
4
|
"description": "Fusion vendored fork: pi coding-agent extension that routes LLM calls through the Claude Code CLI. Forked from rchern/pi-claude-cli (MIT). See UPSTREAM.md.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"private": true,
|
|
@@ -3,6 +3,21 @@ import { describe, expect, it, vi } from "vitest";
|
|
|
3
3
|
import * as reportsHook from "../useReports.js";
|
|
4
4
|
import { ReportsView } from "../ReportsView.js";
|
|
5
5
|
|
|
6
|
+
// ReportDetailPanel transitively calls useReportPreview → fetch(), and jsdom
|
|
7
|
+
// has no fetch. The rejection lands after teardown and React's state update
|
|
8
|
+
// then references `window`, surfacing as an unhandled error that fails the
|
|
9
|
+
// suite. Stub the preview API to resolve synchronously.
|
|
10
|
+
vi.mock("../api.js", () => ({
|
|
11
|
+
listReports: vi.fn().mockResolvedValue([]),
|
|
12
|
+
getReport: vi.fn().mockResolvedValue(null),
|
|
13
|
+
getReportPreviewHtml: vi.fn().mockResolvedValue(""),
|
|
14
|
+
getReportExportUrl: vi.fn().mockReturnValue(""),
|
|
15
|
+
approveReport: vi.fn().mockResolvedValue(null),
|
|
16
|
+
rejectReport: vi.fn().mockResolvedValue(null),
|
|
17
|
+
publishReport: vi.fn().mockResolvedValue(null),
|
|
18
|
+
getShareBlocks: vi.fn().mockResolvedValue({}),
|
|
19
|
+
}));
|
|
20
|
+
|
|
6
21
|
describe("ReportsView", () => {
|
|
7
22
|
it("renders list and compare toggle", () => {
|
|
8
23
|
vi.spyOn(reportsHook, "useReports").mockReturnValue({
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import "@testing-library/jest-dom/vitest";
|
|
2
|
-
import {
|
|
2
|
+
import { cleanup } from "@testing-library/react";
|
|
3
|
+
import { afterEach, vi } from "vitest";
|
|
4
|
+
|
|
5
|
+
// @testing-library/react only auto-registers cleanup when vitest globals are
|
|
6
|
+
// enabled. We don't enable globals here, so we wire it manually — otherwise
|
|
7
|
+
// React leaves the test tree mounted, its scheduler fires a deferred update
|
|
8
|
+
// via setImmediate after the jsdom environment is torn down, and the suite
|
|
9
|
+
// fails with "ReferenceError: window is not defined".
|
|
10
|
+
afterEach(() => cleanup());
|
|
3
11
|
|
|
4
12
|
if (typeof window !== "undefined") {
|
|
5
13
|
Object.defineProperty(window, "matchMedia", {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@runfusion/fusion",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.35.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Fusion CLI: HTTP API server, daemon, dashboard launcher, and task tooling for the Fusion AI coding agent.",
|
|
6
6
|
"homepage": "https://github.com/Runfusion/Fusion#readme",
|
|
@@ -132,6 +132,7 @@ Create a task via AI-guided planning mode — interactive conversation to refine
|
|
|
132
132
|
| Parameter | Type | Required | Description |
|
|
133
133
|
|-----------|------|----------|-------------|
|
|
134
134
|
| `description` | string | — | Initial plan description (optional) — the AI will ask clarifying questions if not provided |
|
|
135
|
+
| `baseBranch` | string | — | Optional base branch for the task created from this planning session |
|
|
135
136
|
|
|
136
137
|
## GitHub Tools
|
|
137
138
|
|
|
@@ -177,6 +178,7 @@ Create a new mission — a high-level objective that can span multiple milestone
|
|
|
177
178
|
| `title` | string | ✓ | Mission title — brief but descriptive |
|
|
178
179
|
| `description` | string | — | Detailed mission objectives and context |
|
|
179
180
|
| `autoAdvance` | boolean | — | Automatically activate the next pending slice when the current slice completes |
|
|
181
|
+
| `baseBranch` | string | — | Optional integration base branch for tasks triaged from this mission |
|
|
180
182
|
|
|
181
183
|
### fn_mission_list
|
|
182
184
|
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import{r as s,a as bn,j as t,R as vn}from"./vendor-react-K0fH_qHe.js";import{c as xn,a9 as Rs,a7 as As,bc as Es,bd as os,aF as Mt,be as Ts,ac as Is,bf as Zt,t as yn,bg as wn,bh as $s,bi as Sn,bj as es,w as Cn,bk as kn,bl as jn,bm as Nn,bn as Mn,bo as Rn,bp as An,bq as En,s as Tn,br as In,i as $n,k as Xs,bs as Dn,bt as Pn,bu as Js,bv as Fn,bw as Ln,bx as _n,p as zn,by as Hn,bz as Un,u as On,bA as Bn,ah as Ys,ai as Qs,bB as Kn,bC as Gn,S as Wn,_ as ts,P as lt,J as ct,av as Vn,bD as Ds,a as Ct,bE as Ps,bF as Fs,bG as Ls,B as dt,ae as qn,af as Xn,b1 as Rt,bH as Jn,bI as Yn,a_ as Qn,bJ as _s,bK as Zn,T as ea,bL as zs,bM as ta,j as Hs,m as sa}from"./index-tJzhtiGM.js";import"./vendor-xterm-DzcZoU0P.js";import"./vendor-codemirror-jBKmHyH0.js";/**
|
|
2
|
-
* @license lucide-react v1.7.0 - ISC
|
|
3
|
-
*
|
|
4
|
-
* This source code is licensed under the ISC license.
|
|
5
|
-
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
-
*/const na=[["path",{d:"M5 3h14",key:"7usisc"}],["path",{d:"m18 13-6-6-6 6",key:"1kf1n9"}],["path",{d:"M12 7v14",key:"1akyts"}]],aa=xn("arrow-up-to-line",na),ss="kb-chat-active-session";function Us(n){const r=typeof n=="string"?n.trim():"",d=r.indexOf("/");return!r||d<=0||d>=r.length-1?{}:{modelProvider:r.slice(0,d),modelId:r.slice(d+1)}}function ra(n){const r=n?.toolCalls;if(!Array.isArray(r))return;const d=r.map(i=>{if(!i||typeof i!="object")return null;const f=i,p=typeof f.toolName=="string"?f.toolName:"";if(!p)return null;const S=f.args;return{toolName:p,...S&&typeof S=="object"?{args:S}:{},isError:!!f.isError,result:f.result,status:"completed"}}).filter(i=>i!==null);return d.length>0?d:void 0}function ia(n){const r=n?.fallback;if(!r||typeof r!="object")return;const d=r,i=typeof d.primaryModel=="string"?d.primaryModel:"",f=typeof d.fallbackModel=="string"?d.fallbackModel:"",p=d.triggerPoint;if(!(!i||!f||p!=="session-creation"&&p!=="prompt-time"))return{primaryModel:i,fallbackModel:f,triggerPoint:p}}function oa(n){const r=n?.failureInfo;if(!r||typeof r!="object")return;const d=r,i=typeof d.summary=="string"?d.summary.trim():"";if(!i)return;const f=(()=>{const p=d.reference;if(!p||typeof p!="object")return;const S=p,h=typeof S.kind=="string"?S.kind.trim():"",P=typeof S.id=="string"?S.id.trim():"";if(!(!h||!P))return{kind:h,id:P,...typeof S.label=="string"&&S.label.trim()?{label:S.label.trim()}:{}}})();return{summary:i,...typeof d.errorClass=="string"&&d.errorClass.trim()?{errorClass:d.errorClass.trim()}:{},...typeof d.code=="string"&&d.code.trim()?{code:d.code.trim()}:{},...typeof d.detail=="string"&&d.detail.trim()?{detail:d.detail.trim()}:{},...f?{reference:f}:{}}}function Os(n){return typeof n=="string"?{summary:n.trim()||"Failed to get response"}:{summary:typeof n.summary=="string"&&n.summary.trim()?n.summary.trim():"Failed to get response",...typeof n.errorClass=="string"&&n.errorClass.trim()?{errorClass:n.errorClass.trim()}:{},...typeof n.code=="string"&&n.code.trim()?{code:n.code.trim()}:{},...typeof n.detail=="string"&&n.detail.trim()?{detail:n.detail.trim()}:{},...n.reference?{reference:n.reference}:{}}}function ns(n){return{id:n.id,sessionId:n.sessionId,role:n.role,content:n.content,thinkingOutput:n.thinkingOutput,toolCalls:ra(n.metadata),fallbackInfo:ia(n.metadata),failureInfo:oa(n.metadata),attachments:n.attachments,createdAt:n.createdAt}}function ca(n,r){const d=s.useCallback(l=>l?`${Rs.CHAT_SESSIONS_PREFIX}${l}`:null,[]),i=s.useCallback((l,u)=>l&&u?`${Rs.CHAT_MESSAGES_PREFIX}${l}:${u}`:null,[]),f=s.useCallback(l=>{const u=d(l);return u?As(u,{maxAgeMs:Es})??[]:[]},[d]),[p,S]=s.useState(()=>f(n)),[h,P]=s.useState(null),[Q,Z]=s.useState(()=>f(n).length===0),[w,E]=s.useState([]),[H,C]=s.useState(!1),[ee,k]=s.useState(!1),[B,R]=s.useState(""),[q,L]=s.useState(""),[F,T]=s.useState([]),[te,M]=s.useState(""),[j,y]=s.useState(""),[g,c]=s.useState(!0),{agentsMap:Ce}=os(n),v=s.useRef(null),N=s.useRef(null),me=s.useRef(!1),ce=s.useRef(""),he=s.useRef(null),Ke=s.useRef(p),V=s.useRef(h),tt=s.useRef(w),W=s.useRef(ee);Ke.current=p,V.current=h,tt.current=w,W.current=ee,s.useEffect(()=>{ce.current=te},[te]);const $e=s.useRef(new Set),le=s.useRef(0),we=s.useRef(n);we.current!==n&&(Mt({view:"useChat",trigger:"project-context-change",projectId:n,replayAttempted:!1,detail:{previousProjectId:we.current??null}}),we.current=n,le.current++);const fe=s.useCallback(async()=>{Ke.current.length===0&&Z(!0);try{const u=[...(await Ts(n)).sessions].sort((I,X)=>new Date(X.updatedAt).getTime()-new Date(I.updatedAt).getTime());S(u);const b=d(n);b&&Is(b,u,{maxBytes:5e5})}catch{const l=f(n);if(Ke.current.length===0&&l.length===0){const u=d(n);u&&Zt(u)}}finally{Z(!1)}},[d,n]);s.useEffect(()=>{const l=f(n);S(l),Z(l.length===0)},[n,f]),s.useEffect(()=>{fe()},[fe,n]);const ut=s.useRef(()=>{}),Se=s.useRef(!1);s.useEffect(()=>{Se.current=!1,N.current=null},[n]),s.useEffect(()=>{if(Q||Se.current||V.current)return;const l=yn(ss,n);if(!l){Se.current=!0;return}const u=p.find(b=>b.id===l);if(u){Se.current=!0,ut.current(l,u);return}Se.current=!0},[Q,p,n]);const He=s.useCallback((l,u)=>{const b=i(l,u);return b?As(b,{maxAgeMs:Es})??[]:[]},[i]),ge=s.useCallback(l=>{const u=He(n,l);return u.length>0?(E(u),C(!1),!0):(E([]),!1)},[n,He]),ae=s.useCallback(async(l,u)=>{const b=typeof u?.offset=="number"&&u.offset>0,I=i(n,l),X=b?[]:He(n,l),A=X.length>0;!b&&A?(E(X),C(!1)):C(!0);try{const J=await wn(l,{limit:50,...u},n),U=J.messages.map(ns);b?E(O=>[...U,...O]):(E(U),I&&Is(I,U,{maxBytes:5e5})),c(J.messages.length>=50)}catch{!b&&tt.current.length===0&&A&&(E(X),C(!1))}finally{C(!1)}},[i,n,He]),Ue=s.useCallback(()=>{he.current?.(),he.current=null,ce.current="",M(""),R(""),L(""),T([]),k(!1)},[]),mt=s.useCallback(()=>{ce.current="",M("")},[]),se=s.useCallback(()=>{const l=ce.current.trim();l&&(ce.current="",M(""),ke.current(l))},[]),oe=s.useCallback((l,u,b)=>{if(v.current||!l)return!0;me.current=!1,u&&(R(u.streamingText),L(u.streamingThinking),T(u.toolCalls)),k(!0);const{handlers:I}=$s({sessionId:l,tempUserMessageId:"",setStreamingText:R,setStreamingThinking:L,setStreamingToolCalls:T,cancelStreamingFlushesRef:he,addToast:b?.silent?void 0:r,onFallbackSession:(A,J)=>{const U=Us(A.fallbackModel);S(O=>O.map(K=>K.id===J?{...K,...U}:K)),P(O=>O&&O.id===J?{...O,...U}:O)},onDone:()=>{R(""),L(""),T([]),k(!1),W.current=!1,v.current=null,N.current=null,ae(l),se()},onError:A=>{R(""),L(""),T([]),k(!1),W.current=!1,v.current=null,N.current=null;const J=Os(A);b?.silent||r?.(J.summary,"error"),ae(l),se()}});Mt({view:"useChat",trigger:"sse-open",projectId:n,replayAttempted:typeof u?.replayFromEventId=="number",replayFromEventId:u?.replayFromEventId??null,lastEventId:u?.replayFromEventId??null});const X=Sn(l,I,n,{...typeof u?.replayFromEventId=="number"?{lastEventId:u.replayFromEventId}:{}});return v.current=X,N.current={sessionId:l,replayFromEventId:typeof u?.replayFromEventId=="number"?u.replayFromEventId:null},!0},[r,ae,n,se]),xe=s.useCallback((l,u)=>{const b=V.current?.id??null;if(l&&b===l&&!u)return;v.current&&(v.current.close(),v.current=null),N.current=null;const I=u??p.find(X=>X.id===l);P(I||null),l&&es(l,n).then(({session:X})=>{!X.isGenerating||!X.inFlightGeneration||P(A=>!A||A.id!==l?A:{...A,...X})}).catch(()=>{}),Ue(),c(!0),l?(ge(l),ae(l)):E([]),I?.isGenerating&&oe(I.id,I.inFlightGeneration),l?Cn(ss,l,n):kn(ss,n)},[oe,ge,p,ae,n,Ue]);ut.current=xe;const De=s.useCallback(async l=>{const u=await jn(l,n);v.current&&(v.current.close(),v.current=null),N.current=null;const b={id:u.session.id,title:u.session.title,agentId:u.session.agentId,status:u.session.status,modelProvider:u.session.modelProvider,modelId:u.session.modelId,createdAt:u.session.createdAt,updatedAt:u.session.updatedAt};return S(I=>I.some(X=>X.id===b.id)?I:[b,...I]),Ue(),xe(b.id,b),b},[n,Ue,xe]),st=s.useCallback(async l=>{await Nn(l,{status:"archived"},n),S(u=>u.filter(b=>b.id!==l)),h?.id===l&&(N.current=null,P(null),E([]))},[h,n]),Ge=s.useCallback(async l=>{h?.id===l&&v.current&&(v.current.close(),v.current=null),h?.id===l&&(N.current=null),await Mn(l,n);const u=i(n,l);u&&Zt(u),S(b=>b.filter(I=>I.id!==l)),h?.id===l&&(P(null),E([]))},[h,i,n]),We=s.useCallback(async()=>{!h||!g||await ae(h.id,{offset:w.length})},[h,g,ae,w.length]),Oe=s.useCallback(()=>{h&&(me.current=!0,he.current?.(),he.current=null,v.current?.close(),v.current=null,N.current=null,Rn(h.id,n).catch(()=>{}),k(!1),W.current=!1,R(""),L(""),T([]),se())},[h,n,se]),ke=s.useRef(()=>{}),je=An(),pe=s.useCallback(async l=>{try{await fe();const u=await es(l,n);V.current?.id===l&&P(b=>!b||b.id!==l?b:{...b,...u.session}),u.session.isGenerating?(R(""),L(""),T([]),k(!0),W.current=!0,oe(l,u.session.inFlightGeneration,{silent:!0})):(R(""),L(""),T([]),k(!1),W.current=!1,await ae(l))}catch{}},[oe,ae,n,fe]),Ne=s.useCallback((l,u)=>{if(!h)return;if(W.current){ce.current=l,M(l);return}me.current=!1,v.current&&(v.current.close(),v.current=null),N.current=null;const b=`temp-${Date.now()}`,I={id:b,sessionId:h.id,role:"user",content:l,createdAt:new Date().toISOString()};E(A=>[...A,I]),R(""),L(""),T([]),k(!0);const{handlers:X}=$s({sessionId:h.id,tempUserMessageId:b,setStreamingText:R,setStreamingThinking:L,setStreamingToolCalls:T,cancelStreamingFlushesRef:he,addToast:r,onFallbackSession:(A,J)=>{const U=Us(A.fallbackModel);S(O=>O.map(K=>K.id===J?{...K,...U}:K)),P(O=>O&&O.id===J?{...O,...U}:O)},onDone:({messageId:A,message:J,accumulated:U})=>{const O=J?{...ns(J),...U.text.length>0?{content:U.text}:{}}:{id:A||`msg-${Date.now()}`,sessionId:h.id,role:"assistant",content:U.text,thinkingOutput:U.thinking,toolCalls:U.toolCalls.length>0?U.toolCalls:void 0,fallbackInfo:U.fallbackInfo,createdAt:new Date().toISOString()};$e.current.add(O.id),E(K=>[...K,O]),R(""),L(""),T([]),k(!1),W.current=!1,v.current=null,N.current=null,setTimeout(()=>{$e.current.delete(O.id)},1e3),fe(),se()},onError:(A,J)=>{const U=Os(A),O=typeof A=="string"?A:U.summary,K=In(O);E(G=>{const D=G.filter(Y=>Y.id!==J);return K?D:[...D,{id:`error-${Date.now()}`,sessionId:h.id,role:"assistant",content:U.summary,failureInfo:U,createdAt:new Date().toISOString()}]}),R(""),L(""),T([]),k(!1),W.current=!1,v.current=null,N.current=null,console.error("[useChat] Stream error:",A),K?(console.info("[useChat] Suppressed tab-suspension stream error:",A),h?.id&&(R(""),L(""),T([]),k(!0),W.current=!0,pe(h.id))):(r?.(U.summary,"error"),fe()),me.current||se()}});v.current=En(h.id,l,X,u,n)},[h,n,fe,r,oe,pe,se]);ke.current=Ne;const Ve=j?p.filter(l=>l.title?.toLowerCase().includes(j.toLowerCase())||l.agentId.toLowerCase().includes(j.toLowerCase())):p;return s.useEffect(()=>{if(!h?.id||h.isGenerating!==!0||v.current)return;const l=typeof h.inFlightGeneration?.replayFromEventId=="number"?h.inFlightGeneration.replayFromEventId:null,u=N.current;u?.sessionId===h.id&&u.replayFromEventId===l||oe(h.id,h.inFlightGeneration,{silent:!0})},[h?.id,h?.isGenerating,h?.inFlightGeneration,oe]),s.useEffect(()=>{if(!V.current?.isGenerating||(v.current||oe(V.current.id,V.current.inFlightGeneration),!W.current||v.current||!V.current))return;const l=setInterval(async()=>{if(!W.current||v.current||!V.current){clearInterval(l);return}try{(await Ts(n)).sessions.find(I=>I.id===V.current?.id)?.isGenerating||(clearInterval(l),await ae(V.current.id),R(""),L(""),T([]),k(!1),W.current=!1,se())}catch{}},3e3);return()=>clearInterval(l)},[oe,ae,n,h,se]),s.useEffect(()=>je.onBecameVisible(()=>{const u=V.current;if(!u||v.current)return;const b=le.current;es(u.id,n).then(I=>{if(!(le.current!==b||v.current)){if(I.session.isGenerating){R(""),L(""),T([]),k(!0),W.current=!0,oe(u.id,I.session.inFlightGeneration,{silent:!0});return}W.current&&(R(""),L(""),T([]),k(!1),W.current=!1,se(),ae(u.id))}}).catch(()=>{})}),[oe,ae,n,je,se]),s.useEffect(()=>{const l=le.current,u=n?`?projectId=${encodeURIComponent(n)}`:"",b=()=>le.current!==l,I=K=>{if(b())return;const G=JSON.parse(K.data);S(D=>D.some(Y=>Y.id===G.id)?D:[G,...D])},X=K=>{if(b())return;const G=JSON.parse(K.data);S(D=>[...D.map(re=>re.id===G.id?G:re)]),V.current?.id===G.id&&(P(G),G.isGenerating&&!v.current&&oe(G.id,G.inFlightGeneration))},A=K=>{if(b())return;const{id:G}=JSON.parse(K.data);S(Y=>Y.filter(re=>re.id!==G));const D=i(n,G);D&&Zt(D),V.current?.id===G&&(P(null),E([]))},J=K=>{if(b())return;const G=JSON.parse(K.data),D=ns(G);if(!$e.current.has(D.id)){if(V.current?.id===D.sessionId&&W.current&&!v.current&&D.role==="assistant"){E(Y=>Y.some(re=>re.id===D.id)?Y:[...Y,D]),R(""),L(""),T([]),k(!1),W.current=!1,se();return}V.current?.id===D.sessionId&&!W.current&&E(Y=>{if(Y.some(re=>re.id===D.id))return Y;if(D.role==="user"){const re=Y.findIndex(de=>de.role==="user"&&de.id.startsWith("temp-")&&de.content.trim()===D.content.trim());if(re>=0){const de=[...Y];return de[re]=D,de}}return[...Y,D]})}},U=K=>{if(b())return;const{id:G}=JSON.parse(K.data);E(D=>D.filter(Y=>Y.id!==G))};return Tn(`/api/events${u}`,{events:{"chat:session:created":I,"chat:session:updated":X,"chat:session:deleted":A,"chat:message:added":J,"chat:message:deleted":U}})},[oe,i,n,se]),s.useEffect(()=>()=>{v.current&&(v.current.close(),v.current=null),N.current=null},[]),{sessions:p,activeSession:h,sessionsLoading:Q,messages:w,messagesLoading:H,isStreaming:ee,streamingText:B,streamingThinking:q,streamingToolCalls:F,pendingMessage:te,selectSession:xe,createSession:De,archiveSession:st,deleteSession:Ge,sendMessage:Ne,stopStreaming:Oe,clearPendingMessage:mt,loadMoreMessages:We,hasMoreMessages:g,searchQuery:j,setSearchQuery:y,filteredSessions:Ve,refreshSessions:fe,agentsMap:Ce}}function la(n,r=[]){const d=n.trim().replace(/^#/,"");if(!d)return{ok:!1,error:"Room name is required."};if(/[A-Z]/.test(d))return{ok:!1,error:"Use lowercase letters only."};const i=d.toLowerCase();return i.length>80?{ok:!1,error:"Room names can be at most 80 characters."}:/^[a-z0-9_-]+$/.test(i)?/^[-_]|[-_]$/.test(i)?{ok:!1,error:"Room names cannot start or end with a hyphen or underscore."}:r.some(f=>f.toLowerCase()===i)?{ok:!1,error:"A room with this name already exists."}:{ok:!0,name:i}:{ok:!1,error:"Use lowercase letters, numbers, hyphens, or underscores only."}}function da({isOpen:n,onClose:r,onCreate:d,projectId:i,existingRoomNames:f=[]}){const[p,S]=s.useState(""),[h,P]=s.useState([]),[Q,Z]=s.useState(""),[w,E]=s.useState([]),[H,C]=s.useState(!1),[ee,k]=s.useState(null),[B,R]=s.useState(!1),q=s.useRef(null),L=s.useRef(null);s.useEffect(()=>{n&&(L.current=document.activeElement instanceof HTMLElement?document.activeElement:null,C(!0),k(null),$n(void 0,i).then(g=>P(g)).catch(()=>{P([]),k("Failed to load agents.")}).finally(()=>C(!1)))},[n,i]),s.useEffect(()=>{if(!n){S(""),Z(""),E([]),k(null),R(!1);return}const g=window.requestAnimationFrame(()=>q.current?.focus());return()=>window.cancelAnimationFrame(g)},[n]),s.useEffect(()=>{if(!n)return;const g=c=>{c.key==="Escape"&&r()};return document.addEventListener("keydown",g),()=>document.removeEventListener("keydown",g)},[n,r]),s.useEffect(()=>{n||L.current?.focus()},[n]);const F=s.useMemo(()=>la(p,f),[p,f]),T=s.useMemo(()=>{const g=Q.trim().toLowerCase();return g?h.filter(c=>c.name.toLowerCase().includes(g)):h},[h,Q]),te=s.useMemo(()=>h.filter(g=>w.includes(g.id)),[h,w]),M=F.ok&&w.length>0&&!B&&!H;if(!n)return null;const j=g=>{B||E(c=>c.includes(g)?c.filter(Ce=>Ce!==g):[...c,g])},y=async()=>{if(!F.ok){k(F.error);return}if(w.length===0){k("Select at least one member.");return}k(null),R(!0);try{await d({name:F.name,displayName:`#${F.name}`,memberAgentIds:w}),r()}catch(g){k(g instanceof Error?g.message:"Failed to create room.")}finally{R(!1)}};return bn.createPortal(t.jsx("div",{className:"modal-overlay open",onClick:g=>g.target===g.currentTarget&&r(),children:t.jsxs("div",{className:"modal modal-lg create-room-modal",role:"dialog","aria-modal":"true","aria-label":"Create room",onClick:g=>g.stopPropagation(),children:[t.jsxs("div",{className:"modal-header",children:[t.jsx("h3",{children:"Create room"}),t.jsx("button",{type:"button",className:"modal-close","aria-label":"Close",onClick:r,children:"×"})]}),t.jsxs("div",{className:"form-group create-room-modal-name-group",children:[t.jsx("label",{htmlFor:"create-room-name",children:"Room name"}),t.jsxs("div",{className:"create-room-modal-name-field",children:[t.jsx("span",{"aria-hidden":"true",className:"create-room-modal-name-hash",children:"#"}),t.jsx("input",{ref:q,id:"create-room-name",className:"input",value:p,disabled:B,onChange:g=>{const c=g.target.value.replace(/^#/,"").replace(/\s+/g,"-").toLowerCase();S(c)}})]}),!F.ok&&t.jsx("div",{className:"form-error",children:F.error})]}),t.jsxs("div",{className:"form-group",children:[t.jsx("label",{htmlFor:"create-room-member-search",children:"Members"}),t.jsx("input",{id:"create-room-member-search",className:"input",placeholder:"Search agents",value:Q,disabled:B,onChange:g=>Z(g.target.value)})]}),te.length>0&&t.jsx("div",{className:"create-room-modal-selected","data-testid":"create-room-selected-chips",children:te.map(g=>t.jsxs("button",{type:"button",className:"btn btn-sm create-room-modal-chip",onClick:()=>j(g.id),disabled:B,children:[g.name," ×"]},g.id))}),t.jsx("div",{className:"create-room-modal-member-list","data-testid":"create-room-member-list",children:H?t.jsx("div",{className:"create-room-modal-empty",children:"Loading agents..."}):T.length===0?t.jsx("div",{className:"create-room-modal-empty",children:h.length===0?"No agents in this project yet.":"No agents match your search."}):T.map(g=>{const c=w.includes(g.id);return t.jsxs("button",{type:"button",className:`create-room-modal-member-row${c?" create-room-modal-member-row--selected":""}`,onClick:()=>j(g.id),disabled:B,children:[t.jsx(Xs,{agent:g,size:20}),t.jsx("span",{children:g.name}),t.jsx("span",{className:"create-room-modal-member-role",children:g.role})]},g.id)})}),ee&&t.jsx("div",{className:"form-group",children:t.jsx("div",{className:"form-error",children:ee})}),t.jsxs("div",{className:"modal-actions",children:[t.jsx("button",{type:"button",className:"btn",onClick:r,disabled:B,children:"Cancel"}),t.jsx("button",{type:"button",className:"btn btn-primary",onClick:()=>void y(),disabled:!M,children:B?"Creating...":"Create room"})]})]})}),document.body)}const ua=640;let as=!1;function ma(n){return Math.max(40,Math.min(n,ua))}function Zs(n){const r=new Date(n),i=new Date().getTime()-r.getTime(),f=Math.floor(i/1e3),p=Math.floor(f/60),S=Math.floor(p/60),h=Math.floor(S/24);return f<60?"just now":p<60?`${p}m ago`:S<24?`${S}h ago`:h<7?`${h}d ago`:r.toLocaleDateString()}function Bs(n,r){if(!n||!r)return null;const d=r.toLowerCase();if(d.includes("claude")){let f=r.replace(/^claude[- ]/i,"Claude ").replace(/sonnet[- ](\d+)[- ](\d+)/i,"Sonnet $1.$2").replace(/sonnet[- ](\d+)/i,"Sonnet $1").replace(/haiku[- ](\d+)/i,"Haiku $1").replace(/opus[- ](\d+)/i,"Opus $1").replace(/sonnet/i,"Sonnet").replace(/haiku/i,"Haiku").replace(/opus/i,"Opus").replace(/-/g," ").trim();return f=f.replace(/\s+/g," "),f.length>30?f.slice(0,30)+"…":f}if(d.includes("gpt")||d.includes("openai")){const f=r.replace(/^gpt-4-turbo$/i,"GPT-4 Turbo").replace(/^gpt-4o-mini$/i,"GPT-4o Mini").replace(/^gpt-4o$/i,"GPT-4o").replace(/^gpt-4$/i,"GPT-4").replace(/^gpt-o1-preview$/i,"GPT-o1 Preview").replace(/^gpt-o1-mini$/i,"GPT-o1 Mini").replace(/^gpt-o1$/i,"GPT-o1").replace(/^gpt/i,"GPT").trim();return f.length>30?f.slice(0,30)+"…":f}if(d.includes("gemini")){const f=r.replace(/^gemini[- ]/i,"Gemini ").replace(/pro[- ](\d+)[- ](\d+)/i,"Pro $1.$2").replace(/pro[- ](\d+)/i,"Pro $1").replace(/-/g," ").replace(/\s+/g," ").trim();return f.length>30?f.slice(0,30)+"…":f}const i=r.replace(/-/g," ").replace(/^\w/,f=>f.toUpperCase()).replace(/\s+/g," ").trim();return i.length>30?i.slice(0,30)+"…":i}function Nt(n,r){return n.length<=r?n:`${n.slice(0,r)}…`}function ha(n){if(!n)return null;const r=Object.entries(n);return r.length===0?null:r.map(([d,i])=>{const f=typeof i=="string"?i:(()=>{try{return JSON.stringify(i)}catch{return String(i)}})();return`${d}=${Nt(f,50)}`}).join(", ")}function fa(n){if(n===void 0)return null;if(typeof n=="string")return Nt(n,200);try{return Nt(JSON.stringify(n),200)}catch{return Nt(String(n),200)}}function ga(n){if(!n)return null;if(n.kind==="mailbox"||n.kind==="mailbox-message"){const r=typeof window>"u"?"/":window.location.pathname||"/",d=new URLSearchParams(typeof window>"u"?"":window.location.search);return d.set("view","mailbox"),d.set("mailbox-message",n.id),`${r}?${d.toString()}#message-${encodeURIComponent(n.id)}`}return null}function pa(n){if(!n)return null;const r=n.label??`${n.kind} ${n.id}`,d=ga(n),i=`chat-failure-reference-${n.kind}-${n.id}`.replace(/[^a-zA-Z0-9_-]+/g,"-").toLowerCase();return t.jsxs("div",{className:"chat-message-failure-reference",children:[t.jsx("span",{className:"chat-message-failure-reference-label",children:"Reference"}),t.jsx("span",{className:"chat-message-failure-reference-value",children:r}),d?t.jsx("a",{className:"btn btn-sm chat-message-failure-reference-link",href:d,children:"Open mailbox message"}):t.jsxs("details",{className:"chat-message-failure-reference-details",children:[t.jsx("summary",{className:"btn btn-sm chat-message-failure-reference-link",children:"View failure details"}),t.jsxs("dl",{className:"chat-message-failure-reference-meta",id:i,children:[t.jsxs("div",{children:[t.jsx("dt",{children:"Kind"}),t.jsx("dd",{children:n.kind})]}),t.jsxs("div",{children:[t.jsx("dt",{children:"ID"}),t.jsx("dd",{children:n.id})]}),n.label&&t.jsxs("div",{children:[t.jsx("dt",{children:"Label"}),t.jsx("dd",{children:n.label})]})]})]})]})}function en(n){if(!n||n.length===0)return null;const r=(w,E)=>{const H=w.status==="running",C=w.status==="completed"&&w.isError,ee=ha(w.args),k=fa(w.result),B=H?ee:k?`result: ${k}`:ee?`args: ${ee}`:null,R=H?"running":C?"error":"completed";return t.jsxs("details",{className:`chat-tool-call${H?" chat-tool-call--running":""}${C?" chat-tool-call--error":""}`,open:H,children:[t.jsxs("summary",{children:[t.jsx("span",{className:"chat-tool-call-status-dot","aria-hidden":"true"}),t.jsx("span",{className:"chat-tool-call-name",title:w.toolName,children:w.toolName}),B&&t.jsx("span",{className:"chat-tool-call-preview",title:B,children:B}),t.jsx("span",{className:"chat-tool-call-status-text",children:R})]}),t.jsxs("div",{className:"chat-tool-call-content",children:[ee&&t.jsxs("div",{className:"chat-tool-call-row",children:[t.jsx("span",{className:"chat-tool-call-label",children:"args"}),t.jsx("span",{className:"chat-tool-call-value",children:ee})]}),k&&t.jsxs("div",{className:`chat-tool-call-row${C?" chat-tool-call-row--error":""}`,children:[t.jsx("span",{className:"chat-tool-call-label",children:"result"}),t.jsx("span",{className:"chat-tool-call-value",children:k})]})]})]},`${w.toolName}-${E}`)},d="chat-tool-calls";if(n.length===1)return t.jsxs("div",{className:d,"data-testid":"chat-tool-calls",children:[t.jsxs("div",{className:"chat-tool-calls-header",children:[t.jsx(zs,{size:12,"aria-hidden":"true"}),t.jsx("span",{children:"Tool calls"})]}),r(n[0],0)]});const i=n.filter(w=>w.status==="running").length,f=n.filter(w=>w.status==="completed"&&w.isError).length,p=i>0,S=Array.from(new Set(n.map(w=>w.toolName))),h=S.slice(0,5),P=Math.max(0,S.length-h.length),Q=P>0?`${h.join(", ")}, +${P} more`:h.join(", "),Z=p?`(${i} running)`:f>0?`(${f} ${f===1?"error":"errors"})`:null;return t.jsx("div",{className:d,"data-testid":"chat-tool-calls",children:t.jsxs("details",{className:"chat-tool-calls-group","data-testid":"chat-tool-calls-group",open:p,children:[t.jsxs("summary",{className:"chat-tool-calls-group-summary",children:[t.jsx(zs,{size:12,"aria-hidden":"true"}),t.jsxs("span",{className:"chat-tool-calls-count",children:[n.length," tool calls"]}),t.jsx("span",{className:"chat-tool-calls-names",title:Q,children:Q}),Z&&t.jsx("span",{className:"chat-tool-calls-group-status",children:Z})]}),n.map((w,E)=>r(w,E))]})})}const tn={p:({children:n,...r})=>t.jsx("p",{...r,children:_s(n)}),li:({children:n,...r})=>t.jsx("li",{...r,children:_s(n)}),pre:({children:n,...r})=>t.jsx("pre",{...r,className:"chat-markdown-pre",children:n}),code:({children:n,...r})=>{const d=typeof n=="string"?n:vn.Children.toArray(n).join(""),i=Rt(d);return i.length===1&&typeof i[0]=="string"?t.jsx("code",{...r,children:n}):t.jsx("code",{...r,children:i})},table:({children:n,...r})=>t.jsx("table",{...r,className:"chat-markdown-table",children:n})},et="__fn_agent__",ba=280,kt=180,jt=500,Ks="fusion:chat-sidebar-width",rs="fusion:chat-scope",va="fusion:chat-draft:";function Gs(n,r){return r?`${va}${n}:${r}`:null}function Ws(n){if(!n)return"";try{return localStorage.getItem(n)??""}catch{return""}}const xa=["image/png","image/jpeg","image/gif","image/webp","text/plain","application/json","text/yaml","text/markdown","text/csv","application/xml","text/x-log"];function Vs(n){const r=/(^|[\s])\/([^\s]*)$/.exec(n);if(!r)return null;const d=r[1]??"",i=r[2]??"",f=r.index+d.length;return{filter:i,start:f,end:n.length}}function ya(n,r){const d=n.slice(0,r),i=/(^|[\s\n])@([\w-]*)$/.exec(d);if(!i)return null;const f=i[2]??"",p=d.length-f.length-1;return{filter:f,start:p,end:r}}function wa(n){const r=n?.runtimeConfig;if(!r||typeof r!="object")return null;const d=Reflect.get(r,"modelProvider"),i=Reflect.get(r,"modelId");return typeof d!="string"||d.trim().length===0||typeof i!="string"||i.trim().length===0?null:{provider:d,modelId:i}}function qs(n,r,d){if(n?.modelProvider&&n?.modelId)return{provider:n.modelProvider,modelId:n.modelId};const i=wa(r??void 0);return i||(d.provider&&d.modelId?{provider:d.provider,modelId:d.modelId}:null)}function Sa({projectId:n,onClose:r,onCreate:d}){const[i,f]=s.useState("agent"),{agents:p,loading:S}=os(n),[h,P]=s.useState(""),{models:Q,favoriteProviders:Z,favoriteModels:w,loading:E,refresh:H}=Js(),[C,ee]=s.useState(""),[k,B]=s.useState(Z),[R,q]=s.useState(w);s.useEffect(()=>{B(Z)},[Z]),s.useEffect(()=>{q(w)},[w]);const L=s.useCallback(async M=>{const j=k,g=j.includes(M)?j.filter(c=>c!==M):[M,...j];B(g);try{await Hs({favoriteProviders:g,favoriteModels:R}),await H()}catch{B(j)}},[k,R,H]),F=s.useCallback(async M=>{const j=R,g=j.includes(M)?j.filter(c=>c!==M):[M,...j];q(g);try{await Hs({favoriteProviders:k,favoriteModels:g}),await H()}catch{q(j)}},[R,k,H]),T=M=>{if(M.preventDefault(),i==="agent"){if(!h)return;d({agentId:h});return}if(!C)return;const j=C.indexOf("/");if(j<=0)return;const y=C.slice(0,j),g=C.slice(j+1);d({agentId:et,modelProvider:y,modelId:g})},te=i==="agent"?!h:!C;return t.jsx("div",{className:"chat-new-dialog-backdrop chat-view-dialog-backdrop",onClick:r,role:"dialog","aria-modal":"true",children:t.jsxs("div",{className:"chat-new-dialog chat-view-dialog",onClick:M=>M.stopPropagation(),children:[t.jsx("h3",{children:"New Chat"}),t.jsxs("div",{className:"chat-new-dialog-mode-toggle","data-testid":"chat-new-dialog-mode-toggle",children:[t.jsx("button",{type:"button",className:`chat-new-dialog-mode-btn${i==="agent"?" chat-new-dialog-mode-btn--active":""}`,"data-testid":"chat-new-dialog-mode-agent",onClick:()=>{f("agent"),ee("")},children:"Agent"}),t.jsx("button",{type:"button",className:`chat-new-dialog-mode-btn${i==="model"?" chat-new-dialog-mode-btn--active":""}`,"data-testid":"chat-new-dialog-mode-model",onClick:()=>{f("model"),P("")},children:"Model"})]}),t.jsxs("form",{onSubmit:T,children:[i==="agent"&&t.jsxs("label",{className:"chat-new-dialog-model-label",children:["Agent",S?t.jsx("div",{className:"chat-new-dialog-loading",children:"Loading agents..."}):p.length===0?t.jsx("div",{className:"chat-new-dialog-empty",children:"No agents available"}):t.jsx("div",{className:"chat-new-dialog-agent-list",children:p.map(M=>t.jsxs("button",{type:"button",className:`chat-new-dialog-agent-item${h===M.id?" chat-new-dialog-agent-item--selected":""}`,onClick:()=>P(M.id),"data-testid":`agent-option-${M.id}`,children:[t.jsx(dt,{size:16}),t.jsx("span",{className:"chat-new-dialog-agent-name",children:M.name}),t.jsx("span",{className:"chat-new-dialog-agent-role",children:M.role})]},M.id))})]}),i==="model"&&t.jsx("div",{className:"chat-new-dialog-model-dropdown","data-testid":"chat-new-dialog-model-section",children:E?t.jsx("div",{className:"chat-new-dialog-loading",children:"Loading models..."}):t.jsx(sa,{models:Q,value:C,onChange:ee,label:"Model",placeholder:"Select a model",favoriteProviders:k,onToggleFavorite:L,favoriteModels:R,onToggleModelFavorite:F})}),t.jsxs("div",{className:"chat-new-dialog-actions",children:[t.jsx("button",{type:"button",className:"btn btn-sm",onClick:r,children:"Cancel"}),t.jsx("button",{type:"submit",className:"btn btn-sm btn-primary",disabled:te,children:"Create"})]})]})]})})}const is=s.memo(function({message:r,forcePlain:d,agentName:i,hideAssistantIdentity:f,showAssistantModelTag:p,activeModelTag:S,activeModelProvider:h,activeSessionId:P,mentionAgentsByName:Q,roomContext:Z,copyAction:w,onScrollToTop:E}){const H=r.role==="assistant",C=H?r.failureInfo:void 0,ee=H&&(!f||!!C),k=s.useMemo(()=>{if(H)return null;const q=r.content,L=/@([\w-]+)/g,F=[];let T=0,te=L.exec(q);for(;te;){const[M,j=""]=te,y=te.index;y>T&&F.push(q.slice(T,y));const g=j.replace(/_/g," ").toLowerCase(),c=Q.get(g);if(c){const Ce=!!(Z&&!Z.memberIds.has(c.id)),v=Ce?`Not a member of ${Z?.roomName}`:void 0;F.push(t.jsxs("span",{className:`chat-mention-chip${Ce?" chat-mention-chip--non-member":""}`,title:v,"aria-label":v,children:["@",c.name.replace(/\s+/g,"_")]},`${c.id}-${y}`))}else F.push(M);T=y+M.length,te=L.exec(q)}return T<q.length&&F.push(q.slice(T)),F.length===0?q:F},[H,r.content,Q,Z]),B=s.useMemo(()=>{const q=r.attachments;if(!q||q.length===0)return null;const L=r.roomId?`/api/chat/rooms/${encodeURIComponent(r.roomId)}/attachments/`:P?`/api/chat/sessions/${encodeURIComponent(P)}/attachments/`:null;return L?t.jsx("div",{className:"chat-message-attachments",children:q.map(F=>{const T=F.mimeType.startsWith("image/"),te=F.id||F.filename,M=`${L}${encodeURIComponent(F.filename)}`;return T?t.jsx("a",{className:"chat-message-attachment-link","data-testid":"chat-message-attachment",href:M,target:"_blank",rel:"noopener noreferrer",children:t.jsx("img",{className:"chat-message-attachment",src:M,alt:F.originalName})},te):t.jsxs("a",{className:"chat-message-attachment-file","data-testid":"chat-message-attachment",href:M,target:"_blank",rel:"noopener noreferrer",children:[t.jsx(Zn,{size:14}),t.jsx("span",{children:F.originalName})]},te)})}):null},[r.attachments,r.roomId,P]),R=s.useMemo(()=>H?C?t.jsxs("div",{className:"chat-message-content chat-message-content--failure",children:[t.jsxs("div",{className:"chat-message-failure-summary-row",children:[t.jsx("span",{className:"status-dot status-dot--error","aria-hidden":"true"}),t.jsx("span",{className:"chat-message-failure-label",children:"Response failed"})]}),t.jsx("div",{className:"chat-message-failure-summary",children:C.summary}),(C.errorClass||C.code)&&t.jsxs("div",{className:"chat-message-failure-badges",children:[C.errorClass&&t.jsx("span",{className:"chat-message-failure-badge",children:C.errorClass}),C.code&&t.jsx("span",{className:"chat-message-failure-badge",children:C.code})]}),(C.detail||C.reference)&&t.jsxs("details",{className:"chat-message-failure-details",children:[t.jsxs("summary",{children:[t.jsx(ea,{size:14,"aria-hidden":"true"}),t.jsx("span",{children:"Failure details"})]}),C.detail&&t.jsx("pre",{className:"chat-message-failure-detail",children:Rt(C.detail)}),pa(C.reference)]})]}):d?t.jsx("div",{className:"chat-message-content chat-message-content--plain",children:r.content}):t.jsx("div",{className:"chat-message-content chat-message-content--markdown",children:t.jsx(Ys,{remarkPlugins:[Qs],components:tn,children:r.content})}):null,[C,d,H,r.content]);return t.jsxs("div",{className:`chat-message chat-message--${r.role}${C?" chat-message--failure":""}`,"data-testid":`chat-message-${r.id}`,"data-message-id":r.id,children:[ee&&t.jsxs("div",{className:"chat-message-avatar",children:[h?t.jsx(lt,{provider:h,size:"sm"}):t.jsx(dt,{size:14}),t.jsx("span",{children:i}),p&&S&&t.jsx("span",{className:"chat-model-tag",children:S})]}),H?R:t.jsx("div",{className:"chat-message-content",children:k}),H&&!C&&(w||E)&&t.jsxs("div",{className:"chat-message-actions",children:[w,E&&t.jsx("button",{type:"button",className:"btn-icon chat-message-scroll-to-top-action","aria-label":"Scroll message to top","data-testid":`chat-message-scroll-to-top-${r.id}`,onClick:()=>E(r.id),children:t.jsx(aa,{size:14})})]}),en(r.toolCalls),r.thinkingOutput&&t.jsxs("details",{className:"chat-message-thinking",children:[t.jsx("summary",{children:"Thinking"}),t.jsx("pre",{className:"chat-message-thinking-content",children:Rt(r.thinkingOutput)})]}),B,t.jsx("div",{className:"chat-message-time",children:Zs(r.createdAt)})]})});function Ra({projectId:n,addToast:r,experimentalFeatures:d}){s.useEffect(()=>(Mt({view:"ChatView",trigger:as?"route-active":"remount",projectId:n,replayAttempted:!1}),as=!1,()=>{as=!0,Mt({view:"ChatView",trigger:"route-inactive",projectId:n,replayAttempted:!1})}),[n]);const{activeSession:i,sessionsLoading:f,messages:p,messagesLoading:S,isStreaming:h,streamingText:P,streamingThinking:Q,streamingToolCalls:Z,selectSession:w,createSession:E,archiveSession:H,deleteSession:C,sendMessage:ee,stopStreaming:k,pendingMessage:B,clearPendingMessage:R,searchQuery:q,setSearchQuery:L,filteredSessions:F,agentsMap:T}=ca(n,r),[te,M]=s.useState(!1),j=d?.chatRooms===!0,[y,g]=s.useState(()=>{try{if(localStorage.getItem(rs)==="rooms"&&j)return"rooms"}catch{}return"direct"}),c=Dn(n,r),{isUnread:Ce,markRead:v}=Pn(n),[N,me]=s.useState(()=>{const e=Gs(y,y==="rooms"?c.activeRoom?.id:i?.id);return Ws(e)}),[ce,he]=s.useState(null),[Ke,V]=s.useState(null),[tt,W]=s.useState(null),[$e,le]=s.useState(!0),[we,fe]=s.useState(ba),[ut,Se]=s.useState(!1),{agentsMap:He}=os(n),ge=s.useMemo(()=>T.size>0?T:He,[He,T]),{defaultProvider:ae,defaultModelId:Ue}=Js(),mt=s.useMemo(()=>({provider:ae,modelId:Ue}),[Ue,ae]),{skills:se,loading:oe}=Fn(n),[xe,De]=s.useState(!1),[st,Ge]=s.useState(""),[We,Oe]=s.useState(0),[ke,je]=s.useState(""),[pe,Ne]=s.useState(!1),[Ve,l]=s.useState(0),[u,b]=s.useState(-1),[I,X]=s.useState(!1),[A,J]=s.useState([]),[U,O]=s.useState(!1),[K,G]=s.useState(!1),[D,Y]=s.useState({}),[re,de]=s.useState(!1),[ht,nt]=s.useState(!1),{pushNav:cs}=Ln(),[,ft]=s.useState(!1),[sn,nn]=s.useState({top:0,left:0}),_=_n({projectId:n}),At=s.useCallback(e=>{if(!e||!_.mentionActive)return;const a=e.getBoundingClientRect();nn({top:a.top-260,left:a.left+8})},[_.mentionActive]),ls=s.useRef(null),ds=s.useRef(null),us=s.useRef(null),Me=s.useRef(!1),Et=s.useRef(null),ms=s.useRef(null),Pe=s.useRef(null),gt=s.useRef(0),Tt=s.useRef(null),It=s.useRef(null),Re=s.useRef(null),be=s.useRef(null),$t=s.useRef(null),pt=s.useRef(!1),Ae=s.useRef(null),ie=s.useRef(null),hs=s.useRef(null),fs=s.useRef([]),qe=s.useRef(0),at=s.useRef(new Map),$=zn()==="mobile";s.useEffect(()=>{i?.id&&v("direct",i.id,i.lastMessageAt??i.updatedAt)},[i?.id,i?.lastMessageAt,i?.updatedAt,v]),s.useEffect(()=>{c.activeRoom?.id&&v("room",c.activeRoom.id,c.activeRoom.updatedAt)},[c.activeRoom?.id,c.activeRoom?.updatedAt,v]),s.useEffect(()=>{if(!i?.id||p.length===0)return;const e=p[p.length-1];v("direct",i.id,e?.createdAt??i.lastMessageAt??i.updatedAt)},[i?.id,i?.lastMessageAt,i?.updatedAt,v,p]),s.useEffect(()=>{if(!c.activeRoom?.id||c.messages.length===0)return;const e=c.messages[c.messages.length-1];v("room",c.activeRoom.id,e?.createdAt??c.activeRoom.updatedAt)},[v,c.activeRoom?.id,c.activeRoom?.updatedAt,c.messages]),s.useEffect(()=>{try{const e=localStorage.getItem(Ks);if(!e)return;const a=Number.parseInt(e,10);if(Number.isNaN(a))return;const o=Math.max(kt,Math.min(jt,a));fe(o)}catch{}},[]),s.useEffect(()=>{try{const e=localStorage.getItem(rs);if(e==="direct"){g("direct");return}e==="rooms"&&j&&g("rooms")}catch{}},[j]),s.useEffect(()=>{if(!j&&y==="rooms"){g("direct");return}try{localStorage.setItem(rs,y)}catch{}},[j,y]);const ue=Gs(y,y==="rooms"?c.activeRoom?.id:i?.id),Dt=s.useRef(ue);s.useEffect(()=>{ue!==Dt.current&&(Dt.current=ue,me(Ws(ue)))},[ue]),s.useEffect(()=>{if(!(!ue||Dt.current!==ue))try{if(N){localStorage.setItem(ue,N);return}localStorage.removeItem(ue)}catch{}},[ue,N]);const ne=j&&y==="rooms"&&!!c.activeRoom,{keyboardOverlap:gs,keyboardOpen:Pt}=Hn({enabled:$&&(!!i||ne)}),ye=s.useMemo(()=>{const e=st.trim().toLowerCase();return(e?se.filter(o=>o.name.toLowerCase().includes(e)):se).slice(0,10)},[se,st]),Xe=s.useMemo(()=>Array.from(ge.values()),[ge]),Ee=s.useMemo(()=>!j||y!=="rooms"||!c.activeRoom?null:{roomId:c.activeRoom.id,roomName:c.activeRoom.name,memberIds:new Set(c.activeRoomMembers.map(e=>e.agentId))},[j,y,c.activeRoom,c.activeRoomMembers]),Be=s.useMemo(()=>{const e=Xe.filter(m=>Un(m.name,ke));if(!Ee)return e;const a=e.filter(m=>Ee.memberIds.has(m.id));if(ke.trim().length===0)return a;const o=e.filter(m=>!Ee.memberIds.has(m.id));return[...a,...o]},[Xe,ke,Ee]),Ft=s.useMemo(()=>{const e=new Map;for(const a of Xe)e.set(a.name.toLowerCase(),a);return e},[Xe]);s.useEffect(()=>{Oe(0)},[ye]),s.useEffect(()=>{l(0)},[ke,pe]),s.useEffect(()=>()=>{Re.current!==null&&window.clearTimeout(Re.current)},[]);const Je=s.useCallback(()=>ne?c.activeRoom?.id??null:i?.id??null,[ne,c.activeRoom?.id,i?.id]),ps=s.useCallback((e,a)=>typeof CSS<"u"&&typeof CSS.escape=="function"?e.querySelector(`.chat-message[data-message-id="${CSS.escape(a)}"]`):e.querySelector(`.chat-message[data-message-id="${a.replace(/"/g,'\\"')}"]`),[]),bt=s.useCallback(()=>{const e=be.current,a=Je();if(!e||!a)return;const o=e.querySelector(".chat-message[data-message-id]"),m=o?.getAttribute("data-message-id")??null,x=o?o.offsetTop-e.scrollTop:0;It.current={threadId:a,scrollTop:e.scrollTop,scrollHeight:e.scrollHeight,clientHeight:e.clientHeight,anchorMessageId:m,anchorOffset:x,wasPinnedBefore:!Me.current}},[Je]),bs=s.useCallback(()=>{const e=be.current;if(!e)return;const o=e.scrollTop+e.clientHeight>=e.scrollHeight-50;G(!o),Me.current=!o,bt()},[bt]),Te=s.useCallback(e=>{if(!e.isConnected)return;let a=0,o=0,m=-1;const x=6,z=()=>{if(e.isConnected){if(e.scrollTop=e.scrollHeight,e.scrollHeight===m?o+=1:(o=0,m=e.scrollHeight),a+=1,a>=x||o>=2){G(!1),Me.current=!1;return}window.requestAnimationFrame(z)}};z()},[]),rt=ne?c.messages:p;s.useLayoutEffect(()=>{const e=be.current,a=Je(),o=It.current;if(!e||!a||!o||o.threadId!==a||o.wasPinnedBefore)return;let m=o.scrollTop;if(o.anchorMessageId){const x=ps(e,o.anchorMessageId);x?m=x.offsetTop-o.anchorOffset:m=o.scrollTop+(e.scrollHeight-o.scrollHeight)}else m=o.scrollTop+(e.scrollHeight-o.scrollHeight);e.scrollTop=Math.max(0,m),Me.current=!0,G(!0),It.current=null},[rt,Je,ps]);const Lt=s.useCallback(e=>{},[rt.length,ne]),Fe=s.useCallback(e=>{Lt(e);const a=be.current;a&&Te(a)},[Te,Lt]);s.useLayoutEffect(()=>{Pe.current!==null&&(window.clearTimeout(Pe.current),Pe.current=null);const e=ne?c.activeRoom?.id??null:i?.id??null;if(!e){Et.current=null;return}const a={threadId:e,loaded:ne?!c.messagesLoading:!S,hasMessages:ne?c.messages.length>0:p.length>0},o=Et.current,m=o?.threadId!==e,x=o?.threadId===e&&!o.loaded&&a.loaded,z=o?.threadId===e&&!o.hasMessages&&a.hasMessages;if(!(o===null||m||x||z))return;const Ie=be.current;if(Ie)return Lt(m?"thread-change":x?"finished-loading":z?"first-messages":"mount"),Te(Ie),ne||(Pe.current=window.setTimeout(()=>{if(Pe.current=null,Me.current)return;const Qe=be.current;Qe&&Te(Qe)},250)),Et.current=a,()=>{Pe.current!==null&&(window.clearTimeout(Pe.current),Pe.current=null)}},[ne,c.activeRoom?.id,c.messages.length,c.messagesLoading,i?.id,p.length,S,Te]),s.useEffect(()=>{!h||Me.current||Fe("streaming")},[h,P,Q,Fe]),s.useEffect(()=>{const e=Je();if(!e){gt.current=0,Tt.current=null;return}if(Tt.current!==e){Tt.current=e,gt.current=rt.length;return}const a=gt.current,o=rt.length,m=o>a,x=!Me.current;gt.current=o,m&&x&&Fe("new-message")},[rt,Je,Fe]),s.useEffect(()=>{gs<=0||!be.current||Fe("keyboard")},[gs,Fe]),On($&&Pt),s.useLayoutEffect(()=>{if(!$||!i&&!ne||typeof window>"u")return;const e=$t.current,a=window.visualViewport;if(!e||!a)return;const o=x=>{if(!(x instanceof HTMLElement))return!1;if(x.tagName==="TEXTAREA")return!0;if(x.tagName!=="INPUT")return!1;const z=x.type.toLowerCase();return["","text","search","email","url","tel","password","number"].includes(z)},m=()=>{if(pt.current){e.classList.remove("chat-thread--keyboard-active");return}const x=Math.max(0,window.innerHeight-a.offsetTop-a.height),z=a.offsetTop||0;e.style.setProperty("--vv-height",`${a.height}px`),e.style.setProperty("--vv-offset-top",`${z}px`),e.style.setProperty("--keyboard-overlap",`${x}px`);const ze=(x>0||z>0)&&o(document.activeElement);e.classList.toggle("chat-thread--keyboard-active",ze)};return m(),a.addEventListener("resize",m),a.addEventListener("scroll",m),document.addEventListener("focusin",m),document.addEventListener("focusout",m),window.addEventListener("pageshow",m),document.addEventListener("visibilitychange",m),()=>{a.removeEventListener("resize",m),a.removeEventListener("scroll",m),document.removeEventListener("focusin",m),document.removeEventListener("focusout",m),window.removeEventListener("pageshow",m),document.removeEventListener("visibilitychange",m),e.classList.remove("chat-thread--keyboard-active")}},[i,$,ne]),s.useEffect(()=>{const e=()=>he(null);if(ce)return document.addEventListener("click",e),()=>document.removeEventListener("click",e)},[ce]),s.useEffect(()=>{if(!$||!Pt)return;const e=a=>{a.target?.closest(".chat-messages")||a.preventDefault()};return document.addEventListener("touchmove",e,{passive:!1}),()=>{document.removeEventListener("touchmove",e)}},[$,Pt]),s.useEffect(()=>{if(!$||!i)return;const e=()=>{const a=ie.current;a&&document.activeElement===a&&(a.blur(),window.setTimeout(()=>{a.focus({preventScroll:!0})},0))};return document.addEventListener("visibilitychange",e),window.addEventListener("pageshow",e),()=>{document.removeEventListener("visibilitychange",e),window.removeEventListener("pageshow",e)}},[$,i]),s.useEffect(()=>{const e=ms.current;if(ms.current=y,y!=="direct"||e!==null&&e!=="rooms")return;const a=be.current;a&&(Te(a),Me.current=!1,G(!1))},[y,Te]),s.useEffect(()=>{if(!i&&!ne||ne&&!$)return;const e=()=>{bt()},a=()=>{document.visibilityState==="visible"&&e()};return document.addEventListener("visibilitychange",a),window.addEventListener("pageshow",e),()=>{document.removeEventListener("visibilitychange",a),window.removeEventListener("pageshow",e)}},[$,i,ne,bt]),s.useEffect(()=>{if(ne||typeof ResizeObserver>"u")return;const e=be.current;if(!e)return;const a=new ResizeObserver(()=>{Me.current||Te(e)});return a.observe(e),()=>{a.disconnect()}},[ne,Te,i?.id,y]),s.useEffect(()=>{fs.current=A},[A]),s.useEffect(()=>()=>{for(const e of fs.current)e.previewUrl&&URL.revokeObjectURL(e.previewUrl);for(const e of at.current.values())window.clearTimeout(e);at.current.clear()},[]);const vt=s.useCallback(e=>{if(!e||e.length===0)return;const a=[];for(const o of Array.from(e)){if(!xa.includes(o.type))continue;const m=o.type.startsWith("image/");a.push({file:o,previewUrl:m?URL.createObjectURL(o):""})}a.length>0&&J(o=>[...o,...a])},[]),an=s.useCallback(e=>{J(a=>{const o=a[e];return o?.previewUrl&&URL.revokeObjectURL(o.previewUrl),a.filter((m,x)=>x!==e)})},[]),rn=s.useCallback(e=>{const a=e.clipboardData?.files;if(!a||a.length===0)return;const o=Array.from(a).filter(m=>m.type.startsWith("image/"));o.length!==0&&vt(o)},[vt]),on=s.useCallback(async e=>{try{await E(e),M(!1),$&&le(!1)}catch{r("Failed to create chat session","error")}},[E,r,$]),ve=s.useCallback(e=>{const a=e??ie.current;a&&(a.style.height="auto",a.style.height=`${ma(a.scrollHeight)}px`)},[]),vs=s.useCallback(e=>{ie.current=e,e&&ve(e)},[ve]);s.useLayoutEffect(()=>{ve()},[y,N,i?.id,c.activeRoom?.id,ve]);const Ye=s.useCallback(()=>{if(me(""),ue)try{localStorage.removeItem(ue)}catch{}De(!1),Ge(""),Ne(!1),je(""),b(-1),J(e=>{for(const a of e)a.previewUrl&&URL.revokeObjectURL(a.previewUrl);return[]})},[ue]),_t=s.useCallback(()=>{const e=N.trim(),a=A.map(o=>o.file);if(!(!e&&a.length===0||!i)){if(e==="/clear"||e==="/new"){Ye(),R(),k(),E({agentId:i.agentId,modelProvider:i.modelProvider??void 0,modelId:i.modelId??void 0}).catch(()=>{r("Failed to clear conversation","error")});return}Ye(),ee(e,a)}},[N,A,i,Ye,k,R,E,r,ee]),zt=s.useCallback(async()=>{const e=N.trim();if(e){if(j&&y==="rooms"){if(!c.activeRoom)return;if(e==="/clear"||e==="/new"){Ye();try{await c.clearRoom(c.activeRoom.id)}catch{r("Failed to clear room conversation","error")}return}const a=N;Ye();try{await c.sendRoomMessage(e,{files:A.map(o=>o.file)})}catch(o){if(o instanceof Bn){const x=o.message.trim()?o.message:"Message sent, but assistant reply failed";r(`Message sent, but assistant reply failed: ${x}`,"error");return}me(a);const m=o instanceof Error&&o.message.trim()?o.message:"Failed to send room message";r(m,"error")}return}_t()}},[N,A,j,y,c,c.clearRoom,Ye,r,_t]),Ht=s.useCallback(e=>{me(a=>{const o=Vs(a);if(!o)return a;const m=`/skill:${e.name} `,x=a.slice(0,o.start)+m+a.slice(o.end);return window.requestAnimationFrame(()=>{ie.current&&(ve(ie.current),ie.current.focus())}),x}),De(!1),Ge(""),Oe(0)},[ve]),xt=s.useCallback(e=>{const a=ie.current;if(!a||u<0)return;const o=a.selectionStart??qe.current,m=a.selectionEnd??o,x=Math.max(o,m),z=Math.min(u,x),Ie=`${`@${e.name.replace(/\s+/g,"_")}`} `,Qe=N.slice(0,z)+Ie+N.slice(x),Ze=z+Ie.length;me(Qe),Ne(!1),je(""),l(0),b(-1),window.requestAnimationFrame(()=>{ie.current&&(ve(ie.current),ie.current.focus(),ie.current.setSelectionRange(Ze,Ze))})},[u,N,ve]),it=s.useCallback((e,a)=>{const m=ie.current?.selectionStart??qe.current,x=N.lastIndexOf("#",m),z=x>=0?x+a.length:e.length;me(e),_.dismissMention(),ft(!1),window.requestAnimationFrame(()=>{ie.current&&(ve(ie.current),ie.current.focus(),ie.current.setSelectionRange(z,z))})},[_,N,ve]),xs=s.useCallback(e=>{if(qe.current=e.currentTarget.selectionStart??qe.current,_.mentionActive&&_.combinedItems.length>0){if(_.handleKeyDown(e,N),e.key==="Enter"||e.key==="Tab"){const a=_.combinedItems[_.selectedIndex];a?.kind==="task"?it(_.selectTask(a.task,N),`#${a.task.id}`):a?.kind==="file"&&it(_.selectFile(a.file,N),`#${a.file.path}`)}return}if(pe&&e.key==="ArrowDown"){e.preventDefault(),Be.length>0&&l(a=>(a+1)%Be.length);return}if(pe&&e.key==="ArrowUp"){e.preventDefault(),Be.length>0&&l(a=>a===0?Be.length-1:a-1);return}if(pe&&e.key==="Enter"){e.preventDefault();const a=Be[Ve]??Be[0];a&&xt(a);return}if(pe&&e.key==="Escape"){e.preventDefault(),Ne(!1),je(""),b(-1);return}if(xe&&e.key==="ArrowDown"){e.preventDefault(),ye.length>0&&Oe(a=>(a+1)%ye.length);return}if(xe&&e.key==="ArrowUp"){e.preventDefault(),ye.length>0&&Oe(a=>a===0?ye.length-1:a-1);return}if(xe&&(e.key==="Enter"||e.key==="Tab")&&ye.length>0){e.preventDefault();const a=ye[We]??ye[0];a&&Ht(a);return}if(xe&&e.key==="Escape"){e.preventDefault(),De(!1);return}e.key==="Enter"&&!e.shiftKey&&(e.preventDefault(),zt())},[pe,Be,Ve,xt,xe,ye,We,Ht,zt,_,it,N]),yt=s.useCallback((e,a)=>{const o=ya(e,a);if(o){Ne(!0),je(o.filter),b(o.start);return}Ne(!1),je(""),b(-1)},[]),ys=s.useCallback(e=>{const a=e.target,o=a.value,m=a.selectionStart??o.length;ve(a),qe.current=m,me(o);const x=Vs(o);x?(De(!0),Ge(x.filter)):(De(!1),Ge("")),yt(o,m),_.detectMention(o,m),ft(_.mentionActive),_.mentionActive&&At(a)},[yt,ve]),wt=s.useCallback(e=>{const a=e.currentTarget,o=a.selectionStart??a.value.length;qe.current=o,yt(a.value,o),_.detectMention(a.value,o),ft(_.mentionActive),_.mentionActive&&At(a)},[yt,_,At]),ws=s.useCallback(e=>{e.key!=="Escape"&&wt(e)},[wt]),Ss=s.useCallback(()=>{typeof window<"u"&&window.innerWidth<=768&&(pt.current=!0,Ae.current!==null&&window.clearTimeout(Ae.current),Ae.current=window.setTimeout(()=>{pt.current=!1,Ae.current=null},450)),Re.current!==null&&window.clearTimeout(Re.current),Re.current=window.setTimeout(()=>{De(!1),Ne(!1),je(""),b(-1),ft(!1),_.dismissMention(),Re.current=null},120)},[_]),Cs=s.useCallback(()=>{pt.current=!1,Ae.current!==null&&(window.clearTimeout(Ae.current),Ae.current=null),Re.current!==null&&(window.clearTimeout(Re.current),Re.current=null),typeof window<"u"&&window.innerWidth<=768&&queueMicrotask(()=>{(window.scrollY!==0||window.scrollX!==0)&&window.scrollTo(0,0)})},[]);s.useEffect(()=>()=>{Ae.current!==null&&window.clearTimeout(Ae.current)},[]);const cn=s.useCallback(async e=>{he(null);try{await H(e),r("Conversation archived","success")}catch{r("Failed to archive conversation","error")}},[H,r]),ln=s.useCallback(async e=>{V(null),he(null);try{await C(e),r("Conversation deleted","success")}catch{r("Failed to delete conversation","error")}},[C,r]),ot=s.useCallback(e=>{try{localStorage.setItem(Ks,String(e))}catch{}},[]),dn=s.useCallback(e=>{if($)return;e.preventDefault(),e.stopPropagation();const a=e.currentTarget;typeof a.setPointerCapture=="function"&&a.setPointerCapture(e.pointerId);const o=e.clientX,m=we;let x=m;document.body.style.userSelect="none";const z=Ie=>{const Qe=Ie.clientX-o,Ze=Math.max(kt,Math.min(jt,m+Qe));x=Ze,fe(Ze),ot(Ze)},ze=Ie=>{typeof a.releasePointerCapture=="function"&&a.releasePointerCapture(Ie.pointerId),document.body.style.userSelect="",document.removeEventListener("pointermove",z),document.removeEventListener("pointerup",ze),ot(x)};document.addEventListener("pointermove",z),document.addEventListener("pointerup",ze)},[$,ot,we]),un=s.useCallback(e=>{if($||e.key!=="ArrowLeft"&&e.key!=="ArrowRight")return;e.preventDefault();const a=e.shiftKey?50:10,o=e.key==="ArrowLeft"?-a:a,m=Math.max(kt,Math.min(jt,we+o));fe(m),ot(m)},[$,ot,we]),ks=s.useCallback(e=>{const a=F.find(o=>o.id===e);v("direct",e,a?.lastMessageAt??a?.updatedAt),w(e),de(!1),$&&le(!1)},[F,$,v,w]),Ut=s.useCallback(()=>{w(""),le(!0),de(!1)},[w]),Ot=s.useCallback(()=>{c.selectRoom(null),le(!0),de(!1)},[c]),mn=()=>t.jsxs("div",{className:"chat-empty-state",children:[t.jsx(ta,{size:48,strokeWidth:1.5}),t.jsx("h2",{children:"Start a new conversation"}),t.jsxs("button",{className:"btn btn-primary",onClick:()=>M(!0),children:[t.jsx(ct,{size:16}),"New Chat"]})]}),Bt=qs(i,i?.agentId?ge.get(i.agentId)??null:null,mt),Le=Bs(Bt?.provider,Bt?.modelId),_e=Bt?.provider??null,Kt=!!(i||h||p.length>0),St=y==="rooms"?ne:!!i,js=s.useRef(St);s.useEffect(()=>{const e=js.current;js.current=St,$&&(e||!St||cs({type:"view",revert:y==="rooms"?Ot:Ut}))},[y,Ut,Ot,St,$,cs]);const Gt=i?.agentId===et?Le??"Fusion":i?.title||ge.get(i?.agentId??"")?.name||i?.agentId||"Chat",Ns=!!(Le&&Le!==Gt),hn=$&&y==="direct"&&!!i,Wt=ge.get(i?.agentId??"")?.name||(i?.agentId===et?Le??"Fusion":i?.agentId?.slice(0,30)??"Fusion"),Vt=!1,qt=i?.agentId===et,fn=B.length>50?`${B.slice(0,50)}…`:B,gn=s.useCallback(()=>{X(e=>!e)},[]);s.useEffect(()=>{if(!re)return;const e=a=>{ds.current?.contains(a.target)||de(!1)};return document.addEventListener("mousedown",e),()=>{document.removeEventListener("mousedown",e)}},[re]),s.useEffect(()=>{if(!ht)return;const e=o=>{us.current?.contains(o.target)||nt(!1)},a=o=>{o.key==="Escape"&&nt(!1)};return document.addEventListener("mousedown",e),document.addEventListener("keydown",a),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("keydown",a)}},[ht]),s.useEffect(()=>{(!$||y!=="direct"||$e)&&de(!1)},[$,y,$e]),s.useEffect(()=>{nt(!1)},[c.activeRoom?.id]);const Xt=s.useCallback((e,a)=>{const o=at.current.get(e);o&&window.clearTimeout(o),Y(x=>({...x,[e]:a}));const m=window.setTimeout(()=>{Y(x=>{const{[e]:z,...ze}=x;return ze}),at.current.delete(e)},2e3);at.current.set(e,m)},[]),Ms=s.useCallback(async(e,a)=>{try{if(!navigator.clipboard?.writeText)throw new Error("Clipboard API unavailable");await navigator.clipboard.writeText(a),Xt(e,"success")}catch{Xt(e,"error")}},[Xt]),pn=s.useCallback((e,a=!1)=>a?t.jsx("div",{className:"chat-message-content chat-message-content--plain",children:e}):t.jsx("div",{className:"chat-message-content chat-message-content--markdown",children:t.jsx(Ys,{remarkPlugins:[Qs],components:tn,children:e})}),[]),Jt=i?.agentId===et,Yt=s.useCallback((e,a,o)=>t.jsx("button",{type:"button",className:`btn-icon chat-message-copy-action${D[e]==="success"?" chat-message-copy-action--success":""}${D[e]==="error"?" chat-message-copy-action--error":""}`,"data-testid":o??`chat-copy-response-${e}`,"aria-label":D[e]==="success"?"Response copied":D[e]==="error"?"Copy failed":"Copy response",onClick:()=>{Ms(e,a)},children:D[e]==="success"?t.jsx(Kn,{size:14}):t.jsx(Gn,{size:14})}),[D,Ms]),Qt=s.useCallback(e=>{const a=be.current;if(!a)return;const o=`[data-testid="chat-message-${e}"]`,m=a.querySelector(o);if(!m)return;const x=m.getBoundingClientRect().top-a.getBoundingClientRect().top+a.scrollTop,z=typeof window<"u"&&window.matchMedia?.("(prefers-reduced-motion: reduce)").matches;a.scrollTo({top:x,behavior:z?"auto":"smooth"})},[]);return t.jsxs("div",{className:"chat-view",children:[t.jsxs("div",{className:`chat-sidebar${$e?"":" chat-sidebar--hidden"}`,style:$?void 0:{width:`${we}px`},children:[j&&t.jsxs("div",{className:"chat-sidebar-scope-toggle",role:"tablist","data-testid":"chat-sidebar-scope-toggle",children:[t.jsx("button",{type:"button",role:"tab",className:`chat-sidebar-scope-btn${y==="direct"?" chat-sidebar-scope-btn--active":""}`,"aria-selected":y==="direct","data-testid":"chat-sidebar-scope-direct",onClick:()=>g("direct"),children:"Direct"}),t.jsx("button",{type:"button",role:"tab",className:`chat-sidebar-scope-btn${y==="rooms"?" chat-sidebar-scope-btn--active":""}`,"aria-selected":y==="rooms","data-testid":"chat-sidebar-scope-rooms",onClick:()=>g("rooms"),children:"Rooms"})]}),!j||y==="direct"?t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"chat-sidebar-search-container",children:t.jsxs("div",{className:"chat-sidebar-search-wrapper",children:[t.jsx(Wn,{size:14,className:"chat-sidebar-search-icon"}),t.jsx("input",{type:"text",className:"chat-sidebar-search",placeholder:"Search conversations...",value:q,onChange:e=>L(e.target.value),"data-testid":"chat-search-input"})]})}),t.jsx("div",{className:"chat-session-list chat-sidebar-list",children:f?t.jsx("div",{className:"chat-empty-state chat-empty-state--padded",children:"Loading..."}):F.length===0?t.jsx("div",{className:"chat-empty-state chat-empty-state--padded",children:"No conversations yet"}):F.map(e=>{const a=i?.id===e.id,o=!a&&Ce("direct",e.id,e.lastMessageAt??e.updatedAt),m=qs(e,ge.get(e.agentId)??null,mt),x=Bs(m?.provider,m?.modelId)??"Fusion";return t.jsxs("div",{className:`chat-session-item${a?" chat-session-item--active":""}`,onClick:()=>ks(e.id),onContextMenu:z=>{z.preventDefault(),he({sessionId:e.id,x:z.clientX,y:z.clientY})},"data-testid":`chat-session-${e.id}`,children:[t.jsx("button",{className:"chat-session-delete-btn",onClick:z=>{z.stopPropagation(),V(e.id)},"data-testid":"chat-session-delete-btn","aria-label":"Delete conversation",children:t.jsx(ts,{size:14})}),t.jsxs("div",{className:"chat-session-title",children:[e.title||"Untitled",o?t.jsx("span",{className:"chat-unread-dot","data-testid":`chat-unread-dot-${e.id}`,"aria-label":"Unread messages"}):null]}),t.jsx("div",{className:"chat-session-preview",children:e.lastMessagePreview||"No messages"}),t.jsxs("div",{className:"chat-session-meta",children:[t.jsxs("span",{className:"chat-session-meta-model",children:[m?.provider?t.jsx(lt,{provider:m.provider,size:"sm"}):null,t.jsx("span",{children:ge.get(e.agentId)?.name||(e.agentId===et?x:e.agentId.slice(0,30))})]}),t.jsx("span",{children:e.updatedAt?Zs(e.updatedAt):""})]})]},e.id)})})]}):t.jsxs("div",{className:"chat-sidebar-rooms","data-testid":"chat-sidebar-rooms",children:[!$&&t.jsx("div",{className:"chat-sidebar-rooms-header","data-testid":"chat-sidebar-rooms-header",children:t.jsxs("button",{type:"button",className:"btn btn-sm btn-primary","data-testid":"chat-create-room-btn",onClick:()=>Se(!0),children:[t.jsx(ct,{size:14}),"Create room"]})}),c.rooms.length===0?t.jsx("div",{className:"chat-sidebar-rooms-empty","data-testid":"chat-sidebar-rooms-empty",children:"No rooms yet."}):t.jsx("div",{className:"chat-session-list chat-sidebar-list",children:c.rooms.map(e=>{const a=c.activeRoom?.id===e.id,o=!a&&Ce("room",e.id,e.updatedAt);return t.jsxs("div",{role:"button",tabIndex:0,className:`chat-room-item${a?" chat-room-item--active":""}`,"data-testid":`chat-room-item-${e.slug}`,onClick:()=>{v("room",e.id,e.updatedAt),c.selectRoom(e.id),$&&le(!1)},onKeyDown:m=>{(m.key==="Enter"||m.key===" ")&&(m.preventDefault(),v("room",e.id,e.updatedAt),c.selectRoom(e.id),$&&le(!1))},children:[t.jsxs("span",{className:"chat-room-item-details",children:[t.jsxs("span",{className:"chat-room-item-name-row",children:[t.jsxs("span",{className:"chat-room-item-name",children:["#",e.name]}),o?t.jsx("span",{className:"chat-unread-dot","data-testid":`chat-unread-dot-${e.id}`,"aria-label":"Unread messages"}):null]}),a?t.jsxs("span",{className:"chat-room-item-meta",children:[c.activeRoomMembers.length," ",c.activeRoomMembers.length===1?"member":"members"]}):null]}),t.jsx("button",{type:"button",className:"btn-icon chat-room-item-delete","data-testid":`chat-room-delete-${e.slug}`,"aria-label":`Delete room ${e.name}`,onClick:m=>{m.stopPropagation(),W(e.id)},children:t.jsx(ts,{size:14})})]},e.id)})})]}),y==="rooms"?$?t.jsx("div",{className:"chat-sidebar-footer",children:t.jsxs("button",{type:"button",className:"btn btn-sm btn-primary chat-sidebar-footer-btn","data-testid":"chat-create-room-btn",onClick:()=>Se(!0),children:[t.jsx(ct,{size:14}),"Create room"]})}):null:t.jsx("div",{className:"chat-sidebar-footer",children:t.jsxs("button",{className:"btn btn-sm btn-primary chat-sidebar-footer-btn",onClick:()=>M(!0),"data-testid":"chat-new-btn",children:[t.jsx(ct,{size:14}),"New Chat"]})})]}),!$&&$e&&t.jsx("div",{className:"chat-sidebar-resize-handle",role:"separator","aria-orientation":"vertical","aria-valuemin":kt,"aria-valuemax":jt,"aria-valuenow":we,"aria-label":"Resize chat sidebar",tabIndex:0,onPointerDown:dn,onKeyDown:un}),ce&&t.jsxs("div",{className:"chat-session-context-menu",style:{top:ce.y,left:ce.x},onClick:e=>e.stopPropagation(),children:[t.jsxs("button",{onClick:()=>cn(ce.sessionId),"data-testid":"chat-context-archive",children:[t.jsx(Vn,{size:14}),"Archive"]}),t.jsxs("button",{onClick:()=>{he(null),V(ce.sessionId)},"data-testid":"chat-context-delete",children:[t.jsx(ts,{size:14}),"Delete"]})]}),Ke&&t.jsx("div",{className:"chat-new-dialog-backdrop chat-view-dialog-backdrop",onClick:()=>V(null),children:t.jsxs("div",{className:"chat-new-dialog chat-view-dialog",onClick:e=>e.stopPropagation(),children:[t.jsx("h3",{children:"Delete Conversation?"}),t.jsx("p",{className:"chat-view-delete-dialog-copy",children:"This action cannot be undone. All messages in this conversation will be permanently deleted."}),t.jsxs("div",{className:"chat-new-dialog-actions",children:[t.jsx("button",{className:"btn btn-sm",onClick:()=>V(null),children:"Cancel"}),t.jsx("button",{className:"btn btn-sm btn-danger",onClick:()=>void ln(Ke),children:"Delete"})]})]})}),j&&tt&&t.jsx("div",{className:"chat-new-dialog-backdrop chat-view-dialog-backdrop",onClick:()=>W(null),children:t.jsxs("div",{className:"chat-new-dialog chat-view-dialog",onClick:e=>e.stopPropagation(),children:[t.jsx("h3",{children:"Delete Room?"}),t.jsx("p",{className:"chat-view-delete-dialog-copy",children:"This action cannot be undone. This room and all its messages will be permanently deleted."}),t.jsxs("div",{className:"chat-new-dialog-actions",children:[t.jsx("button",{className:"btn btn-sm",onClick:()=>W(null),children:"Cancel"}),t.jsx("button",{className:"btn btn-sm btn-danger",onClick:()=>{(async()=>{try{await c.deleteRoom(tt),W(null)}catch{r("Failed to delete room","error")}})()},children:"Delete"})]})]})}),j&&y==="rooms"?t.jsxs("div",{ref:$t,className:"chat-thread",children:[c.activeRoom?t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"chat-room-thread-header",children:[$&&t.jsx("button",{className:"btn-icon",onClick:Ot,"data-testid":"chat-back-btn",children:t.jsx(Ds,{size:16})}),t.jsxs("div",{className:"chat-room-switcher-menu",ref:us,children:[t.jsxs("button",{type:"button",className:"chat-room-switcher-trigger","data-testid":"chat-room-switcher-trigger","aria-haspopup":"menu","aria-expanded":ht,onClick:()=>nt(e=>!e),children:[t.jsxs("span",{className:"chat-thread-header-title",children:["#",c.activeRoom.name]}),t.jsx(Ct,{size:16,"aria-hidden":"true"})]}),ht&&t.jsx("div",{role:"menu",className:"chat-room-switcher-dropdown","data-testid":"chat-room-switcher-dropdown",children:c.rooms.map(e=>t.jsxs("button",{type:"button",role:"menuitem",className:`chat-room-switcher-option${e.id===c.activeRoom?.id?" chat-room-switcher-option--active":""}`,"data-testid":`chat-room-switcher-option-${e.id}`,onClick:()=>{v("room",e.id,e.updatedAt),c.selectRoom(e.id),nt(!1)},children:["#",e.name]},e.id))})]}),t.jsx("div",{className:"chat-room-thread-members",children:c.activeRoomMembers.map(e=>t.jsx(Xs,{agent:ge.get(e.agentId)??{id:e.agentId,name:e.agentId.slice(0,30)}},e.agentId))})]}),t.jsxs("div",{className:"chat-messages",ref:be,onScroll:bs,children:[c.messagesLoading?t.jsx("div",{className:"chat-empty-state",children:"Loading messages..."}):c.messages.length===0?t.jsx("div",{className:"chat-empty-state",children:"No messages yet. Start the conversation!"}):c.messages.map(e=>{const a=e.senderAgentId?ge.get(e.senderAgentId)?.name??e.senderAgentId.slice(0,30):"You",o={id:e.id,sessionId:e.roomId,role:e.role,content:e.content,thinkingOutput:e.thinkingOutput??void 0,toolCalls:void 0,fallbackInfo:void 0,attachments:e.attachments,createdAt:e.createdAt};return t.jsx(is,{message:o,forcePlain:I,agentName:a,hideAssistantIdentity:!1,showAssistantModelTag:!1,activeModelTag:null,activeModelProvider:null,activeSessionId:c.activeRoom?.id??null,mentionAgentsByName:Ft,roomContext:Ee,onScrollToTop:Qt},e.id)}),t.jsx("div",{ref:ls})]}),c.activeRoom&&K&&t.jsxs("button",{type:"button",className:"btn btn-sm chat-jump-to-latest","data-testid":"chat-jump-to-latest",onClick:()=>Fe("fab-click"),children:[t.jsx(Ct,{size:14}),"Latest"]})]}):t.jsx("div",{className:"chat-room-empty-pane","data-testid":"chat-rooms-empty-pane",children:"Select a room or create one"}),c.activeRoom&&t.jsx("div",{className:"chat-input-area",children:t.jsxs("div",{className:"chat-input-row",children:[t.jsxs("div",{className:"chat-input-wrapper",children:[t.jsx("textarea",{ref:vs,className:"chat-input-textarea",placeholder:"Type a message...",value:N,onChange:ys,onKeyDown:xs,onKeyUp:ws,onClick:wt,onBlur:Ss,onFocus:Cs,onTouchStart:e=>{typeof window>"u"||window.innerWidth>768||Ps()&&document.activeElement!==e.currentTarget&&(e.preventDefault(),e.currentTarget.focus({preventScroll:!0}))},rows:1,"data-testid":"chat-input"}),t.jsx(Fs,{agents:Xe,filter:ke,highlightedIndex:Ve,visible:pe,onSelect:xt,position:"below",roomMemberIds:Ee?.memberIds,roomName:Ee?.roomName})]}),t.jsx("button",{type:"button",className:"chat-input-send",onPointerDown:e=>{e.pointerType&&e.pointerType!=="mouse"&&e.preventDefault()},onMouseDown:e=>{e.preventDefault()},onClick:()=>{zt()},disabled:!N.trim(),"data-testid":"chat-send-btn",style:{touchAction:"manipulation"},children:t.jsx(Ls,{size:16})})]})})]}):t.jsxs("div",{ref:$t,className:"chat-thread",children:[(Kt||!$)&&t.jsxs("div",{className:"chat-thread-header",children:[$&&Kt&&t.jsx("button",{className:"btn-icon",onClick:Ut,"data-testid":"chat-back-btn",children:t.jsx(Ds,{size:16})}),t.jsx("div",{className:"chat-thread-header-identity","data-testid":"chat-thread-header-identity",children:hn?t.jsxs("div",{className:"chat-mobile-session-menu",ref:ds,children:[t.jsxs("button",{type:"button",className:"btn chat-mobile-session-trigger","data-testid":"chat-mobile-session-trigger","aria-haspopup":"menu","aria-expanded":re,onClick:()=>de(e=>!e),children:[_e?t.jsx(lt,{provider:_e,size:"md"}):t.jsx(dt,{size:16}),t.jsx("span",{className:"chat-thread-header-title",children:Gt}),Ns&&t.jsx("span",{className:"chat-model-tag",children:Le}),t.jsx(Ct,{size:16,"aria-hidden":"true"})]}),re&&t.jsx("div",{className:"chat-mobile-session-dropdown",role:"menu","data-testid":"chat-mobile-session-dropdown",children:F.map(e=>t.jsx("button",{type:"button",role:"menuitem",className:`chat-mobile-session-option${i?.id===e.id?" chat-mobile-session-option--active":""}`,"data-testid":`chat-mobile-session-option-${e.id}`,onClick:()=>ks(e.id),children:t.jsx("span",{className:"chat-mobile-session-option-title",children:e.title||"Untitled"})},e.id))})]}):t.jsxs(t.Fragment,{children:[_e?t.jsx(lt,{provider:_e,size:"md"}):t.jsx(dt,{size:16}),t.jsx("span",{className:"chat-thread-header-title",children:Gt}),Ns&&t.jsx("span",{className:"chat-model-tag",children:Le})]})}),Kt&&t.jsx("button",{type:"button",className:`chat-thread-header-render-toggle${I?" chat-thread-header-render-toggle--plain":""}`,"data-testid":"chat-thread-render-toggle","aria-label":I?"Show all messages as rendered Markdown":"Show all messages as plain text",onClick:gn,children:I?t.jsx(qn,{size:14}):t.jsx(Xn,{size:14})}),!$&&t.jsxs("button",{className:"btn btn-sm btn-primary chat-thread-header-new-chat",onClick:()=>M(!0),"data-testid":"chat-thread-new-chat-btn",children:[t.jsx(ct,{size:14}),"New Chat"]})]}),t.jsxs("div",{className:"chat-messages",ref:be,onScroll:bs,children:[h?t.jsxs(t.Fragment,{children:[p.map(e=>t.jsx(is,{message:e,forcePlain:I,agentName:Wt,hideAssistantIdentity:qt,showAssistantModelTag:Vt,activeModelTag:Le,activeModelProvider:_e,activeSessionId:i?.id??null,mentionAgentsByName:Ft,roomContext:null,copyAction:Jt&&e.role==="assistant"?Yt(e.id,e.content):void 0,onScrollToTop:Qt},e.id)),t.jsxs("div",{className:"chat-message chat-message--assistant chat-message--streaming",children:[!qt&&t.jsxs("div",{className:"chat-message-avatar",children:[_e?t.jsx(lt,{provider:_e,size:"sm"}):t.jsx(dt,{size:14}),t.jsx("span",{children:Wt}),Vt]}),P?pn(P,I):t.jsx("div",{className:"chat-message-content chat-message-content--waiting",children:Q?"Thinking…":"Connecting…"}),Jt&&P&&Yt("__streaming__",P,"chat-copy-response-streaming"),en(Z),Q&&t.jsxs("details",{className:"chat-message-thinking",children:[t.jsx("summary",{children:"Thinking"}),t.jsx("pre",{className:"chat-message-thinking-content",children:Rt(Q)})]}),t.jsxs("div",{className:"chat-typing-indicator",children:[t.jsx("span",{}),t.jsx("span",{}),t.jsx("span",{})]})]})]}):S?t.jsx("div",{className:"chat-empty-state",children:"Loading messages..."}):p.length===0&&!i?mn():p.length===0&&i?t.jsx("div",{className:"chat-empty-state",children:"No messages yet. Start the conversation!"}):t.jsx(t.Fragment,{children:p.map(e=>t.jsx(is,{message:e,forcePlain:I,agentName:Wt,hideAssistantIdentity:qt,showAssistantModelTag:Vt,activeModelTag:Le,activeModelProvider:_e,activeSessionId:i?.id??null,mentionAgentsByName:Ft,roomContext:null,copyAction:Jt&&e.role==="assistant"?Yt(e.id,e.content):void 0,onScrollToTop:Qt},e.id))}),t.jsx("div",{ref:ls})]}),K&&t.jsxs("button",{type:"button",className:"btn btn-sm chat-jump-to-latest","data-testid":"chat-jump-to-latest",onClick:()=>Fe("fab-click"),children:[t.jsx(Ct,{size:14}),"Latest"]}),i&&t.jsxs("div",{className:"chat-input-area",children:[t.jsx("input",{ref:hs,type:"file",accept:"image/*,.txt,.json,.yaml,.yml,.log,.csv,.xml,.md",multiple:!0,style:{display:"none"},onChange:e=>{vt(e.target.files),e.target.value=""}}),xe&&t.jsx("div",{className:"chat-skill-menu","data-testid":"chat-skill-menu",role:"listbox","aria-label":"Skill suggestions",children:oe?t.jsx("div",{className:"chat-skill-menu-empty",children:"Loading skills…"}):ye.length===0?t.jsx("div",{className:"chat-skill-menu-empty",children:st?"No skills found":"No skills available"}):ye.map((e,a)=>t.jsxs("button",{type:"button",role:"option","aria-selected":a===We,className:`chat-skill-menu-item${a===We?" chat-skill-menu-item--highlighted":""}`,onMouseDown:o=>o.preventDefault(),onMouseEnter:()=>Oe(a),onClick:()=>Ht(e),children:[t.jsx("span",{className:"chat-skill-menu-item-name",children:e.name}),t.jsx("span",{className:"chat-skill-menu-item-description",title:e.relativePath,children:e.relativePath})]},e.id))}),A.length>0&&t.jsx("div",{className:"chat-attachment-previews","data-testid":"chat-attachment-previews",children:A.map((e,a)=>t.jsxs("div",{className:"chat-attachment-preview","data-testid":`chat-attachment-preview-${a}`,children:[e.previewUrl?t.jsx("img",{src:e.previewUrl,alt:e.file.name}):t.jsx("span",{className:"chat-attachment-preview-name",children:e.file.name}),t.jsx("button",{type:"button",className:"chat-attachment-remove",onClick:()=>an(a),"data-testid":`chat-attachment-remove-${a}`,"aria-label":`Remove ${e.file.name}`,children:"×"})]},e.previewUrl||`${e.file.name}-${a}`))}),t.jsxs("div",{className:"chat-input-row",children:[t.jsx("button",{type:"button",className:"btn-icon chat-attach-btn","data-testid":"chat-attach-btn","aria-label":"Attach files",onClick:()=>hs.current?.click(),children:t.jsx(Jn,{size:16})}),t.jsxs("div",{className:`chat-input-wrapper${U?" chat-input-wrapper--dragover":""}`,onDragOver:e=>{e.preventDefault(),O(!0)},onDragLeave:()=>O(!1),onDrop:e=>{e.preventDefault(),O(!1),vt(e.dataTransfer.files)},children:[t.jsx("textarea",{ref:vs,className:"chat-input-textarea",placeholder:"Type a message...",value:N,onChange:ys,onKeyDown:xs,onKeyUp:ws,onClick:wt,onBlur:Ss,onFocus:Cs,onPaste:rn,onTouchStart:e=>{typeof window>"u"||window.innerWidth>768||Ps()&&document.activeElement!==e.currentTarget&&(e.preventDefault(),e.currentTarget.focus({preventScroll:!0}))},rows:1,"data-testid":"chat-input"}),t.jsx(Fs,{agents:Xe,filter:ke,highlightedIndex:Ve,visible:pe,onSelect:xt,position:"below",roomMemberIds:Ee?.memberIds,roomName:Ee?.roomName}),t.jsx(Yn,{visible:_.mentionActive&&!pe,position:sn,tasks:_.tasks,files:_.files,selectedIndex:_.selectedIndex,onSelectTask:e=>{it(_.selectTask(e,N),`#${e.id}`)},onSelectFile:e=>{it(_.selectFile(e,N),`#${e.path}`)},loading:_.loading}),B&&t.jsxs("div",{className:"chat-pending-message","data-testid":"chat-pending-indicator",children:[t.jsx("span",{children:`Queued: ${fn}`}),t.jsx("button",{type:"button",className:"chat-pending-message-dismiss","aria-label":"Dismiss queued message","data-testid":"chat-pending-dismiss",onClick:R,children:"×"})]})]}),h?t.jsx("button",{className:"chat-input-stop",onClick:k,"aria-label":"Stop generation","data-testid":"chat-stop-btn",children:t.jsx(Qn,{size:14})}):t.jsx("button",{type:"button",className:"chat-input-send",onPointerDown:e=>{e.pointerType&&e.pointerType!=="mouse"&&e.preventDefault()},onMouseDown:e=>{e.preventDefault()},onClick:()=>{_t()},disabled:!N.trim()&&A.length===0,"data-testid":"chat-send-btn",style:{touchAction:"manipulation"},children:t.jsx(Ls,{size:16})})]})]})]}),j&&t.jsx(da,{isOpen:ut,onClose:()=>Se(!1),projectId:n,existingRoomNames:c.rooms.map(e=>e.name),onCreate:async e=>{await c.createRoom({name:e.name,memberAgentIds:e.memberAgentIds}),y!=="rooms"&&g("rooms"),Se(!1),$&&le(!1)}}),te&&t.jsx(Sa,{projectId:n,onClose:()=>M(!1),onCreate:on})]})}export{Ra as ChatView,ma as clampChatInputHeight,qs as resolveSessionProvider};
|