@runfusion/fusion 0.27.0 → 0.27.1
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 +1865 -576
- package/dist/client/assets/{AgentDetailView-DwLmRXTY.js → AgentDetailView-shgiiUb4.js} +1 -1
- package/dist/client/assets/{AgentsView-CV3vm7Qk.css → AgentsView-B3ADnF0D.css} +1 -1
- package/dist/client/assets/{AgentsView-D-N6aA0P.js → AgentsView-CpwqOVDz.js} +8 -8
- package/dist/client/assets/ChatView-DyRBOIKL.js +1 -0
- package/dist/client/assets/{DevServerView-BiA1nYtt.js → DevServerView-Cdelj9-m.js} +1 -1
- package/dist/client/assets/{DirectoryPicker-DvBviDG6.js → DirectoryPicker-C0kmRv0u.js} +1 -1
- package/dist/client/assets/{DocumentsView-BWXOxpuq.js → DocumentsView-B94U9ijs.js} +1 -1
- package/dist/client/assets/{EvalsView-CJFbtL7i.js → EvalsView-O_4YWy--.js} +1 -1
- package/dist/client/assets/{ExperimentalAgentOnboardingModal-DuGIPd0B.js → ExperimentalAgentOnboardingModal-CkEiF85-.js} +1 -1
- package/dist/client/assets/{InsightsView-BBpRiolN.js → InsightsView-D-Qe0tRr.js} +1 -1
- package/dist/client/assets/{MemoryView-48LuNkKk.js → MemoryView-CoRUmRvb.js} +1 -1
- package/dist/client/assets/{NodesView-CGQWSNZM.js → NodesView-DQzXjcLc.js} +1 -1
- package/dist/client/assets/{PiExtensionsManager-i-7UL2oh.js → PiExtensionsManager-Dn1LmFbq.js} +1 -1
- package/dist/client/assets/{PluginManager-DoSAykD6.js → PluginManager-Y0fs-6No.js} +1 -1
- package/dist/client/assets/{ResearchView-XZuRtOxE.js → ResearchView-CjOxKhdS.js} +1 -1
- package/dist/client/assets/{SettingsModal-CmeF8CN4.js → SettingsModal-Bg1-3JO_.js} +1 -1
- package/dist/client/assets/SettingsModal-DL7tjJQa.js +31 -0
- package/dist/client/assets/{SetupWizardModal-CgtvpMX9.js → SetupWizardModal-DuzYPbuJ.js} +1 -1
- package/dist/client/assets/{SkillsView-DErYRumF.js → SkillsView-BIFoVNUf.js} +1 -1
- package/dist/client/assets/{StashRecoveryView-QJrNS4Vg.js → StashRecoveryView-C52KsV7f.js} +1 -1
- package/dist/client/assets/{TodoView-BD9NRwq0.js → TodoView-sS_mT0Y7.js} +1 -1
- package/dist/client/assets/{dashboard-view-Ws9_ZnKu.js → dashboard-view-MB-86hAu.js} +1 -1
- package/dist/client/assets/{folder-open-CHSlllzf.js → folder-open-B9cwJ-OX.js} +1 -1
- package/dist/client/assets/{index-bEwSVl7B.js → index-BOjPRqEk.js} +161 -161
- package/dist/client/assets/index-BmSEq8Rb.css +1 -0
- package/dist/client/assets/{star-BgVwWAPz.js → star-BDn04UYV.js} +1 -1
- package/dist/client/assets/{upload-CAzycxr9.js → upload-zdPPycKQ.js} +1 -1
- package/dist/client/assets/{users-CZnxCCCJ.js → users-CPYZjK2g.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 +1721 -532
- 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-roadmap/package.json +1 -1
- package/dist/plugins/fusion-plugin-whatsapp-chat/package.json +1 -1
- package/package.json +1 -1
- package/skill/fusion/SKILL.md +1 -1
- package/skill/fusion/references/engine-tools.md +1 -1
- package/skill/fusion/references/extension-tools.md +1 -0
- package/skill/fusion/workflows/task-management.md +3 -1
- package/dist/client/assets/ChatView-DnCdKu8Z.js +0 -1
- package/dist/client/assets/SettingsModal-DBcjf9Bu.js +0 -31
- package/dist/client/assets/index-DCovGm5b.css +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fusion/pi-claude-cli",
|
|
3
|
-
"version": "0.27.
|
|
3
|
+
"version": "0.27.1",
|
|
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,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@runfusion/fusion",
|
|
3
|
-
"version": "0.27.
|
|
3
|
+
"version": "0.27.1",
|
|
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",
|
package/skill/fusion/SKILL.md
CHANGED
|
@@ -61,7 +61,7 @@ Based on the user's request, route to the appropriate workflow:
|
|
|
61
61
|
<quick_reference>
|
|
62
62
|
|
|
63
63
|
**Create a task:**
|
|
64
|
-
Use `fn_task_create` with a descriptive message. Include the problem AND desired outcome.
|
|
64
|
+
Use `fn_task_create` with a descriptive message. Include the problem AND desired outcome, and set `priority` (`low`/`normal`/`high`/`urgent`) when urgency matters.
|
|
65
65
|
|
|
66
66
|
**List tasks:**
|
|
67
67
|
Use `fn_task_list` to see all tasks grouped by column. Use `column` param to filter.
|
|
@@ -11,7 +11,7 @@ These tools are **not** part of the user-invokable extension surface. They are i
|
|
|
11
11
|
|
|
12
12
|
| Tool | Agent Types | Purpose | Parameters |
|
|
13
13
|
|---|---|---|---|
|
|
14
|
-
| `fn_task_create` | triage, executor, heartbeat | Create a follow-up task from within an agent run | `description` (string), `dependencies?` (string[]) |
|
|
14
|
+
| `fn_task_create` | triage, executor, heartbeat | Create a follow-up task from within an agent run | `description` (string), `dependencies?` (string[]), `priority?` (`low` \| `normal` \| `high` \| `urgent`) |
|
|
15
15
|
| `fn_task_log` | executor, heartbeat | Write significant task log entries | `message` (string), `outcome?` (string) |
|
|
16
16
|
| `fn_task_document_write` | triage, executor, heartbeat | Save/update a named task document revision | `key` (string), `content` (string), `author?` (string) |
|
|
17
17
|
| `fn_task_document_read` | triage, executor, heartbeat | Read one task document or list all | `key?` (string) |
|
|
@@ -17,6 +17,7 @@ Create a new task on the Fusion task board. The task enters the planning column
|
|
|
17
17
|
| `description` | string | ✓ | What needs to be done — be descriptive |
|
|
18
18
|
| `depends` | array | — | Task IDs this depends on (e.g. ['FN-001', 'FN-002']) |
|
|
19
19
|
| `agentId` | string | — | Agent ID to assign this task to (e.g. 'agent-abc123') |
|
|
20
|
+
| `priority` | string(enum) | — | Task priority (low, normal, high, urgent) |
|
|
20
21
|
|
|
21
22
|
### fn_task_update
|
|
22
23
|
|
|
@@ -17,6 +17,7 @@ Use only the public `fn_*` extension tools in this workflow. Do not substitute i
|
|
|
17
17
|
- Include the problem AND the desired outcome
|
|
18
18
|
- Be specific — the AI triage agent uses your description to write the specification
|
|
19
19
|
- Optionally add dependencies with the `depends` parameter
|
|
20
|
+
- Optionally set urgency with `priority` (`low`, `normal`, `high`, `urgent`)
|
|
20
21
|
|
|
21
22
|
2. The task enters **triage** where the AI auto-generates a PROMPT.md with:
|
|
22
23
|
- Steps, file scope, acceptance criteria
|
|
@@ -29,7 +30,8 @@ Example:
|
|
|
29
30
|
```
|
|
30
31
|
fn_task_create({
|
|
31
32
|
description: "The login form doesn't validate email format before submission. Add client-side email validation that shows an inline error message when the email is invalid. Use the existing form validation pattern from the signup form.",
|
|
32
|
-
depends: ["FN-042"]
|
|
33
|
+
depends: ["FN-042"],
|
|
34
|
+
priority: "high"
|
|
33
35
|
})
|
|
34
36
|
```
|
|
35
37
|
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as s,a as Fs,j as t}from"./vendor-react-K0fH_qHe.js";import{i as dt,b3 as es,t as hs,b4 as zs,b5 as ts,b6 as Us,w as Pt,b7 as ze,b8 as _s,b9 as Os,ba as Hs,bb as Bs,bc as Ws,bd as Gs,s as fs,be as Vs,bf as Ks,bg as Rt,bh as qs,bi as Js,bj as Ys,bk as Xs,k as gs,bl as Qs,p as Zs,bm as en,bn as tn,u as sn,bo as nn,ab as ps,ac as bs,bp as an,bq as rn,S as on,W as At,P as Ye,I as ot,ao as cn,br as ss,bs as ns,bt as as,B as Xe,a as rs,a8 as ln,a9 as dn,bu as un,bv as mn,aS as hn,bw as fn,bx as os,by as gn,h as pn,j as is,m as bn}from"./index-bEwSVl7B.js";import"./vendor-xterm-DzcZoU0P.js";const Et="kb-chat-active-session";function cs(n){const r=typeof n=="string"?n.trim():"",m=r.indexOf("/");return!r||m<=0||m>=r.length-1?{}:{modelProvider:r.slice(0,m),modelId:r.slice(m+1)}}function vn(n){const r=n?.toolCalls;if(!Array.isArray(r))return;const m=r.map(o=>{if(!o||typeof o!="object")return null;const l=o,x=typeof l.toolName=="string"?l.toolName:"";if(!x)return null;const D=l.args;return{toolName:x,...D&&typeof D=="object"?{args:D}:{},isError:!!l.isError,result:l.result,status:"completed"}}).filter(o=>o!==null);return m.length>0?m:void 0}function xn(n){const r=n?.fallback;if(!r||typeof r!="object")return;const m=r,o=typeof m.primaryModel=="string"?m.primaryModel:"",l=typeof m.fallbackModel=="string"?m.fallbackModel:"",x=m.triggerPoint;if(!(!o||!l||x!=="session-creation"&&x!=="prompt-time"))return{primaryModel:o,fallbackModel:l,triggerPoint:x}}function Tt(n){return{id:n.id,sessionId:n.sessionId,role:n.role,content:n.content,thinkingOutput:n.thinkingOutput,toolCalls:vn(n.metadata),fallbackInfo:xn(n.metadata),attachments:n.attachments,createdAt:n.createdAt}}function wn(n,r){const[m,o]=s.useState([]),[l,x]=s.useState(null),[D,P]=s.useState(!0),[$,y]=s.useState([]),[ee,v]=s.useState(!1),[z,S]=s.useState(!1),[ne,R]=s.useState(""),[A,f]=s.useState(""),[k,E]=s.useState([]),[I,T]=s.useState(""),[oe,te]=s.useState(""),[U,b]=s.useState(!0),[h,d]=s.useState(new Map),i=s.useRef(null),u=s.useRef(!1),w=s.useRef(""),M=s.useRef(null),J=s.useRef(m),_=s.useRef(l),Y=s.useRef(z);J.current=m,_.current=l,Y.current=z,s.useEffect(()=>{w.current=I},[I]);const Re=s.useRef(new Set),V=s.useRef(0),pe=s.useRef(n);pe.current!==n&&(pe.current=n,V.current++),s.useEffect(()=>{const g=V.current;dt(void 0,n).then(p=>{if(V.current!==g)return;const C=new Map;for(const L of p)C.set(L.id,L);d(C)}).catch(()=>{})},[n]);const Ae=s.useCallback(async()=>{P(!0);try{const p=[...(await es(n)).sessions].sort((C,L)=>new Date(L.updatedAt).getTime()-new Date(C.updatedAt).getTime());o(p)}catch{}finally{P(!1)}},[n]);s.useEffect(()=>{Ae()},[Ae]);const De=s.useRef(()=>{}),X=s.useRef(!1);s.useEffect(()=>{X.current=!1},[n]),s.useEffect(()=>{if(D||X.current||_.current)return;const g=hs(Et,n);if(!g){X.current=!0;return}const p=m.find(C=>C.id===g);if(p){X.current=!0,De.current(g,p);return}X.current=!0},[D,m,n]);const N=s.useCallback(async(g,p)=>{v(!0);try{const C=await zs(g,{limit:50,...p},n),L=C.messages.map(Tt);p?.offset&&p.offset>0?y(Q=>[...L,...Q]):y(L),b(C.messages.length>=50)}catch{}finally{v(!1)}},[n]),ie=s.useCallback(()=>{M.current?.(),M.current=null,w.current="",T(""),R(""),f(""),E([]),S(!1)},[]),ue=s.useCallback((g,p)=>{if(i.current||!g)return!0;u.current=!1,p&&(R(p.streamingText),f(p.streamingThinking),E(p.toolCalls)),S(!0);const{handlers:C}=ts({sessionId:g,tempUserMessageId:"",setStreamingText:R,setStreamingThinking:f,setStreamingToolCalls:E,cancelStreamingFlushesRef:M,addToast:r,onFallbackSession:(Q,G)=>{const se=cs(Q.fallbackModel);o(O=>O.map(ae=>ae.id===G?{...ae,...se}:ae)),x(O=>O&&O.id===G?{...O,...se}:O)},onDone:()=>{R(""),f(""),E([]),S(!1),Y.current=!1,i.current=null,N(g)},onError:Q=>{R(""),f(""),E([]),S(!1),Y.current=!1,i.current=null;const G=typeof Q=="string"&&Q.trim()?Q:"Failed to get response";r?.(G,"error"),N(g)}}),L=Us(g,C,n,{...typeof p?.replayFromEventId=="number"?{lastEventId:p.replayFromEventId}:{}});return i.current=L,!0},[r,N,n]),be=s.useCallback((g,p)=>{const C=_.current?.id??null;if(g&&C===g&&!p)return;i.current&&(i.current.close(),i.current=null);const L=p??m.find(Q=>Q.id===g);x(L||null),ie(),b(!0),g?N(g):y([]),L?.isGenerating&&ue(L.id,L.inFlightGeneration),g?Pt(Et,g,n):ze(Et,n)},[ue,m,N,n,ie]);De.current=be;const Qe=s.useCallback(async g=>{const p=await _s(g,n);i.current&&(i.current.close(),i.current=null);const C={id:p.session.id,title:p.session.title,agentId:p.session.agentId,status:p.session.status,modelProvider:p.session.modelProvider,modelId:p.session.modelId,createdAt:p.session.createdAt,updatedAt:p.session.updatedAt};return o(L=>L.some(Q=>Q.id===C.id)?L:[C,...L]),ie(),be(C.id,C),y([]),C},[n,ie,be]),ut=s.useCallback(async g=>{await Os(g,{status:"archived"},n),o(p=>p.filter(C=>C.id!==g)),l?.id===g&&(x(null),y([]))},[l,n]),Ze=s.useCallback(async g=>{l?.id===g&&i.current&&(i.current.close(),i.current=null),await Hs(g,n),o(p=>p.filter(C=>C.id!==g)),l?.id===g&&(x(null),y([]))},[l,n]),ve=s.useCallback(async()=>{!l||!U||await N(l.id,{offset:$.length})},[l,U,N,$.length]),xe=s.useCallback(()=>{l&&(u.current=!0,M.current?.(),M.current=null,i.current?.close(),i.current=null,Bs(l.id,n).catch(()=>{}),S(!1),R(""),f(""),E([]))},[l,n]),_e=s.useCallback(()=>{w.current="",T("")},[]),we=s.useRef(()=>{}),ye=Ws(),Se=s.useCallback((g,p)=>{if(!l)return;if(Y.current){w.current=g,T(g);return}u.current=!1,i.current&&(i.current.close(),i.current=null);const C=`temp-${Date.now()}`,L={id:C,sessionId:l.id,role:"user",content:g,createdAt:new Date().toISOString()};y(G=>[...G,L]),R(""),f(""),E([]),S(!0);const{handlers:Q}=ts({sessionId:l.id,tempUserMessageId:C,setStreamingText:R,setStreamingThinking:f,setStreamingToolCalls:E,cancelStreamingFlushesRef:M,addToast:r,onFallbackSession:(G,se)=>{const O=cs(G.fallbackModel);o(ae=>ae.map(F=>F.id===se?{...F,...O}:F)),x(ae=>ae&&ae.id===se?{...ae,...O}:ae)},onDone:({messageId:G,message:se,accumulated:O})=>{const ae=se?Tt(se):{id:G||`msg-${Date.now()}`,sessionId:l.id,role:"assistant",content:O.text,thinkingOutput:O.thinking,toolCalls:O.toolCalls.length>0?O.toolCalls:void 0,fallbackInfo:O.fallbackInfo,createdAt:new Date().toISOString()};Re.current.add(ae.id),y(B=>[...B,ae]),R(""),f(""),E([]),S(!1),Y.current=!1,i.current=null,setTimeout(()=>{Re.current.delete(ae.id)},1e3),Ae();const F=w.current.trim();F&&(w.current="",T(""),we.current(F))},onError:(G,se)=>{y(F=>F.filter(B=>B.id!==se)),R(""),f(""),E([]),S(!1),Y.current=!1,i.current=null,console.error("[useChat] Stream error:",G);const O=typeof G=="string"&&G.trim()?G:"Failed to get response";if(typeof G=="string"&&Vs(G)&&(ye.isHiddenNow()||ye.wasRecentlyHidden(5e3))?(console.info("[useChat] Suppressed tab-suspension stream error:",G),l?.id&&(l.isGenerating?ue(l.id,l.inFlightGeneration):N(l.id))):r?.(O,"error"),!u.current){const F=w.current.trim();F&&(w.current="",T(""),we.current(F))}}});i.current=Gs(l.id,g,Q,p,n)},[l,n,Ae,r,N,ue,ye]);we.current=Se;const ke=oe?m.filter(g=>g.title?.toLowerCase().includes(oe.toLowerCase())||g.agentId.toLowerCase().includes(oe.toLowerCase())):m;return s.useEffect(()=>{if(!_.current?.isGenerating||(i.current||ue(_.current.id,_.current.inFlightGeneration),!Y.current||i.current||!_.current))return;const g=setInterval(async()=>{if(!Y.current||i.current||!_.current){clearInterval(g);return}try{(await es(n)).sessions.find(L=>L.id===_.current?.id)?.isGenerating||(clearInterval(g),await N(_.current.id),R(""),f(""),E([]),S(!1))}catch{}},3e3);return()=>clearInterval(g)},[ue,N,n,l]),s.useEffect(()=>{const g=V.current,p=n?`?projectId=${encodeURIComponent(n)}`:"",C=()=>V.current!==g,L=F=>{if(C())return;const B=JSON.parse(F.data);o(K=>K.some(Z=>Z.id===B.id)?K:[B,...K])},Q=F=>{if(C())return;const B=JSON.parse(F.data);o(K=>[...K.map(ce=>ce.id===B.id?B:ce)]),_.current?.id===B.id&&(x(B),B.isGenerating&&!i.current&&ue(B.id,B.inFlightGeneration))},G=F=>{if(C())return;const{id:B}=JSON.parse(F.data);o(K=>K.filter(Z=>Z.id!==B)),_.current?.id===B&&(x(null),y([]))},se=F=>{if(C())return;const B=JSON.parse(F.data),K=Tt(B);if(!Re.current.has(K.id)){if(_.current?.id===K.sessionId&&Y.current&&!i.current&&K.role==="assistant"){y(Z=>Z.some(ce=>ce.id===K.id)?Z:[...Z,K]),R(""),f(""),E([]),S(!1);return}_.current?.id===K.sessionId&&!Y.current&&y(Z=>{if(Z.some(ce=>ce.id===K.id))return Z;if(K.role==="user"){const ce=Z.findIndex(me=>me.role==="user"&&me.id.startsWith("temp-")&&me.content.trim()===K.content.trim());if(ce>=0){const me=[...Z];return me[ce]=K,me}}return[...Z,K]})}},O=F=>{if(C())return;const{id:B}=JSON.parse(F.data);y(K=>K.filter(Z=>Z.id!==B))};return fs(`/api/events${p}`,{events:{"chat:session:created":L,"chat:session:updated":Q,"chat:session:deleted":G,"chat:message:added":se,"chat:message:deleted":O}})},[ue,n]),s.useEffect(()=>()=>{i.current&&(i.current.close(),i.current=null)},[]),{sessions:m,activeSession:l,sessionsLoading:D,messages:$,messagesLoading:ee,isStreaming:z,streamingText:ne,streamingThinking:A,streamingToolCalls:k,pendingMessage:I,selectSession:be,createSession:Qe,archiveSession:ut,deleteSession:Ze,sendMessage:Se,stopStreaming:xe,clearPendingMessage:_e,loadMoreMessages:ve,hasMoreMessages:U,searchQuery:oe,setSearchQuery:te,filteredSessions:ke,refreshSessions:Ae,agentsMap:h}}const je="fusion:chat-active-room";function $t(n){return[...n].sort((r,m)=>new Date(m.updatedAt).getTime()-new Date(r.updatedAt).getTime())}function Je(n,r){const m=n.findIndex(l=>l.id===r.id);if(m===-1)return $t([r,...n]);const o=[...n];return o[m]=r,$t(o)}function Me(n){try{return JSON.parse(n.data)}catch{return null}}function yn(n,r){return{id:`temp-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,roomId:n,role:"user",content:r,thinkingOutput:null,metadata:null,senderAgentId:null,mentions:[],createdAt:new Date().toISOString()}}function Sn(n,r){const[m,o]=s.useState([]),[l,x]=s.useState(!0),[D,P]=s.useState(null),[$,y]=s.useState(null),[ee,v]=s.useState([]),[z,S]=s.useState([]),[ne,R]=s.useState(!1),A=s.useRef(m),f=s.useRef($),k=s.useRef(0),E=s.useRef(n);A.current=m,f.current=$,E.current!==n&&(E.current=n,k.current+=1);const I=s.useCallback(async(h,d=!0)=>{if(!h){v([]),S([]),R(!1);return}d&&S([]),R(!0);try{const[i,u]=await Promise.all([Ks(h.id,n),Rt(h.id,{limit:100},n)]);v(i.members),S(u.messages)}catch{v([]),S([])}finally{R(!1)}},[n]),T=s.useCallback(async()=>{x(!0);try{const h=await qs({},n),d=$t(h.rooms);o(d),P(null);const i=hs(je,n);if(i){const u=d.find(w=>w.id===i)??null;u?(y(u),I(u,!0)):ze(je,n)}}catch(h){const d=h instanceof Error?h.message:"Failed to load chat rooms";P(d),r?.(d,"error")}finally{x(!1)}},[r,I,n]),oe=s.useCallback(h=>{if(!h){y(null),ze(je,n),I(null,!0);return}const d=A.current.find(i=>i.id===h)??null;y(d),d&&(Pt(je,d.id,n),I(d,!0))},[I,n]),te=s.useCallback(async h=>{const i=(await Js({name:h.name,memberAgentIds:h.memberAgentIds},n)).room;return o(u=>Je(u,i)),y(i),Pt(je,i.id,n),await I(i,!0),i},[I,n]),U=s.useCallback(async h=>{await Ys(h,n),o(d=>d.filter(i=>i.id!==h)),f.current?.id===h&&(y(null),v([]),S([]),ze(je,n))},[n]),b=s.useCallback(async(h,d)=>{const i=f.current,u=i?.id;if(!u)throw new Error("Select a room before sending a message");const w=yn(u,h);f.current?.id===u&&S(M=>[...M,w]);try{const M=await Xs(u,{content:h,...d?.attachments?{attachments:d.attachments}:{}},n);M.message?.createdAt&&i&&o(_=>Je(_,{...i,updatedAt:M.message.createdAt})),f.current?.id===u&&S(_=>_.map(Y=>Y.id===w.id?M.message:Y));const J=await Rt(u,{limit:100},n);if(f.current?.id!==u)return;S(J.messages)}catch(M){try{const J=await Rt(u,{limit:100},n);f.current?.id===u&&S(J.messages)}catch{f.current?.id===u&&S(J=>J.filter(_=>_.id!==w.id))}throw M}},[n]);return s.useEffect(()=>{T()},[T]),s.useEffect(()=>{const h=k.current,d=n?`/api/events?projectId=${encodeURIComponent(n)}`:"/api/events";return fs(d,{onReconnect:()=>{T()},events:{"chat:room:created":i=>{if(k.current!==h)return;const u=Me(i);u&&o(w=>Je(w,u))},"chat:room:updated":i=>{if(k.current!==h)return;const u=Me(i);u&&(o(w=>Je(w,u)),f.current?.id===u.id&&y(u))},"chat:room:deleted":i=>{if(k.current!==h)return;const u=Me(i);u?.id&&(o(w=>w.filter(M=>M.id!==u.id)),f.current?.id===u.id&&(y(null),v([]),S([]),ze(je,n)))},"chat:room:member:added":i=>{if(k.current!==h)return;const u=Me(i);!u||f.current?.id!==u.roomId||v(w=>w.some(M=>M.agentId===u.agentId)?w:[...w,u])},"chat:room:member:removed":i=>{if(k.current!==h)return;const u=Me(i);!u||f.current?.id!==u.roomId||v(w=>w.filter(M=>M.agentId!==u.agentId))},"chat:room:message:added":i=>{if(k.current!==h)return;const u=Me(i);u&&(o(w=>{const M=w.find(J=>J.id===u.roomId);return M?Je(w,{...M,updatedAt:u.createdAt}):w}),f.current?.id===u.roomId&&S(w=>{if(w.some(M=>M.id===u.id))return w;if(u.role==="user"){const M=w.findIndex(J=>J.role==="user"&&J.id.startsWith("temp-")&&J.content.trim()===u.content.trim());if(M>=0){const J=[...w];return J[M]=u,J}}return[...w,u]}))},"chat:room:message:updated":i=>{if(k.current!==h)return;const u=Me(i);!u||f.current?.id!==u.roomId||S(w=>w.map(M=>M.id===u.id?u:M))},"chat:room:message:deleted":i=>{if(k.current!==h)return;const u=Me(i);u?.id&&S(w=>w.filter(M=>M.id!==u.id))}}})},[n,T]),s.useEffect(()=>{$&&(m.some(h=>h.id===$.id)||(y(null),v([]),S([]),ze(je,n)))},[$,n,m]),{rooms:m,roomsLoading:l,roomsError:D,activeRoom:$,activeRoomMembers:ee,messages:z,messagesLoading:ne,selectRoom:oe,createRoom:te,deleteRoom:U,sendRoomMessage:b,refreshRooms:T}}function kn(n,r=[]){const m=n.trim().replace(/^#/,"");if(!m)return{ok:!1,error:"Room name is required."};if(/[A-Z]/.test(m))return{ok:!1,error:"Use lowercase letters only."};const o=m.toLowerCase();return o.length>80?{ok:!1,error:"Room names can be at most 80 characters."}:/^[a-z0-9_-]+$/.test(o)?/^[-_]|[-_]$/.test(o)?{ok:!1,error:"Room names cannot start or end with a hyphen or underscore."}:r.some(l=>l.toLowerCase()===o)?{ok:!1,error:"A room with this name already exists."}:{ok:!0,name:o}:{ok:!1,error:"Use lowercase letters, numbers, hyphens, or underscores only."}}function Nn({isOpen:n,onClose:r,onCreate:m,projectId:o,existingRoomNames:l=[]}){const[x,D]=s.useState(""),[P,$]=s.useState([]),[y,ee]=s.useState(""),[v,z]=s.useState([]),[S,ne]=s.useState(!1),[R,A]=s.useState(null),[f,k]=s.useState(!1),E=s.useRef(null),I=s.useRef(null);s.useEffect(()=>{n&&(I.current=document.activeElement instanceof HTMLElement?document.activeElement:null,ne(!0),A(null),dt(void 0,o).then(d=>$(d)).catch(()=>{$([]),A("Failed to load agents.")}).finally(()=>ne(!1)))},[n,o]),s.useEffect(()=>{if(!n){D(""),ee(""),z([]),A(null),k(!1);return}const d=window.requestAnimationFrame(()=>E.current?.focus());return()=>window.cancelAnimationFrame(d)},[n]),s.useEffect(()=>{if(!n)return;const d=i=>{i.key==="Escape"&&r()};return document.addEventListener("keydown",d),()=>document.removeEventListener("keydown",d)},[n,r]),s.useEffect(()=>{n||I.current?.focus()},[n]);const T=s.useMemo(()=>kn(x,l),[x,l]),oe=s.useMemo(()=>{const d=y.trim().toLowerCase();return d?P.filter(i=>i.name.toLowerCase().includes(d)):P},[P,y]),te=s.useMemo(()=>P.filter(d=>v.includes(d.id)),[P,v]),U=T.ok&&v.length>0&&!f&&!S;if(!n)return null;const b=d=>{f||z(i=>i.includes(d)?i.filter(u=>u!==d):[...i,d])},h=async()=>{if(!T.ok){A(T.error);return}if(v.length===0){A("Select at least one member.");return}A(null),k(!0);try{await m({name:T.name,displayName:`#${T.name}`,memberAgentIds:v}),r()}catch(d){A(d instanceof Error?d.message:"Failed to create room.")}finally{k(!1)}};return Fs.createPortal(t.jsx("div",{className:"modal-overlay open",onClick:d=>d.target===d.currentTarget&&r(),children:t.jsxs("div",{className:"modal modal-lg create-room-modal",role:"dialog","aria-modal":"true","aria-label":"Create room",onClick:d=>d.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:E,id:"create-room-name",className:"input",value:x,disabled:f,onChange:d=>{const i=d.target.value.replace(/^#/,"").replace(/\s+/g,"-").toLowerCase();D(i)}})]}),!T.ok&&t.jsx("div",{className:"form-error",children:T.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:y,disabled:f,onChange:d=>ee(d.target.value)})]}),te.length>0&&t.jsx("div",{className:"create-room-modal-selected","data-testid":"create-room-selected-chips",children:te.map(d=>t.jsxs("button",{type:"button",className:"btn btn-sm create-room-modal-chip",onClick:()=>b(d.id),disabled:f,children:[d.name," ×"]},d.id))}),t.jsx("div",{className:"create-room-modal-member-list","data-testid":"create-room-member-list",children:S?t.jsx("div",{className:"create-room-modal-empty",children:"Loading agents..."}):oe.length===0?t.jsx("div",{className:"create-room-modal-empty",children:P.length===0?"No agents in this project yet.":"No agents match your search."}):oe.map(d=>{const i=v.includes(d.id);return t.jsxs("button",{type:"button",className:`create-room-modal-member-row${i?" create-room-modal-member-row--selected":""}`,onClick:()=>b(d.id),disabled:f,children:[t.jsx(gs,{agent:d,size:20}),t.jsx("span",{children:d.name}),t.jsx("span",{className:"create-room-modal-member-role",children:d.role})]},d.id)})}),R&&t.jsx("div",{className:"form-group",children:t.jsx("div",{className:"form-error",children:R})}),t.jsxs("div",{className:"modal-actions",children:[t.jsx("button",{type:"button",className:"btn",onClick:r,disabled:f,children:"Cancel"}),t.jsx("button",{type:"button",className:"btn btn-primary",onClick:()=>void h(),disabled:!U,children:f?"Creating...":"Create room"})]})]})}),document.body)}function vs(n){const r=new Date(n),o=new Date().getTime()-r.getTime(),l=Math.floor(o/1e3),x=Math.floor(l/60),D=Math.floor(x/60),P=Math.floor(D/24);return l<60?"just now":x<60?`${x}m ago`:D<24?`${D}h ago`:P<7?`${P}d ago`:r.toLocaleDateString()}function ls(n,r){if(!n||!r)return null;const m=r.toLowerCase();if(m.includes("claude")){let l=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 l=l.replace(/\s+/g," "),l.length>30?l.slice(0,30)+"…":l}if(m.includes("gpt")||m.includes("openai")){const l=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 l.length>30?l.slice(0,30)+"…":l}if(m.includes("gemini")){const l=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 l.length>30?l.slice(0,30)+"…":l}const o=r.replace(/-/g," ").replace(/^\w/,l=>l.toUpperCase()).replace(/\s+/g," ").trim();return o.length>30?o.slice(0,30)+"…":o}function lt(n,r){return n.length<=r?n:`${n.slice(0,r)}…`}function Cn(n){if(!n)return null;const r=Object.entries(n);return r.length===0?null:r.map(([m,o])=>{const l=typeof o=="string"?o:(()=>{try{return JSON.stringify(o)}catch{return String(o)}})();return`${m}=${lt(l,50)}`}).join(", ")}function jn(n){if(n===void 0)return null;if(typeof n=="string")return lt(n,200);try{return lt(JSON.stringify(n),200)}catch{return lt(String(n),200)}}function xs(n){if(!n||n.length===0)return null;const r=(v,z)=>{const S=v.status==="running",ne=v.status==="completed"&&v.isError,R=Cn(v.args),A=jn(v.result),f=S?R:A?`result: ${A}`:R?`args: ${R}`:null,k=S?"running":ne?"error":"completed";return t.jsxs("details",{className:`chat-tool-call${S?" chat-tool-call--running":""}${ne?" chat-tool-call--error":""}`,open:S,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:v.toolName,children:v.toolName}),f&&t.jsx("span",{className:"chat-tool-call-preview",title:f,children:f}),t.jsx("span",{className:"chat-tool-call-status-text",children:k})]}),t.jsxs("div",{className:"chat-tool-call-content",children:[R&&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:R})]}),A&&t.jsxs("div",{className:`chat-tool-call-row${ne?" 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:A})]})]})]},`${v.toolName}-${z}`)},m="chat-tool-calls";if(n.length===1)return t.jsxs("div",{className:m,"data-testid":"chat-tool-calls",children:[t.jsxs("div",{className:"chat-tool-calls-header",children:[t.jsx(os,{size:12,"aria-hidden":"true"}),t.jsx("span",{children:"Tool calls"})]}),r(n[0],0)]});const o=n.filter(v=>v.status==="running").length,l=n.filter(v=>v.status==="completed"&&v.isError).length,x=o>0,D=Array.from(new Set(n.map(v=>v.toolName))),P=D.slice(0,5),$=Math.max(0,D.length-P.length),y=$>0?`${P.join(", ")}, +${$} more`:P.join(", "),ee=x?`(${o} running)`:l>0?`(${l} ${l===1?"error":"errors"})`:null;return t.jsx("div",{className:m,"data-testid":"chat-tool-calls",children:t.jsxs("details",{className:"chat-tool-calls-group","data-testid":"chat-tool-calls-group",open:x,children:[t.jsxs("summary",{className:"chat-tool-calls-group-summary",children:[t.jsx(os,{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:y,children:y}),ee&&t.jsx("span",{className:"chat-tool-calls-group-status",children:ee})]}),n.map((v,z)=>r(v,z))]})})}const ws={pre:({children:n,...r})=>t.jsx("pre",{...r,className:"chat-markdown-pre",children:n}),table:({children:n,...r})=>t.jsx("table",{...r,className:"chat-markdown-table",children:n})},Ue="__fn_agent__",Mn=280,it=180,ct=500,ds="fusion:chat-sidebar-width",us="fusion:chat-scope",Rn=["image/png","image/jpeg","image/gif","image/webp","text/plain","application/json","text/yaml","text/markdown","text/csv","application/xml","text/x-log"];function ms(n){const r=/(^|[\s])\/([^\s]*)$/.exec(n);if(!r)return null;const m=r[1]??"",o=r[2]??"",l=r.index+m.length;return{filter:o,start:l,end:n.length}}function An(n,r){const m=n.slice(0,r),o=/(^|[\s\n])@([\w-]*)$/.exec(m);if(!o)return null;const l=o[2]??"",x=m.length-l.length-1;return{filter:l,start:x,end:r}}function En({projectId:n,onClose:r,onCreate:m}){const[o,l]=s.useState("agent"),[x,D]=s.useState([]),[P,$]=s.useState(!0),[y,ee]=s.useState(""),[v,z]=s.useState([]),[S,ne]=s.useState(!0),[R,A]=s.useState(""),[f,k]=s.useState([]),[E,I]=s.useState([]);s.useEffect(()=>{let b=!1;return $(!0),dt(void 0,n).then(h=>{b||D(h)}).catch(()=>{b||D([])}).finally(()=>{b||$(!1)}),()=>{b=!0}},[n]),s.useEffect(()=>{ne(!0),pn().then(b=>{z(b.models),k(b.favoriteProviders),I(b.favoriteModels)}).catch(()=>{z([]),k([]),I([])}).finally(()=>{ne(!1)})},[]);const T=s.useCallback(async b=>{const h=f,i=h.includes(b)?h.filter(u=>u!==b):[b,...h];k(i);try{await is({favoriteProviders:i,favoriteModels:E})}catch{k(h)}},[f,E]),oe=s.useCallback(async b=>{const h=E,i=h.includes(b)?h.filter(u=>u!==b):[b,...h];I(i);try{await is({favoriteProviders:f,favoriteModels:i})}catch{I(h)}},[E,f]),te=b=>{if(b.preventDefault(),o==="agent"){if(!y)return;m({agentId:y});return}if(!R)return;const h=R.indexOf("/");if(h<=0)return;const d=R.slice(0,h),i=R.slice(h+1);m({agentId:Ue,modelProvider:d,modelId:i})},U=o==="agent"?!y:!R;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:b=>b.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${o==="agent"?" chat-new-dialog-mode-btn--active":""}`,"data-testid":"chat-new-dialog-mode-agent",onClick:()=>{l("agent"),A("")},children:"Agent"}),t.jsx("button",{type:"button",className:`chat-new-dialog-mode-btn${o==="model"?" chat-new-dialog-mode-btn--active":""}`,"data-testid":"chat-new-dialog-mode-model",onClick:()=>{l("model"),ee("")},children:"Model"})]}),t.jsxs("form",{onSubmit:te,children:[o==="agent"&&t.jsxs("label",{className:"chat-new-dialog-model-label",children:["Agent",P?t.jsx("div",{className:"chat-new-dialog-loading",children:"Loading agents..."}):x.length===0?t.jsx("div",{className:"chat-new-dialog-empty",children:"No agents available"}):t.jsx("div",{className:"chat-new-dialog-agent-list",children:x.map(b=>t.jsxs("button",{type:"button",className:`chat-new-dialog-agent-item${y===b.id?" chat-new-dialog-agent-item--selected":""}`,onClick:()=>ee(b.id),"data-testid":`agent-option-${b.id}`,children:[t.jsx(Xe,{size:16}),t.jsx("span",{className:"chat-new-dialog-agent-name",children:b.name}),t.jsx("span",{className:"chat-new-dialog-agent-role",children:b.role})]},b.id))})]}),o==="model"&&t.jsx("div",{className:"chat-new-dialog-model-dropdown","data-testid":"chat-new-dialog-model-section",children:S?t.jsx("div",{className:"chat-new-dialog-loading",children:"Loading models..."}):t.jsx(bn,{models:v,value:R,onChange:A,label:"Model",placeholder:"Select a model",favoriteProviders:f,onToggleFavorite:T,favoriteModels:E,onToggleModelFavorite:oe})}),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:U,children:"Create"})]})]})]})})}const Dt=s.memo(function({message:r,forcePlain:m,agentName:o,hideAssistantIdentity:l,showAssistantModelTag:x,activeModelTag:D,activeModelProvider:P,activeSessionId:$,mentionAgentsByName:y,roomContext:ee,copyAction:v}){const z=r.role==="assistant",S=s.useMemo(()=>{if(z)return null;const A=r.content,f=/@([\w-]+)/g,k=[];let E=0,I=f.exec(A);for(;I;){const[T,oe=""]=I,te=I.index;te>E&&k.push(A.slice(E,te));const U=oe.replace(/_/g," ").toLowerCase(),b=y.get(U);if(b){const h=!!(ee&&!ee.memberIds.has(b.id)),d=h?`Not a member of ${ee?.roomName}`:void 0;k.push(t.jsxs("span",{className:`chat-mention-chip${h?" chat-mention-chip--non-member":""}`,title:d,"aria-label":d,children:["@",b.name.replace(/\s+/g,"_")]},`${b.id}-${te}`))}else k.push(T);E=te+T.length,I=f.exec(A)}return E<A.length&&k.push(A.slice(E)),k.length===0?A:k},[z,r.content,y,ee]),ne=s.useMemo(()=>{const A=r.attachments;if(!A||A.length===0||!$)return null;const f=`/api/chat/sessions/${encodeURIComponent($)}/attachments/`;return t.jsx("div",{className:"chat-message-attachments",children:A.map(k=>{const E=k.mimeType.startsWith("image/"),I=k.id||k.filename,T=`${f}${encodeURIComponent(k.filename)}`;return E?t.jsx("a",{className:"chat-message-attachment-link","data-testid":"chat-message-attachment",href:T,target:"_blank",rel:"noopener noreferrer",children:t.jsx("img",{className:"chat-message-attachment",src:T,alt:k.originalName})},I):t.jsxs("a",{className:"chat-message-attachment-file","data-testid":"chat-message-attachment",href:T,target:"_blank",rel:"noopener noreferrer",children:[t.jsx(fn,{size:14}),t.jsx("span",{children:k.originalName})]},I)})})},[r.attachments,$]),R=s.useMemo(()=>z?m?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(ps,{remarkPlugins:[bs],components:ws,children:r.content})}):null,[z,m,r.content]);return t.jsxs("div",{className:`chat-message chat-message--${r.role}`,"data-testid":`chat-message-${r.id}`,children:[z&&!l&&t.jsxs("div",{className:"chat-message-avatar",children:[P?t.jsx(Ye,{provider:P,size:"sm"}):t.jsx(Xe,{size:14}),t.jsx("span",{children:o}),x&&D&&t.jsx("span",{className:"chat-model-tag",children:D})]}),z?R:t.jsx("div",{className:"chat-message-content",children:S}),v,xs(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:r.thinkingOutput})]}),ne,t.jsx("div",{className:"chat-message-time",children:vs(r.createdAt)})]})});function In({projectId:n,addToast:r,experimentalFeatures:m}){const{activeSession:o,sessionsLoading:l,messages:x,messagesLoading:D,isStreaming:P,streamingText:$,streamingThinking:y,streamingToolCalls:ee,selectSession:v,createSession:z,archiveSession:S,deleteSession:ne,sendMessage:R,stopStreaming:A,pendingMessage:f,clearPendingMessage:k,searchQuery:E,setSearchQuery:I,filteredSessions:T}=wn(n,r),[oe,te]=s.useState(!1),[U,b]=s.useState(""),[h,d]=s.useState(null),[i,u]=s.useState(null),[w,M]=s.useState(null),[J,_]=s.useState(!0),[Y,Re]=s.useState(Mn),[V,pe]=s.useState("direct"),[Ae,De]=s.useState(!1),X=m?.chatRooms===!0,N=Sn(n,r),[ie,ue]=s.useState(new Map),[be,Qe]=s.useState([]),[ut,Ze]=s.useState(!0),[ve,xe]=s.useState(!1),[_e,we]=s.useState(""),[ye,Se]=s.useState(0),[ke,g]=s.useState(""),[p,C]=s.useState(!1),[L,Q]=s.useState(0),[G,se]=s.useState(-1),[O,ae]=s.useState(!1),[F,B]=s.useState([]),[K,Z]=s.useState(!1),[ce,me]=s.useState(!1),[Pe,It]=s.useState({}),[et,Oe]=s.useState(!1),[,He]=s.useState(!1),[ys,Ss]=s.useState({top:0,left:0}),W=Qs({projectId:n}),mt=s.useCallback(e=>{if(!e||!W.mentionActive)return;const a=e.getBoundingClientRect();Ss({top:a.top-260,left:a.left+8})},[W.mentionActive]),Lt=s.useRef(null),Ft=s.useRef(null),ht=s.useRef(!1),ft=s.useRef(null),he=s.useRef(null),Ee=s.useRef(null),re=s.useRef(null),zt=s.useRef(null),Ut=s.useRef([]),Be=s.useRef(0),We=s.useRef(new Map),H=Zs()==="mobile";s.useEffect(()=>{try{const e=localStorage.getItem(ds);if(!e)return;const a=Number.parseInt(e,10);if(Number.isNaN(a))return;const c=Math.max(it,Math.min(ct,a));Re(c)}catch{}},[]),s.useEffect(()=>{try{const e=localStorage.getItem(us);if(e==="direct"){pe("direct");return}e==="rooms"&&X&&pe("rooms")}catch{}},[X]),s.useEffect(()=>{if(!X&&V==="rooms"){pe("direct");return}try{localStorage.setItem(us,V)}catch{}},[X,V]);const ks=X&&V==="rooms"&&!!N.activeRoom,{keyboardOverlap:tt,viewportHeight:_t,viewportOffsetTop:Ot,keyboardOpen:Ge}=en({enabled:H&&(!!o||ks)}),Ht=tt>0||Ot>0,Bt=Ge&&Ht?{"--keyboard-overlap":`${tt}px`,"--vv-offset-top":`${Ot}px`,..._t!==null?{"--vv-height":`${_t}px`}:{}}:{},Wt=`chat-thread${Ge&&Ht?" chat-thread--keyboard-active":""}`,le=s.useMemo(()=>{const e=_e.trim().toLowerCase();return(e?be.filter(c=>c.name.toLowerCase().includes(e)):be).slice(0,10)},[be,_e]),$e=s.useMemo(()=>Array.from(ie.values()),[ie]),fe=s.useMemo(()=>!X||V!=="rooms"||!N.activeRoom?null:{roomId:N.activeRoom.id,roomName:N.activeRoom.name,memberIds:new Set(N.activeRoomMembers.map(e=>e.agentId))},[X,V,N.activeRoom,N.activeRoomMembers]),Te=s.useMemo(()=>{const e=$e.filter(j=>tn(j.name,ke));if(!fe)return e;const a=e.filter(j=>fe.memberIds.has(j.id));if(ke.trim().length===0)return a;const c=e.filter(j=>!fe.memberIds.has(j.id));return[...a,...c]},[$e,ke,fe]),gt=s.useMemo(()=>{const e=new Map;for(const a of $e)e.set(a.name.toLowerCase(),a);return e},[$e]);s.useEffect(()=>{Se(0)},[le]),s.useEffect(()=>{Q(0)},[ke,p]),s.useEffect(()=>()=>{he.current!==null&&window.clearTimeout(he.current)},[]);const Gt=s.useCallback(()=>{const e=Ee.current;if(!e)return;const c=e.scrollTop+e.clientHeight>=e.scrollHeight-50;me(!c),ht.current=!c},[]),Ie=s.useCallback(e=>{if(!e.isConnected)return;let a=0,c=0,j=-1;const q=6,de=()=>{if(e.isConnected){if(e.scrollTop=e.scrollHeight,e.scrollHeight===j?c+=1:(c=0,j=e.scrollHeight),a+=1,a>=q||c>=2){me(!1),ht.current=!1;return}window.requestAnimationFrame(de)}};de()},[]),Ve=s.useCallback(()=>{const e=Ee.current;e&&Ie(e)},[Ie]);s.useLayoutEffect(()=>{const e=o?.id??null;if(!e){ft.current=null;return}const a={sessionId:e,loaded:!D,hasMessages:x.length>0},c=ft.current,j=c?.sessionId!==e,q=c?.sessionId===e&&!c.loaded&&a.loaded,de=c?.sessionId===e&&!c.hasMessages&&a.hasMessages;if(!(c===null||j||q||de))return;const ge=Ee.current;ge&&(Ie(ge),ft.current=a)},[o?.id,x.length,D,Ie]),s.useEffect(()=>{ht.current||Ve()},[x,$,y,P,Ve]),s.useEffect(()=>{tt<=0||!Ee.current||Ve()},[tt,Ve]),sn(H&&Ge),s.useEffect(()=>{const e=()=>d(null);if(h)return document.addEventListener("click",e),()=>document.removeEventListener("click",e)},[h]),s.useEffect(()=>{if(!H||!Ge)return;const e=a=>{a.target?.closest(".chat-messages")||a.preventDefault()};return document.addEventListener("touchmove",e,{passive:!1}),()=>{document.removeEventListener("touchmove",e)}},[H,Ge]),s.useEffect(()=>{if(!H||!o)return;const e=()=>{const a=re.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)}},[H,o]),s.useEffect(()=>{if(!H||!o)return;const e=()=>{const c=Ee.current;c&&Ie(c)},a=()=>{document.visibilityState==="visible"&&e()};return document.addEventListener("visibilitychange",a),window.addEventListener("pageshow",e),()=>{document.removeEventListener("visibilitychange",a),window.removeEventListener("pageshow",e)}},[H,o,Ie]),s.useEffect(()=>{let e=!1;const a=n;return dt(void 0,n).then(c=>{if(e||a!==n)return;const j=new Map;for(const q of c)j.set(q.id,q);ue(j)}).catch(()=>{}),()=>{e=!0}},[n]),s.useEffect(()=>{let e=!1;return Ze(!0),nn(n).then(a=>{e||Qe(a)}).catch(()=>{e||Qe([])}).finally(()=>{e||Ze(!1)}),()=>{e=!0}},[n]),s.useEffect(()=>{Ut.current=F},[F]),s.useEffect(()=>()=>{for(const e of Ut.current)e.previewUrl&&URL.revokeObjectURL(e.previewUrl);for(const e of We.current.values())window.clearTimeout(e);We.current.clear()},[]);const st=s.useCallback(e=>{if(!e||e.length===0)return;const a=[];for(const c of Array.from(e)){if(!Rn.includes(c.type))continue;const j=c.type.startsWith("image/");a.push({file:c,previewUrl:j?URL.createObjectURL(c):""})}a.length>0&&B(c=>[...c,...a])},[]),Ns=s.useCallback(e=>{B(a=>{const c=a[e];return c?.previewUrl&&URL.revokeObjectURL(c.previewUrl),a.filter((j,q)=>q!==e)})},[]),Cs=s.useCallback(e=>{const a=e.clipboardData?.files;if(!a||a.length===0)return;const c=Array.from(a).filter(j=>j.type.startsWith("image/"));c.length!==0&&st(c)},[st]),js=s.useCallback(async e=>{try{await z(e),te(!1),H&&_(!1)}catch{r("Failed to create chat session","error")}},[z,r,H]),Ke=s.useCallback(()=>{b(""),xe(!1),we(""),C(!1),g(""),se(-1),B(e=>{for(const a of e)a.previewUrl&&URL.revokeObjectURL(a.previewUrl);return[]})},[]),pt=s.useCallback(()=>{const e=U.trim(),a=F.map(c=>c.file);if(!(!e&&a.length===0||!o)){if(e==="/clear"||e==="/new"){Ke(),A(),k(),z({agentId:o.agentId,modelProvider:o.modelProvider??void 0,modelId:o.modelId??void 0}).catch(()=>{r("Failed to clear conversation","error")});return}Ke(),R(e,a)}},[U,F,o,Ke,A,k,z,r,R]),bt=s.useCallback(async()=>{const e=U.trim();if(e){if(X&&V==="rooms"){if(!N.activeRoom)return;try{await N.sendRoomMessage(e),Ke()}catch(a){const c=a instanceof Error&&a.message.trim()?a.message:"Failed to send room message";r(c,"error")}return}pt()}},[U,X,V,N,Ke,r,pt]),vt=s.useCallback(e=>{b(a=>{const c=ms(a);if(!c)return a;const j=`/skill:${e.name} `,q=a.slice(0,c.start)+j+a.slice(c.end);return window.requestAnimationFrame(()=>{re.current&&(re.current.style.height="auto",re.current.style.height=`${Math.min(re.current.scrollHeight,120)}px`,re.current.focus())}),q}),xe(!1),we(""),Se(0)},[]),nt=s.useCallback(e=>{const a=re.current;if(!a||G<0)return;const c=a.selectionStart??Be.current,j=a.selectionEnd??c,q=Math.max(c,j),de=Math.min(G,q),ge=`${`@${e.name.replace(/\s+/g,"_")}`} `,Mt=U.slice(0,de)+ge+U.slice(q),Fe=de+ge.length;b(Mt),C(!1),g(""),Q(0),se(-1),window.requestAnimationFrame(()=>{re.current&&(re.current.style.height="auto",re.current.style.height=`${Math.min(re.current.scrollHeight,120)}px`,re.current.focus(),re.current.setSelectionRange(Fe,Fe))})},[G,U]),Vt=s.useCallback(e=>{if(Be.current=e.currentTarget.selectionStart??Be.current,W.mentionActive&&W.files.length>0){if(W.handleKeyDown(e,U),e.key==="Enter"||e.key==="Tab"){const a=W.files[W.selectedIndex];if(a){const c=W.selectFile(a,U);b(c),W.dismissMention(),He(!1)}}return}if(p&&e.key==="ArrowDown"){e.preventDefault(),Te.length>0&&Q(a=>(a+1)%Te.length);return}if(p&&e.key==="ArrowUp"){e.preventDefault(),Te.length>0&&Q(a=>a===0?Te.length-1:a-1);return}if(p&&e.key==="Enter"){e.preventDefault();const a=Te[L]??Te[0];a&&nt(a);return}if(p&&e.key==="Escape"){e.preventDefault(),C(!1),g(""),se(-1);return}if(ve&&e.key==="ArrowDown"){e.preventDefault(),le.length>0&&Se(a=>(a+1)%le.length);return}if(ve&&e.key==="ArrowUp"){e.preventDefault(),le.length>0&&Se(a=>a===0?le.length-1:a-1);return}if(ve&&(e.key==="Enter"||e.key==="Tab")&&le.length>0){e.preventDefault();const a=le[ye]??le[0];a&&vt(a);return}if(ve&&e.key==="Escape"){e.preventDefault(),xe(!1);return}e.key==="Enter"&&!e.shiftKey&&(e.preventDefault(),bt())},[p,Te,L,nt,ve,le,ye,vt,bt,W,U]),at=s.useCallback((e,a)=>{const c=An(e,a);if(c){C(!0),g(c.filter),se(c.start);return}C(!1),g(""),se(-1)},[]),Kt=s.useCallback(e=>{const a=e.target,c=a.value,j=a.selectionStart??c.length;Be.current=j,b(c);const q=ms(c);q?(xe(!0),we(q.filter)):(xe(!1),we("")),at(c,j),W.detectMention(c,j),He(W.mentionActive),W.mentionActive&&mt(a),a.style.height="auto",a.style.height=`${Math.min(a.scrollHeight,120)}px`},[at]),rt=s.useCallback(e=>{const a=e.currentTarget,c=a.selectionStart??a.value.length;Be.current=c,at(a.value,c),W.detectMention(a.value,c),He(W.mentionActive),W.mentionActive&&mt(a)},[at,W,mt]),qt=s.useCallback(e=>{e.key!=="Escape"&&rt(e)},[rt]),Jt=s.useCallback(()=>{he.current!==null&&window.clearTimeout(he.current),he.current=window.setTimeout(()=>{xe(!1),C(!1),g(""),se(-1),He(!1),W.dismissMention(),he.current=null},120)},[W]),Yt=s.useCallback(()=>{he.current!==null&&(window.clearTimeout(he.current),he.current=null),typeof window<"u"&&window.innerWidth<=768&&window.setTimeout(()=>{(window.scrollY!==0||window.scrollX!==0)&&window.scrollTo(0,0)},0)},[]),Ms=s.useCallback(async e=>{d(null);try{await S(e),r("Conversation archived","success")}catch{r("Failed to archive conversation","error")}},[S,r]),Rs=s.useCallback(async e=>{u(null),d(null);try{await ne(e),r("Conversation deleted","success")}catch{r("Failed to delete conversation","error")}},[ne,r]),qe=s.useCallback(e=>{try{localStorage.setItem(ds,String(e))}catch{}},[]),As=s.useCallback(e=>{if(H)return;e.preventDefault(),e.stopPropagation();const a=e.currentTarget;typeof a.setPointerCapture=="function"&&a.setPointerCapture(e.pointerId);const c=e.clientX,j=Y;let q=j;document.body.style.userSelect="none";const de=ge=>{const Mt=ge.clientX-c,Fe=Math.max(it,Math.min(ct,j+Mt));q=Fe,Re(Fe),qe(Fe)},Le=ge=>{typeof a.releasePointerCapture=="function"&&a.releasePointerCapture(ge.pointerId),document.body.style.userSelect="",document.removeEventListener("pointermove",de),document.removeEventListener("pointerup",Le),qe(q)};document.addEventListener("pointermove",de),document.addEventListener("pointerup",Le)},[H,qe,Y]),Es=s.useCallback(e=>{if(H||e.key!=="ArrowLeft"&&e.key!=="ArrowRight")return;e.preventDefault();const a=e.shiftKey?50:10,c=e.key==="ArrowLeft"?-a:a,j=Math.max(it,Math.min(ct,Y+c));Re(j),qe(j)},[H,qe,Y]),Xt=s.useCallback(e=>{v(e),Oe(!1),H&&_(!1)},[v,H]),Ts=s.useCallback(()=>{v(""),_(!0),Oe(!1)},[v]),Ds=()=>t.jsxs("div",{className:"chat-empty-state",children:[t.jsx(gn,{size:48,strokeWidth:1.5}),t.jsx("h2",{children:"Start a new conversation"}),t.jsxs("button",{className:"btn btn-primary",onClick:()=>te(!0),children:[t.jsx(ot,{size:16}),"New Chat"]})]}),Ne=ls(o?.modelProvider,o?.modelId),Ce=o?.modelProvider??null,xt=!!(o||P||x.length>0),wt=o?.agentId===Ue?Ne??"Fusion":o?.title||ie.get(o?.agentId??"")?.name||o?.agentId||"Chat",Qt=!!(Ne&&Ne!==wt),Ps=H&&V==="direct"&&!!o,yt=ie.get(o?.agentId??"")?.name||(o?.agentId===Ue?Ne??"Fusion":o?.agentId?.slice(0,30)??"Fusion"),St=!1,kt=o?.agentId===Ue,$s=f.length>50?`${f.slice(0,50)}…`:f,Is=s.useCallback(()=>{ae(e=>!e)},[]);s.useEffect(()=>{if(!et)return;const e=a=>{Ft.current?.contains(a.target)||Oe(!1)};return document.addEventListener("mousedown",e),()=>{document.removeEventListener("mousedown",e)}},[et]),s.useEffect(()=>{(!H||V!=="direct"||J)&&Oe(!1)},[H,V,J]);const Nt=s.useCallback((e,a)=>{const c=We.current.get(e);c&&window.clearTimeout(c),It(q=>({...q,[e]:a}));const j=window.setTimeout(()=>{It(q=>{const{[e]:de,...Le}=q;return Le}),We.current.delete(e)},2e3);We.current.set(e,j)},[]),Zt=s.useCallback(async(e,a)=>{try{if(!navigator.clipboard?.writeText)throw new Error("Clipboard API unavailable");await navigator.clipboard.writeText(a),Nt(e,"success")}catch{Nt(e,"error")}},[Nt]),Ls=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(ps,{remarkPlugins:[bs],components:ws,children:e})}),[]),Ct=o?.agentId===Ue,jt=s.useCallback((e,a,c)=>t.jsx("button",{type:"button",className:`btn-icon chat-message-copy-action${Pe[e]==="success"?" chat-message-copy-action--success":""}${Pe[e]==="error"?" chat-message-copy-action--error":""}`,"data-testid":c??`chat-copy-response-${e}`,"aria-label":Pe[e]==="success"?"Response copied":Pe[e]==="error"?"Copy failed":"Copy response",onClick:()=>{Zt(e,a)},children:Pe[e]==="success"?t.jsx(an,{size:14}):t.jsx(rn,{size:14})}),[Pe,Zt]);return t.jsxs("div",{className:"chat-view",children:[t.jsxs("div",{className:`chat-sidebar${J?"":" chat-sidebar--hidden"}`,style:H?void 0:{width:`${Y}px`},children:[X&&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${V==="direct"?" chat-sidebar-scope-btn--active":""}`,"aria-selected":V==="direct","data-testid":"chat-sidebar-scope-direct",onClick:()=>pe("direct"),children:"Direct"}),t.jsx("button",{type:"button",role:"tab",className:`chat-sidebar-scope-btn${V==="rooms"?" chat-sidebar-scope-btn--active":""}`,"aria-selected":V==="rooms","data-testid":"chat-sidebar-scope-rooms",onClick:()=>pe("rooms"),children:"Rooms"})]}),!X||V==="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(on,{size:14,className:"chat-sidebar-search-icon"}),t.jsx("input",{type:"text",className:"chat-sidebar-search",placeholder:"Search conversations...",value:E,onChange:e=>I(e.target.value),"data-testid":"chat-search-input"})]})}),t.jsx("div",{className:"chat-session-list chat-sidebar-list",children:l?t.jsx("div",{style:{padding:"12px",color:"var(--text-secondary)",fontSize:"13px"},children:"Loading..."}):T.length===0?t.jsx("div",{style:{padding:"12px",color:"var(--text-secondary)",fontSize:"13px"},children:"No conversations yet"}):T.map(e=>t.jsxs("div",{className:`chat-session-item${o?.id===e.id?" chat-session-item--active":""}`,onClick:()=>Xt(e.id),onContextMenu:a=>{a.preventDefault(),d({sessionId:e.id,x:a.clientX,y:a.clientY})},"data-testid":`chat-session-${e.id}`,children:[t.jsx("button",{className:"chat-session-delete-btn",onClick:a=>{a.stopPropagation(),u(e.id)},"data-testid":"chat-session-delete-btn","aria-label":"Delete conversation",children:t.jsx(At,{size:14})}),t.jsx("div",{className:"chat-session-title",children:e.title||"Untitled"}),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:[e.modelProvider&&t.jsx(Ye,{provider:e.modelProvider,size:"sm"}),t.jsx("span",{children:ie.get(e.agentId)?.name||(e.agentId===Ue?ls(e.modelProvider,e.modelId)??"Fusion":e.agentId.slice(0,30))})]}),t.jsx("span",{children:e.updatedAt?vs(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",children:t.jsxs("button",{type:"button",className:"btn btn-sm btn-primary","data-testid":"chat-create-room-btn",onClick:()=>De(!0),children:[t.jsx(ot,{size:14}),"Create room"]})}),N.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:N.rooms.map(e=>{const a=N.activeRoom?.id===e.id,c=a?N.activeRoomMembers.length:"—";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:()=>{N.selectRoom(e.id),H&&_(!1)},onKeyDown:j=>{(j.key==="Enter"||j.key===" ")&&(j.preventDefault(),N.selectRoom(e.id),H&&_(!1))},children:[t.jsxs("span",{className:"chat-room-item-details",children:[t.jsxs("span",{className:"chat-room-item-name",children:["#",e.name]}),t.jsxs("span",{className:"chat-room-item-meta",children:[c," ",c===1?"member":"members"]})]}),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:j=>{j.stopPropagation(),M(e.id)},children:t.jsx(At,{size:14})})]},e.id)})})]}),t.jsx("div",{className:"chat-sidebar-footer",children:t.jsxs("button",{className:"btn btn-sm btn-primary chat-sidebar-footer-btn",onClick:()=>te(!0),"data-testid":"chat-new-btn",children:[t.jsx(ot,{size:14}),"New Chat"]})})]}),!H&&J&&t.jsx("div",{className:"chat-sidebar-resize-handle",role:"separator","aria-orientation":"vertical","aria-valuemin":it,"aria-valuemax":ct,"aria-valuenow":Y,"aria-label":"Resize chat sidebar",tabIndex:0,onPointerDown:As,onKeyDown:Es}),h&&t.jsxs("div",{className:"chat-session-context-menu",style:{top:h.y,left:h.x},onClick:e=>e.stopPropagation(),children:[t.jsxs("button",{onClick:()=>Ms(h.sessionId),"data-testid":"chat-context-archive",children:[t.jsx(cn,{size:14}),"Archive"]}),t.jsxs("button",{onClick:()=>{d(null),u(h.sessionId)},"data-testid":"chat-context-delete",children:[t.jsx(At,{size:14}),"Delete"]})]}),i&&t.jsx("div",{className:"chat-new-dialog-backdrop chat-view-dialog-backdrop",onClick:()=>u(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:()=>u(null),children:"Cancel"}),t.jsx("button",{className:"btn btn-sm btn-danger",onClick:()=>void Rs(i),children:"Delete"})]})]})}),X&&w&&t.jsx("div",{className:"chat-new-dialog-backdrop chat-view-dialog-backdrop",onClick:()=>M(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:()=>M(null),children:"Cancel"}),t.jsx("button",{className:"btn btn-sm btn-danger",onClick:()=>{(async()=>{try{await N.deleteRoom(w),M(null)}catch{r("Failed to delete room","error")}})()},children:"Delete"})]})]})}),X&&V==="rooms"?t.jsxs("div",{className:Wt,style:Bt,children:[N.activeRoom?t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"chat-room-thread-header",children:[H&&t.jsx("button",{className:"btn-icon",onClick:()=>{N.selectRoom(null),_(!0)},"data-testid":"chat-back-btn",children:t.jsx(ss,{size:16})}),t.jsxs("div",{className:"chat-thread-header-title",children:["#",N.activeRoom.name]}),t.jsx("div",{className:"chat-room-thread-members",children:N.activeRoomMembers.map(e=>t.jsx(gs,{agent:ie.get(e.agentId)??{id:e.agentId,name:e.agentId.slice(0,30)}},e.agentId))})]}),t.jsxs("div",{className:"chat-messages",ref:Ee,onScroll:Gt,children:[N.messagesLoading?t.jsx("div",{style:{color:"var(--text-secondary)",fontSize:"13px"},children:"Loading messages..."}):N.messages.length===0?t.jsx("div",{style:{color:"var(--text-secondary)",fontSize:"13px"},children:"No messages yet. Start the conversation!"}):N.messages.map(e=>{const a=e.senderAgentId?ie.get(e.senderAgentId)?.name??e.senderAgentId.slice(0,30):"You",c={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(Dt,{message:c,forcePlain:O,agentName:a,hideAssistantIdentity:!1,showAssistantModelTag:!1,activeModelTag:null,activeModelProvider:null,activeSessionId:N.activeRoom?.id??null,mentionAgentsByName:gt,roomContext:fe},e.id)}),t.jsx("div",{ref:Lt})]})]}):t.jsx("div",{className:"chat-room-empty-pane","data-testid":"chat-rooms-empty-pane",children:"Select a room or create one"}),N.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:re,className:"chat-input-textarea",placeholder:"Type a message...",value:U,onChange:Kt,onKeyDown:Vt,onKeyUp:qt,onClick:rt,onBlur:Jt,onFocus:Yt,onTouchStart:e=>{typeof window>"u"||window.innerWidth>768||document.activeElement!==e.currentTarget&&(e.preventDefault(),e.currentTarget.focus({preventScroll:!0}))},rows:1,"data-testid":"chat-input"}),t.jsx(ns,{agents:$e,filter:ke,highlightedIndex:L,visible:p,onSelect:nt,position:"below",roomMemberIds:fe?.memberIds,roomName:fe?.roomName})]}),t.jsx("button",{type:"button",className:"chat-input-send",onClick:()=>{bt()},disabled:!U.trim(),"data-testid":"chat-send-btn",style:{touchAction:"manipulation"},children:t.jsx(as,{size:16})})]})})]}):t.jsxs("div",{className:Wt,style:Bt,children:[(xt||!H)&&t.jsxs("div",{className:"chat-thread-header",children:[H&&xt&&t.jsx("button",{className:"btn-icon",onClick:Ts,"data-testid":"chat-back-btn",children:t.jsx(ss,{size:16})}),t.jsx("div",{className:"chat-thread-header-identity","data-testid":"chat-thread-header-identity",children:Ps?t.jsxs("div",{className:"chat-mobile-session-menu",ref:Ft,children:[t.jsxs("button",{type:"button",className:"btn-icon chat-mobile-session-trigger","data-testid":"chat-mobile-session-trigger","aria-haspopup":"menu","aria-expanded":et,onClick:()=>Oe(e=>!e),children:[Ce?t.jsx(Ye,{provider:Ce,size:"md"}):t.jsx(Xe,{size:16}),t.jsx("span",{className:"chat-thread-header-title",children:wt}),Qt&&t.jsx("span",{className:"chat-model-tag",children:Ne}),t.jsx(rs,{"aria-hidden":"true"})]}),et&&t.jsx("div",{className:"chat-mobile-session-dropdown",role:"menu","data-testid":"chat-mobile-session-dropdown",children:T.map(e=>t.jsx("button",{type:"button",role:"menuitem",className:`chat-mobile-session-option${o?.id===e.id?" chat-mobile-session-option--active":""}`,"data-testid":`chat-mobile-session-option-${e.id}`,onClick:()=>Xt(e.id),children:t.jsx("span",{className:"chat-mobile-session-option-title",children:e.title||"Untitled"})},e.id))})]}):t.jsxs(t.Fragment,{children:[Ce?t.jsx(Ye,{provider:Ce,size:"md"}):t.jsx(Xe,{size:16}),t.jsx("span",{className:"chat-thread-header-title",children:wt}),Qt&&t.jsx("span",{className:"chat-model-tag",children:Ne})]})}),xt&&t.jsx("button",{type:"button",className:`chat-thread-header-render-toggle${O?" chat-thread-header-render-toggle--plain":""}`,"data-testid":"chat-thread-render-toggle","aria-label":O?"Show all messages as rendered Markdown":"Show all messages as plain text",onClick:Is,children:O?t.jsx(ln,{size:14}):t.jsx(dn,{size:14})}),!H&&t.jsxs("button",{className:"btn btn-sm btn-primary chat-thread-header-new-chat",onClick:()=>te(!0),"data-testid":"chat-thread-new-chat-btn",children:[t.jsx(ot,{size:14}),"New Chat"]})]}),t.jsxs("div",{className:"chat-messages",ref:Ee,onScroll:Gt,children:[P?t.jsxs(t.Fragment,{children:[x.map(e=>t.jsx(Dt,{message:e,forcePlain:O,agentName:yt,hideAssistantIdentity:kt,showAssistantModelTag:St,activeModelTag:Ne,activeModelProvider:Ce,activeSessionId:o?.id??null,mentionAgentsByName:gt,roomContext:null,copyAction:Ct&&e.role==="assistant"?jt(e.id,e.content):void 0},e.id)),t.jsxs("div",{className:"chat-message chat-message--assistant chat-message--streaming",children:[!kt&&t.jsxs("div",{className:"chat-message-avatar",children:[Ce?t.jsx(Ye,{provider:Ce,size:"sm"}):t.jsx(Xe,{size:14}),t.jsx("span",{children:yt}),St]}),$?Ls($,O):t.jsx("div",{className:"chat-message-content chat-message-content--waiting",children:y?"Thinking…":"Connecting…"}),Ct&&$&&jt("__streaming__",$,"chat-copy-response-streaming"),xs(ee),y&&t.jsxs("details",{className:"chat-message-thinking",children:[t.jsx("summary",{children:"Thinking"}),t.jsx("pre",{className:"chat-message-thinking-content",children:y})]}),t.jsxs("div",{className:"chat-typing-indicator",children:[t.jsx("span",{}),t.jsx("span",{}),t.jsx("span",{})]})]})]}):D?t.jsx("div",{style:{color:"var(--text-secondary)",fontSize:"13px"},children:"Loading messages..."}):x.length===0&&!o?Ds():x.length===0&&o?t.jsx("div",{style:{color:"var(--text-secondary)",fontSize:"13px"},children:"No messages yet. Start the conversation!"}):t.jsx(t.Fragment,{children:x.map(e=>t.jsx(Dt,{message:e,forcePlain:O,agentName:yt,hideAssistantIdentity:kt,showAssistantModelTag:St,activeModelTag:Ne,activeModelProvider:Ce,activeSessionId:o?.id??null,mentionAgentsByName:gt,roomContext:null,copyAction:Ct&&e.role==="assistant"?jt(e.id,e.content):void 0},e.id))}),t.jsx("div",{ref:Lt})]}),ce&&t.jsxs("button",{type:"button",className:"btn btn-sm chat-jump-to-latest","data-testid":"chat-jump-to-latest",onClick:Ve,children:[t.jsx(rs,{size:14}),"Latest"]}),o&&t.jsxs("div",{className:"chat-input-area",children:[t.jsx("input",{ref:zt,type:"file",accept:"image/*,.txt,.json,.yaml,.yml,.log,.csv,.xml,.md",multiple:!0,style:{display:"none"},onChange:e=>{st(e.target.files),e.target.value=""}}),ve&&t.jsx("div",{className:"chat-skill-menu","data-testid":"chat-skill-menu",role:"listbox","aria-label":"Skill suggestions",children:ut?t.jsx("div",{className:"chat-skill-menu-empty",children:"Loading skills…"}):le.length===0?t.jsx("div",{className:"chat-skill-menu-empty",children:_e?"No skills found":"No skills available"}):le.map((e,a)=>t.jsxs("button",{type:"button",role:"option","aria-selected":a===ye,className:`chat-skill-menu-item${a===ye?" chat-skill-menu-item--highlighted":""}`,onMouseDown:c=>c.preventDefault(),onMouseEnter:()=>Se(a),onClick:()=>vt(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))}),F.length>0&&t.jsx("div",{className:"chat-attachment-previews","data-testid":"chat-attachment-previews",children:F.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:()=>Ns(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:()=>zt.current?.click(),children:t.jsx(un,{size:16})}),t.jsxs("div",{className:`chat-input-wrapper${K?" chat-input-wrapper--dragover":""}`,onDragOver:e=>{e.preventDefault(),Z(!0)},onDragLeave:()=>Z(!1),onDrop:e=>{e.preventDefault(),Z(!1),st(e.dataTransfer.files)},children:[t.jsx("textarea",{ref:re,className:"chat-input-textarea",placeholder:"Type a message...",value:U,onChange:Kt,onKeyDown:Vt,onKeyUp:qt,onClick:rt,onBlur:Jt,onFocus:Yt,onPaste:Cs,onTouchStart:e=>{typeof window>"u"||window.innerWidth>768||document.activeElement!==e.currentTarget&&(e.preventDefault(),e.currentTarget.focus({preventScroll:!0}))},rows:1,"data-testid":"chat-input"}),t.jsx(ns,{agents:$e,filter:ke,highlightedIndex:L,visible:p,onSelect:nt,position:"below",roomMemberIds:fe?.memberIds,roomName:fe?.roomName}),t.jsx(mn,{visible:W.mentionActive&&!p,position:ys,files:W.files,selectedIndex:W.selectedIndex,onSelect:e=>{const a=W.selectFile(e,U);b(a),W.dismissMention(),He(!1),re.current?.focus()},loading:W.loading}),f&&t.jsxs("div",{className:"chat-pending-message","data-testid":"chat-pending-indicator",children:[t.jsx("span",{children:`Queued: ${$s}`}),t.jsx("button",{type:"button",className:"chat-pending-message-dismiss","aria-label":"Dismiss queued message","data-testid":"chat-pending-dismiss",onClick:k,children:"×"})]})]}),P?t.jsx("button",{className:"chat-input-stop",onClick:A,"aria-label":"Stop generation","data-testid":"chat-stop-btn",children:t.jsx(hn,{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:()=>{pt()},disabled:!U.trim()&&F.length===0,"data-testid":"chat-send-btn",style:{touchAction:"manipulation"},children:t.jsx(as,{size:16})})]})]})]}),X&&t.jsx(Nn,{isOpen:Ae,onClose:()=>De(!1),projectId:n,existingRoomNames:N.rooms.map(e=>e.name),onCreate:async e=>{await N.createRoom({name:e.name,memberAgentIds:e.memberAgentIds}),De(!1)}}),oe&&t.jsx(En,{projectId:n,onClose:()=>te(!1),onCreate:js})]})}export{In as ChatView};
|