@runfusion/fusion 0.20.0 → 0.21.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 +30 -3
- package/dist/client/assets/{AgentDetailView-C6BG7O7i.js → AgentDetailView-Dg7Qa1rG.js} +1 -1
- package/dist/client/assets/{ChatView-DeXUYwSY.js → ChatView-ODq-kBk6.js} +1 -1
- package/dist/client/assets/{DevServerView-Dariyxt_.js → DevServerView-6PS9Lvl7.js} +1 -1
- package/dist/client/assets/{DirectoryPicker-SchiK-Aq.js → DirectoryPicker-B3dza2Dq.js} +1 -1
- package/dist/client/assets/{DocumentsView-C6v-tBhG.js → DocumentsView-Bu9YYlki.js} +1 -1
- package/dist/client/assets/{InsightsView-Cqim12az.js → InsightsView-CqDethVs.js} +1 -1
- package/dist/client/assets/{MemoryView-CakLoJtY.js → MemoryView-BLIm9Vr7.js} +1 -1
- package/dist/client/assets/{NodesView-BxGm3poT.js → NodesView-DEXvp3WT.js} +1 -1
- package/dist/client/assets/{PiExtensionsManager-lJbmskyZ.js → PiExtensionsManager-C2YjI9o2.js} +1 -1
- package/dist/client/assets/{PluginManager-BZjNNf9m.js → PluginManager-Dnf-LhYw.js} +1 -1
- package/dist/client/assets/{ResearchView-Bzsr9V0y.js → ResearchView-Z0TZ7WGo.js} +1 -1
- package/dist/client/assets/{RoadmapsView-CeKks_OI.js → RoadmapsView-DPcfX5MS.js} +1 -1
- package/dist/client/assets/{SettingsModal-D-9CLguN.js → SettingsModal-B6RN9VYe.js} +3 -3
- package/dist/client/assets/{SettingsModal-YdeVPhRJ.js → SettingsModal-BRNAPR1u.js} +1 -1
- package/dist/client/assets/{SetupWizardModal-DAC04LlA.js → SetupWizardModal-BFc3xID2.js} +1 -1
- package/dist/client/assets/{SkillsView-CClC_5RN.js → SkillsView-CipGahOR.js} +1 -1
- package/dist/client/assets/index-NFptaeUQ.js +1222 -0
- package/dist/client/assets/{star-DxVRh9VT.js → star-B314SwLA.js} +1 -1
- package/dist/client/assets/{users-3SD3oNMQ.js → users-Bu_ltePs.js} +1 -1
- package/dist/client/index.html +1 -1
- package/dist/client/version.json +1 -1
- package/dist/droid-cli/package.json +1 -1
- package/dist/extension.js +18 -0
- package/dist/pi-claude-cli/package.json +1 -1
- package/dist/plugins/fusion-plugin-dependency-graph/package.json +1 -1
- package/package.json +2 -1
- package/dist/client/assets/index-CrHLf3pB.js +0 -1222
package/dist/bin.js
CHANGED
|
@@ -3815,6 +3815,7 @@ This means a caller passed a .fusion directory where a project root was expected
|
|
|
3815
3815
|
);
|
|
3816
3816
|
this.migrate();
|
|
3817
3817
|
this.ensureRoutinesSchemaCompatibility();
|
|
3818
|
+
this.ensureInsightRunsSchemaCompatibility();
|
|
3818
3819
|
const configNow = (/* @__PURE__ */ new Date()).toISOString();
|
|
3819
3820
|
this.db.exec(
|
|
3820
3821
|
`INSERT OR IGNORE INTO config (id, nextId, nextWorkflowStepId, settings, workflowSteps, updatedAt) VALUES (1, 1, 1, '${JSON.stringify(DEFAULT_PROJECT_SETTINGS)}', '[]', '${configNow}')`
|
|
@@ -3862,6 +3863,23 @@ This means a caller passed a .fusion directory where a project root was expected
|
|
|
3862
3863
|
this.db.exec("CREATE INDEX IF NOT EXISTS idxRoutinesEnabled ON routines(enabled)");
|
|
3863
3864
|
this.db.exec("CREATE INDEX IF NOT EXISTS idxRoutinesScope ON routines(scope)");
|
|
3864
3865
|
}
|
|
3866
|
+
/**
|
|
3867
|
+
* Applies idempotent compatibility fixes for the project_insight_runs table.
|
|
3868
|
+
*
|
|
3869
|
+
* The `lifecycle` and `cancelledAt` columns were added to SCHEMA_SQL and
|
|
3870
|
+
* retroactively inserted into migration v33's CREATE TABLE, with a safety-net
|
|
3871
|
+
* in migration v59. However, databases that were already at v59+ when the
|
|
3872
|
+
* commit landed never re-run v59, leaving the columns missing. Running this
|
|
3873
|
+
* unconditionally on every init guarantees the columns exist.
|
|
3874
|
+
*/
|
|
3875
|
+
ensureInsightRunsSchemaCompatibility() {
|
|
3876
|
+
if (!this.hasTable("project_insight_runs")) {
|
|
3877
|
+
return;
|
|
3878
|
+
}
|
|
3879
|
+
this.addColumnIfMissing("project_insight_runs", "lifecycle", "TEXT");
|
|
3880
|
+
this.addColumnIfMissing("project_insight_runs", "cancelledAt", "TEXT");
|
|
3881
|
+
this.db.exec(`CREATE INDEX IF NOT EXISTS idxInsightRunsProjectTriggerStatus ON project_insight_runs(projectId, trigger, status)`);
|
|
3882
|
+
}
|
|
3865
3883
|
migrate() {
|
|
3866
3884
|
const version = this.getSchemaVersion() || 1;
|
|
3867
3885
|
if (version >= SCHEMA_VERSION) return;
|
|
@@ -168355,8 +168373,9 @@ function HelpOverlay() {
|
|
|
168355
168373
|
["[Shift+Tab]", "Cycle focused panel / pane backward"],
|
|
168356
168374
|
["[1-5]", "Jump to panel (Main: System/Logs/Stats/Utilities/Settings)"],
|
|
168357
168375
|
["[\u2190 / \u2192]", "Switch pane (Agents, Settings, Files, Git)"],
|
|
168358
|
-
["[\u2192] / [n]", "Next panel (Main)"],
|
|
168359
|
-
["[\u2190] / [p]", "Previous panel (Main)"],
|
|
168376
|
+
["[\u2192] / [\u2193] / [n]", "Next panel (Main; \u2191/\u2193 scroll on Logs)"],
|
|
168377
|
+
["[\u2190] / [\u2191] / [p]", "Previous panel (Main; \u2191/\u2193 scroll on Logs)"],
|
|
168378
|
+
["[Enter]", "Expand log + release mouse for text selection (Logs)"],
|
|
168360
168379
|
["[r]", "Refresh stats (Utilities)"],
|
|
168361
168380
|
["[c]", "Clear logs (Utilities)"],
|
|
168362
168381
|
["[k]", "Kill all vitest processes (Utilities)"],
|
|
@@ -170955,7 +170974,7 @@ function DashboardApp({ controller }) {
|
|
|
170955
170974
|
}
|
|
170956
170975
|
});
|
|
170957
170976
|
}, [controller]);
|
|
170958
|
-
const wantsMouse = state.mode === "interactive" ? state.interactiveView === "files" || state.interactiveView === "git" || state.interactiveView === "board" : state.activeSection === "logs";
|
|
170977
|
+
const wantsMouse = state.mode === "interactive" ? state.interactiveView === "files" || state.interactiveView === "git" || state.interactiveView === "board" : state.activeSection === "logs" && !state.logsExpandedMode;
|
|
170959
170978
|
useEffect2(() => {
|
|
170960
170979
|
if (state.mouseEnabled !== wantsMouse) {
|
|
170961
170980
|
controller.setMouseEnabled(wantsMouse);
|
|
@@ -171107,6 +171126,14 @@ function DashboardApp({ controller }) {
|
|
|
171107
171126
|
}
|
|
171108
171127
|
return;
|
|
171109
171128
|
}
|
|
171129
|
+
if (key.downArrow && state.activeSection !== "logs") {
|
|
171130
|
+
controller.cycleSection(1);
|
|
171131
|
+
return;
|
|
171132
|
+
}
|
|
171133
|
+
if (key.upArrow && state.activeSection !== "logs") {
|
|
171134
|
+
controller.cycleSection(-1);
|
|
171135
|
+
return;
|
|
171136
|
+
}
|
|
171110
171137
|
if (state.activeSection === "utilities") {
|
|
171111
171138
|
void controller.handleUtilityAction(input);
|
|
171112
171139
|
return;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{r as t,j as e}from"./vendor-react-K0fH_qHe.js";import{h as cs,c_ as et,c$ as st,d0 as tt,d1 as at,V as _,R as os,T as Ss,d2 as nt,L as ss,a7 as $e,C as Es,e as Ls,d3 as it,d4 as rt,d5 as lt,b1 as $s,c7 as ct,d6 as ot,cb as Z,d7 as dt,d8 as Ds,d9 as Ps,z as Ue,aA as ut,aB as is,a4 as Ve,da as ks,a5 as De,a8 as mt,X as zs,F as Pe,a2 as Je,db as Bs,dc as Hs,dd as ht,c1 as ft,a3 as gt,b4 as xt,s as Os,de as bt,df as vt,dg as pt,dh as jt,di as rs,dj as Is,dk as Nt,dl as ts,b7 as yt,dm as St,q as kt,dn as _s,dp as Ct,p as re,dq as Vs,dr as Rt,ds as wt,dt as Ft,du as We,d as Ke,M as Ye,r as Xe,c as Us,dv as Mt,dw as At,ak as Tt,aJ as Et,aK as Cs,dx as Lt,dy as $t,aL as Dt,dz as ls,dA as Pt,dB as zt,dC as Bt,dD as Ht,dE as Js,dF as Ot,dG as It,dH as _t,dI as Vt}from"./index-
|
|
1
|
+
import{r as t,j as e}from"./vendor-react-K0fH_qHe.js";import{h as cs,c_ as et,c$ as st,d0 as tt,d1 as at,V as _,R as os,T as Ss,d2 as nt,L as ss,a7 as $e,C as Es,e as Ls,d3 as it,d4 as rt,d5 as lt,b1 as $s,c7 as ct,d6 as ot,cb as Z,d7 as dt,d8 as Ds,d9 as Ps,z as Ue,aA as ut,aB as is,a4 as Ve,da as ks,a5 as De,a8 as mt,X as zs,F as Pe,a2 as Je,db as Bs,dc as Hs,dd as ht,c1 as ft,a3 as gt,b4 as xt,s as Os,de as bt,df as vt,dg as pt,dh as jt,di as rs,dj as Is,dk as Nt,dl as ts,b7 as yt,dm as St,q as kt,dn as _s,dp as Ct,p as re,dq as Vs,dr as Rt,ds as wt,dt as Ft,du as We,d as Ke,M as Ye,r as Xe,c as Us,dv as Mt,dw as At,ak as Tt,aJ as Et,aK as Cs,dx as Lt,dy as $t,aL as Dt,dz as ls,dA as Pt,dB as zt,dC as Bt,dD as Ht,dE as Js,dF as Ot,dG as It,dH as _t,dI as Vt}from"./index-NFptaeUQ.js";import{S as Gs}from"./star-B314SwLA.js";import"./vendor-xterm-DzcZoU0P.js";/**
|
|
2
2
|
* @license lucide-react v1.7.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as s,j as t}from"./vendor-react-K0fH_qHe.js";import{ak as st,al as dt,am as Bt,an as Gt,ao as Vt,ap as Kt,aq as qt,ar as Xt,as as Jt,at as Yt,au as Qt,av as Zt,z as es,aw as ts,ax as ss,ay as ns,N as as,az as rs,M as vt,r as wt,S as is,a7 as ut,P as Ze,o as ls,aA as cs,aB as Oe,E as os,d as ds,aC as us,aD as hs,aE as ms,a5 as fs,aF as gs,aG as ps,aH as ht,aI as xs,aJ as vs,aK as mt,aL as ws}from"./index-CrHLf3pB.js";import"./vendor-xterm-DzcZoU0P.js";const et="kb-chat-active-session";function bs(a){const r=typeof a=="string"?a.trim():"",l=r.indexOf("/");return!r||l<=0||l>=r.length-1?{}:{modelProvider:r.slice(0,l),modelId:r.slice(l+1)}}function Ss(a){const r=a?.toolCalls;if(!Array.isArray(r))return;const l=r.map(d=>{if(!d||typeof d!="object")return null;const i=d,w=typeof i.toolName=="string"?i.toolName:"";if(!w)return null;const y=i.args;return{toolName:w,...y&&typeof y=="object"?{args:y}:{},isError:!!i.isError,result:i.result,status:"completed"}}).filter(d=>d!==null);return l.length>0?l:void 0}function ks(a){const r=a?.fallback;if(!r||typeof r!="object")return;const l=r,d=typeof l.primaryModel=="string"?l.primaryModel:"",i=typeof l.fallbackModel=="string"?l.fallbackModel:"",w=l.triggerPoint;if(!(!d||!i||w!=="session-creation"&&w!=="prompt-time"))return{primaryModel:d,fallbackModel:i,triggerPoint:w}}function tt(a){return{id:a.id,sessionId:a.sessionId,role:a.role,content:a.content,thinkingOutput:a.thinkingOutput,toolCalls:Ss(a.metadata),fallbackInfo:ks(a.metadata),attachments:a.attachments,createdAt:a.createdAt}}function ys(a,r){const[l,d]=s.useState([]),[i,w]=s.useState(null),[y,T]=s.useState(!0),[$,x]=s.useState([]),[V,S]=s.useState(!1),[P,b]=s.useState(!1),[F,h]=s.useState(""),[N,v]=s.useState(""),[E,D]=s.useState([]),[L,ee]=s.useState(""),[z,_]=s.useState(""),[J,m]=s.useState(!0),[C,ce]=s.useState(new Map),g=s.useRef(null),se=s.useRef(!1),Y=s.useRef(""),Q=s.useRef(null),ye=s.useRef(l),I=s.useRef(i),ve=s.useRef(P);ye.current=l,I.current=i,ve.current=P,s.useEffect(()=>{Y.current=L},[L]);const fe=s.useRef(new Set),oe=s.useRef(0),De=s.useRef(a);De.current!==a&&(De.current=a,oe.current++),s.useEffect(()=>{const o=oe.current;st(void 0,a).then(f=>{if(oe.current!==o)return;const p=new Map;for(const k of f)p.set(k.id,k);ce(p)}).catch(()=>{})},[a]);const de=s.useCallback(async()=>{T(!0);try{const f=[...(await dt(a)).sessions].sort((p,k)=>new Date(k.updatedAt).getTime()-new Date(p.updatedAt).getTime());d(f)}catch{}finally{T(!1)}},[a]);s.useEffect(()=>{de()},[de]);const re=s.useRef(()=>{}),Z=s.useRef(!1);s.useEffect(()=>{Z.current=!1},[a]),s.useEffect(()=>{if(y||Z.current||I.current)return;const o=Bt(et,a);if(!o){Z.current=!0;return}const f=l.find(p=>p.id===o);if(f){Z.current=!0,re.current(o,f);return}Z.current=!0},[y,l,a]);const ne=s.useCallback(async(o,f)=>{S(!0);try{const p=await Gt(o,{limit:50,...f},a),k=p.messages.map(tt);f?.offset&&f.offset>0?x(q=>[...k,...q]):x(k),m(p.messages.length>=50)}catch{}finally{S(!1)}},[a]),ie=s.useCallback(()=>{Q.current?.(),Q.current=null,Y.current="",ee(""),h(""),v(""),D([]),b(!1)},[]),le=s.useCallback((o,f)=>{const p=I.current?.id??null;if(o&&p===o&&!f)return;g.current&&(g.current.close(),g.current=null);const k=f??l.find(q=>q.id===o);w(k||null),ie(),m(!0),o?ne(o):x([]),k?.isGenerating&&(b(!0),h("")),o?Vt(et,o,a):Kt(et,a)},[l,ne,a,ie]);re.current=le;const ge=s.useCallback(async o=>{const f=await qt(o,a);g.current&&(g.current.close(),g.current=null);const p={id:f.session.id,title:f.session.title,agentId:f.session.agentId,status:f.session.status,modelProvider:f.session.modelProvider,modelId:f.session.modelId,createdAt:f.session.createdAt,updatedAt:f.session.updatedAt};return d(k=>k.some(q=>q.id===p.id)?k:[p,...k]),ie(),le(p.id,p),x([]),p},[a,ie,le]),we=s.useCallback(async o=>{await Xt(o,{status:"archived"},a),d(f=>f.filter(p=>p.id!==o)),i?.id===o&&(w(null),x([]))},[i,a]),ue=s.useCallback(async o=>{i?.id===o&&g.current&&(g.current.close(),g.current=null),await Jt(o,a),d(f=>f.filter(p=>p.id!==o)),i?.id===o&&(w(null),x([]))},[i,a]),ae=s.useCallback(async()=>{!i||!J||await ne(i.id,{offset:$.length})},[i,J,ne,$.length]),he=s.useCallback(()=>{i&&(se.current=!0,Q.current?.(),Q.current=null,g.current?.close(),g.current=null,Yt(i.id,a).catch(()=>{}),b(!1),h(""),v(""),D([]))},[i,a]),Ce=s.useCallback(()=>{Y.current="",ee("")},[]),me=s.useCallback((o,f)=>{if(!i)return;if(P){Y.current=o,ee(o);return}se.current=!1,g.current&&(g.current.close(),g.current=null);const p=`temp-${Date.now()}`,k={id:p,sessionId:i.id,role:"user",content:o,createdAt:new Date().toISOString()};x(K=>[...K,k]),h(""),v(""),D([]),b(!0);const{handlers:q}=Qt({sessionId:i.id,tempUserMessageId:p,setStreamingText:h,setStreamingThinking:v,setStreamingToolCalls:D,cancelStreamingFlushesRef:Q,addToast:r,onFallbackSession:(K,X)=>{const M=bs(K.fallbackModel);d(H=>H.map(R=>R.id===X?{...R,...M}:R)),w(H=>H&&H.id===X?{...H,...M}:H)},onDone:({messageId:K,message:X,accumulated:M})=>{const H=X?tt(X):{id:K||`msg-${Date.now()}`,sessionId:i.id,role:"assistant",content:M.text,thinkingOutput:M.thinking,toolCalls:M.toolCalls.length>0?M.toolCalls:void 0,fallbackInfo:M.fallbackInfo,createdAt:new Date().toISOString()};fe.current.add(H.id),x(u=>[...u,H]),h(""),v(""),D([]),b(!1),g.current=null,setTimeout(()=>{fe.current.delete(H.id)},1e3),de();const R=Y.current.trim();R&&(Y.current="",ee(""),me(R))},onError:(K,X)=>{if(x(M=>M.filter(H=>H.id!==X)),h(""),v(""),D([]),b(!1),g.current=null,console.error("[useChat] Stream error:",K),r?.(typeof K=="string"&&K.trim()?K:"Failed to get response","error"),!se.current){const M=Y.current.trim();M&&(Y.current="",ee(""),me(M))}}});g.current=Zt(i.id,o,q,f,a)},[i,P,a,de,r]),Ne=z?l.filter(o=>o.title?.toLowerCase().includes(z.toLowerCase())||o.agentId.toLowerCase().includes(z.toLowerCase())):l;return s.useEffect(()=>{if(!P||g.current||!I.current)return;const o=setInterval(async()=>{if(!ve.current||g.current||!I.current){clearInterval(o);return}try{(await dt(a)).sessions.find(k=>k.id===I.current?.id)?.isGenerating||(clearInterval(o),await ne(I.current.id),h(""),v(""),D([]),b(!1))}catch{}},3e3);return()=>clearInterval(o)},[P,ne,a]),s.useEffect(()=>{const o=oe.current,f=a?`?projectId=${encodeURIComponent(a)}`:"",p=()=>oe.current!==o,k=R=>{if(p())return;const u=JSON.parse(R.data);d(j=>j.some(U=>U.id===u.id)?j:[u,...j])},q=R=>{if(p())return;const u=JSON.parse(R.data);d(j=>[...j.map(O=>O.id===u.id?u:O)]),I.current?.id===u.id&&w(u)},K=R=>{if(p())return;const{id:u}=JSON.parse(R.data);d(j=>j.filter(U=>U.id!==u)),I.current?.id===u&&(w(null),x([]))},X=R=>{if(p())return;const u=JSON.parse(R.data),j=tt(u);if(!fe.current.has(j.id)){if(I.current?.id===j.sessionId&&ve.current&&!g.current&&j.role==="assistant"){x(U=>U.some(O=>O.id===j.id)?U:[...U,j]),h(""),v(""),D([]),b(!1);return}I.current?.id===j.sessionId&&!ve.current&&x(U=>U.some(O=>O.id===j.id)?U:[...U,j])}},M=R=>{if(p())return;const{id:u}=JSON.parse(R.data);x(j=>j.filter(U=>U.id!==u))};return es(`/api/events${f}`,{events:{"chat:session:created":k,"chat:session:updated":q,"chat:session:deleted":K,"chat:message:added":X,"chat:message:deleted":M}})},[a]),s.useEffect(()=>()=>{g.current&&(g.current.close(),g.current=null)},[]),{sessions:l,activeSession:i,sessionsLoading:y,messages:$,messagesLoading:V,isStreaming:P,streamingText:F,streamingThinking:N,streamingToolCalls:E,pendingMessage:L,selectSession:le,createSession:ge,archiveSession:we,deleteSession:ue,sendMessage:me,stopStreaming:he,clearPendingMessage:Ce,loadMoreMessages:ae,hasMoreMessages:J,searchQuery:z,setSearchQuery:_,filteredSessions:Ne,refreshSessions:de,agentsMap:C}}function bt(a){const r=new Date(a),d=new Date().getTime()-r.getTime(),i=Math.floor(d/1e3),w=Math.floor(i/60),y=Math.floor(w/60),T=Math.floor(y/24);return i<60?"just now":w<60?`${w}m ago`:y<24?`${y}h ago`:T<7?`${T}d ago`:r.toLocaleDateString()}function ft(a,r){if(!a||!r)return null;const l=r.toLowerCase();if(l.includes("claude")){let i=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 i=i.replace(/\s+/g," "),i.length>30?i.slice(0,30)+"…":i}if(l.includes("gpt")||l.includes("openai")){const i=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 i.length>30?i.slice(0,30)+"…":i}if(l.includes("gemini")){const i=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 i.length>30?i.slice(0,30)+"…":i}const d=r.replace(/-/g," ").replace(/^\w/,i=>i.toUpperCase()).replace(/\s+/g," ").trim();return d.length>30?d.slice(0,30)+"…":d}function Ue(a,r){return a.length<=r?a:`${a.slice(0,r)}…`}function Cs(a){if(!a)return null;const r=Object.entries(a);return r.length===0?null:r.map(([l,d])=>{const i=typeof d=="string"?d:(()=>{try{return JSON.stringify(d)}catch{return String(d)}})();return`${l}=${Ue(i,50)}`}).join(", ")}function Ns(a){if(a===void 0)return null;if(typeof a=="string")return Ue(a,200);try{return Ue(JSON.stringify(a),200)}catch{return Ue(String(a),200)}}function St(a){if(!a||a.length===0)return null;const r=(S,P)=>{const b=S.status==="running",F=S.status==="completed"&&S.isError,h=Cs(S.args),N=Ns(S.result),v=b?h:N?`result: ${N}`:h?`args: ${h}`:null,E=b?"running":F?"error":"completed";return t.jsxs("details",{className:`chat-tool-call${b?" chat-tool-call--running":""}${F?" chat-tool-call--error":""}`,open:b,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",children:S.toolName}),v&&t.jsx("span",{className:"chat-tool-call-preview",title:v,children:v}),t.jsx("span",{className:"chat-tool-call-status-text",children:E})]}),t.jsxs("div",{className:"chat-tool-call-content",children:[h&&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:h})]}),N&&t.jsxs("div",{className:`chat-tool-call-row${F?" 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:N})]})]})]},`${S.toolName}-${P}`)},l="chat-tool-calls";if(a.length===1)return t.jsxs("div",{className:l,"data-testid":"chat-tool-calls",children:[t.jsxs("div",{className:"chat-tool-calls-header",children:[t.jsx(ht,{size:12,"aria-hidden":"true"}),t.jsx("span",{children:"Tool calls"})]}),r(a[0],0)]});const d=a.filter(S=>S.status==="running").length,i=a.filter(S=>S.status==="completed"&&S.isError).length,w=d>0,y=Array.from(new Set(a.map(S=>S.toolName))),T=y.slice(0,5),$=Math.max(0,y.length-T.length),x=$>0?`${T.join(", ")}, +${$} more`:T.join(", "),V=w?`(${d} running)`:i>0?`(${i} ${i===1?"error":"errors"})`:null;return t.jsx("div",{className:l,"data-testid":"chat-tool-calls",children:t.jsxs("details",{className:"chat-tool-calls-group","data-testid":"chat-tool-calls-group",open:w,children:[t.jsxs("summary",{className:"chat-tool-calls-group-summary",children:[t.jsx(ht,{size:12,"aria-hidden":"true"}),t.jsxs("span",{children:[a.length," tool calls"]}),t.jsx("span",{className:"chat-tool-calls-names",title:x,children:x}),V&&t.jsx("span",{className:"chat-tool-calls-group-status",children:V})]}),a.map((S,P)=>r(S,P))]})})}const kt={pre:({children:a,...r})=>t.jsx("pre",{...r,className:"chat-markdown-pre",children:a}),table:({children:a,...r})=>t.jsx("table",{...r,className:"chat-markdown-table",children:a})},Pe="__fn_agent__",js=280,Le=180,ze=500,gt="fusion:chat-sidebar-width",Ms=["image/png","image/jpeg","image/gif","image/webp","text/plain","application/json","text/yaml","text/markdown","text/csv","application/xml","text/x-log"];function pt(a){const r=/(^|[\s])\/([^\s]*)$/.exec(a);if(!r)return null;const l=r[1]??"",d=r[2]??"",i=r.index+l.length;return{filter:d,start:i,end:a.length}}function As(a,r){const l=a.slice(0,r),d=/(^|[\s\n])@([\w-]*)$/.exec(l);if(!d)return null;const i=d[2]??"",w=l.length-i.length-1;return{filter:i,start:w,end:r}}function Ts({projectId:a,onClose:r,onCreate:l}){const[d,i]=s.useState("agent"),[w,y]=s.useState([]),[T,$]=s.useState(!0),[x,V]=s.useState(""),[S,P]=s.useState([]),[b,F]=s.useState(!0),[h,N]=s.useState(""),[v,E]=s.useState([]),[D,L]=s.useState([]);s.useEffect(()=>{let m=!1;return $(!0),st(void 0,a).then(C=>{m||y(C)}).catch(()=>{m||y([])}).finally(()=>{m||$(!1)}),()=>{m=!0}},[a]),s.useEffect(()=>{F(!0),vs().then(m=>{P(m.models),E(m.favoriteProviders),L(m.favoriteModels)}).catch(()=>{P([]),E([]),L([])}).finally(()=>{F(!1)})},[]);const ee=s.useCallback(async m=>{const C=v,g=C.includes(m)?C.filter(se=>se!==m):[m,...C];E(g);try{await mt({favoriteProviders:g,favoriteModels:D})}catch{E(C)}},[v,D]),z=s.useCallback(async m=>{const C=D,g=C.includes(m)?C.filter(se=>se!==m):[m,...C];L(g);try{await mt({favoriteProviders:v,favoriteModels:g})}catch{L(C)}},[D,v]),_=m=>{if(m.preventDefault(),d==="agent"){if(!x)return;l({agentId:x});return}if(!h)return;const C=h.indexOf("/");if(C<=0)return;const ce=h.slice(0,C),g=h.slice(C+1);l({agentId:Pe,modelProvider:ce,modelId:g})},J=d==="agent"?!x:!h;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${d==="agent"?" chat-new-dialog-mode-btn--active":""}`,"data-testid":"chat-new-dialog-mode-agent",onClick:()=>{i("agent"),N("")},children:"Agent"}),t.jsx("button",{type:"button",className:`chat-new-dialog-mode-btn${d==="model"?" chat-new-dialog-mode-btn--active":""}`,"data-testid":"chat-new-dialog-mode-model",onClick:()=>{i("model"),V("")},children:"Model"})]}),t.jsxs("form",{onSubmit:_,children:[d==="agent"&&t.jsxs("label",{className:"chat-new-dialog-model-label",children:["Agent",T?t.jsx("div",{className:"chat-new-dialog-loading",children:"Loading agents..."}):w.length===0?t.jsx("div",{className:"chat-new-dialog-empty",children:"No agents available"}):t.jsx("div",{className:"chat-new-dialog-agent-list",children:w.map(m=>t.jsxs("button",{type:"button",className:`chat-new-dialog-agent-item${x===m.id?" chat-new-dialog-agent-item--selected":""}`,onClick:()=>V(m.id),"data-testid":`agent-option-${m.id}`,children:[t.jsx(Oe,{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))})]}),d==="model"&&t.jsx("div",{className:"chat-new-dialog-model-dropdown","data-testid":"chat-new-dialog-model-section",children:b?t.jsx("div",{className:"chat-new-dialog-loading",children:"Loading models..."}):t.jsx(ws,{models:S,value:h,onChange:N,label:"Model",placeholder:"Select a model",favoriteProviders:v,onToggleFavorite:ee,favoriteModels:D,onToggleModelFavorite:z})}),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:J,children:"Create"})]})]})]})})}const xt=s.memo(function({message:r,forcePlain:l,agentName:d,hideAssistantIdentity:i,showAssistantModelTag:w,activeModelTag:y,activeSessionId:T,mentionAgentsByName:$}){const x=r.role==="assistant",V=s.useMemo(()=>{if(x)return null;const b=r.content,F=/@([\w-]+)/g,h=[];let N=0,v=F.exec(b);for(;v;){const[E,D=""]=v,L=v.index;L>N&&h.push(b.slice(N,L));const ee=D.replace(/_/g," ").toLowerCase(),z=$.get(ee);z?h.push(t.jsxs("span",{className:"chat-mention-chip",children:["@",z.name.replace(/\s+/g,"_")]},`${z.id}-${L}`)):h.push(E),N=L+E.length,v=F.exec(b)}return N<b.length&&h.push(b.slice(N)),h.length===0?b:h},[x,r.content,$]),S=s.useMemo(()=>{const b=r.attachments;if(!b||b.length===0||!T)return null;const F=`/api/chat/sessions/${encodeURIComponent(T)}/attachments/`;return t.jsx("div",{className:"chat-message-attachments",children:b.map(h=>{const N=h.mimeType.startsWith("image/"),v=h.id||h.filename,E=`${F}${encodeURIComponent(h.filename)}`;return N?t.jsx("a",{className:"chat-message-attachment-link","data-testid":"chat-message-attachment",href:E,target:"_blank",rel:"noopener noreferrer",children:t.jsx("img",{className:"chat-message-attachment",src:E,alt:h.originalName})},v):t.jsxs("a",{className:"chat-message-attachment-file","data-testid":"chat-message-attachment",href:E,target:"_blank",rel:"noopener noreferrer",children:[t.jsx(ps,{size:14}),t.jsx("span",{children:h.originalName})]},v)})})},[r.attachments,T]),P=s.useMemo(()=>x?l?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(vt,{remarkPlugins:[wt],components:kt,children:r.content})}):null,[x,l,r.content]);return t.jsxs("div",{className:`chat-message chat-message--${r.role}`,"data-testid":`chat-message-${r.id}`,children:[x&&!i&&t.jsxs("div",{className:"chat-message-avatar",children:[t.jsx(Oe,{size:14}),t.jsx("span",{children:d}),w&&y&&t.jsx("span",{className:"chat-model-tag",children:y})]}),x?P:t.jsx("div",{className:"chat-message-content",children:V}),St(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})]}),S,t.jsx("div",{className:"chat-message-time",children:bt(r.createdAt)})]})});function Es({projectId:a,addToast:r}){const{activeSession:l,sessionsLoading:d,messages:i,messagesLoading:w,isStreaming:y,streamingText:T,streamingThinking:$,streamingToolCalls:x,selectSession:V,createSession:S,archiveSession:P,deleteSession:b,sendMessage:F,stopStreaming:h,pendingMessage:N,clearPendingMessage:v,searchQuery:E,setSearchQuery:D,filteredSessions:L}=ys(a,r),[ee,z]=s.useState(!1),[_,J]=s.useState(""),[m,C]=s.useState(null),[ce,g]=s.useState(null),[se,Y]=s.useState(!0),[Q,ye]=s.useState(js),[I,ve]=s.useState(new Map),[fe,oe]=s.useState([]),[De,de]=s.useState(!0),[re,Z]=s.useState(!1),[ne,ie]=s.useState(""),[le,ge]=s.useState(0),[we,ue]=s.useState(""),[ae,he]=s.useState(!1),[Ce,me]=s.useState(0),[Ne,o]=s.useState(-1),[f,p]=s.useState(!1),[k,q]=s.useState([]),[K,X]=s.useState(!1),[,M]=s.useState(!1),[H,R]=s.useState({top:0,left:0}),u=ts({projectId:a}),j=s.useCallback(e=>{if(!e||!u.mentionActive)return;const n=e.getBoundingClientRect();R({top:n.top-260,left:n.left+8})},[u.mentionActive]),U=s.useRef(null),O=s.useRef(null),_e=s.useRef(null),W=s.useRef(null),Re=s.useRef(!1),$e=s.useRef(!1),nt=s.useRef(null),at=s.useRef([]),je=s.useRef(0),B=ss()==="mobile";s.useEffect(()=>{try{const e=localStorage.getItem(gt);if(!e)return;const n=Number.parseInt(e,10);if(Number.isNaN(n))return;const c=Math.max(Le,Math.min(ze,n));ye(c)}catch{}},[]);const{keyboardOverlap:He,viewportHeight:rt,viewportOffsetTop:yt,keyboardOpen:it}=ns({enabled:B&&!!l}),Ct=it?{"--keyboard-overlap":`${He}px`,"--vv-offset-top":`${yt}px`,...rt!==null?{"--vv-height":`${rt}px`}:{}}:{},te=s.useMemo(()=>{const e=ne.trim().toLowerCase();return(e?fe.filter(c=>c.name.toLowerCase().includes(e)):fe).slice(0,10)},[fe,ne]),be=s.useMemo(()=>Array.from(I.values()),[I]),pe=s.useMemo(()=>{const e=we.trim().toLowerCase();return e?be.filter(n=>n.name.toLowerCase().includes(e)):be},[be,we]),lt=s.useMemo(()=>{const e=new Map;for(const n of be)e.set(n.name.toLowerCase(),n);return e},[be]);s.useEffect(()=>{ge(0)},[te]),s.useEffect(()=>{me(0)},[we,ae]),s.useEffect(()=>()=>{O.current!==null&&window.clearTimeout(O.current)},[]),s.useEffect(()=>{const e=_e.current;e&&(e.scrollTop=e.scrollHeight)},[i,T,$,y]),s.useEffect(()=>{if(He<=0)return;const e=_e.current;e&&(e.scrollTop=e.scrollHeight)},[He]),as(B&&it),s.useEffect(()=>{const e=()=>C(null);if(m)return document.addEventListener("click",e),()=>document.removeEventListener("click",e)},[m]),s.useEffect(()=>{let e=!1;const n=a;return st(void 0,a).then(c=>{if(e||n!==a)return;const A=new Map;for(const G of c)A.set(G.id,G);ve(A)}).catch(()=>{}),()=>{e=!0}},[a]),s.useEffect(()=>{let e=!1;return de(!0),rs(a).then(n=>{e||oe(n)}).catch(()=>{e||oe([])}).finally(()=>{e||de(!1)}),()=>{e=!0}},[a]),s.useEffect(()=>{at.current=k},[k]),s.useEffect(()=>()=>{for(const e of at.current)e.previewUrl&&URL.revokeObjectURL(e.previewUrl)},[]);const Ee=s.useCallback(e=>{if(!e||e.length===0)return;const n=[];for(const c of Array.from(e)){if(!Ms.includes(c.type))continue;const A=c.type.startsWith("image/");n.push({file:c,previewUrl:A?URL.createObjectURL(c):""})}n.length>0&&q(c=>[...c,...n])},[]),Nt=s.useCallback(e=>{q(n=>{const c=n[e];return c?.previewUrl&&URL.revokeObjectURL(c.previewUrl),n.filter((A,G)=>G!==e)})},[]),jt=s.useCallback(e=>{const n=e.clipboardData?.files;if(!n||n.length===0)return;const c=Array.from(n).filter(A=>A.type.startsWith("image/"));c.length!==0&&Ee(c)},[Ee]),Mt=s.useCallback(async e=>{try{await S(e),z(!1),B&&Y(!1)}catch{r("Failed to create chat session","error")}},[S,r,B]),We=s.useCallback(()=>{J(""),Z(!1),ie(""),he(!1),ue(""),o(-1),q(e=>{for(const n of e)n.previewUrl&&URL.revokeObjectURL(n.previewUrl);return[]})},[]),Me=s.useCallback(()=>{const e=_.trim(),n=k.map(c=>c.file);if(!(!e&&n.length===0||!l)){if(e==="/clear"){We(),h(),v(),S({agentId:l.agentId,modelProvider:l.modelProvider??void 0,modelId:l.modelId??void 0}).catch(()=>{r("Failed to clear conversation","error")});return}We(),F(e,n)}},[_,k,l,We,h,v,S,r,F]),Ie=s.useCallback(()=>{if(typeof window>"u"||window.innerWidth>768)return;const e=W.current;if(!e||e.disabled)return;const n=window.scrollX,c=window.scrollY;e.focus({preventScroll:!0}),window.requestAnimationFrame(()=>{(window.scrollX!==n||window.scrollY!==c)&&window.scrollTo(n,c)})},[]),ct=s.useCallback(()=>{typeof window>"u"||window.innerWidth>768||(Re.current=!0)},[]),Be=s.useCallback(e=>{J(n=>{const c=pt(n);if(!c)return n;const A=`/skill:${e.name} `,G=n.slice(0,c.start)+A+n.slice(c.end);return window.requestAnimationFrame(()=>{W.current&&(W.current.style.height="auto",W.current.style.height=`${Math.min(W.current.scrollHeight,120)}px`,W.current.focus())}),G}),Z(!1),ie(""),ge(0)},[]),Ge=s.useCallback(e=>{const n=W.current;if(!n||Ne<0)return;const c=n.selectionStart??je.current,A=n.selectionEnd??c,G=Math.max(c,A),Te=Math.min(Ne,G),Se=`${`@${e.name.replace(/\s+/g,"_")}`} `,Qe=_.slice(0,Te)+Se+_.slice(G),ke=Te+Se.length;J(Qe),he(!1),ue(""),me(0),o(-1),window.requestAnimationFrame(()=>{W.current&&(W.current.style.height="auto",W.current.style.height=`${Math.min(W.current.scrollHeight,120)}px`,W.current.focus(),W.current.setSelectionRange(ke,ke))})},[Ne,_]),At=s.useCallback(e=>{if(je.current=e.currentTarget.selectionStart??je.current,u.mentionActive&&u.files.length>0){if(u.handleKeyDown(e,_),e.key==="Enter"||e.key==="Tab"){const n=u.files[u.selectedIndex];if(n){const c=u.selectFile(n,_);J(c),u.dismissMention(),M(!1)}}return}if(ae&&e.key==="ArrowDown"){e.preventDefault(),pe.length>0&&me(n=>(n+1)%pe.length);return}if(ae&&e.key==="ArrowUp"){e.preventDefault(),pe.length>0&&me(n=>n===0?pe.length-1:n-1);return}if(ae&&e.key==="Enter"){e.preventDefault();const n=pe[Ce]??pe[0];n&&Ge(n);return}if(ae&&e.key==="Escape"){e.preventDefault(),he(!1),ue(""),o(-1);return}if(re&&e.key==="ArrowDown"){e.preventDefault(),te.length>0&&ge(n=>(n+1)%te.length);return}if(re&&e.key==="ArrowUp"){e.preventDefault(),te.length>0&&ge(n=>n===0?te.length-1:n-1);return}if(re&&(e.key==="Enter"||e.key==="Tab")&&te.length>0){e.preventDefault();const n=te[le]??te[0];n&&Be(n);return}if(re&&e.key==="Escape"){e.preventDefault(),Z(!1);return}e.key==="Enter"&&!e.shiftKey&&(e.preventDefault(),Me())},[ae,pe,Ce,Ge,re,te,le,Be,Me,u,_]),Fe=s.useCallback((e,n)=>{const c=As(e,n);if(c){he(!0),ue(c.filter),o(c.start);return}he(!1),ue(""),o(-1)},[]),Tt=s.useCallback(e=>{const n=e.target,c=n.value,A=n.selectionStart??c.length;je.current=A,J(c);const G=pt(c);G?(Z(!0),ie(G.filter)):(Z(!1),ie("")),Fe(c,A),u.detectMention(c,A),M(u.mentionActive),u.mentionActive&&j(n),n.style.height="auto",n.style.height=`${Math.min(n.scrollHeight,120)}px`},[Fe]),Ve=s.useCallback(e=>{const n=e.currentTarget,c=n.selectionStart??n.value.length;je.current=c,Fe(n.value,c),u.detectMention(n.value,c),M(u.mentionActive),u.mentionActive&&j(n)},[Fe,u,j]),Pt=s.useCallback(e=>{e.key!=="Escape"&&Ve(e)},[Ve]),Dt=s.useCallback(()=>{if(Re.current){window.requestAnimationFrame(()=>{Ie()});return}O.current!==null&&window.clearTimeout(O.current),O.current=window.setTimeout(()=>{Z(!1),he(!1),ue(""),o(-1),M(!1),u.dismissMention(),O.current=null},120)},[u,Ie]),Rt=s.useCallback(()=>{O.current!==null&&(window.clearTimeout(O.current),O.current=null)},[]),$t=s.useCallback(async e=>{C(null);try{await P(e),r("Conversation archived","success")}catch{r("Failed to archive conversation","error")}},[P,r]),Et=s.useCallback(async e=>{g(null),C(null);try{await b(e),r("Conversation deleted","success")}catch{r("Failed to delete conversation","error")}},[b,r]),Ae=s.useCallback(e=>{try{localStorage.setItem(gt,String(e))}catch{}},[]),It=s.useCallback(e=>{if(B)return;e.preventDefault(),e.stopPropagation();const n=e.currentTarget;typeof n.setPointerCapture=="function"&&n.setPointerCapture(e.pointerId);const c=e.clientX,A=Q;let G=A;document.body.style.userSelect="none";const Te=Se=>{const Qe=Se.clientX-c,ke=Math.max(Le,Math.min(ze,A+Qe));G=ke,ye(ke),Ae(ke)},Ye=Se=>{typeof n.releasePointerCapture=="function"&&n.releasePointerCapture(Se.pointerId),document.body.style.userSelect="",document.removeEventListener("pointermove",Te),document.removeEventListener("pointerup",Ye),Ae(G)};document.addEventListener("pointermove",Te),document.addEventListener("pointerup",Ye)},[B,Ae,Q]),Ft=s.useCallback(e=>{if(B||e.key!=="ArrowLeft"&&e.key!=="ArrowRight")return;e.preventDefault();const n=e.shiftKey?50:10,c=e.key==="ArrowLeft"?-n:n,A=Math.max(Le,Math.min(ze,Q+c));ye(A),Ae(A)},[B,Ae,Q]),Lt=s.useCallback(e=>{V(e),B&&Y(!1)},[V,B]),zt=s.useCallback(()=>{V(""),Y(!0)},[V]),Ut=()=>t.jsxs("div",{className:"chat-empty-state",children:[t.jsx(xs,{size:48,strokeWidth:1.5}),t.jsx("h2",{children:"Start a new conversation"}),t.jsxs("button",{className:"btn btn-primary",onClick:()=>z(!0),children:[t.jsx(Ze,{size:16}),"New Chat"]})]}),xe=ft(l?.modelProvider,l?.modelId),Ke=!!(l||y||i.length>0),ot=l?.agentId===Pe?xe??"Fusion":l?.title||I.get(l?.agentId??"")?.name||l?.agentId||"Chat",Ot=!!(xe&&xe!==ot),qe=I.get(l?.agentId??"")?.name||(l?.agentId===Pe?xe??"Fusion":l?.agentId?.slice(0,30)??"Fusion"),Xe=!1,Je=l?.agentId===Pe,_t=N.length>50?`${N.slice(0,50)}…`:N,Ht=s.useCallback(()=>{p(e=>!e)},[]),Wt=s.useCallback((e,n=!1)=>n?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(vt,{remarkPlugins:[wt],components:kt,children:e})}),[]);return t.jsxs("div",{className:"chat-view",children:[t.jsxs("div",{className:`chat-sidebar${se?"":" chat-sidebar--hidden"}`,style:B?void 0:{width:`${Q}px`},children:[t.jsx("div",{className:"chat-sidebar-search",children:t.jsxs("div",{className:"chat-sidebar-search-wrapper",children:[t.jsx(is,{size:14,className:"chat-sidebar-search-icon"}),t.jsx("input",{type:"text",className:"chat-sidebar-search",placeholder:"Search conversations...",value:E,onChange:e=>D(e.target.value),"data-testid":"chat-search-input"})]})}),t.jsx("div",{className:"chat-session-list chat-sidebar-list",children:d?t.jsx("div",{style:{padding:"12px",color:"var(--text-secondary)",fontSize:"13px"},children:"Loading..."}):L.length===0?t.jsx("div",{style:{padding:"12px",color:"var(--text-secondary)",fontSize:"13px"},children:"No conversations yet"}):L.map(e=>t.jsxs("div",{className:`chat-session-item${l?.id===e.id?" chat-session-item--active":""}`,onClick:()=>Lt(e.id),onContextMenu:n=>{n.preventDefault(),C({sessionId:e.id,x:n.clientX,y:n.clientY})},"data-testid":`chat-session-${e.id}`,children:[t.jsx("button",{className:"chat-session-delete-btn",onClick:n=>{n.stopPropagation(),g(e.id)},"data-testid":"chat-session-delete-btn","aria-label":"Delete conversation",children:t.jsx(ut,{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.jsx("span",{children:I.get(e.agentId)?.name||(e.agentId===Pe?ft(e.modelProvider,e.modelId)??"Fusion":e.agentId.slice(0,30))}),t.jsx("span",{children:e.updatedAt?bt(e.updatedAt):""})]})]},e.id))}),t.jsx("div",{className:"chat-sidebar-footer",children:t.jsxs("button",{className:"btn btn-sm btn-primary chat-sidebar-footer-btn",onClick:()=>z(!0),"data-testid":"chat-new-btn",children:[t.jsx(Ze,{size:14}),"New Chat"]})})]}),!B&&se&&t.jsx("div",{className:"chat-sidebar-resize-handle",role:"separator","aria-orientation":"vertical","aria-valuemin":Le,"aria-valuemax":ze,"aria-valuenow":Q,"aria-label":"Resize chat sidebar",tabIndex:0,onPointerDown:It,onKeyDown:Ft}),m&&t.jsxs("div",{className:"chat-session-context-menu",style:{top:m.y,left:m.x},onClick:e=>e.stopPropagation(),children:[t.jsxs("button",{onClick:()=>$t(m.sessionId),"data-testid":"chat-context-archive",children:[t.jsx(ls,{size:14}),"Archive"]}),t.jsxs("button",{onClick:()=>{C(null),g(m.sessionId)},"data-testid":"chat-context-delete",children:[t.jsx(ut,{size:14}),"Delete"]})]}),ce&&t.jsx("div",{className:"chat-new-dialog-backdrop chat-view-dialog-backdrop",onClick:()=>g(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:()=>g(null),children:"Cancel"}),t.jsx("button",{className:"btn btn-sm btn-danger",onClick:()=>void Et(ce),children:"Delete"})]})]})}),t.jsxs("div",{className:"chat-thread",style:Ct,children:[(Ke||!B)&&t.jsxs("div",{className:"chat-thread-header",children:[B&&Ke&&t.jsx("button",{className:"btn-icon",onClick:zt,"data-testid":"chat-back-btn",children:t.jsx(cs,{size:16})}),t.jsx(Oe,{size:16}),t.jsx("span",{className:"chat-thread-header-title",children:ot}),Ot&&t.jsx("span",{className:"chat-model-tag",children:xe}),Ke&&t.jsx("button",{type:"button",className:`chat-thread-header-render-toggle${f?" chat-thread-header-render-toggle--plain":""}`,"data-testid":"chat-thread-render-toggle","aria-label":f?"Show all messages as rendered Markdown":"Show all messages as plain text",onClick:Ht,children:f?t.jsx(os,{size:14}):t.jsx(ds,{size:14})}),!B&&t.jsxs("button",{className:"btn btn-sm btn-primary chat-thread-header-new-chat",onClick:()=>z(!0),"data-testid":"chat-thread-new-chat-btn",children:[t.jsx(Ze,{size:14}),"New Chat"]})]}),t.jsxs("div",{className:"chat-messages",ref:_e,children:[y?t.jsxs(t.Fragment,{children:[i.map(e=>t.jsx(xt,{message:e,forcePlain:f,agentName:qe,hideAssistantIdentity:Je,showAssistantModelTag:Xe,activeModelTag:xe,activeSessionId:l?.id??null,mentionAgentsByName:lt},e.id)),t.jsxs("div",{className:"chat-message chat-message--assistant chat-message--streaming",children:[!Je&&t.jsxs("div",{className:"chat-message-avatar",children:[t.jsx(Oe,{size:14}),t.jsx("span",{children:qe}),Xe]}),T?Wt(T,f):t.jsx("div",{className:"chat-message-content chat-message-content--waiting",children:$?"Thinking…":"Connecting…"}),St(x),$&&t.jsxs("details",{className:"chat-message-thinking",children:[t.jsx("summary",{children:"Thinking"}),t.jsx("pre",{className:"chat-message-thinking-content",children:$})]}),t.jsxs("div",{className:"chat-typing-indicator",children:[t.jsx("span",{}),t.jsx("span",{}),t.jsx("span",{})]})]})]}):w?t.jsx("div",{style:{color:"var(--text-secondary)",fontSize:"13px"},children:"Loading messages..."}):i.length===0&&!l?Ut():i.length===0&&l?t.jsx("div",{style:{color:"var(--text-secondary)",fontSize:"13px"},children:"No messages yet. Start the conversation!"}):t.jsx(t.Fragment,{children:i.map(e=>t.jsx(xt,{message:e,forcePlain:f,agentName:qe,hideAssistantIdentity:Je,showAssistantModelTag:Xe,activeModelTag:xe,activeSessionId:l?.id??null,mentionAgentsByName:lt},e.id))}),t.jsx("div",{ref:U})]}),l&&t.jsxs("div",{className:"chat-input-area",children:[t.jsx("input",{ref:nt,type:"file",accept:"image/*,.txt,.json,.yaml,.yml,.log,.csv,.xml,.md",multiple:!0,style:{display:"none"},onChange:e=>{Ee(e.target.files),e.target.value=""}}),re&&t.jsx("div",{className:"chat-skill-menu","data-testid":"chat-skill-menu",role:"listbox","aria-label":"Skill suggestions",children:De?t.jsx("div",{className:"chat-skill-menu-empty",children:"Loading skills…"}):te.length===0?t.jsx("div",{className:"chat-skill-menu-empty",children:ne?"No skills found":"No skills available"}):te.map((e,n)=>t.jsxs("button",{type:"button",role:"option","aria-selected":n===le,className:`chat-skill-menu-item${n===le?" chat-skill-menu-item--highlighted":""}`,onMouseDown:c=>c.preventDefault(),onMouseEnter:()=>ge(n),onClick:()=>Be(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))}),k.length>0&&t.jsx("div",{className:"chat-attachment-previews","data-testid":"chat-attachment-previews",children:k.map((e,n)=>t.jsxs("div",{className:"chat-attachment-preview","data-testid":`chat-attachment-preview-${n}`,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:()=>Nt(n),"data-testid":`chat-attachment-remove-${n}`,"aria-label":`Remove ${e.file.name}`,children:"×"})]},e.previewUrl||`${e.file.name}-${n}`))}),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:()=>nt.current?.click(),children:t.jsx(us,{size:16})}),t.jsxs("div",{className:`chat-input-wrapper${K?" chat-input-wrapper--dragover":""}`,onDragOver:e=>{e.preventDefault(),X(!0)},onDragLeave:()=>X(!1),onDrop:e=>{e.preventDefault(),X(!1),Ee(e.dataTransfer.files)},children:[t.jsx("textarea",{ref:W,className:"chat-input-textarea",placeholder:"Type a message...",value:_,onChange:Tt,onKeyDown:At,onKeyUp:Pt,onClick:Ve,onBlur:Dt,onFocus:Rt,onPaste:jt,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(hs,{agents:be,filter:we,highlightedIndex:Ce,visible:ae,onSelect:Ge,position:"below"}),t.jsx(ms,{visible:u.mentionActive&&!ae,position:H,files:u.files,selectedIndex:u.selectedIndex,onSelect:e=>{const n=u.selectFile(e,_);J(n),u.dismissMention(),M(!1),W.current?.focus()},loading:u.loading}),N&&t.jsxs("div",{className:"chat-pending-message","data-testid":"chat-pending-indicator",children:[t.jsx("span",{children:`Queued: ${_t}`}),t.jsx("button",{type:"button",className:"chat-pending-message-dismiss","aria-label":"Dismiss queued message","data-testid":"chat-pending-dismiss",onClick:v,children:"×"})]})]}),y?t.jsx("button",{className:"chat-input-stop",onClick:h,"aria-label":"Stop generation","data-testid":"chat-stop-btn",children:t.jsx(fs,{size:14})}):t.jsx("button",{type:"button",className:"chat-input-send",onPointerDown:e=>{typeof window>"u"||window.innerWidth>768||(e.preventDefault(),e.pointerType&&e.pointerType!=="mouse"&&($e.current=!0,ct(),Ie(),Me(),window.setTimeout(()=>{Re.current=!1},1500)))},onTouchStart:e=>{typeof window>"u"||window.innerWidth>768||(e.preventDefault(),$e.current=!0,ct(),Ie(),Me(),window.setTimeout(()=>{Re.current=!1},1500))},onMouseDown:e=>{typeof window>"u"||window.innerWidth>768||e.preventDefault()},onClick:()=>{if($e.current){$e.current=!1;return}Me()},disabled:!_.trim()&&k.length===0,"data-testid":"chat-send-btn",children:t.jsx(gs,{size:16})})]})]})]}),ee&&t.jsx(Ts,{projectId:a,onClose:()=>z(!1),onCreate:Mt})]})}export{Es as ChatView};
|
|
1
|
+
import{r as s,j as t}from"./vendor-react-K0fH_qHe.js";import{ak as st,al as dt,am as Bt,an as Gt,ao as Vt,ap as Kt,aq as qt,ar as Xt,as as Jt,at as Yt,au as Qt,av as Zt,z as es,aw as ts,ax as ss,ay as ns,N as as,az as rs,M as vt,r as wt,S as is,a7 as ut,P as Ze,o as ls,aA as cs,aB as Oe,E as os,d as ds,aC as us,aD as hs,aE as ms,a5 as fs,aF as gs,aG as ps,aH as ht,aI as xs,aJ as vs,aK as mt,aL as ws}from"./index-NFptaeUQ.js";import"./vendor-xterm-DzcZoU0P.js";const et="kb-chat-active-session";function bs(a){const r=typeof a=="string"?a.trim():"",l=r.indexOf("/");return!r||l<=0||l>=r.length-1?{}:{modelProvider:r.slice(0,l),modelId:r.slice(l+1)}}function Ss(a){const r=a?.toolCalls;if(!Array.isArray(r))return;const l=r.map(d=>{if(!d||typeof d!="object")return null;const i=d,w=typeof i.toolName=="string"?i.toolName:"";if(!w)return null;const y=i.args;return{toolName:w,...y&&typeof y=="object"?{args:y}:{},isError:!!i.isError,result:i.result,status:"completed"}}).filter(d=>d!==null);return l.length>0?l:void 0}function ks(a){const r=a?.fallback;if(!r||typeof r!="object")return;const l=r,d=typeof l.primaryModel=="string"?l.primaryModel:"",i=typeof l.fallbackModel=="string"?l.fallbackModel:"",w=l.triggerPoint;if(!(!d||!i||w!=="session-creation"&&w!=="prompt-time"))return{primaryModel:d,fallbackModel:i,triggerPoint:w}}function tt(a){return{id:a.id,sessionId:a.sessionId,role:a.role,content:a.content,thinkingOutput:a.thinkingOutput,toolCalls:Ss(a.metadata),fallbackInfo:ks(a.metadata),attachments:a.attachments,createdAt:a.createdAt}}function ys(a,r){const[l,d]=s.useState([]),[i,w]=s.useState(null),[y,T]=s.useState(!0),[$,x]=s.useState([]),[V,S]=s.useState(!1),[P,b]=s.useState(!1),[F,h]=s.useState(""),[N,v]=s.useState(""),[E,D]=s.useState([]),[L,ee]=s.useState(""),[z,_]=s.useState(""),[J,m]=s.useState(!0),[C,ce]=s.useState(new Map),g=s.useRef(null),se=s.useRef(!1),Y=s.useRef(""),Q=s.useRef(null),ye=s.useRef(l),I=s.useRef(i),ve=s.useRef(P);ye.current=l,I.current=i,ve.current=P,s.useEffect(()=>{Y.current=L},[L]);const fe=s.useRef(new Set),oe=s.useRef(0),De=s.useRef(a);De.current!==a&&(De.current=a,oe.current++),s.useEffect(()=>{const o=oe.current;st(void 0,a).then(f=>{if(oe.current!==o)return;const p=new Map;for(const k of f)p.set(k.id,k);ce(p)}).catch(()=>{})},[a]);const de=s.useCallback(async()=>{T(!0);try{const f=[...(await dt(a)).sessions].sort((p,k)=>new Date(k.updatedAt).getTime()-new Date(p.updatedAt).getTime());d(f)}catch{}finally{T(!1)}},[a]);s.useEffect(()=>{de()},[de]);const re=s.useRef(()=>{}),Z=s.useRef(!1);s.useEffect(()=>{Z.current=!1},[a]),s.useEffect(()=>{if(y||Z.current||I.current)return;const o=Bt(et,a);if(!o){Z.current=!0;return}const f=l.find(p=>p.id===o);if(f){Z.current=!0,re.current(o,f);return}Z.current=!0},[y,l,a]);const ne=s.useCallback(async(o,f)=>{S(!0);try{const p=await Gt(o,{limit:50,...f},a),k=p.messages.map(tt);f?.offset&&f.offset>0?x(q=>[...k,...q]):x(k),m(p.messages.length>=50)}catch{}finally{S(!1)}},[a]),ie=s.useCallback(()=>{Q.current?.(),Q.current=null,Y.current="",ee(""),h(""),v(""),D([]),b(!1)},[]),le=s.useCallback((o,f)=>{const p=I.current?.id??null;if(o&&p===o&&!f)return;g.current&&(g.current.close(),g.current=null);const k=f??l.find(q=>q.id===o);w(k||null),ie(),m(!0),o?ne(o):x([]),k?.isGenerating&&(b(!0),h("")),o?Vt(et,o,a):Kt(et,a)},[l,ne,a,ie]);re.current=le;const ge=s.useCallback(async o=>{const f=await qt(o,a);g.current&&(g.current.close(),g.current=null);const p={id:f.session.id,title:f.session.title,agentId:f.session.agentId,status:f.session.status,modelProvider:f.session.modelProvider,modelId:f.session.modelId,createdAt:f.session.createdAt,updatedAt:f.session.updatedAt};return d(k=>k.some(q=>q.id===p.id)?k:[p,...k]),ie(),le(p.id,p),x([]),p},[a,ie,le]),we=s.useCallback(async o=>{await Xt(o,{status:"archived"},a),d(f=>f.filter(p=>p.id!==o)),i?.id===o&&(w(null),x([]))},[i,a]),ue=s.useCallback(async o=>{i?.id===o&&g.current&&(g.current.close(),g.current=null),await Jt(o,a),d(f=>f.filter(p=>p.id!==o)),i?.id===o&&(w(null),x([]))},[i,a]),ae=s.useCallback(async()=>{!i||!J||await ne(i.id,{offset:$.length})},[i,J,ne,$.length]),he=s.useCallback(()=>{i&&(se.current=!0,Q.current?.(),Q.current=null,g.current?.close(),g.current=null,Yt(i.id,a).catch(()=>{}),b(!1),h(""),v(""),D([]))},[i,a]),Ce=s.useCallback(()=>{Y.current="",ee("")},[]),me=s.useCallback((o,f)=>{if(!i)return;if(P){Y.current=o,ee(o);return}se.current=!1,g.current&&(g.current.close(),g.current=null);const p=`temp-${Date.now()}`,k={id:p,sessionId:i.id,role:"user",content:o,createdAt:new Date().toISOString()};x(K=>[...K,k]),h(""),v(""),D([]),b(!0);const{handlers:q}=Qt({sessionId:i.id,tempUserMessageId:p,setStreamingText:h,setStreamingThinking:v,setStreamingToolCalls:D,cancelStreamingFlushesRef:Q,addToast:r,onFallbackSession:(K,X)=>{const M=bs(K.fallbackModel);d(H=>H.map(R=>R.id===X?{...R,...M}:R)),w(H=>H&&H.id===X?{...H,...M}:H)},onDone:({messageId:K,message:X,accumulated:M})=>{const H=X?tt(X):{id:K||`msg-${Date.now()}`,sessionId:i.id,role:"assistant",content:M.text,thinkingOutput:M.thinking,toolCalls:M.toolCalls.length>0?M.toolCalls:void 0,fallbackInfo:M.fallbackInfo,createdAt:new Date().toISOString()};fe.current.add(H.id),x(u=>[...u,H]),h(""),v(""),D([]),b(!1),g.current=null,setTimeout(()=>{fe.current.delete(H.id)},1e3),de();const R=Y.current.trim();R&&(Y.current="",ee(""),me(R))},onError:(K,X)=>{if(x(M=>M.filter(H=>H.id!==X)),h(""),v(""),D([]),b(!1),g.current=null,console.error("[useChat] Stream error:",K),r?.(typeof K=="string"&&K.trim()?K:"Failed to get response","error"),!se.current){const M=Y.current.trim();M&&(Y.current="",ee(""),me(M))}}});g.current=Zt(i.id,o,q,f,a)},[i,P,a,de,r]),Ne=z?l.filter(o=>o.title?.toLowerCase().includes(z.toLowerCase())||o.agentId.toLowerCase().includes(z.toLowerCase())):l;return s.useEffect(()=>{if(!P||g.current||!I.current)return;const o=setInterval(async()=>{if(!ve.current||g.current||!I.current){clearInterval(o);return}try{(await dt(a)).sessions.find(k=>k.id===I.current?.id)?.isGenerating||(clearInterval(o),await ne(I.current.id),h(""),v(""),D([]),b(!1))}catch{}},3e3);return()=>clearInterval(o)},[P,ne,a]),s.useEffect(()=>{const o=oe.current,f=a?`?projectId=${encodeURIComponent(a)}`:"",p=()=>oe.current!==o,k=R=>{if(p())return;const u=JSON.parse(R.data);d(j=>j.some(U=>U.id===u.id)?j:[u,...j])},q=R=>{if(p())return;const u=JSON.parse(R.data);d(j=>[...j.map(O=>O.id===u.id?u:O)]),I.current?.id===u.id&&w(u)},K=R=>{if(p())return;const{id:u}=JSON.parse(R.data);d(j=>j.filter(U=>U.id!==u)),I.current?.id===u&&(w(null),x([]))},X=R=>{if(p())return;const u=JSON.parse(R.data),j=tt(u);if(!fe.current.has(j.id)){if(I.current?.id===j.sessionId&&ve.current&&!g.current&&j.role==="assistant"){x(U=>U.some(O=>O.id===j.id)?U:[...U,j]),h(""),v(""),D([]),b(!1);return}I.current?.id===j.sessionId&&!ve.current&&x(U=>U.some(O=>O.id===j.id)?U:[...U,j])}},M=R=>{if(p())return;const{id:u}=JSON.parse(R.data);x(j=>j.filter(U=>U.id!==u))};return es(`/api/events${f}`,{events:{"chat:session:created":k,"chat:session:updated":q,"chat:session:deleted":K,"chat:message:added":X,"chat:message:deleted":M}})},[a]),s.useEffect(()=>()=>{g.current&&(g.current.close(),g.current=null)},[]),{sessions:l,activeSession:i,sessionsLoading:y,messages:$,messagesLoading:V,isStreaming:P,streamingText:F,streamingThinking:N,streamingToolCalls:E,pendingMessage:L,selectSession:le,createSession:ge,archiveSession:we,deleteSession:ue,sendMessage:me,stopStreaming:he,clearPendingMessage:Ce,loadMoreMessages:ae,hasMoreMessages:J,searchQuery:z,setSearchQuery:_,filteredSessions:Ne,refreshSessions:de,agentsMap:C}}function bt(a){const r=new Date(a),d=new Date().getTime()-r.getTime(),i=Math.floor(d/1e3),w=Math.floor(i/60),y=Math.floor(w/60),T=Math.floor(y/24);return i<60?"just now":w<60?`${w}m ago`:y<24?`${y}h ago`:T<7?`${T}d ago`:r.toLocaleDateString()}function ft(a,r){if(!a||!r)return null;const l=r.toLowerCase();if(l.includes("claude")){let i=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 i=i.replace(/\s+/g," "),i.length>30?i.slice(0,30)+"…":i}if(l.includes("gpt")||l.includes("openai")){const i=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 i.length>30?i.slice(0,30)+"…":i}if(l.includes("gemini")){const i=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 i.length>30?i.slice(0,30)+"…":i}const d=r.replace(/-/g," ").replace(/^\w/,i=>i.toUpperCase()).replace(/\s+/g," ").trim();return d.length>30?d.slice(0,30)+"…":d}function Ue(a,r){return a.length<=r?a:`${a.slice(0,r)}…`}function Cs(a){if(!a)return null;const r=Object.entries(a);return r.length===0?null:r.map(([l,d])=>{const i=typeof d=="string"?d:(()=>{try{return JSON.stringify(d)}catch{return String(d)}})();return`${l}=${Ue(i,50)}`}).join(", ")}function Ns(a){if(a===void 0)return null;if(typeof a=="string")return Ue(a,200);try{return Ue(JSON.stringify(a),200)}catch{return Ue(String(a),200)}}function St(a){if(!a||a.length===0)return null;const r=(S,P)=>{const b=S.status==="running",F=S.status==="completed"&&S.isError,h=Cs(S.args),N=Ns(S.result),v=b?h:N?`result: ${N}`:h?`args: ${h}`:null,E=b?"running":F?"error":"completed";return t.jsxs("details",{className:`chat-tool-call${b?" chat-tool-call--running":""}${F?" chat-tool-call--error":""}`,open:b,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",children:S.toolName}),v&&t.jsx("span",{className:"chat-tool-call-preview",title:v,children:v}),t.jsx("span",{className:"chat-tool-call-status-text",children:E})]}),t.jsxs("div",{className:"chat-tool-call-content",children:[h&&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:h})]}),N&&t.jsxs("div",{className:`chat-tool-call-row${F?" 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:N})]})]})]},`${S.toolName}-${P}`)},l="chat-tool-calls";if(a.length===1)return t.jsxs("div",{className:l,"data-testid":"chat-tool-calls",children:[t.jsxs("div",{className:"chat-tool-calls-header",children:[t.jsx(ht,{size:12,"aria-hidden":"true"}),t.jsx("span",{children:"Tool calls"})]}),r(a[0],0)]});const d=a.filter(S=>S.status==="running").length,i=a.filter(S=>S.status==="completed"&&S.isError).length,w=d>0,y=Array.from(new Set(a.map(S=>S.toolName))),T=y.slice(0,5),$=Math.max(0,y.length-T.length),x=$>0?`${T.join(", ")}, +${$} more`:T.join(", "),V=w?`(${d} running)`:i>0?`(${i} ${i===1?"error":"errors"})`:null;return t.jsx("div",{className:l,"data-testid":"chat-tool-calls",children:t.jsxs("details",{className:"chat-tool-calls-group","data-testid":"chat-tool-calls-group",open:w,children:[t.jsxs("summary",{className:"chat-tool-calls-group-summary",children:[t.jsx(ht,{size:12,"aria-hidden":"true"}),t.jsxs("span",{children:[a.length," tool calls"]}),t.jsx("span",{className:"chat-tool-calls-names",title:x,children:x}),V&&t.jsx("span",{className:"chat-tool-calls-group-status",children:V})]}),a.map((S,P)=>r(S,P))]})})}const kt={pre:({children:a,...r})=>t.jsx("pre",{...r,className:"chat-markdown-pre",children:a}),table:({children:a,...r})=>t.jsx("table",{...r,className:"chat-markdown-table",children:a})},Pe="__fn_agent__",js=280,Le=180,ze=500,gt="fusion:chat-sidebar-width",Ms=["image/png","image/jpeg","image/gif","image/webp","text/plain","application/json","text/yaml","text/markdown","text/csv","application/xml","text/x-log"];function pt(a){const r=/(^|[\s])\/([^\s]*)$/.exec(a);if(!r)return null;const l=r[1]??"",d=r[2]??"",i=r.index+l.length;return{filter:d,start:i,end:a.length}}function As(a,r){const l=a.slice(0,r),d=/(^|[\s\n])@([\w-]*)$/.exec(l);if(!d)return null;const i=d[2]??"",w=l.length-i.length-1;return{filter:i,start:w,end:r}}function Ts({projectId:a,onClose:r,onCreate:l}){const[d,i]=s.useState("agent"),[w,y]=s.useState([]),[T,$]=s.useState(!0),[x,V]=s.useState(""),[S,P]=s.useState([]),[b,F]=s.useState(!0),[h,N]=s.useState(""),[v,E]=s.useState([]),[D,L]=s.useState([]);s.useEffect(()=>{let m=!1;return $(!0),st(void 0,a).then(C=>{m||y(C)}).catch(()=>{m||y([])}).finally(()=>{m||$(!1)}),()=>{m=!0}},[a]),s.useEffect(()=>{F(!0),vs().then(m=>{P(m.models),E(m.favoriteProviders),L(m.favoriteModels)}).catch(()=>{P([]),E([]),L([])}).finally(()=>{F(!1)})},[]);const ee=s.useCallback(async m=>{const C=v,g=C.includes(m)?C.filter(se=>se!==m):[m,...C];E(g);try{await mt({favoriteProviders:g,favoriteModels:D})}catch{E(C)}},[v,D]),z=s.useCallback(async m=>{const C=D,g=C.includes(m)?C.filter(se=>se!==m):[m,...C];L(g);try{await mt({favoriteProviders:v,favoriteModels:g})}catch{L(C)}},[D,v]),_=m=>{if(m.preventDefault(),d==="agent"){if(!x)return;l({agentId:x});return}if(!h)return;const C=h.indexOf("/");if(C<=0)return;const ce=h.slice(0,C),g=h.slice(C+1);l({agentId:Pe,modelProvider:ce,modelId:g})},J=d==="agent"?!x:!h;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${d==="agent"?" chat-new-dialog-mode-btn--active":""}`,"data-testid":"chat-new-dialog-mode-agent",onClick:()=>{i("agent"),N("")},children:"Agent"}),t.jsx("button",{type:"button",className:`chat-new-dialog-mode-btn${d==="model"?" chat-new-dialog-mode-btn--active":""}`,"data-testid":"chat-new-dialog-mode-model",onClick:()=>{i("model"),V("")},children:"Model"})]}),t.jsxs("form",{onSubmit:_,children:[d==="agent"&&t.jsxs("label",{className:"chat-new-dialog-model-label",children:["Agent",T?t.jsx("div",{className:"chat-new-dialog-loading",children:"Loading agents..."}):w.length===0?t.jsx("div",{className:"chat-new-dialog-empty",children:"No agents available"}):t.jsx("div",{className:"chat-new-dialog-agent-list",children:w.map(m=>t.jsxs("button",{type:"button",className:`chat-new-dialog-agent-item${x===m.id?" chat-new-dialog-agent-item--selected":""}`,onClick:()=>V(m.id),"data-testid":`agent-option-${m.id}`,children:[t.jsx(Oe,{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))})]}),d==="model"&&t.jsx("div",{className:"chat-new-dialog-model-dropdown","data-testid":"chat-new-dialog-model-section",children:b?t.jsx("div",{className:"chat-new-dialog-loading",children:"Loading models..."}):t.jsx(ws,{models:S,value:h,onChange:N,label:"Model",placeholder:"Select a model",favoriteProviders:v,onToggleFavorite:ee,favoriteModels:D,onToggleModelFavorite:z})}),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:J,children:"Create"})]})]})]})})}const xt=s.memo(function({message:r,forcePlain:l,agentName:d,hideAssistantIdentity:i,showAssistantModelTag:w,activeModelTag:y,activeSessionId:T,mentionAgentsByName:$}){const x=r.role==="assistant",V=s.useMemo(()=>{if(x)return null;const b=r.content,F=/@([\w-]+)/g,h=[];let N=0,v=F.exec(b);for(;v;){const[E,D=""]=v,L=v.index;L>N&&h.push(b.slice(N,L));const ee=D.replace(/_/g," ").toLowerCase(),z=$.get(ee);z?h.push(t.jsxs("span",{className:"chat-mention-chip",children:["@",z.name.replace(/\s+/g,"_")]},`${z.id}-${L}`)):h.push(E),N=L+E.length,v=F.exec(b)}return N<b.length&&h.push(b.slice(N)),h.length===0?b:h},[x,r.content,$]),S=s.useMemo(()=>{const b=r.attachments;if(!b||b.length===0||!T)return null;const F=`/api/chat/sessions/${encodeURIComponent(T)}/attachments/`;return t.jsx("div",{className:"chat-message-attachments",children:b.map(h=>{const N=h.mimeType.startsWith("image/"),v=h.id||h.filename,E=`${F}${encodeURIComponent(h.filename)}`;return N?t.jsx("a",{className:"chat-message-attachment-link","data-testid":"chat-message-attachment",href:E,target:"_blank",rel:"noopener noreferrer",children:t.jsx("img",{className:"chat-message-attachment",src:E,alt:h.originalName})},v):t.jsxs("a",{className:"chat-message-attachment-file","data-testid":"chat-message-attachment",href:E,target:"_blank",rel:"noopener noreferrer",children:[t.jsx(ps,{size:14}),t.jsx("span",{children:h.originalName})]},v)})})},[r.attachments,T]),P=s.useMemo(()=>x?l?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(vt,{remarkPlugins:[wt],components:kt,children:r.content})}):null,[x,l,r.content]);return t.jsxs("div",{className:`chat-message chat-message--${r.role}`,"data-testid":`chat-message-${r.id}`,children:[x&&!i&&t.jsxs("div",{className:"chat-message-avatar",children:[t.jsx(Oe,{size:14}),t.jsx("span",{children:d}),w&&y&&t.jsx("span",{className:"chat-model-tag",children:y})]}),x?P:t.jsx("div",{className:"chat-message-content",children:V}),St(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})]}),S,t.jsx("div",{className:"chat-message-time",children:bt(r.createdAt)})]})});function Es({projectId:a,addToast:r}){const{activeSession:l,sessionsLoading:d,messages:i,messagesLoading:w,isStreaming:y,streamingText:T,streamingThinking:$,streamingToolCalls:x,selectSession:V,createSession:S,archiveSession:P,deleteSession:b,sendMessage:F,stopStreaming:h,pendingMessage:N,clearPendingMessage:v,searchQuery:E,setSearchQuery:D,filteredSessions:L}=ys(a,r),[ee,z]=s.useState(!1),[_,J]=s.useState(""),[m,C]=s.useState(null),[ce,g]=s.useState(null),[se,Y]=s.useState(!0),[Q,ye]=s.useState(js),[I,ve]=s.useState(new Map),[fe,oe]=s.useState([]),[De,de]=s.useState(!0),[re,Z]=s.useState(!1),[ne,ie]=s.useState(""),[le,ge]=s.useState(0),[we,ue]=s.useState(""),[ae,he]=s.useState(!1),[Ce,me]=s.useState(0),[Ne,o]=s.useState(-1),[f,p]=s.useState(!1),[k,q]=s.useState([]),[K,X]=s.useState(!1),[,M]=s.useState(!1),[H,R]=s.useState({top:0,left:0}),u=ts({projectId:a}),j=s.useCallback(e=>{if(!e||!u.mentionActive)return;const n=e.getBoundingClientRect();R({top:n.top-260,left:n.left+8})},[u.mentionActive]),U=s.useRef(null),O=s.useRef(null),_e=s.useRef(null),W=s.useRef(null),Re=s.useRef(!1),$e=s.useRef(!1),nt=s.useRef(null),at=s.useRef([]),je=s.useRef(0),B=ss()==="mobile";s.useEffect(()=>{try{const e=localStorage.getItem(gt);if(!e)return;const n=Number.parseInt(e,10);if(Number.isNaN(n))return;const c=Math.max(Le,Math.min(ze,n));ye(c)}catch{}},[]);const{keyboardOverlap:He,viewportHeight:rt,viewportOffsetTop:yt,keyboardOpen:it}=ns({enabled:B&&!!l}),Ct=it?{"--keyboard-overlap":`${He}px`,"--vv-offset-top":`${yt}px`,...rt!==null?{"--vv-height":`${rt}px`}:{}}:{},te=s.useMemo(()=>{const e=ne.trim().toLowerCase();return(e?fe.filter(c=>c.name.toLowerCase().includes(e)):fe).slice(0,10)},[fe,ne]),be=s.useMemo(()=>Array.from(I.values()),[I]),pe=s.useMemo(()=>{const e=we.trim().toLowerCase();return e?be.filter(n=>n.name.toLowerCase().includes(e)):be},[be,we]),lt=s.useMemo(()=>{const e=new Map;for(const n of be)e.set(n.name.toLowerCase(),n);return e},[be]);s.useEffect(()=>{ge(0)},[te]),s.useEffect(()=>{me(0)},[we,ae]),s.useEffect(()=>()=>{O.current!==null&&window.clearTimeout(O.current)},[]),s.useEffect(()=>{const e=_e.current;e&&(e.scrollTop=e.scrollHeight)},[i,T,$,y]),s.useEffect(()=>{if(He<=0)return;const e=_e.current;e&&(e.scrollTop=e.scrollHeight)},[He]),as(B&&it),s.useEffect(()=>{const e=()=>C(null);if(m)return document.addEventListener("click",e),()=>document.removeEventListener("click",e)},[m]),s.useEffect(()=>{let e=!1;const n=a;return st(void 0,a).then(c=>{if(e||n!==a)return;const A=new Map;for(const G of c)A.set(G.id,G);ve(A)}).catch(()=>{}),()=>{e=!0}},[a]),s.useEffect(()=>{let e=!1;return de(!0),rs(a).then(n=>{e||oe(n)}).catch(()=>{e||oe([])}).finally(()=>{e||de(!1)}),()=>{e=!0}},[a]),s.useEffect(()=>{at.current=k},[k]),s.useEffect(()=>()=>{for(const e of at.current)e.previewUrl&&URL.revokeObjectURL(e.previewUrl)},[]);const Ee=s.useCallback(e=>{if(!e||e.length===0)return;const n=[];for(const c of Array.from(e)){if(!Ms.includes(c.type))continue;const A=c.type.startsWith("image/");n.push({file:c,previewUrl:A?URL.createObjectURL(c):""})}n.length>0&&q(c=>[...c,...n])},[]),Nt=s.useCallback(e=>{q(n=>{const c=n[e];return c?.previewUrl&&URL.revokeObjectURL(c.previewUrl),n.filter((A,G)=>G!==e)})},[]),jt=s.useCallback(e=>{const n=e.clipboardData?.files;if(!n||n.length===0)return;const c=Array.from(n).filter(A=>A.type.startsWith("image/"));c.length!==0&&Ee(c)},[Ee]),Mt=s.useCallback(async e=>{try{await S(e),z(!1),B&&Y(!1)}catch{r("Failed to create chat session","error")}},[S,r,B]),We=s.useCallback(()=>{J(""),Z(!1),ie(""),he(!1),ue(""),o(-1),q(e=>{for(const n of e)n.previewUrl&&URL.revokeObjectURL(n.previewUrl);return[]})},[]),Me=s.useCallback(()=>{const e=_.trim(),n=k.map(c=>c.file);if(!(!e&&n.length===0||!l)){if(e==="/clear"){We(),h(),v(),S({agentId:l.agentId,modelProvider:l.modelProvider??void 0,modelId:l.modelId??void 0}).catch(()=>{r("Failed to clear conversation","error")});return}We(),F(e,n)}},[_,k,l,We,h,v,S,r,F]),Ie=s.useCallback(()=>{if(typeof window>"u"||window.innerWidth>768)return;const e=W.current;if(!e||e.disabled)return;const n=window.scrollX,c=window.scrollY;e.focus({preventScroll:!0}),window.requestAnimationFrame(()=>{(window.scrollX!==n||window.scrollY!==c)&&window.scrollTo(n,c)})},[]),ct=s.useCallback(()=>{typeof window>"u"||window.innerWidth>768||(Re.current=!0)},[]),Be=s.useCallback(e=>{J(n=>{const c=pt(n);if(!c)return n;const A=`/skill:${e.name} `,G=n.slice(0,c.start)+A+n.slice(c.end);return window.requestAnimationFrame(()=>{W.current&&(W.current.style.height="auto",W.current.style.height=`${Math.min(W.current.scrollHeight,120)}px`,W.current.focus())}),G}),Z(!1),ie(""),ge(0)},[]),Ge=s.useCallback(e=>{const n=W.current;if(!n||Ne<0)return;const c=n.selectionStart??je.current,A=n.selectionEnd??c,G=Math.max(c,A),Te=Math.min(Ne,G),Se=`${`@${e.name.replace(/\s+/g,"_")}`} `,Qe=_.slice(0,Te)+Se+_.slice(G),ke=Te+Se.length;J(Qe),he(!1),ue(""),me(0),o(-1),window.requestAnimationFrame(()=>{W.current&&(W.current.style.height="auto",W.current.style.height=`${Math.min(W.current.scrollHeight,120)}px`,W.current.focus(),W.current.setSelectionRange(ke,ke))})},[Ne,_]),At=s.useCallback(e=>{if(je.current=e.currentTarget.selectionStart??je.current,u.mentionActive&&u.files.length>0){if(u.handleKeyDown(e,_),e.key==="Enter"||e.key==="Tab"){const n=u.files[u.selectedIndex];if(n){const c=u.selectFile(n,_);J(c),u.dismissMention(),M(!1)}}return}if(ae&&e.key==="ArrowDown"){e.preventDefault(),pe.length>0&&me(n=>(n+1)%pe.length);return}if(ae&&e.key==="ArrowUp"){e.preventDefault(),pe.length>0&&me(n=>n===0?pe.length-1:n-1);return}if(ae&&e.key==="Enter"){e.preventDefault();const n=pe[Ce]??pe[0];n&&Ge(n);return}if(ae&&e.key==="Escape"){e.preventDefault(),he(!1),ue(""),o(-1);return}if(re&&e.key==="ArrowDown"){e.preventDefault(),te.length>0&&ge(n=>(n+1)%te.length);return}if(re&&e.key==="ArrowUp"){e.preventDefault(),te.length>0&&ge(n=>n===0?te.length-1:n-1);return}if(re&&(e.key==="Enter"||e.key==="Tab")&&te.length>0){e.preventDefault();const n=te[le]??te[0];n&&Be(n);return}if(re&&e.key==="Escape"){e.preventDefault(),Z(!1);return}e.key==="Enter"&&!e.shiftKey&&(e.preventDefault(),Me())},[ae,pe,Ce,Ge,re,te,le,Be,Me,u,_]),Fe=s.useCallback((e,n)=>{const c=As(e,n);if(c){he(!0),ue(c.filter),o(c.start);return}he(!1),ue(""),o(-1)},[]),Tt=s.useCallback(e=>{const n=e.target,c=n.value,A=n.selectionStart??c.length;je.current=A,J(c);const G=pt(c);G?(Z(!0),ie(G.filter)):(Z(!1),ie("")),Fe(c,A),u.detectMention(c,A),M(u.mentionActive),u.mentionActive&&j(n),n.style.height="auto",n.style.height=`${Math.min(n.scrollHeight,120)}px`},[Fe]),Ve=s.useCallback(e=>{const n=e.currentTarget,c=n.selectionStart??n.value.length;je.current=c,Fe(n.value,c),u.detectMention(n.value,c),M(u.mentionActive),u.mentionActive&&j(n)},[Fe,u,j]),Pt=s.useCallback(e=>{e.key!=="Escape"&&Ve(e)},[Ve]),Dt=s.useCallback(()=>{if(Re.current){window.requestAnimationFrame(()=>{Ie()});return}O.current!==null&&window.clearTimeout(O.current),O.current=window.setTimeout(()=>{Z(!1),he(!1),ue(""),o(-1),M(!1),u.dismissMention(),O.current=null},120)},[u,Ie]),Rt=s.useCallback(()=>{O.current!==null&&(window.clearTimeout(O.current),O.current=null)},[]),$t=s.useCallback(async e=>{C(null);try{await P(e),r("Conversation archived","success")}catch{r("Failed to archive conversation","error")}},[P,r]),Et=s.useCallback(async e=>{g(null),C(null);try{await b(e),r("Conversation deleted","success")}catch{r("Failed to delete conversation","error")}},[b,r]),Ae=s.useCallback(e=>{try{localStorage.setItem(gt,String(e))}catch{}},[]),It=s.useCallback(e=>{if(B)return;e.preventDefault(),e.stopPropagation();const n=e.currentTarget;typeof n.setPointerCapture=="function"&&n.setPointerCapture(e.pointerId);const c=e.clientX,A=Q;let G=A;document.body.style.userSelect="none";const Te=Se=>{const Qe=Se.clientX-c,ke=Math.max(Le,Math.min(ze,A+Qe));G=ke,ye(ke),Ae(ke)},Ye=Se=>{typeof n.releasePointerCapture=="function"&&n.releasePointerCapture(Se.pointerId),document.body.style.userSelect="",document.removeEventListener("pointermove",Te),document.removeEventListener("pointerup",Ye),Ae(G)};document.addEventListener("pointermove",Te),document.addEventListener("pointerup",Ye)},[B,Ae,Q]),Ft=s.useCallback(e=>{if(B||e.key!=="ArrowLeft"&&e.key!=="ArrowRight")return;e.preventDefault();const n=e.shiftKey?50:10,c=e.key==="ArrowLeft"?-n:n,A=Math.max(Le,Math.min(ze,Q+c));ye(A),Ae(A)},[B,Ae,Q]),Lt=s.useCallback(e=>{V(e),B&&Y(!1)},[V,B]),zt=s.useCallback(()=>{V(""),Y(!0)},[V]),Ut=()=>t.jsxs("div",{className:"chat-empty-state",children:[t.jsx(xs,{size:48,strokeWidth:1.5}),t.jsx("h2",{children:"Start a new conversation"}),t.jsxs("button",{className:"btn btn-primary",onClick:()=>z(!0),children:[t.jsx(Ze,{size:16}),"New Chat"]})]}),xe=ft(l?.modelProvider,l?.modelId),Ke=!!(l||y||i.length>0),ot=l?.agentId===Pe?xe??"Fusion":l?.title||I.get(l?.agentId??"")?.name||l?.agentId||"Chat",Ot=!!(xe&&xe!==ot),qe=I.get(l?.agentId??"")?.name||(l?.agentId===Pe?xe??"Fusion":l?.agentId?.slice(0,30)??"Fusion"),Xe=!1,Je=l?.agentId===Pe,_t=N.length>50?`${N.slice(0,50)}…`:N,Ht=s.useCallback(()=>{p(e=>!e)},[]),Wt=s.useCallback((e,n=!1)=>n?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(vt,{remarkPlugins:[wt],components:kt,children:e})}),[]);return t.jsxs("div",{className:"chat-view",children:[t.jsxs("div",{className:`chat-sidebar${se?"":" chat-sidebar--hidden"}`,style:B?void 0:{width:`${Q}px`},children:[t.jsx("div",{className:"chat-sidebar-search",children:t.jsxs("div",{className:"chat-sidebar-search-wrapper",children:[t.jsx(is,{size:14,className:"chat-sidebar-search-icon"}),t.jsx("input",{type:"text",className:"chat-sidebar-search",placeholder:"Search conversations...",value:E,onChange:e=>D(e.target.value),"data-testid":"chat-search-input"})]})}),t.jsx("div",{className:"chat-session-list chat-sidebar-list",children:d?t.jsx("div",{style:{padding:"12px",color:"var(--text-secondary)",fontSize:"13px"},children:"Loading..."}):L.length===0?t.jsx("div",{style:{padding:"12px",color:"var(--text-secondary)",fontSize:"13px"},children:"No conversations yet"}):L.map(e=>t.jsxs("div",{className:`chat-session-item${l?.id===e.id?" chat-session-item--active":""}`,onClick:()=>Lt(e.id),onContextMenu:n=>{n.preventDefault(),C({sessionId:e.id,x:n.clientX,y:n.clientY})},"data-testid":`chat-session-${e.id}`,children:[t.jsx("button",{className:"chat-session-delete-btn",onClick:n=>{n.stopPropagation(),g(e.id)},"data-testid":"chat-session-delete-btn","aria-label":"Delete conversation",children:t.jsx(ut,{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.jsx("span",{children:I.get(e.agentId)?.name||(e.agentId===Pe?ft(e.modelProvider,e.modelId)??"Fusion":e.agentId.slice(0,30))}),t.jsx("span",{children:e.updatedAt?bt(e.updatedAt):""})]})]},e.id))}),t.jsx("div",{className:"chat-sidebar-footer",children:t.jsxs("button",{className:"btn btn-sm btn-primary chat-sidebar-footer-btn",onClick:()=>z(!0),"data-testid":"chat-new-btn",children:[t.jsx(Ze,{size:14}),"New Chat"]})})]}),!B&&se&&t.jsx("div",{className:"chat-sidebar-resize-handle",role:"separator","aria-orientation":"vertical","aria-valuemin":Le,"aria-valuemax":ze,"aria-valuenow":Q,"aria-label":"Resize chat sidebar",tabIndex:0,onPointerDown:It,onKeyDown:Ft}),m&&t.jsxs("div",{className:"chat-session-context-menu",style:{top:m.y,left:m.x},onClick:e=>e.stopPropagation(),children:[t.jsxs("button",{onClick:()=>$t(m.sessionId),"data-testid":"chat-context-archive",children:[t.jsx(ls,{size:14}),"Archive"]}),t.jsxs("button",{onClick:()=>{C(null),g(m.sessionId)},"data-testid":"chat-context-delete",children:[t.jsx(ut,{size:14}),"Delete"]})]}),ce&&t.jsx("div",{className:"chat-new-dialog-backdrop chat-view-dialog-backdrop",onClick:()=>g(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:()=>g(null),children:"Cancel"}),t.jsx("button",{className:"btn btn-sm btn-danger",onClick:()=>void Et(ce),children:"Delete"})]})]})}),t.jsxs("div",{className:"chat-thread",style:Ct,children:[(Ke||!B)&&t.jsxs("div",{className:"chat-thread-header",children:[B&&Ke&&t.jsx("button",{className:"btn-icon",onClick:zt,"data-testid":"chat-back-btn",children:t.jsx(cs,{size:16})}),t.jsx(Oe,{size:16}),t.jsx("span",{className:"chat-thread-header-title",children:ot}),Ot&&t.jsx("span",{className:"chat-model-tag",children:xe}),Ke&&t.jsx("button",{type:"button",className:`chat-thread-header-render-toggle${f?" chat-thread-header-render-toggle--plain":""}`,"data-testid":"chat-thread-render-toggle","aria-label":f?"Show all messages as rendered Markdown":"Show all messages as plain text",onClick:Ht,children:f?t.jsx(os,{size:14}):t.jsx(ds,{size:14})}),!B&&t.jsxs("button",{className:"btn btn-sm btn-primary chat-thread-header-new-chat",onClick:()=>z(!0),"data-testid":"chat-thread-new-chat-btn",children:[t.jsx(Ze,{size:14}),"New Chat"]})]}),t.jsxs("div",{className:"chat-messages",ref:_e,children:[y?t.jsxs(t.Fragment,{children:[i.map(e=>t.jsx(xt,{message:e,forcePlain:f,agentName:qe,hideAssistantIdentity:Je,showAssistantModelTag:Xe,activeModelTag:xe,activeSessionId:l?.id??null,mentionAgentsByName:lt},e.id)),t.jsxs("div",{className:"chat-message chat-message--assistant chat-message--streaming",children:[!Je&&t.jsxs("div",{className:"chat-message-avatar",children:[t.jsx(Oe,{size:14}),t.jsx("span",{children:qe}),Xe]}),T?Wt(T,f):t.jsx("div",{className:"chat-message-content chat-message-content--waiting",children:$?"Thinking…":"Connecting…"}),St(x),$&&t.jsxs("details",{className:"chat-message-thinking",children:[t.jsx("summary",{children:"Thinking"}),t.jsx("pre",{className:"chat-message-thinking-content",children:$})]}),t.jsxs("div",{className:"chat-typing-indicator",children:[t.jsx("span",{}),t.jsx("span",{}),t.jsx("span",{})]})]})]}):w?t.jsx("div",{style:{color:"var(--text-secondary)",fontSize:"13px"},children:"Loading messages..."}):i.length===0&&!l?Ut():i.length===0&&l?t.jsx("div",{style:{color:"var(--text-secondary)",fontSize:"13px"},children:"No messages yet. Start the conversation!"}):t.jsx(t.Fragment,{children:i.map(e=>t.jsx(xt,{message:e,forcePlain:f,agentName:qe,hideAssistantIdentity:Je,showAssistantModelTag:Xe,activeModelTag:xe,activeSessionId:l?.id??null,mentionAgentsByName:lt},e.id))}),t.jsx("div",{ref:U})]}),l&&t.jsxs("div",{className:"chat-input-area",children:[t.jsx("input",{ref:nt,type:"file",accept:"image/*,.txt,.json,.yaml,.yml,.log,.csv,.xml,.md",multiple:!0,style:{display:"none"},onChange:e=>{Ee(e.target.files),e.target.value=""}}),re&&t.jsx("div",{className:"chat-skill-menu","data-testid":"chat-skill-menu",role:"listbox","aria-label":"Skill suggestions",children:De?t.jsx("div",{className:"chat-skill-menu-empty",children:"Loading skills…"}):te.length===0?t.jsx("div",{className:"chat-skill-menu-empty",children:ne?"No skills found":"No skills available"}):te.map((e,n)=>t.jsxs("button",{type:"button",role:"option","aria-selected":n===le,className:`chat-skill-menu-item${n===le?" chat-skill-menu-item--highlighted":""}`,onMouseDown:c=>c.preventDefault(),onMouseEnter:()=>ge(n),onClick:()=>Be(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))}),k.length>0&&t.jsx("div",{className:"chat-attachment-previews","data-testid":"chat-attachment-previews",children:k.map((e,n)=>t.jsxs("div",{className:"chat-attachment-preview","data-testid":`chat-attachment-preview-${n}`,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:()=>Nt(n),"data-testid":`chat-attachment-remove-${n}`,"aria-label":`Remove ${e.file.name}`,children:"×"})]},e.previewUrl||`${e.file.name}-${n}`))}),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:()=>nt.current?.click(),children:t.jsx(us,{size:16})}),t.jsxs("div",{className:`chat-input-wrapper${K?" chat-input-wrapper--dragover":""}`,onDragOver:e=>{e.preventDefault(),X(!0)},onDragLeave:()=>X(!1),onDrop:e=>{e.preventDefault(),X(!1),Ee(e.dataTransfer.files)},children:[t.jsx("textarea",{ref:W,className:"chat-input-textarea",placeholder:"Type a message...",value:_,onChange:Tt,onKeyDown:At,onKeyUp:Pt,onClick:Ve,onBlur:Dt,onFocus:Rt,onPaste:jt,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(hs,{agents:be,filter:we,highlightedIndex:Ce,visible:ae,onSelect:Ge,position:"below"}),t.jsx(ms,{visible:u.mentionActive&&!ae,position:H,files:u.files,selectedIndex:u.selectedIndex,onSelect:e=>{const n=u.selectFile(e,_);J(n),u.dismissMention(),M(!1),W.current?.focus()},loading:u.loading}),N&&t.jsxs("div",{className:"chat-pending-message","data-testid":"chat-pending-indicator",children:[t.jsx("span",{children:`Queued: ${_t}`}),t.jsx("button",{type:"button",className:"chat-pending-message-dismiss","aria-label":"Dismiss queued message","data-testid":"chat-pending-dismiss",onClick:v,children:"×"})]})]}),y?t.jsx("button",{className:"chat-input-stop",onClick:h,"aria-label":"Stop generation","data-testid":"chat-stop-btn",children:t.jsx(fs,{size:14})}):t.jsx("button",{type:"button",className:"chat-input-send",onPointerDown:e=>{typeof window>"u"||window.innerWidth>768||(e.preventDefault(),e.pointerType&&e.pointerType!=="mouse"&&($e.current=!0,ct(),Ie(),Me(),window.setTimeout(()=>{Re.current=!1},1500)))},onTouchStart:e=>{typeof window>"u"||window.innerWidth>768||(e.preventDefault(),$e.current=!0,ct(),Ie(),Me(),window.setTimeout(()=>{Re.current=!1},1500))},onMouseDown:e=>{typeof window>"u"||window.innerWidth>768||e.preventDefault()},onClick:()=>{if($e.current){$e.current=!1;return}Me()},disabled:!_.trim()&&k.length===0,"data-testid":"chat-send-btn",children:t.jsx(gs,{size:16})})]})]})]}),ee&&t.jsx(Ts,{projectId:a,onClose:()=>z(!1),onCreate:Mt})]})}export{Es as ChatView};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r,j as t}from"./vendor-react-K0fH_qHe.js";import{bo as De,bp as de,bq as Ze,br as ue,z as Ue,bs as ge,bt as we,bu as xe,bv as ye,bw as et,bx as ae,by as tt,bz as rt,bA as st,bB as nt,bC as at,bD as ie,V as ee,S as it,bE as lt,bF as ct,C as ot,bG as Me,bH as Ae,bI as dt,a4 as ut,a5 as vt,a6 as mt,d as ft,s as pt,R as ht}from"./index-CrHLf3pB.js";import"./vendor-xterm-DzcZoU0P.js";const ve=500,bt=3e3;function B(e){return e instanceof Error?e.message:String(e)}function Pe(e){return e.length<=ve?e:e.slice(-ve)}function le(e,i){return Pe([...e,i])}function I(e){try{return JSON.parse(e)}catch{return null}}function Y(e){const i=e.text??"";return e.stream==="stderr"?`[stderr] ${i}`:i}function gt(e){return e?.previewUrl??null}async function Se(e){return tt(e)}async function Ne(e,i){return rt(e,i)}async function wt(e){return st(e)}async function xt(e){return nt(e)}async function je(e){return at(e)}function V(e){try{return e()}catch{return null}}function ce(){return typeof V(()=>de)=="function"&&typeof V(()=>De)=="function"}function W(e){return{config:{id:e.id??"default",name:e.name??"Dev Server",command:e.command??"",cwd:e.cwd??"."},status:e.status,runtime:e.pid?{pid:e.pid,startedAt:e.startedAt??new Date().toISOString(),exitCode:e.exitCode??void 0,previewUrl:e.previewUrl}:void 0,previewUrl:e.previewUrl??e.detectedUrl??e.manualUrl??void 0,logHistory:(e.logs??[]).map(i=>({timestamp:new Date().toISOString(),stream:i.startsWith("[stderr]")?"stderr":"stdout",text:i.replace(/^\[stderr\]\s*/,"")}))}}function yt(e){const[i,o]=r.useState(null),[b,y]=r.useState([]),[w,f]=r.useState([]),[k,U]=r.useState([]),[C,P]=r.useState(!0),[S,u]=r.useState(null),n=r.useRef(0),[d,M]=r.useState(null),R=r.useCallback(a=>{if(o(a),a?.logHistory){const s=a.logHistory.slice(-ve).map(Y);f(s)}},[]),A=r.useCallback(async()=>{const a=n.current;try{if(ce())if(d){const s=await De(d,e);if(n.current!==a)return;R(s)}else{const s=await de(e);if(n.current!==a)return;y(s),s.length>0&&(M(s[0].config.id),R(s[0]))}else{const s=await Se(e);if(n.current!==a)return;const c=W(s);y([c]),R(c)}u(null)}catch(s){if(n.current!==a)return;u(B(s))}},[R,e,d]);r.useEffect(()=>{n.current+=1;const a=n.current;o(null),y([]),f([]),U([]),P(!0),u(null),M(null),(async()=>{try{const[c,l]=await Promise.allSettled([ce()?de(e):Se(e).then(N=>[W(N)]),typeof V(()=>ae)=="function"?ae(e):je(e).then(N=>N.map(g=>({name:g.name,command:g.command,cwd:g.cwd,scriptName:g.scriptName,packagePath:g.packagePath})))]);if(n.current!==a)return;let v=null;if(c.status==="fulfilled"){const N=c.value;if(y(N),N.length>0){const g=N[0];ce()&&M(g.config.id),R(g)}}else v=B(c.reason);l.status==="fulfilled"&&U(l.value),v&&u(v)}catch(c){if(n.current!==a)return;u(B(c))}finally{n.current===a&&P(!1)}})()},[R,e]),r.useEffect(()=>{const a=d?Ze(d,e):typeof V(()=>ue)=="function"?ue(e):null;if(!a)return;const s=n.current,c=Ue(a,{events:{history:l=>{if(n.current!==s)return;const v=I(l.data);if(v?.lines){const N=v.lines.map(Y);f(Pe(N))}},log:l=>{if(n.current!==s)return;const v=I(l.data);if(v){const N=typeof v.line=="string"?v.line:Y(v);f(g=>le(g,N))}},"dev-server:log":l=>{if(n.current!==s)return;const v=I(l.data);if(v){const N=typeof v.line=="string"?v.line:Y(v);f(g=>le(g,N))}},"dev-server:output":l=>{if(n.current!==s)return;const v=I(l.data);v?.line&&f(N=>le(N,v.line))},status:l=>{if(n.current!==s)return;const v=I(l.data),N=v?.status;N&&o(g=>g&&{...g,status:N,runtime:v.pid?{...g.runtime??{startedAt:new Date().toISOString()},pid:v.pid}:g.runtime})},"dev-server:status":l=>{if(n.current!==s)return;const v=I(l.data);if(v?.status){const N=W(v);o(N),y([N])}},stopped:()=>{n.current},failed:()=>{n.current}},onReconnect:()=>{n.current===s&&A()},onError:()=>{n.current===s&&u(l=>l??"Lost log stream connection.")}});return()=>{c()}},[e,A,d]),r.useEffect(()=>{if(i?.status!=="running"&&i?.status!=="starting")return;const a=setInterval(()=>{A()},bt);return()=>{clearInterval(a)}},[A,i?.status]);const _=r.useCallback(async(a,s)=>{n.current+=1;const c=n.current;try{let l;if(d&&typeof V(()=>ge)=="function")l=await ge(d,e);else{const v=await Ne({command:a,cwd:s},e);l=W(v)}if(n.current!==c)return;o(l),u(null)}catch(l){if(n.current!==c)return;throw u(B(l)),l}},[e,d]),D=r.useCallback(async()=>{n.current+=1;const a=n.current;try{let s;if(d&&typeof V(()=>we)=="function")s=await we(d,e);else{const c=await wt(e);s=W(c)}if(n.current!==a)return;o(s),u(null)}catch(s){if(n.current!==a)return;throw u(B(s)),s}},[e,d]),j=r.useCallback(async()=>{n.current+=1;const a=n.current;try{let s;if(d&&typeof V(()=>xe)=="function")s=await xe(d,e);else{const c=await xt(e);s=W(c)}if(n.current!==a)return;o(s),u(null)}catch(s){if(n.current!==a)return;throw u(B(s)),s}},[e,d]),T=r.useCallback(async a=>{n.current+=1;const s=n.current;try{let c;if(d&&typeof V(()=>ye)=="function")c=await ye(d,a,e);else{const l=await et({url:a},e);c={url:l.manualUrl??l.previewUrl??l.detectedUrl??null,source:l.manualUrl?"manual":"auto"}}if(n.current!==s)return;o(l=>l?{...l,previewUrl:c.url??void 0}:null),u(null)}catch(c){if(n.current!==s)return;throw u(B(c)),c}},[e,d]),h=r.useCallback(async()=>{n.current+=1;const a=n.current;try{let s;try{s=await ae(e)}catch{s=(await je(e)).map(l=>({name:l.name,command:l.command,cwd:l.cwd,scriptName:l.scriptName,packagePath:l.packagePath}))}if(n.current!==a)return;U(s),u(null)}catch(s){if(n.current!==a)return;throw u(B(s)),s}},[e]),p=r.useCallback(async(a,s)=>{if(typeof a!="string"&&!d)try{const v=a,N=await Ne({command:v.command,cwd:v.cwd,scriptName:v.scriptName,packagePath:v.packagePath??v.cwd},e),g=W(N);o(g),y([g]),u(null);return}catch(v){throw u(B(v)),v}const c=typeof a=="string"?a:a.command,l=typeof a=="string"?s:a.cwd;await _(c,l)},[e,_,d]),E=r.useCallback(async()=>{await D()},[D]),L=r.useCallback(async()=>{await j()},[j]),z=r.useCallback(async a=>{await T(a)},[T]),$=r.useCallback(async()=>{await h()},[h]),O=r.useCallback(async()=>{await A()},[A]),H=gt(i),x=i?{...i,pid:i.runtime?.pid}:null;return{session:i,sessions:b,logs:w,detectedCommands:k,previewUrl:H,isLoading:C,error:S,startServer:_,stopServer:D,restartServer:j,setPreviewUrl:T,detectCommands:h,refresh:A,candidates:k,serverState:x,loading:C,start:p,stop:E,restart:L,setManualUrl:z,detect:$,refreshStatus:O}}const ke=500,Ce=100;function Te(e){return e.length>ke?e.slice(-ke):e}function ze(e){return e==="stderr"?"stderr":"stdout"}function K(e){try{return JSON.parse(e.data)}catch{return null}}function Z(e,i){return{id:typeof e.id=="number"&&Number.isFinite(e.id)?e.id:i,text:typeof e.text=="string"?e.text:"",stream:ze(e.stream),timestamp:typeof e.timestamp=="string"?e.timestamp:""}}function St(e,i){return{id:i,text:e,stream:"stdout",timestamp:""}}function oe(e,i){if(i.length===0)return e;const o=[...e],b=new Set(e.map(y=>y.id));for(const y of i)b.has(y.id)||(b.add(y.id),o.push(y));return o.sort((y,w)=>y.id-w.id),Te(o)}function Nt(e,i){const[o,b]=r.useState([]),[y,w]=r.useState(!1),[f,k]=r.useState(!1),[U,C]=r.useState(!1),[P,S]=r.useState(null),u=r.useRef(null),n=r.useRef(!1),d=r.useRef(0),M=r.useRef(0),R=r.useRef(e),A=r.useRef(i),_=r.useRef(0),D=r.useRef(1);(R.current!==e||A.current!==i)&&(R.current=e,A.current=i,d.current++,n.current=!0,_.current=0,D.current=1,b([]),w(!1),k(!1),C(!1),S(null),u.current&&(u.current(),u.current=null)),r.useEffect(()=>{if(!i){u.current&&(u.current(),u.current=null);return}const E=d.current,L=++M.current;n.current=!1,w(!0);const z=(x,a)=>{const s=Te(x);b(s),S(a),C(a!==null?a>s.length:!1);const c=s.length>0?s[s.length-1].id:0;_.current=c,D.current=c+1},$=x=>{if(n.current||d.current!==E||!x||typeof x!="object")return;const a=x.lines;if(!Array.isArray(a))return;if(a.length>0&&typeof a[0]=="string"){const c=a.filter(l=>typeof l=="string").map((l,v)=>St(l,v+1));z(c,c.length);return}const s=a.filter(c=>!!c&&typeof c=="object").map((c,l)=>Z(c,l+1));z(s,s.length)},O=x=>{if(n.current||d.current!==E)return;const a=typeof x.text=="string"?x.text:typeof x.line=="string"?x.line:null;if(!a)return;const s=D.current,c=typeof x.id=="number"&&Number.isFinite(x.id)?x.id:s,l={id:c,text:a,stream:ze(x.stream),timestamp:typeof x.timestamp=="string"?x.timestamp:""};_.current=Math.max(_.current,c),D.current=Math.max(D.current,c+1),b(v=>oe(v,[l])),S(v=>v===null?v:Math.max(v+1,l.id))};async function H(){try{const a=await ie({maxLines:Ce},e);if(n.current||d.current!==E||M.current!==L)return;const s=a.lines.map((c,l)=>Z(c,l+1));z(s,a.totalLines)}catch{if(n.current||d.current!==E||M.current!==L)return;z([],null)}finally{!n.current&&d.current===E&&M.current===L&&w(!1)}const x=ue(e);u.current=Ue(x,{events:{"dev-server:log":a=>{const s=K(a);s&&O(s)},log:a=>{const s=K(a);s&&O(s)},history:a=>{const s=K(a);$(s)},"dev-server:history":a=>{const s=K(a);$(s)}},onReconnect:()=>{n.current||d.current!==E||ie({lastEventId:_.current,maxLines:50},e).then(a=>{if(n.current||d.current!==E)return;const s=a.lines.map((c,l)=>Z(c,D.current+l));if(s.length>0){const c=s[s.length-1].id;_.current=Math.max(_.current,c),D.current=Math.max(D.current,c+1)}b(c=>oe(c,s)),S(a.totalLines)}).catch(()=>{})}})}return H(),()=>{n.current=!0,u.current&&(u.current(),u.current=null)}},[i,e]);const T=r.useCallback(async()=>{if(!i||f)return;const E=d.current,L=o.length;k(!0);try{const z=await ie({maxLines:Ce,offset:L},e);if(n.current||d.current!==E)return;const $=z.lines.map((O,H)=>Z(O,H+1));b(O=>oe($,O)),C(z.totalLines>L+$.length),S(z.totalLines)}catch{}finally{k(!1)}},[i,o.length,f,e]),h=r.useCallback(()=>{b([])},[]),p=u.current!==null&&!y&&!n.current;return{entries:o,loading:y,loadingMore:f,hasMore:U,total:P,loadMore:T,clear:h,logs:o,isStreaming:p,clearLogs:h}}const jt="This preview appears to block iframe embedding. Open it in a new tab instead.",kt="The preview URL could not be loaded. Verify the server is running and the URL is correct.",Ct="Preview is taking longer than expected and may block iframe embedding.";function Et(e){return e==="blocked"?jt:e==="error"?kt:null}function Lt(e,i={}){const{loadTimeoutMs:o=1e4,detectionMethod:b=null}=i,y=r.useRef(null),w=r.useRef(null),[f,k]=r.useState("unknown"),[U,C]=r.useState(null),[P]=r.useState(b),S=r.useCallback(()=>{w.current!==null&&(window.clearTimeout(w.current),w.current=null)},[]),u=r.useCallback(j=>{k(j),C(Et(j))},[]),n=r.useCallback(()=>{k("blocked"),C(Ct)},[]);r.useEffect(()=>{if(S(),!e){k("unknown"),C(null);return}k("unknown"),C(null);let j=!1;return queueMicrotask(()=>{j||(k("loading"),C(null))}),()=>{j=!0,S()}},[S,e]),r.useEffect(()=>{if(f!=="loading"){S();return}const j=setTimeout(()=>{w.current=null,n()},o);return w.current=j,()=>{clearTimeout(j),w.current===j&&(w.current=null)}},[S,f,o,n]);const d=r.useCallback(()=>{const j=y.current;if(!j){u("embedded");return}try{if(j.contentWindow?.location?.href==="about:blank"&&j.src!=="about:blank"){u("blocked");return}}catch{}u("embedded")},[u]),M=r.useCallback(()=>{u("error")},[u]);r.useEffect(()=>{if(S(),!e){k("unknown"),C(null);return}k("unknown"),C(null)},[S]);const R=r.useCallback(()=>{S(),k("unknown"),C(null)},[S]),A=R,_=r.useMemo(()=>f==="embedded",[f]),D=r.useMemo(()=>f==="blocked"||f==="error",[f]);return{embedStatus:f,isEmbedded:_,isBlocked:D,blockReason:U,detectionMethod:P,iframeRef:y,resetEmbedStatus:R,setEmbedStatus:u,retry:A,embedContext:U,handleIframeLoad:d,handleIframeError:M}}const Rt=/\x1b\[[0-9;]*m/g;function me(e){return e.replace(Rt,"")}function _t(e){if(!e)return"";const i=new Date(e);return Number.isNaN(i.getTime())?"":i.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1})}function Dt(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Ut(e){if(e.stream==="stderr")return"error";const i=me(e.text).toLowerCase();return/\b(warn|warning)\b/.test(i)?"warn":/\b(error|fatal)\b/.test(i)?"error":"info"}function Mt(e,i){if(!i)return e;const o=new RegExp(`(${Dt(i)})`,"ig"),b=e.split(o),y=i.toLowerCase();return t.jsx(t.Fragment,{children:b.map((w,f)=>w.toLowerCase()===y?t.jsx("mark",{children:w},`${w}-${f}`):t.jsx("span",{children:w},`${w}-${f}`))})}function At({entries:e,loading:i,loadingMore:o,hasMore:b,total:y,onLoadMore:w,isRunning:f}){const k=r.useRef(null),U=r.useRef(e.length),C=r.useRef(f),[P,S]=r.useState(!1),[u,n]=r.useState(!1),[d,M]=r.useState(""),[R,A]=r.useState("all"),_=r.useMemo(()=>R==="all"?e:e.filter(p=>Ut(p)===R),[e,R]),D=r.useMemo(()=>{const p=d.trim().toLowerCase();return p?_.filter(E=>me(E.text).toLowerCase().includes(p)):_},[_,d]),j=D.length,T=r.useCallback(()=>{const p=k.current;p&&(p.scrollTop=p.scrollHeight,n(!1))},[]);r.useEffect(()=>{const p=C.current,E=U.current,L=e.length>E;f&&(!p||!u&&L)&&T(),C.current=f,U.current=e.length},[e.length,f,u,T]);const h=r.useCallback(()=>{const p=k.current;if(!p)return;const L=p.scrollTop+p.clientHeight>=p.scrollHeight-50;n(!L)},[]);return r.useEffect(()=>{i||e.length===0||!u&&f&&T()},[e,f,u,i,T]),i&&e.length===0?t.jsx("section",{className:"devserver-log-viewer","data-testid":"devserver-log-viewer",children:t.jsxs("div",{className:"devserver-log-viewer__loading","data-testid":"devserver-log-loading",children:[t.jsx(ee,{size:16,className:"devserver-log-viewer__spinner"}),t.jsx("span",{children:"Loading logs…"})]})}):t.jsxs("section",{className:`devserver-log-viewer${P?" devserver-log-viewer--fullscreen":""}`,"data-testid":"devserver-log-viewer",children:[t.jsxs("header",{className:"devserver-log-viewer__toolbar",children:[t.jsxs("div",{className:"devserver-log-viewer__toolbar-meta",children:[t.jsx("span",{className:"devserver-log-viewer__title",children:"Logs"}),t.jsxs("span",{className:"devserver-log-viewer__count","data-testid":"devserver-log-count",children:[y!==null?`${e.length}/${y}`:`${e.length}`," lines"]})]}),t.jsxs("div",{className:"devserver-log-viewer__toolbar-actions",children:[t.jsxs("label",{className:"devserver-log-viewer__severity",htmlFor:"devserver-log-severity-filter",children:[t.jsx("span",{className:"visually-hidden",children:"Filter logs by severity"}),t.jsxs("select",{id:"devserver-log-severity-filter",className:"select devserver-log-viewer__severity-select",value:R,onChange:p=>A(p.target.value),"data-testid":"devserver-log-severity-filter","aria-label":"Filter logs by severity",children:[t.jsx("option",{value:"all",children:"All severities"}),t.jsx("option",{value:"info",children:"Info"}),t.jsx("option",{value:"warn",children:"Warn"}),t.jsx("option",{value:"error",children:"Error"})]})]}),t.jsxs("label",{className:"devserver-log-viewer__search",htmlFor:"devserver-log-search",children:[t.jsx("span",{className:"visually-hidden",children:"Search logs"}),t.jsx(it,{size:14}),t.jsx("input",{id:"devserver-log-search",className:"input devserver-log-viewer__search-input",type:"text",value:d,onChange:p=>M(p.target.value),placeholder:"Search logs","data-testid":"devserver-log-search-input","aria-label":"Search logs"})]}),d.trim().length>0&&t.jsxs("span",{className:"devserver-log-viewer__matches","data-testid":"devserver-log-match-count",children:[j," match",j===1?"":"es"]}),t.jsx("button",{type:"button",className:"btn btn-sm btn-icon",onClick:()=>S(p=>!p),"data-testid":"devserver-log-fullscreen-toggle","aria-label":P?"Exit fullscreen logs":"Enter fullscreen logs",children:P?t.jsx(lt,{size:14}):t.jsx(ct,{size:14})})]})]}),t.jsxs("div",{className:"devserver-log-viewer__body",children:[b&&t.jsx("div",{className:"devserver-log-viewer__load-more","data-testid":"devserver-log-load-more",children:t.jsx("button",{type:"button",className:"btn btn-sm touch-target",onClick:w,disabled:o,"data-testid":"devserver-log-load-more-button",children:o?t.jsxs(t.Fragment,{children:[t.jsx(ee,{size:14,className:"devserver-log-viewer__spinner"}),"Loading older logs…"]}):"Load older logs"})}),t.jsxs("div",{ref:k,className:"devserver-log-viewer__content",onScroll:h,"data-testid":"devserver-log-content",children:[!i&&D.length===0&&t.jsx("p",{className:"devserver-log-viewer__empty","data-testid":"devserver-log-empty",children:e.length===0?"No logs yet. Start the dev server to see output.":_.length===0?"No log lines match the selected severity.":"No log lines match your search."}),D.map(p=>{const E=me(p.text),L=_t(p.timestamp);return t.jsxs("div",{className:"devserver-log-line",children:[L&&t.jsx("span",{className:"devserver-log-timestamp","data-testid":"devserver-log-timestamp",children:L}),p.stream==="stderr"&&t.jsx("span",{className:"devserver-log-stream-badge","data-testid":"devserver-log-stderr-badge",children:"ERR"}),t.jsx("span",{className:"devserver-log-text",children:Mt(E,d.trim())})]},p.id)})]}),u&&f&&t.jsxs("button",{type:"button",className:"btn btn-sm devserver-log-viewer__new-logs-button",onClick:T,"data-testid":"devserver-log-jump-button",children:[t.jsx(ot,{size:14}),"New logs"]})]})]})}const Pt="devserver-preview-iframe";function Tt({url:e,embedStatus:i,onEmbedStatusChange:o,iframeRef:b,blockReason:y,onRetry:w,className:f=Pt,embedContext:k}){const U=y??k??null,[C,P]=r.useState(0);r.useEffect(()=>{!e||i!=="unknown"||(P(d=>d+1),o("loading"))},[i,o,e]);const S=r.useCallback(()=>{const d=b.current;if(!d){o("embedded");return}try{if(d.contentWindow?.location?.href==="about:blank"&&d.src!=="about:blank"){o("blocked");return}}catch{}o("embedded")},[b,o]),u=r.useCallback(d=>{d.stopPropagation(),o("error")},[o]),n=r.useCallback(()=>{e&&window.open(e,"_blank","noopener,noreferrer")},[e]);return e?t.jsxs("div",{className:"devserver-preview-iframe-shell",children:[t.jsx("iframe",{src:e,ref:b,sandbox:"allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox",className:f,title:"Dev server preview",onLoad:S,onError:u,onErrorCapture:u,"data-testid":"devserver-preview-iframe"},`${e}-${C}`),i==="loading"&&t.jsxs("div",{className:"devserver-preview-overlay","data-testid":"devserver-preview-loading",children:[t.jsx(ee,{size:16,className:"dev-server-spin"}),t.jsx("span",{children:"Loading preview..."})]}),i==="blocked"&&t.jsxs("div",{className:"devserver-preview-blocked-panel",role:"alert","data-testid":"devserver-preview-blocked-panel",children:[t.jsx(Me,{className:"devserver-preview-blocked-icon","aria-hidden":"true"}),t.jsxs("div",{children:[t.jsx("p",{className:"devserver-preview-blocked-title",children:"Preview cannot be embedded"}),U&&t.jsx("p",{className:"devserver-preview-blocked-context",children:U})]}),t.jsx("p",{className:"devserver-preview-blocked-description",children:"You can view the preview in a separate browser tab."}),t.jsxs("div",{className:"devserver-preview-blocked-actions",children:[t.jsx("button",{type:"button",className:"btn btn-primary",onClick:n,children:"Open in new tab"}),w&&t.jsx("button",{type:"button",className:"btn btn-sm",onClick:w,children:"Retry"})]})]}),i==="error"&&t.jsxs("div",{className:"devserver-preview-error-panel",role:"alert","data-testid":"devserver-preview-error-panel",children:[t.jsx(Ae,{className:"devserver-preview-blocked-icon","aria-hidden":"true"}),t.jsxs("div",{children:[t.jsx("p",{className:"devserver-preview-blocked-title",children:"Unable to load preview"}),U&&t.jsx("p",{className:"devserver-preview-blocked-context",children:U})]}),t.jsx("p",{className:"devserver-preview-blocked-description",children:"You can view the preview in a separate browser tab."}),t.jsxs("div",{className:"devserver-preview-blocked-actions",children:[t.jsx("button",{type:"button",className:"btn btn-primary",onClick:n,children:"Open in new tab"}),w&&t.jsx("button",{type:"button",className:"btn btn-sm",onClick:w,children:"Retry"})]})]})]}):null}const Ee={stopped:{className:"dev-server-status-badge--stopped",label:"Stopped"},starting:{className:"dev-server-status-badge--starting",label:"Starting..."},running:{className:"dev-server-status-badge--running",label:"Running"},stopping:{className:"dev-server-status-badge--starting",label:"Stopping..."},failed:{className:"dev-server-status-badge--failed",label:"Failed"}};function Le(e){return e instanceof Error?e.message:String(e)}function Fe(e){return e==="."?"root":e}function Re(e){return e?e==="root"?".":e:null}function _e(e,i,o){return!i||e.scriptName!==i?!1:o?Fe(e.cwd)===o:!0}function zt(e){return e.cwd==="."?"root":e.cwd}function Ft(e){return e.length<=60?e:`${e.slice(0,60)}…`}function Ht({addToast:e,projectId:i}){const{session:o,detectedCommands:b,previewUrl:y,isLoading:w,error:f,startServer:k,stopServer:U,restartServer:C,setPreviewUrl:P,detectCommands:S,refresh:u}=yt(i),n=o?.status??"stopped",d=n==="running"||n==="starting",M=Ee[n]??Ee.stopped,{entries:R,loading:A,loadingMore:_,hasMore:D,total:j,loadMore:T}=Nt(i,!!i),h=y,p=o?.config?.cwd??null,[E,L]=r.useState(!0),[z,$]=r.useState(""),[O,H]=r.useState(""),[x,a]=r.useState(null),[s,c]=r.useState(null),[l,v]=r.useState("embedded"),N=l==="embedded"?h:null,{embedStatus:g,setEmbedStatus:$e,resetEmbedStatus:X,iframeRef:G,isEmbedded:Oe,isBlocked:te,blockReason:re,retry:fe}=Lt(N),[pe,q]=r.useState(!1),he=r.useRef(g);r.useEffect(()=>{const m=he.current!==g;te&&m&&q(!0),g==="embedded"&&q(!1),he.current=g},[g,te]),r.useEffect(()=>{q(!1)},[h]);const J=r.useMemo(()=>{if(!x)return null;const m=Re(p);return b.find(F=>!(F.scriptName!==x||m&&F.cwd!==m||o?.config?.command&&F.command!==o.config.command))??b.find(F=>_e(F,x,p))??null},[b,o?.config?.command,x,p]);r.useEffect(()=>{typeof S=="function"&&S().catch(m=>{e(Le(m),"error")})},[e,S]),r.useEffect(()=>{if(x){L(!1);return}L(!0)},[x]),r.useEffect(()=>{if(o?.status==="running"||o?.status==="starting"){o.config?.command?.trim().length>0&&$(o.config.command);return}if(J){$(J.command);return}b.length>0&&$(m=>m.trim().length>0?m:b[0]?.command??"")},[b,J,o?.config?.command,o?.status]),r.useEffect(()=>{H(h??"")},[h]);const se=r.useCallback(()=>{h&&window.open(h,"_blank","noopener,noreferrer")},[h]),be=r.useCallback(()=>{q(!1),fe()},[fe]),Be=r.useCallback(()=>{try{const m=G.current;if(m?.contentWindow){m.contentWindow.location.reload(),q(!1),X();return}}catch{}if(!(!h||!G.current))try{const m=new URL(h);m.searchParams.set("_t",Date.now().toString()),G.current.src=m.toString(),q(!1),X()}catch{G.current.src=h,q(!1),X()}},[h,G,X]),Q=r.useCallback(async(m,F,ne)=>{c(m);try{await F(),e(ne,"success")}catch(Ke){e(Le(Ke),"error")}finally{c(null)}},[e]),He=r.useCallback(m=>{a(m.scriptName),L(!1),$(m.command),e(`Selected ${m.scriptName} script.`,"success")},[e]),Ve=r.useCallback(()=>{a(null),L(!0),e("Cleared selected dev server script.","success")},[e]),qe=()=>{const m=z.trim();if(m.length===0){e("Enter a command before starting the dev server.","warning");return}const F=Re(p)??".",ne=J?.cwd??F;Q("start",()=>k(m,ne),"Dev server started.")},We=()=>{Q("stop",U,"Dev server stopped.")},Ge=()=>{Q("restart",C,"Dev server restarted.")},Ie=()=>{const m=O.trim(),F=m.length>0?m:null;Q("preview",()=>P(F),F?"Preview URL updated.":"Preview URL override cleared.")},Xe=r.useCallback(()=>{f&&u()},[f,u]),Je=n==="starting"||n==="running"||s!==null,Qe=n==="stopped"||s!==null,Ye=n==="stopped"||n==="starting"||s!==null;return t.jsxs("div",{className:"dev-server-view","data-testid":"dev-server-view",children:[t.jsxs("section",{className:"dev-server-header","aria-label":"Dev server controls header",children:[t.jsxs("div",{className:"dev-server-header-title",children:[t.jsx(dt,{size:16}),t.jsx("h2",{children:"Dev Server"}),t.jsx("span",{className:`dev-server-status-badge ${M.className}`,"data-testid":"dev-server-status-badge",children:M.label})]}),t.jsxs("div",{className:"dev-server-header-actions",children:[t.jsxs("button",{type:"button",className:"btn btn-primary btn-sm",onClick:qe,disabled:Je,"data-testid":"dev-server-start-button",children:[t.jsx(ut,{size:14}),t.jsx("span",{children:s==="start"?"Starting...":"Start"})]}),t.jsxs("button",{type:"button",className:"btn btn-danger btn-sm",onClick:We,disabled:Qe,"data-testid":"dev-server-stop-button",children:[t.jsx(vt,{size:14}),t.jsx("span",{children:s==="stop"?"Stopping...":"Stop"})]}),t.jsxs("button",{type:"button",className:"btn btn-sm",onClick:Ge,disabled:Ye,"data-testid":"dev-server-restart-button",children:[t.jsx(mt,{size:14}),t.jsx("span",{children:s==="restart"?"Restarting...":"Restart"})]})]})]}),t.jsxs("section",{className:"dev-server-panel dev-server-config","aria-label":"Dev server configuration",children:[t.jsxs("div",{className:"dev-server-section-header",children:[t.jsx("h3",{children:"Configuration"}),w&&t.jsx("span",{className:"dev-server-muted",children:"Loading..."})]}),w&&!o&&b.length===0&&t.jsxs("div",{className:"dev-server-loading-state","data-testid":"dev-server-loading-state",children:[t.jsx(ee,{size:16,className:"dev-server-spin"}),t.jsx("span",{children:"Loading dev server configuration..."})]}),f&&t.jsxs("div",{className:"dev-server-error-box",role:"alert","data-testid":"dev-server-error-box",children:[t.jsx("p",{children:f}),t.jsx("button",{type:"button",className:"btn btn-sm",onClick:Xe,children:"Retry"})]}),t.jsxs("div",{className:"dev-server-section",children:[t.jsx("h3",{children:"Script Selection"}),x&&t.jsxs("div",{className:"dev-server-selected","data-testid":"dev-server-selected-summary",children:[t.jsx("span",{className:"dev-server-candidate-name",children:x}),t.jsx("span",{className:"dev-server-candidate-source",children:p??"root"}),t.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>L(!0),"data-testid":"dev-server-change-selection",children:"Change"}),t.jsx("button",{type:"button",className:"btn btn-danger btn-sm",onClick:Ve,"data-testid":"dev-server-clear-selection",children:"Clear"})]}),E&&b.length===0&&t.jsxs("p",{className:"dev-server-empty-state","data-testid":"dev-server-empty-candidates",children:["No dev server scripts detected. Check that your project has a ",t.jsx("code",{children:"package.json"})," with a ",t.jsx("code",{children:"dev"}),", ",t.jsx("code",{children:"start"}),", or similar script."]}),E&&b.length>0&&t.jsx("div",{className:"dev-server-candidates","data-testid":"dev-server-candidates",children:b.map(m=>{const F=_e(m,x,p);return t.jsxs("button",{type:"button",className:`dev-server-candidate ${F?"dev-server-candidate--selected":""}`,onClick:()=>He(m),"data-testid":`dev-server-candidate-${m.scriptName}-${Fe(m.cwd)}`,children:[t.jsx("span",{className:"dev-server-candidate-name",children:m.scriptName}),t.jsx("span",{className:"dev-server-candidate-command",children:Ft(m.command)}),t.jsx("span",{className:"dev-server-candidate-source",children:zt(m)})]},`${m.cwd}::${m.scriptName}::${m.command}`)})})]}),t.jsxs("div",{className:"dev-server-field-group",children:[t.jsx("label",{htmlFor:"dev-server-command",className:"dev-server-label",children:"Command"}),t.jsx("input",{id:"dev-server-command",className:"input",value:z,onChange:m=>$(m.target.value),placeholder:"pnpm dev","data-testid":"dev-server-command-input",readOnly:n==="running"||n==="starting"})]}),(n==="running"||n==="starting")&&o&&t.jsxs("div",{className:"dev-server-current-command","data-testid":"dev-server-current-command",children:[t.jsx("span",{className:"dev-server-label",children:"Running command"}),t.jsx("code",{children:o.config?.command??z})]}),t.jsxs("div",{className:"dev-server-preview-override",children:[t.jsx("label",{htmlFor:"dev-server-preview-input",className:"dev-server-label",children:"Preview URL Override"}),t.jsx("input",{id:"dev-server-preview-input",className:"input",type:"url",value:O,onChange:m=>H(m.target.value),placeholder:"http://localhost:3000","data-testid":"dev-server-preview-input"}),t.jsx("button",{type:"button",className:"btn btn-primary btn-sm",onClick:Ie,disabled:s==="preview","data-testid":"dev-server-set-preview",children:"Save"})]}),h&&t.jsxs("p",{className:"dev-server-preview-hint",children:["Auto-detected: ",h]})]}),t.jsx("div",{className:"dev-server-content",children:t.jsxs("section",{className:"dev-server-panel dev-server-logs-panel","data-testid":"dev-server-logs-panel","aria-label":"Dev server logs",children:[t.jsxs("div",{className:"dev-server-section-header",children:[t.jsx("h3",{children:"Logs"}),t.jsxs("span",{className:"dev-server-muted",children:[j??R.length," lines"]})]}),t.jsx("div",{className:"dev-server-logs-viewer","data-testid":"dev-server-log-viewer",children:t.jsx(At,{entries:R,loading:A,loadingMore:_,hasMore:D,total:j,onLoadMore:T,isRunning:d})})]})}),t.jsxs("section",{className:"dev-server-panel devserver-preview-panel","data-testid":"devserver-preview-panel","aria-label":"Dev server preview",children:[t.jsxs("div",{className:"devserver-preview-header",children:[t.jsxs("div",{className:"devserver-preview-title",children:[t.jsx(ft,{size:14}),t.jsx("span",{children:"Preview"})]}),t.jsxs("span",{className:"devserver-preview-url-badge devserver-preview-url-badge--auto",title:h??"No preview URL","data-testid":"devserver-preview-url-badge",children:["Auto",h?` · ${h}`:" · Not available"]}),t.jsxs("div",{className:"devserver-preview-actions",children:[t.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>v(m=>m==="embedded"?"external":"embedded"),"data-testid":"devserver-preview-mode-toggle",children:l==="embedded"?"External only":"Embedded"}),t.jsx("button",{type:"button",className:"btn btn-sm btn-icon",title:"Open in new tab",onClick:se,disabled:!h,"data-testid":"devserver-preview-open-tab",children:t.jsx(pt,{})}),t.jsx("button",{type:"button",className:"btn btn-sm btn-icon",title:"Refresh preview",onClick:Be,disabled:!h,"data-testid":"devserver-preview-refresh",children:t.jsx(ht,{})})]})]}),t.jsxs("div",{className:"devserver-preview-container","data-embed-status":g,"data-embedded":Oe?"true":"false",children:[!h&&!d&&t.jsx("p",{className:"devserver-preview-empty",children:"Start a dev server to see a live preview here."}),!h&&d&&t.jsx("p",{className:"devserver-preview-empty",children:"No preview URL detected. Start the dev server or set a manual URL to preview your app."}),h&&l==="external"&&t.jsxs("div",{className:"devserver-preview-external-only","data-testid":"devserver-preview-external-only",children:[t.jsx("p",{children:"Embedded preview is disabled. Open your app in a separate browser tab."}),t.jsx("button",{type:"button",className:"btn btn-primary btn-sm touch-target",onClick:se,"data-testid":"devserver-preview-external-open-tab",children:"Open in new tab"})]}),h&&l==="embedded"&&pe&&te&&t.jsxs("div",{className:g==="error"?"devserver-preview-error-panel":"devserver-preview-blocked-panel","data-testid":"devserver-preview-fallback",role:"alert",children:[g==="error"?t.jsx(Ae,{className:"devserver-preview-blocked-icon","aria-hidden":"true"}):t.jsx(Me,{className:"devserver-preview-blocked-icon","aria-hidden":"true"}),t.jsxs("div",{children:[t.jsx("p",{className:"devserver-preview-blocked-title",children:g==="error"?"Preview failed":"Preview blocked"}),re&&t.jsx("p",{className:"devserver-preview-blocked-context",children:re})]}),t.jsx("p",{className:"devserver-preview-blocked-description",children:"Open the preview in a new tab, or retry embedded mode after checking your server settings."}),t.jsxs("div",{className:"devserver-preview-blocked-actions",children:[t.jsx("button",{type:"button",className:"btn btn-primary",onClick:se,"data-testid":"devserver-preview-fallback-open-tab",children:"Open preview in new tab"}),t.jsx("button",{type:"button",className:"btn btn-sm",onClick:be,"data-testid":"devserver-preview-fallback-retry",children:"Retry embedded preview"})]})]}),h&&l==="embedded"&&!pe&&t.jsx(Tt,{url:h,embedStatus:g,onEmbedStatusChange:$e,iframeRef:G,blockReason:re,onRetry:be})]})]})]})}export{Ht as DevServerView};
|
|
1
|
+
import{r,j as t}from"./vendor-react-K0fH_qHe.js";import{bo as De,bp as de,bq as Ze,br as ue,z as Ue,bs as ge,bt as we,bu as xe,bv as ye,bw as et,bx as ae,by as tt,bz as rt,bA as st,bB as nt,bC as at,bD as ie,V as ee,S as it,bE as lt,bF as ct,C as ot,bG as Me,bH as Ae,bI as dt,a4 as ut,a5 as vt,a6 as mt,d as ft,s as pt,R as ht}from"./index-NFptaeUQ.js";import"./vendor-xterm-DzcZoU0P.js";const ve=500,bt=3e3;function B(e){return e instanceof Error?e.message:String(e)}function Pe(e){return e.length<=ve?e:e.slice(-ve)}function le(e,i){return Pe([...e,i])}function I(e){try{return JSON.parse(e)}catch{return null}}function Y(e){const i=e.text??"";return e.stream==="stderr"?`[stderr] ${i}`:i}function gt(e){return e?.previewUrl??null}async function Se(e){return tt(e)}async function Ne(e,i){return rt(e,i)}async function wt(e){return st(e)}async function xt(e){return nt(e)}async function je(e){return at(e)}function V(e){try{return e()}catch{return null}}function ce(){return typeof V(()=>de)=="function"&&typeof V(()=>De)=="function"}function W(e){return{config:{id:e.id??"default",name:e.name??"Dev Server",command:e.command??"",cwd:e.cwd??"."},status:e.status,runtime:e.pid?{pid:e.pid,startedAt:e.startedAt??new Date().toISOString(),exitCode:e.exitCode??void 0,previewUrl:e.previewUrl}:void 0,previewUrl:e.previewUrl??e.detectedUrl??e.manualUrl??void 0,logHistory:(e.logs??[]).map(i=>({timestamp:new Date().toISOString(),stream:i.startsWith("[stderr]")?"stderr":"stdout",text:i.replace(/^\[stderr\]\s*/,"")}))}}function yt(e){const[i,o]=r.useState(null),[b,y]=r.useState([]),[w,f]=r.useState([]),[k,U]=r.useState([]),[C,P]=r.useState(!0),[S,u]=r.useState(null),n=r.useRef(0),[d,M]=r.useState(null),R=r.useCallback(a=>{if(o(a),a?.logHistory){const s=a.logHistory.slice(-ve).map(Y);f(s)}},[]),A=r.useCallback(async()=>{const a=n.current;try{if(ce())if(d){const s=await De(d,e);if(n.current!==a)return;R(s)}else{const s=await de(e);if(n.current!==a)return;y(s),s.length>0&&(M(s[0].config.id),R(s[0]))}else{const s=await Se(e);if(n.current!==a)return;const c=W(s);y([c]),R(c)}u(null)}catch(s){if(n.current!==a)return;u(B(s))}},[R,e,d]);r.useEffect(()=>{n.current+=1;const a=n.current;o(null),y([]),f([]),U([]),P(!0),u(null),M(null),(async()=>{try{const[c,l]=await Promise.allSettled([ce()?de(e):Se(e).then(N=>[W(N)]),typeof V(()=>ae)=="function"?ae(e):je(e).then(N=>N.map(g=>({name:g.name,command:g.command,cwd:g.cwd,scriptName:g.scriptName,packagePath:g.packagePath})))]);if(n.current!==a)return;let v=null;if(c.status==="fulfilled"){const N=c.value;if(y(N),N.length>0){const g=N[0];ce()&&M(g.config.id),R(g)}}else v=B(c.reason);l.status==="fulfilled"&&U(l.value),v&&u(v)}catch(c){if(n.current!==a)return;u(B(c))}finally{n.current===a&&P(!1)}})()},[R,e]),r.useEffect(()=>{const a=d?Ze(d,e):typeof V(()=>ue)=="function"?ue(e):null;if(!a)return;const s=n.current,c=Ue(a,{events:{history:l=>{if(n.current!==s)return;const v=I(l.data);if(v?.lines){const N=v.lines.map(Y);f(Pe(N))}},log:l=>{if(n.current!==s)return;const v=I(l.data);if(v){const N=typeof v.line=="string"?v.line:Y(v);f(g=>le(g,N))}},"dev-server:log":l=>{if(n.current!==s)return;const v=I(l.data);if(v){const N=typeof v.line=="string"?v.line:Y(v);f(g=>le(g,N))}},"dev-server:output":l=>{if(n.current!==s)return;const v=I(l.data);v?.line&&f(N=>le(N,v.line))},status:l=>{if(n.current!==s)return;const v=I(l.data),N=v?.status;N&&o(g=>g&&{...g,status:N,runtime:v.pid?{...g.runtime??{startedAt:new Date().toISOString()},pid:v.pid}:g.runtime})},"dev-server:status":l=>{if(n.current!==s)return;const v=I(l.data);if(v?.status){const N=W(v);o(N),y([N])}},stopped:()=>{n.current},failed:()=>{n.current}},onReconnect:()=>{n.current===s&&A()},onError:()=>{n.current===s&&u(l=>l??"Lost log stream connection.")}});return()=>{c()}},[e,A,d]),r.useEffect(()=>{if(i?.status!=="running"&&i?.status!=="starting")return;const a=setInterval(()=>{A()},bt);return()=>{clearInterval(a)}},[A,i?.status]);const _=r.useCallback(async(a,s)=>{n.current+=1;const c=n.current;try{let l;if(d&&typeof V(()=>ge)=="function")l=await ge(d,e);else{const v=await Ne({command:a,cwd:s},e);l=W(v)}if(n.current!==c)return;o(l),u(null)}catch(l){if(n.current!==c)return;throw u(B(l)),l}},[e,d]),D=r.useCallback(async()=>{n.current+=1;const a=n.current;try{let s;if(d&&typeof V(()=>we)=="function")s=await we(d,e);else{const c=await wt(e);s=W(c)}if(n.current!==a)return;o(s),u(null)}catch(s){if(n.current!==a)return;throw u(B(s)),s}},[e,d]),j=r.useCallback(async()=>{n.current+=1;const a=n.current;try{let s;if(d&&typeof V(()=>xe)=="function")s=await xe(d,e);else{const c=await xt(e);s=W(c)}if(n.current!==a)return;o(s),u(null)}catch(s){if(n.current!==a)return;throw u(B(s)),s}},[e,d]),T=r.useCallback(async a=>{n.current+=1;const s=n.current;try{let c;if(d&&typeof V(()=>ye)=="function")c=await ye(d,a,e);else{const l=await et({url:a},e);c={url:l.manualUrl??l.previewUrl??l.detectedUrl??null,source:l.manualUrl?"manual":"auto"}}if(n.current!==s)return;o(l=>l?{...l,previewUrl:c.url??void 0}:null),u(null)}catch(c){if(n.current!==s)return;throw u(B(c)),c}},[e,d]),h=r.useCallback(async()=>{n.current+=1;const a=n.current;try{let s;try{s=await ae(e)}catch{s=(await je(e)).map(l=>({name:l.name,command:l.command,cwd:l.cwd,scriptName:l.scriptName,packagePath:l.packagePath}))}if(n.current!==a)return;U(s),u(null)}catch(s){if(n.current!==a)return;throw u(B(s)),s}},[e]),p=r.useCallback(async(a,s)=>{if(typeof a!="string"&&!d)try{const v=a,N=await Ne({command:v.command,cwd:v.cwd,scriptName:v.scriptName,packagePath:v.packagePath??v.cwd},e),g=W(N);o(g),y([g]),u(null);return}catch(v){throw u(B(v)),v}const c=typeof a=="string"?a:a.command,l=typeof a=="string"?s:a.cwd;await _(c,l)},[e,_,d]),E=r.useCallback(async()=>{await D()},[D]),L=r.useCallback(async()=>{await j()},[j]),z=r.useCallback(async a=>{await T(a)},[T]),$=r.useCallback(async()=>{await h()},[h]),O=r.useCallback(async()=>{await A()},[A]),H=gt(i),x=i?{...i,pid:i.runtime?.pid}:null;return{session:i,sessions:b,logs:w,detectedCommands:k,previewUrl:H,isLoading:C,error:S,startServer:_,stopServer:D,restartServer:j,setPreviewUrl:T,detectCommands:h,refresh:A,candidates:k,serverState:x,loading:C,start:p,stop:E,restart:L,setManualUrl:z,detect:$,refreshStatus:O}}const ke=500,Ce=100;function Te(e){return e.length>ke?e.slice(-ke):e}function ze(e){return e==="stderr"?"stderr":"stdout"}function K(e){try{return JSON.parse(e.data)}catch{return null}}function Z(e,i){return{id:typeof e.id=="number"&&Number.isFinite(e.id)?e.id:i,text:typeof e.text=="string"?e.text:"",stream:ze(e.stream),timestamp:typeof e.timestamp=="string"?e.timestamp:""}}function St(e,i){return{id:i,text:e,stream:"stdout",timestamp:""}}function oe(e,i){if(i.length===0)return e;const o=[...e],b=new Set(e.map(y=>y.id));for(const y of i)b.has(y.id)||(b.add(y.id),o.push(y));return o.sort((y,w)=>y.id-w.id),Te(o)}function Nt(e,i){const[o,b]=r.useState([]),[y,w]=r.useState(!1),[f,k]=r.useState(!1),[U,C]=r.useState(!1),[P,S]=r.useState(null),u=r.useRef(null),n=r.useRef(!1),d=r.useRef(0),M=r.useRef(0),R=r.useRef(e),A=r.useRef(i),_=r.useRef(0),D=r.useRef(1);(R.current!==e||A.current!==i)&&(R.current=e,A.current=i,d.current++,n.current=!0,_.current=0,D.current=1,b([]),w(!1),k(!1),C(!1),S(null),u.current&&(u.current(),u.current=null)),r.useEffect(()=>{if(!i){u.current&&(u.current(),u.current=null);return}const E=d.current,L=++M.current;n.current=!1,w(!0);const z=(x,a)=>{const s=Te(x);b(s),S(a),C(a!==null?a>s.length:!1);const c=s.length>0?s[s.length-1].id:0;_.current=c,D.current=c+1},$=x=>{if(n.current||d.current!==E||!x||typeof x!="object")return;const a=x.lines;if(!Array.isArray(a))return;if(a.length>0&&typeof a[0]=="string"){const c=a.filter(l=>typeof l=="string").map((l,v)=>St(l,v+1));z(c,c.length);return}const s=a.filter(c=>!!c&&typeof c=="object").map((c,l)=>Z(c,l+1));z(s,s.length)},O=x=>{if(n.current||d.current!==E)return;const a=typeof x.text=="string"?x.text:typeof x.line=="string"?x.line:null;if(!a)return;const s=D.current,c=typeof x.id=="number"&&Number.isFinite(x.id)?x.id:s,l={id:c,text:a,stream:ze(x.stream),timestamp:typeof x.timestamp=="string"?x.timestamp:""};_.current=Math.max(_.current,c),D.current=Math.max(D.current,c+1),b(v=>oe(v,[l])),S(v=>v===null?v:Math.max(v+1,l.id))};async function H(){try{const a=await ie({maxLines:Ce},e);if(n.current||d.current!==E||M.current!==L)return;const s=a.lines.map((c,l)=>Z(c,l+1));z(s,a.totalLines)}catch{if(n.current||d.current!==E||M.current!==L)return;z([],null)}finally{!n.current&&d.current===E&&M.current===L&&w(!1)}const x=ue(e);u.current=Ue(x,{events:{"dev-server:log":a=>{const s=K(a);s&&O(s)},log:a=>{const s=K(a);s&&O(s)},history:a=>{const s=K(a);$(s)},"dev-server:history":a=>{const s=K(a);$(s)}},onReconnect:()=>{n.current||d.current!==E||ie({lastEventId:_.current,maxLines:50},e).then(a=>{if(n.current||d.current!==E)return;const s=a.lines.map((c,l)=>Z(c,D.current+l));if(s.length>0){const c=s[s.length-1].id;_.current=Math.max(_.current,c),D.current=Math.max(D.current,c+1)}b(c=>oe(c,s)),S(a.totalLines)}).catch(()=>{})}})}return H(),()=>{n.current=!0,u.current&&(u.current(),u.current=null)}},[i,e]);const T=r.useCallback(async()=>{if(!i||f)return;const E=d.current,L=o.length;k(!0);try{const z=await ie({maxLines:Ce,offset:L},e);if(n.current||d.current!==E)return;const $=z.lines.map((O,H)=>Z(O,H+1));b(O=>oe($,O)),C(z.totalLines>L+$.length),S(z.totalLines)}catch{}finally{k(!1)}},[i,o.length,f,e]),h=r.useCallback(()=>{b([])},[]),p=u.current!==null&&!y&&!n.current;return{entries:o,loading:y,loadingMore:f,hasMore:U,total:P,loadMore:T,clear:h,logs:o,isStreaming:p,clearLogs:h}}const jt="This preview appears to block iframe embedding. Open it in a new tab instead.",kt="The preview URL could not be loaded. Verify the server is running and the URL is correct.",Ct="Preview is taking longer than expected and may block iframe embedding.";function Et(e){return e==="blocked"?jt:e==="error"?kt:null}function Lt(e,i={}){const{loadTimeoutMs:o=1e4,detectionMethod:b=null}=i,y=r.useRef(null),w=r.useRef(null),[f,k]=r.useState("unknown"),[U,C]=r.useState(null),[P]=r.useState(b),S=r.useCallback(()=>{w.current!==null&&(window.clearTimeout(w.current),w.current=null)},[]),u=r.useCallback(j=>{k(j),C(Et(j))},[]),n=r.useCallback(()=>{k("blocked"),C(Ct)},[]);r.useEffect(()=>{if(S(),!e){k("unknown"),C(null);return}k("unknown"),C(null);let j=!1;return queueMicrotask(()=>{j||(k("loading"),C(null))}),()=>{j=!0,S()}},[S,e]),r.useEffect(()=>{if(f!=="loading"){S();return}const j=setTimeout(()=>{w.current=null,n()},o);return w.current=j,()=>{clearTimeout(j),w.current===j&&(w.current=null)}},[S,f,o,n]);const d=r.useCallback(()=>{const j=y.current;if(!j){u("embedded");return}try{if(j.contentWindow?.location?.href==="about:blank"&&j.src!=="about:blank"){u("blocked");return}}catch{}u("embedded")},[u]),M=r.useCallback(()=>{u("error")},[u]);r.useEffect(()=>{if(S(),!e){k("unknown"),C(null);return}k("unknown"),C(null)},[S]);const R=r.useCallback(()=>{S(),k("unknown"),C(null)},[S]),A=R,_=r.useMemo(()=>f==="embedded",[f]),D=r.useMemo(()=>f==="blocked"||f==="error",[f]);return{embedStatus:f,isEmbedded:_,isBlocked:D,blockReason:U,detectionMethod:P,iframeRef:y,resetEmbedStatus:R,setEmbedStatus:u,retry:A,embedContext:U,handleIframeLoad:d,handleIframeError:M}}const Rt=/\x1b\[[0-9;]*m/g;function me(e){return e.replace(Rt,"")}function _t(e){if(!e)return"";const i=new Date(e);return Number.isNaN(i.getTime())?"":i.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1})}function Dt(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Ut(e){if(e.stream==="stderr")return"error";const i=me(e.text).toLowerCase();return/\b(warn|warning)\b/.test(i)?"warn":/\b(error|fatal)\b/.test(i)?"error":"info"}function Mt(e,i){if(!i)return e;const o=new RegExp(`(${Dt(i)})`,"ig"),b=e.split(o),y=i.toLowerCase();return t.jsx(t.Fragment,{children:b.map((w,f)=>w.toLowerCase()===y?t.jsx("mark",{children:w},`${w}-${f}`):t.jsx("span",{children:w},`${w}-${f}`))})}function At({entries:e,loading:i,loadingMore:o,hasMore:b,total:y,onLoadMore:w,isRunning:f}){const k=r.useRef(null),U=r.useRef(e.length),C=r.useRef(f),[P,S]=r.useState(!1),[u,n]=r.useState(!1),[d,M]=r.useState(""),[R,A]=r.useState("all"),_=r.useMemo(()=>R==="all"?e:e.filter(p=>Ut(p)===R),[e,R]),D=r.useMemo(()=>{const p=d.trim().toLowerCase();return p?_.filter(E=>me(E.text).toLowerCase().includes(p)):_},[_,d]),j=D.length,T=r.useCallback(()=>{const p=k.current;p&&(p.scrollTop=p.scrollHeight,n(!1))},[]);r.useEffect(()=>{const p=C.current,E=U.current,L=e.length>E;f&&(!p||!u&&L)&&T(),C.current=f,U.current=e.length},[e.length,f,u,T]);const h=r.useCallback(()=>{const p=k.current;if(!p)return;const L=p.scrollTop+p.clientHeight>=p.scrollHeight-50;n(!L)},[]);return r.useEffect(()=>{i||e.length===0||!u&&f&&T()},[e,f,u,i,T]),i&&e.length===0?t.jsx("section",{className:"devserver-log-viewer","data-testid":"devserver-log-viewer",children:t.jsxs("div",{className:"devserver-log-viewer__loading","data-testid":"devserver-log-loading",children:[t.jsx(ee,{size:16,className:"devserver-log-viewer__spinner"}),t.jsx("span",{children:"Loading logs…"})]})}):t.jsxs("section",{className:`devserver-log-viewer${P?" devserver-log-viewer--fullscreen":""}`,"data-testid":"devserver-log-viewer",children:[t.jsxs("header",{className:"devserver-log-viewer__toolbar",children:[t.jsxs("div",{className:"devserver-log-viewer__toolbar-meta",children:[t.jsx("span",{className:"devserver-log-viewer__title",children:"Logs"}),t.jsxs("span",{className:"devserver-log-viewer__count","data-testid":"devserver-log-count",children:[y!==null?`${e.length}/${y}`:`${e.length}`," lines"]})]}),t.jsxs("div",{className:"devserver-log-viewer__toolbar-actions",children:[t.jsxs("label",{className:"devserver-log-viewer__severity",htmlFor:"devserver-log-severity-filter",children:[t.jsx("span",{className:"visually-hidden",children:"Filter logs by severity"}),t.jsxs("select",{id:"devserver-log-severity-filter",className:"select devserver-log-viewer__severity-select",value:R,onChange:p=>A(p.target.value),"data-testid":"devserver-log-severity-filter","aria-label":"Filter logs by severity",children:[t.jsx("option",{value:"all",children:"All severities"}),t.jsx("option",{value:"info",children:"Info"}),t.jsx("option",{value:"warn",children:"Warn"}),t.jsx("option",{value:"error",children:"Error"})]})]}),t.jsxs("label",{className:"devserver-log-viewer__search",htmlFor:"devserver-log-search",children:[t.jsx("span",{className:"visually-hidden",children:"Search logs"}),t.jsx(it,{size:14}),t.jsx("input",{id:"devserver-log-search",className:"input devserver-log-viewer__search-input",type:"text",value:d,onChange:p=>M(p.target.value),placeholder:"Search logs","data-testid":"devserver-log-search-input","aria-label":"Search logs"})]}),d.trim().length>0&&t.jsxs("span",{className:"devserver-log-viewer__matches","data-testid":"devserver-log-match-count",children:[j," match",j===1?"":"es"]}),t.jsx("button",{type:"button",className:"btn btn-sm btn-icon",onClick:()=>S(p=>!p),"data-testid":"devserver-log-fullscreen-toggle","aria-label":P?"Exit fullscreen logs":"Enter fullscreen logs",children:P?t.jsx(lt,{size:14}):t.jsx(ct,{size:14})})]})]}),t.jsxs("div",{className:"devserver-log-viewer__body",children:[b&&t.jsx("div",{className:"devserver-log-viewer__load-more","data-testid":"devserver-log-load-more",children:t.jsx("button",{type:"button",className:"btn btn-sm touch-target",onClick:w,disabled:o,"data-testid":"devserver-log-load-more-button",children:o?t.jsxs(t.Fragment,{children:[t.jsx(ee,{size:14,className:"devserver-log-viewer__spinner"}),"Loading older logs…"]}):"Load older logs"})}),t.jsxs("div",{ref:k,className:"devserver-log-viewer__content",onScroll:h,"data-testid":"devserver-log-content",children:[!i&&D.length===0&&t.jsx("p",{className:"devserver-log-viewer__empty","data-testid":"devserver-log-empty",children:e.length===0?"No logs yet. Start the dev server to see output.":_.length===0?"No log lines match the selected severity.":"No log lines match your search."}),D.map(p=>{const E=me(p.text),L=_t(p.timestamp);return t.jsxs("div",{className:"devserver-log-line",children:[L&&t.jsx("span",{className:"devserver-log-timestamp","data-testid":"devserver-log-timestamp",children:L}),p.stream==="stderr"&&t.jsx("span",{className:"devserver-log-stream-badge","data-testid":"devserver-log-stderr-badge",children:"ERR"}),t.jsx("span",{className:"devserver-log-text",children:Mt(E,d.trim())})]},p.id)})]}),u&&f&&t.jsxs("button",{type:"button",className:"btn btn-sm devserver-log-viewer__new-logs-button",onClick:T,"data-testid":"devserver-log-jump-button",children:[t.jsx(ot,{size:14}),"New logs"]})]})]})}const Pt="devserver-preview-iframe";function Tt({url:e,embedStatus:i,onEmbedStatusChange:o,iframeRef:b,blockReason:y,onRetry:w,className:f=Pt,embedContext:k}){const U=y??k??null,[C,P]=r.useState(0);r.useEffect(()=>{!e||i!=="unknown"||(P(d=>d+1),o("loading"))},[i,o,e]);const S=r.useCallback(()=>{const d=b.current;if(!d){o("embedded");return}try{if(d.contentWindow?.location?.href==="about:blank"&&d.src!=="about:blank"){o("blocked");return}}catch{}o("embedded")},[b,o]),u=r.useCallback(d=>{d.stopPropagation(),o("error")},[o]),n=r.useCallback(()=>{e&&window.open(e,"_blank","noopener,noreferrer")},[e]);return e?t.jsxs("div",{className:"devserver-preview-iframe-shell",children:[t.jsx("iframe",{src:e,ref:b,sandbox:"allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox",className:f,title:"Dev server preview",onLoad:S,onError:u,onErrorCapture:u,"data-testid":"devserver-preview-iframe"},`${e}-${C}`),i==="loading"&&t.jsxs("div",{className:"devserver-preview-overlay","data-testid":"devserver-preview-loading",children:[t.jsx(ee,{size:16,className:"dev-server-spin"}),t.jsx("span",{children:"Loading preview..."})]}),i==="blocked"&&t.jsxs("div",{className:"devserver-preview-blocked-panel",role:"alert","data-testid":"devserver-preview-blocked-panel",children:[t.jsx(Me,{className:"devserver-preview-blocked-icon","aria-hidden":"true"}),t.jsxs("div",{children:[t.jsx("p",{className:"devserver-preview-blocked-title",children:"Preview cannot be embedded"}),U&&t.jsx("p",{className:"devserver-preview-blocked-context",children:U})]}),t.jsx("p",{className:"devserver-preview-blocked-description",children:"You can view the preview in a separate browser tab."}),t.jsxs("div",{className:"devserver-preview-blocked-actions",children:[t.jsx("button",{type:"button",className:"btn btn-primary",onClick:n,children:"Open in new tab"}),w&&t.jsx("button",{type:"button",className:"btn btn-sm",onClick:w,children:"Retry"})]})]}),i==="error"&&t.jsxs("div",{className:"devserver-preview-error-panel",role:"alert","data-testid":"devserver-preview-error-panel",children:[t.jsx(Ae,{className:"devserver-preview-blocked-icon","aria-hidden":"true"}),t.jsxs("div",{children:[t.jsx("p",{className:"devserver-preview-blocked-title",children:"Unable to load preview"}),U&&t.jsx("p",{className:"devserver-preview-blocked-context",children:U})]}),t.jsx("p",{className:"devserver-preview-blocked-description",children:"You can view the preview in a separate browser tab."}),t.jsxs("div",{className:"devserver-preview-blocked-actions",children:[t.jsx("button",{type:"button",className:"btn btn-primary",onClick:n,children:"Open in new tab"}),w&&t.jsx("button",{type:"button",className:"btn btn-sm",onClick:w,children:"Retry"})]})]})]}):null}const Ee={stopped:{className:"dev-server-status-badge--stopped",label:"Stopped"},starting:{className:"dev-server-status-badge--starting",label:"Starting..."},running:{className:"dev-server-status-badge--running",label:"Running"},stopping:{className:"dev-server-status-badge--starting",label:"Stopping..."},failed:{className:"dev-server-status-badge--failed",label:"Failed"}};function Le(e){return e instanceof Error?e.message:String(e)}function Fe(e){return e==="."?"root":e}function Re(e){return e?e==="root"?".":e:null}function _e(e,i,o){return!i||e.scriptName!==i?!1:o?Fe(e.cwd)===o:!0}function zt(e){return e.cwd==="."?"root":e.cwd}function Ft(e){return e.length<=60?e:`${e.slice(0,60)}…`}function Ht({addToast:e,projectId:i}){const{session:o,detectedCommands:b,previewUrl:y,isLoading:w,error:f,startServer:k,stopServer:U,restartServer:C,setPreviewUrl:P,detectCommands:S,refresh:u}=yt(i),n=o?.status??"stopped",d=n==="running"||n==="starting",M=Ee[n]??Ee.stopped,{entries:R,loading:A,loadingMore:_,hasMore:D,total:j,loadMore:T}=Nt(i,!!i),h=y,p=o?.config?.cwd??null,[E,L]=r.useState(!0),[z,$]=r.useState(""),[O,H]=r.useState(""),[x,a]=r.useState(null),[s,c]=r.useState(null),[l,v]=r.useState("embedded"),N=l==="embedded"?h:null,{embedStatus:g,setEmbedStatus:$e,resetEmbedStatus:X,iframeRef:G,isEmbedded:Oe,isBlocked:te,blockReason:re,retry:fe}=Lt(N),[pe,q]=r.useState(!1),he=r.useRef(g);r.useEffect(()=>{const m=he.current!==g;te&&m&&q(!0),g==="embedded"&&q(!1),he.current=g},[g,te]),r.useEffect(()=>{q(!1)},[h]);const J=r.useMemo(()=>{if(!x)return null;const m=Re(p);return b.find(F=>!(F.scriptName!==x||m&&F.cwd!==m||o?.config?.command&&F.command!==o.config.command))??b.find(F=>_e(F,x,p))??null},[b,o?.config?.command,x,p]);r.useEffect(()=>{typeof S=="function"&&S().catch(m=>{e(Le(m),"error")})},[e,S]),r.useEffect(()=>{if(x){L(!1);return}L(!0)},[x]),r.useEffect(()=>{if(o?.status==="running"||o?.status==="starting"){o.config?.command?.trim().length>0&&$(o.config.command);return}if(J){$(J.command);return}b.length>0&&$(m=>m.trim().length>0?m:b[0]?.command??"")},[b,J,o?.config?.command,o?.status]),r.useEffect(()=>{H(h??"")},[h]);const se=r.useCallback(()=>{h&&window.open(h,"_blank","noopener,noreferrer")},[h]),be=r.useCallback(()=>{q(!1),fe()},[fe]),Be=r.useCallback(()=>{try{const m=G.current;if(m?.contentWindow){m.contentWindow.location.reload(),q(!1),X();return}}catch{}if(!(!h||!G.current))try{const m=new URL(h);m.searchParams.set("_t",Date.now().toString()),G.current.src=m.toString(),q(!1),X()}catch{G.current.src=h,q(!1),X()}},[h,G,X]),Q=r.useCallback(async(m,F,ne)=>{c(m);try{await F(),e(ne,"success")}catch(Ke){e(Le(Ke),"error")}finally{c(null)}},[e]),He=r.useCallback(m=>{a(m.scriptName),L(!1),$(m.command),e(`Selected ${m.scriptName} script.`,"success")},[e]),Ve=r.useCallback(()=>{a(null),L(!0),e("Cleared selected dev server script.","success")},[e]),qe=()=>{const m=z.trim();if(m.length===0){e("Enter a command before starting the dev server.","warning");return}const F=Re(p)??".",ne=J?.cwd??F;Q("start",()=>k(m,ne),"Dev server started.")},We=()=>{Q("stop",U,"Dev server stopped.")},Ge=()=>{Q("restart",C,"Dev server restarted.")},Ie=()=>{const m=O.trim(),F=m.length>0?m:null;Q("preview",()=>P(F),F?"Preview URL updated.":"Preview URL override cleared.")},Xe=r.useCallback(()=>{f&&u()},[f,u]),Je=n==="starting"||n==="running"||s!==null,Qe=n==="stopped"||s!==null,Ye=n==="stopped"||n==="starting"||s!==null;return t.jsxs("div",{className:"dev-server-view","data-testid":"dev-server-view",children:[t.jsxs("section",{className:"dev-server-header","aria-label":"Dev server controls header",children:[t.jsxs("div",{className:"dev-server-header-title",children:[t.jsx(dt,{size:16}),t.jsx("h2",{children:"Dev Server"}),t.jsx("span",{className:`dev-server-status-badge ${M.className}`,"data-testid":"dev-server-status-badge",children:M.label})]}),t.jsxs("div",{className:"dev-server-header-actions",children:[t.jsxs("button",{type:"button",className:"btn btn-primary btn-sm",onClick:qe,disabled:Je,"data-testid":"dev-server-start-button",children:[t.jsx(ut,{size:14}),t.jsx("span",{children:s==="start"?"Starting...":"Start"})]}),t.jsxs("button",{type:"button",className:"btn btn-danger btn-sm",onClick:We,disabled:Qe,"data-testid":"dev-server-stop-button",children:[t.jsx(vt,{size:14}),t.jsx("span",{children:s==="stop"?"Stopping...":"Stop"})]}),t.jsxs("button",{type:"button",className:"btn btn-sm",onClick:Ge,disabled:Ye,"data-testid":"dev-server-restart-button",children:[t.jsx(mt,{size:14}),t.jsx("span",{children:s==="restart"?"Restarting...":"Restart"})]})]})]}),t.jsxs("section",{className:"dev-server-panel dev-server-config","aria-label":"Dev server configuration",children:[t.jsxs("div",{className:"dev-server-section-header",children:[t.jsx("h3",{children:"Configuration"}),w&&t.jsx("span",{className:"dev-server-muted",children:"Loading..."})]}),w&&!o&&b.length===0&&t.jsxs("div",{className:"dev-server-loading-state","data-testid":"dev-server-loading-state",children:[t.jsx(ee,{size:16,className:"dev-server-spin"}),t.jsx("span",{children:"Loading dev server configuration..."})]}),f&&t.jsxs("div",{className:"dev-server-error-box",role:"alert","data-testid":"dev-server-error-box",children:[t.jsx("p",{children:f}),t.jsx("button",{type:"button",className:"btn btn-sm",onClick:Xe,children:"Retry"})]}),t.jsxs("div",{className:"dev-server-section",children:[t.jsx("h3",{children:"Script Selection"}),x&&t.jsxs("div",{className:"dev-server-selected","data-testid":"dev-server-selected-summary",children:[t.jsx("span",{className:"dev-server-candidate-name",children:x}),t.jsx("span",{className:"dev-server-candidate-source",children:p??"root"}),t.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>L(!0),"data-testid":"dev-server-change-selection",children:"Change"}),t.jsx("button",{type:"button",className:"btn btn-danger btn-sm",onClick:Ve,"data-testid":"dev-server-clear-selection",children:"Clear"})]}),E&&b.length===0&&t.jsxs("p",{className:"dev-server-empty-state","data-testid":"dev-server-empty-candidates",children:["No dev server scripts detected. Check that your project has a ",t.jsx("code",{children:"package.json"})," with a ",t.jsx("code",{children:"dev"}),", ",t.jsx("code",{children:"start"}),", or similar script."]}),E&&b.length>0&&t.jsx("div",{className:"dev-server-candidates","data-testid":"dev-server-candidates",children:b.map(m=>{const F=_e(m,x,p);return t.jsxs("button",{type:"button",className:`dev-server-candidate ${F?"dev-server-candidate--selected":""}`,onClick:()=>He(m),"data-testid":`dev-server-candidate-${m.scriptName}-${Fe(m.cwd)}`,children:[t.jsx("span",{className:"dev-server-candidate-name",children:m.scriptName}),t.jsx("span",{className:"dev-server-candidate-command",children:Ft(m.command)}),t.jsx("span",{className:"dev-server-candidate-source",children:zt(m)})]},`${m.cwd}::${m.scriptName}::${m.command}`)})})]}),t.jsxs("div",{className:"dev-server-field-group",children:[t.jsx("label",{htmlFor:"dev-server-command",className:"dev-server-label",children:"Command"}),t.jsx("input",{id:"dev-server-command",className:"input",value:z,onChange:m=>$(m.target.value),placeholder:"pnpm dev","data-testid":"dev-server-command-input",readOnly:n==="running"||n==="starting"})]}),(n==="running"||n==="starting")&&o&&t.jsxs("div",{className:"dev-server-current-command","data-testid":"dev-server-current-command",children:[t.jsx("span",{className:"dev-server-label",children:"Running command"}),t.jsx("code",{children:o.config?.command??z})]}),t.jsxs("div",{className:"dev-server-preview-override",children:[t.jsx("label",{htmlFor:"dev-server-preview-input",className:"dev-server-label",children:"Preview URL Override"}),t.jsx("input",{id:"dev-server-preview-input",className:"input",type:"url",value:O,onChange:m=>H(m.target.value),placeholder:"http://localhost:3000","data-testid":"dev-server-preview-input"}),t.jsx("button",{type:"button",className:"btn btn-primary btn-sm",onClick:Ie,disabled:s==="preview","data-testid":"dev-server-set-preview",children:"Save"})]}),h&&t.jsxs("p",{className:"dev-server-preview-hint",children:["Auto-detected: ",h]})]}),t.jsx("div",{className:"dev-server-content",children:t.jsxs("section",{className:"dev-server-panel dev-server-logs-panel","data-testid":"dev-server-logs-panel","aria-label":"Dev server logs",children:[t.jsxs("div",{className:"dev-server-section-header",children:[t.jsx("h3",{children:"Logs"}),t.jsxs("span",{className:"dev-server-muted",children:[j??R.length," lines"]})]}),t.jsx("div",{className:"dev-server-logs-viewer","data-testid":"dev-server-log-viewer",children:t.jsx(At,{entries:R,loading:A,loadingMore:_,hasMore:D,total:j,onLoadMore:T,isRunning:d})})]})}),t.jsxs("section",{className:"dev-server-panel devserver-preview-panel","data-testid":"devserver-preview-panel","aria-label":"Dev server preview",children:[t.jsxs("div",{className:"devserver-preview-header",children:[t.jsxs("div",{className:"devserver-preview-title",children:[t.jsx(ft,{size:14}),t.jsx("span",{children:"Preview"})]}),t.jsxs("span",{className:"devserver-preview-url-badge devserver-preview-url-badge--auto",title:h??"No preview URL","data-testid":"devserver-preview-url-badge",children:["Auto",h?` · ${h}`:" · Not available"]}),t.jsxs("div",{className:"devserver-preview-actions",children:[t.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>v(m=>m==="embedded"?"external":"embedded"),"data-testid":"devserver-preview-mode-toggle",children:l==="embedded"?"External only":"Embedded"}),t.jsx("button",{type:"button",className:"btn btn-sm btn-icon",title:"Open in new tab",onClick:se,disabled:!h,"data-testid":"devserver-preview-open-tab",children:t.jsx(pt,{})}),t.jsx("button",{type:"button",className:"btn btn-sm btn-icon",title:"Refresh preview",onClick:Be,disabled:!h,"data-testid":"devserver-preview-refresh",children:t.jsx(ht,{})})]})]}),t.jsxs("div",{className:"devserver-preview-container","data-embed-status":g,"data-embedded":Oe?"true":"false",children:[!h&&!d&&t.jsx("p",{className:"devserver-preview-empty",children:"Start a dev server to see a live preview here."}),!h&&d&&t.jsx("p",{className:"devserver-preview-empty",children:"No preview URL detected. Start the dev server or set a manual URL to preview your app."}),h&&l==="external"&&t.jsxs("div",{className:"devserver-preview-external-only","data-testid":"devserver-preview-external-only",children:[t.jsx("p",{children:"Embedded preview is disabled. Open your app in a separate browser tab."}),t.jsx("button",{type:"button",className:"btn btn-primary btn-sm touch-target",onClick:se,"data-testid":"devserver-preview-external-open-tab",children:"Open in new tab"})]}),h&&l==="embedded"&&pe&&te&&t.jsxs("div",{className:g==="error"?"devserver-preview-error-panel":"devserver-preview-blocked-panel","data-testid":"devserver-preview-fallback",role:"alert",children:[g==="error"?t.jsx(Ae,{className:"devserver-preview-blocked-icon","aria-hidden":"true"}):t.jsx(Me,{className:"devserver-preview-blocked-icon","aria-hidden":"true"}),t.jsxs("div",{children:[t.jsx("p",{className:"devserver-preview-blocked-title",children:g==="error"?"Preview failed":"Preview blocked"}),re&&t.jsx("p",{className:"devserver-preview-blocked-context",children:re})]}),t.jsx("p",{className:"devserver-preview-blocked-description",children:"Open the preview in a new tab, or retry embedded mode after checking your server settings."}),t.jsxs("div",{className:"devserver-preview-blocked-actions",children:[t.jsx("button",{type:"button",className:"btn btn-primary",onClick:se,"data-testid":"devserver-preview-fallback-open-tab",children:"Open preview in new tab"}),t.jsx("button",{type:"button",className:"btn btn-sm",onClick:be,"data-testid":"devserver-preview-fallback-retry",children:"Retry embedded preview"})]})]}),h&&l==="embedded"&&!pe&&t.jsx(Tt,{url:h,embedStatus:g,onEmbedStatusChange:$e,iframeRef:G,blockReason:re,onRetry:be})]})]})]})}export{Ht as DevServerView};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as i,j as r}from"./vendor-react-K0fH_qHe.js";import{dQ as g,dR as f,dS as P,cD as b,e as y,g as H,E as C,d as O,V as v,q as z}from"./index-
|
|
1
|
+
import{r as i,j as r}from"./vendor-react-K0fH_qHe.js";import{dQ as g,dR as f,dS as P,cD as b,e as y,g as H,E as C,d as O,V as v,q as z}from"./index-NFptaeUQ.js";function D({value:o,onChange:d,placeholder:m,onInputKeyDown:x,nodeId:l,localNodeId:h}){const[e,n]=i.useState({isOpen:!1,loading:!1,error:null,currentPath:"",parentPath:null,entries:[],showHidden:!1}),a=i.useCallback(async(s,c=!1)=>{n(t=>({...t,loading:!0,error:null}));try{const t=await g(s,c,l,h);n(u=>({...u,loading:!1,currentPath:t.currentPath,parentPath:t.parentPath,entries:t.entries}))}catch(t){n(u=>({...u,loading:!1,error:t instanceof Error?t.message:"Failed to browse directory"}))}},[l,h]),j=i.useCallback(()=>{n(s=>s.isOpen?{...s,isOpen:!1}:{...s,isOpen:!0})},[]);i.useEffect(()=>{e.isOpen&&!e.loading&&e.entries.length===0&&!e.error&&a(o||void 0,e.showHidden)},[e.isOpen,e.loading,e.entries.length,e.error,o,e.showHidden,a,l,h]);const p=i.useCallback(s=>{a(s,e.showHidden)},[a,e.showHidden]),k=i.useCallback(()=>{d(e.currentPath),n(s=>({...s,isOpen:!1}))},[e.currentPath,d]),w=i.useCallback(()=>{n(s=>{const c=!s.showHidden;return{...s,showHidden:c}})},[]);i.useEffect(()=>{e.isOpen&&e.currentPath&&a(e.currentPath,e.showHidden)},[e.showHidden]);const N=e.currentPath?f(e.currentPath):[];return r.jsxs("div",{className:"directory-picker",children:[r.jsxs("div",{className:"directory-picker-input-row",children:[r.jsx("input",{type:"text",className:"input directory-picker-input",value:o,onChange:s=>d(s.target.value),onKeyDown:x,placeholder:m||"/path/to/your/project"}),r.jsxs("button",{type:"button",className:"btn btn-secondary btn-sm directory-picker-browse-btn",onClick:j,"aria-label":e.isOpen?"Close directory browser":"Browse directories",children:[e.isOpen?r.jsx(P,{size:16}):r.jsx(b,{size:16}),r.jsx("span",{children:"Browse"})]})]}),e.isOpen&&r.jsxs("div",{className:"directory-picker-browser",role:"tree","aria-label":"Directory browser",children:[r.jsx("div",{className:"directory-picker-breadcrumbs",children:N.map((s,c)=>r.jsxs("span",{className:"directory-picker-breadcrumb-item",children:[c>0&&r.jsx(y,{size:12,className:"directory-picker-breadcrumb-sep"}),r.jsx("button",{type:"button",className:"directory-picker-breadcrumb",onClick:()=>p(s.path),title:s.path,children:s.label})]},s.path))}),r.jsxs("div",{className:"directory-picker-toolbar",children:[e.parentPath&&r.jsxs("button",{type:"button",className:"btn btn-sm btn-secondary directory-picker-up-btn",onClick:()=>p(e.parentPath),"aria-label":"Go to parent directory",title:"Parent directory",children:[r.jsx(H,{size:14}),r.jsx("span",{children:"Up"})]}),r.jsxs("button",{type:"button",className:"btn btn-sm btn-secondary directory-picker-hidden-toggle",onClick:w,"aria-label":e.showHidden?"Hide hidden directories":"Show hidden directories",title:e.showHidden?"Hide hidden":"Show hidden",children:[e.showHidden?r.jsx(C,{size:14}):r.jsx(O,{size:14}),r.jsx("span",{children:e.showHidden?"Hide hidden":"Show hidden"})]})]}),e.loading?r.jsxs("div",{className:"directory-picker-loading",children:[r.jsx(v,{size:20,className:"animate-spin"}),r.jsx("span",{children:"Loading…"})]}):e.error?r.jsxs("div",{className:"directory-picker-error",children:[r.jsx(z,{size:16}),r.jsx("span",{children:e.error})]}):r.jsx("div",{className:"directory-picker-entries",children:e.entries.length===0?r.jsx("div",{className:"directory-picker-empty",children:"No subdirectories"}):e.entries.map(s=>r.jsxs("button",{type:"button",className:"directory-picker-entry",onClick:()=>p(s.path),role:"treeitem",title:s.path,children:[r.jsx(b,{size:16,className:"directory-picker-entry-icon"}),r.jsx("span",{className:"directory-picker-entry-name",children:s.name}),s.hasChildren&&r.jsx(y,{size:14,className:"directory-picker-entry-arrow"})]},s.path))}),r.jsxs("div",{className:"directory-picker-actions",children:[r.jsx("span",{className:"directory-picker-selected-path",title:e.currentPath,children:e.currentPath}),r.jsx("button",{type:"button",className:"btn btn-primary directory-picker-select-btn",onClick:k,children:"Select"})]})]})]})}export{D};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as s,j as e}from"./vendor-react-K0fH_qHe.js";import{f as oe,a as K,b as le,c as ie,F as z,E as de,d as ue,S as me,X as he,R as pe,A as fe,M as W,r as V,C as X,e as je,g as xe}from"./index-CrHLf3pB.js";import"./vendor-xterm-DzcZoU0P.js";function we(n){const{projectId:c,searchQuery:u,includeProjectFiles:a=!0}=n??{},[x,l]=s.useState([]),[h,i]=s.useState([]),[o,p]=s.useState(!0),[k,b]=s.useState(null),f=s.useRef(null),g=s.useRef(!1),m=s.useRef(null),j=s.useCallback(async()=>{f.current&&f.current.abort();const C=new AbortController;f.current=C;const E=!g.current;E&&p(!0),b(null);const L=oe(u?{q:u}:void 0,c),y=a?K(c):Promise.resolve({files:[]}),[v,F]=await Promise.allSettled([L,y]);if(C.signal.aborted)return;let R=null;if(v.status==="fulfilled"?(l(v.value),g.current=!0):R=v.reason instanceof Error?v.reason.message:String(v.reason),F.status==="fulfilled"){const M=F.value.files,P=u?.trim().toLowerCase(),T=P?M.filter(N=>N.name.toLowerCase().includes(P)||N.path.toLowerCase().includes(P)):M;i(T)}b(R),E&&p(!1)},[a,c,u]);return s.useEffect(()=>(m.current&&clearTimeout(m.current),m.current=setTimeout(()=>{j()},300),()=>{m.current&&clearTimeout(m.current)}),[j]),s.useEffect(()=>(j(),()=>{f.current&&f.current.abort()}),[]),{documents:x,projectFiles:h,loading:o,error:k,refresh:j}}function ke(n,c){const[u,a]=s.useState([]),[x,l]=s.useState(!0),[h,i]=s.useState(null),o=s.useRef(null),p=s.useRef(!1),k=c?.showHidden??!1,b=s.useCallback(async f=>{o.current&&o.current.abort();const g=new AbortController;o.current=g;const m=!p.current;m&&l(!0),i(null);try{const j=await K(n,{showHidden:f?.showHidden??k});if(g.signal.aborted)return;a(j.files),p.current=!0}catch(j){if(g.signal.aborted)return;i(j instanceof Error?j.message:String(j))}finally{!g.signal.aborted&&m&&l(!1)}},[n,k]);return s.useEffect(()=>(p.current=!1,b({showHidden:k}),()=>{o.current&&o.current.abort()}),[b,k]),{files:u,loading:x,error:h,refresh:b}}const be=768;function _(n){return n?new Date(n).toLocaleString():""}function ge(n){return n<1024?`${n} B`:n<1024*1024?`${(n/1024).toFixed(n>=10*1024?0:1)} KB`:`${(n/(1024*1024)).toFixed(1)} MB`}function ve(n,c=200){return n.length<=c?n:`${n.substring(0,c)}…`}function Ne({document:n,renderMarkdown:c,onToggleMarkdown:u}){const[a,x]=s.useState(!1),l=ve(n.content),h=n.content.length>200;return e.jsxs("div",{className:"document-card",children:[e.jsxs("div",{className:"document-card-header",children:[e.jsxs("div",{className:"document-card-key",children:[e.jsx(z,{size:14}),e.jsx("span",{className:"document-card-key-text",children:n.key}),e.jsxs("span",{className:"document-card-revision-badge",children:["v",n.revision]})]}),e.jsx("div",{className:"document-card-actions",children:e.jsx("button",{className:"btn btn-sm document-card-expand-btn",onClick:()=>x(i=>!i),title:a?"Collapse":"Expand","aria-label":a?"Collapse content":"Expand content",children:a?e.jsx(xe,{size:14}):e.jsx(X,{size:14})})})]}),e.jsxs("div",{className:"document-card-meta",children:[e.jsx("span",{className:"document-card-author",children:n.author}),e.jsx("span",{className:"document-card-separator",children:"·"}),e.jsx("span",{className:"document-card-date",children:_(n.updatedAt)})]}),e.jsxs("div",{className:`document-card-content${a?" document-card-content--expanded":""}`,children:[a?e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"document-card-content-header",children:e.jsx("button",{className:"btn btn-sm document-mode-toggle",onClick:u,"aria-label":c?"Switch to plain text":"Switch to markdown","aria-pressed":c,title:c?"Switch to plain text":"Switch to markdown",children:c?"Markdown":"Plain"})}),c?e.jsx("div",{className:"document-card-content-markdown",children:e.jsx("div",{className:"markdown-body",children:e.jsx(W,{remarkPlugins:[V],children:n.content})})}):e.jsx("pre",{className:"document-card-content-text",children:n.content})]}):e.jsx("p",{className:"document-card-preview",children:l}),h&&!a&&e.jsx("p",{className:"document-card-preview-truncated",children:"…"})]})]})}function Se({taskId:n,taskTitle:c,documents:u,onOpenTask:a,renderMarkdownStates:x,onToggleMarkdown:l}){const[h,i]=s.useState(!1);return e.jsxs("div",{className:"documents-group",children:[e.jsxs("div",{className:"documents-group-header",children:[e.jsxs("button",{className:"documents-group-toggle-btn",onClick:()=>i(o=>!o),"aria-expanded":h,"aria-label":`${h?"Collapse":"Expand"} documents for task ${n}`,children:[e.jsx("span",{className:"documents-group-toggle","aria-hidden":"true",children:h?e.jsx(X,{size:16}):e.jsx(je,{size:16})}),e.jsx("span",{className:"documents-group-task-id",children:n}),e.jsx("span",{className:"documents-group-task-title",children:c||"Untitled"})]}),e.jsxs("span",{className:"documents-group-count",children:[u.length," doc",u.length!==1?"s":""]}),e.jsx("button",{className:"documents-group-task-link",onClick:()=>a(n),"aria-label":`Open task ${n}: ${c||"Untitled"}`,children:"Open task"})]}),h&&e.jsx("div",{className:"documents-group-content",children:u.map(o=>e.jsx(Ne,{document:o,renderMarkdown:x.get(o.id)??!1,onToggleMarkdown:()=>l(o.id)},o.id))})]})}function ye({projectId:n,addToast:c,onOpenDetail:u}){const[a,x]=s.useState("project"),[l,h]=s.useState(""),[i,o]=s.useState(null),[p,k]=s.useState(!1),[b,f]=s.useState(null),[g,m]=s.useState(!1),[j,C]=s.useState(null),[E,L]=s.useState(!1),y=s.useRef(0),v=s.useRef(!1),[F,R]=s.useState(!1),[M,P]=s.useState(new Map),T=a==="tasks"?l.trim():"",{documents:N,loading:D,error:J,refresh:B}=we({projectId:n,searchQuery:T||void 0,includeProjectFiles:!1}),{files:S,loading:$,error:Y,refresh:O}=ke(n,{showHidden:p});s.useEffect(()=>{const t=()=>{L(window.innerWidth<=be)};return t(),window.addEventListener("resize",t),()=>{window.removeEventListener("resize",t)}},[]),s.useEffect(()=>{v.current=!1,x("project"),o(null),k(!1),f(null),C(null),m(!1),R(!1),P(new Map)},[n]),s.useEffect(()=>{v.current||D||$||(S.length>0?x("project"):N.length>0&&x("tasks"),v.current=!0)},[N.length,D,S.length,$]);const A=s.useMemo(()=>{const t=new Map;for(const r of N){const d=t.get(r.taskId)||[];t.set(r.taskId,[...d,r])}return Array.from(t.entries()).map(([r,d])=>{const w=[...d].sort((re,ce)=>ce.updatedAt.localeCompare(re.updatedAt));return{taskId:r,taskTitle:w[0]?.taskTitle,documents:w,latestUpdated:w[0]?.updatedAt??""}}).sort((r,d)=>d.latestUpdated.localeCompare(r.latestUpdated))},[N]),H=s.useMemo(()=>{const t=l.trim().toLowerCase();return t?S.filter(r=>{const d=r.path.toLowerCase(),w=r.name.toLowerCase();return d.includes(t)||w.includes(t)}):S},[S,l]);s.useEffect(()=>{if(!i)return;S.some(r=>r.path===i.path)||(o(null),f(null),C(null),m(!1))},[S,i]);const Z=s.useCallback(t=>{h(t.target.value)},[]),I=s.useCallback(()=>{h("")},[]),Q=s.useCallback(t=>{x(t)},[]),ee=s.useCallback(async t=>{try{const r=await le(t,n);u(r)}catch{c(`Failed to open task ${t}`,"error")}},[n,u,c]),se=s.useCallback(async t=>{o(t),m(!0),C(null),f(null);const r=y.current+1;y.current=r;try{const d=await ie("project",t.path,n);if(y.current!==r)return;f(d.content)}catch(d){if(y.current!==r)return;const w=d instanceof Error?d.message:`Failed to open ${t.path}`;C(w),c(w,"error")}finally{y.current===r&&m(!1)}},[n,c]),te=s.useCallback(()=>{o(null),f(null),C(null),m(!1)},[]),ne=s.useCallback(t=>{P(r=>{const d=new Map(r),w=d.get(t)??!1;return d.set(t,!w),d})},[]),U=a==="project"?Y:J,ae=s.useCallback(async()=>{if(a==="project"){await O();return}await B()},[a,O,B]),q=a==="project"?H.length:N.length,G=a==="project"?"Search project markdown files…":"Search task documents…";return e.jsxs("div",{className:"documents-view",children:[e.jsxs("div",{className:"documents-view-header",children:[e.jsxs("div",{className:"documents-view-title-row",children:[e.jsxs("h2",{className:"documents-view-title",children:[e.jsx(z,{size:20}),"Documents"]}),e.jsxs("span",{className:"documents-view-count",children:[q," result",q!==1?"s":""]})]}),e.jsxs("div",{className:"documents-controls-row",children:[e.jsxs("div",{className:"documents-tab-bar",role:"tablist","aria-label":"Documents sections",children:[e.jsxs("button",{className:`btn documents-tab${a==="project"?" active":""}`,role:"tab","aria-selected":a==="project","aria-label":"Show project markdown files",onClick:()=>Q("project"),children:["Project Files",e.jsx("span",{className:"documents-tab-count",children:S.length})]}),e.jsxs("button",{className:`btn documents-tab${a==="tasks"?" active":""}`,role:"tab","aria-selected":a==="tasks","aria-label":"Show task documents",onClick:()=>Q("tasks"),children:["Task Documents",e.jsx("span",{className:"documents-tab-count",children:A.length})]})]}),a==="project"&&e.jsxs("button",{className:"btn btn-sm documents-hidden-toggle",onClick:()=>k(t=>!t),"aria-pressed":p,"aria-label":p?"Hide hidden project files":"Show hidden project files",title:p?"Hide hidden files":"Show hidden files",children:[p?e.jsx(de,{size:14}):e.jsx(ue,{size:14}),p?"Hide Hidden":"Show Hidden"]}),e.jsxs("div",{className:"documents-search",children:[e.jsx(me,{size:16,className:"documents-search-icon"}),e.jsx("input",{type:"text",className:"documents-search-input",placeholder:G,value:l,onChange:Z,"aria-label":G}),l&&e.jsx("button",{className:"documents-search-clear",onClick:I,"aria-label":"Clear search",children:e.jsx(he,{size:16})})]})]})]}),e.jsx("div",{className:"documents-view-content",children:U?e.jsxs("div",{className:"documents-view-error",children:[e.jsxs("p",{children:["Failed to load ",a==="project"?"project files":"task documents",": ",U]}),e.jsxs("button",{className:"btn btn-primary",onClick:()=>void ae(),"aria-label":"Retry loading documents",children:[e.jsx(pe,{size:16}),"Retry"]})]}):a==="project"?$&&S.length===0?e.jsx("div",{className:"documents-view-loading",children:e.jsx("p",{children:"Loading project markdown files…"})}):H.length===0?e.jsx("div",{className:"documents-view-empty",children:l.trim()?e.jsxs("p",{children:['No project markdown files match "',l.trim(),'".']}):e.jsxs(e.Fragment,{children:[e.jsx(z,{size:48,className:"documents-view-empty-icon"}),e.jsx("p",{children:"No Markdown files found in this project."})]})}):e.jsxs("div",{className:`documents-project-layout${E?" documents-project-layout--mobile":""}`,children:[(!E||!i)&&e.jsx("aside",{className:"documents-view-sidebar","aria-label":"Project markdown files",children:e.jsx("ul",{className:"markdown-file-list",children:H.map(t=>{const r=i?.path===t.path;return e.jsx("li",{className:"markdown-file-list-item",children:e.jsxs("button",{className:`markdown-file-item${r?" markdown-file-item--selected":""}`,onClick:()=>void se(t),"aria-label":`Open ${t.path}`,"aria-current":r?"true":void 0,children:[e.jsx("span",{className:"markdown-file-item-name",children:t.name}),e.jsx("span",{className:"markdown-file-item-path",children:t.path}),e.jsxs("span",{className:"markdown-file-item-meta",children:[ge(t.size)," · ",_(t.mtime)]})]})},t.path)})})}),(!E||i)&&e.jsxs("section",{className:"documents-view-main","aria-label":"Project file content preview",children:[E&&i&&e.jsxs("button",{className:"btn btn-sm documents-mobile-back",onClick:te,"aria-label":"Back to project files list",children:[e.jsx(fe,{size:14}),"Back to files"]}),i?e.jsxs("div",{className:"documents-content-viewer",children:[e.jsxs("div",{className:"documents-content-header",children:[e.jsx("p",{className:"documents-file-path-header",children:i.path}),e.jsx("button",{className:"btn btn-sm document-mode-toggle",onClick:()=>R(t=>!t),"aria-label":F?"Switch to plain text":"Switch to markdown","aria-pressed":F,title:F?"Switch to plain text":"Switch to markdown",children:F?"Markdown":"Plain"})]}),g?e.jsx("p",{className:"documents-content-state",children:"Loading file content…"}):j?e.jsx("p",{className:"documents-content-state documents-content-state--error",children:j}):F?e.jsx("div",{className:"documents-content-markdown",children:e.jsx("div",{className:"markdown-body",children:e.jsx(W,{remarkPlugins:[V],children:b??""})})}):e.jsx("pre",{className:"document-card-content-text documents-content-viewer-text",children:b??""})]}):e.jsx("div",{className:"documents-view-empty",children:e.jsx("p",{children:"Select a Markdown file to view its content."})})]})]}):D&&N.length===0?e.jsx("div",{className:"documents-view-loading",children:e.jsx("p",{children:"Loading task documents…"})}):A.length===0?e.jsx("div",{className:"documents-view-empty",children:l.trim()?e.jsxs("p",{children:['No task documents match "',l.trim(),'".']}):e.jsxs(e.Fragment,{children:[e.jsx(z,{size:48,className:"documents-view-empty-icon"}),e.jsx("p",{children:"No task documents yet."}),e.jsx("p",{className:"documents-view-empty-hint",children:"Documents are created in task detail tabs."})]})}):e.jsx("div",{className:"documents-task-list-wrap",children:e.jsx("div",{className:"documents-view-list",children:A.map(({taskId:t,taskTitle:r,documents:d})=>e.jsx(Se,{taskId:t,taskTitle:r,documents:d,onOpenTask:ee,renderMarkdownStates:M,onToggleMarkdown:ne},t))})})})]})}export{ye as DocumentsView};
|
|
1
|
+
import{r as s,j as e}from"./vendor-react-K0fH_qHe.js";import{f as oe,a as K,b as le,c as ie,F as z,E as de,d as ue,S as me,X as he,R as pe,A as fe,M as W,r as V,C as X,e as je,g as xe}from"./index-NFptaeUQ.js";import"./vendor-xterm-DzcZoU0P.js";function we(n){const{projectId:c,searchQuery:u,includeProjectFiles:a=!0}=n??{},[x,l]=s.useState([]),[h,i]=s.useState([]),[o,p]=s.useState(!0),[k,b]=s.useState(null),f=s.useRef(null),g=s.useRef(!1),m=s.useRef(null),j=s.useCallback(async()=>{f.current&&f.current.abort();const C=new AbortController;f.current=C;const E=!g.current;E&&p(!0),b(null);const L=oe(u?{q:u}:void 0,c),y=a?K(c):Promise.resolve({files:[]}),[v,F]=await Promise.allSettled([L,y]);if(C.signal.aborted)return;let R=null;if(v.status==="fulfilled"?(l(v.value),g.current=!0):R=v.reason instanceof Error?v.reason.message:String(v.reason),F.status==="fulfilled"){const M=F.value.files,P=u?.trim().toLowerCase(),T=P?M.filter(N=>N.name.toLowerCase().includes(P)||N.path.toLowerCase().includes(P)):M;i(T)}b(R),E&&p(!1)},[a,c,u]);return s.useEffect(()=>(m.current&&clearTimeout(m.current),m.current=setTimeout(()=>{j()},300),()=>{m.current&&clearTimeout(m.current)}),[j]),s.useEffect(()=>(j(),()=>{f.current&&f.current.abort()}),[]),{documents:x,projectFiles:h,loading:o,error:k,refresh:j}}function ke(n,c){const[u,a]=s.useState([]),[x,l]=s.useState(!0),[h,i]=s.useState(null),o=s.useRef(null),p=s.useRef(!1),k=c?.showHidden??!1,b=s.useCallback(async f=>{o.current&&o.current.abort();const g=new AbortController;o.current=g;const m=!p.current;m&&l(!0),i(null);try{const j=await K(n,{showHidden:f?.showHidden??k});if(g.signal.aborted)return;a(j.files),p.current=!0}catch(j){if(g.signal.aborted)return;i(j instanceof Error?j.message:String(j))}finally{!g.signal.aborted&&m&&l(!1)}},[n,k]);return s.useEffect(()=>(p.current=!1,b({showHidden:k}),()=>{o.current&&o.current.abort()}),[b,k]),{files:u,loading:x,error:h,refresh:b}}const be=768;function _(n){return n?new Date(n).toLocaleString():""}function ge(n){return n<1024?`${n} B`:n<1024*1024?`${(n/1024).toFixed(n>=10*1024?0:1)} KB`:`${(n/(1024*1024)).toFixed(1)} MB`}function ve(n,c=200){return n.length<=c?n:`${n.substring(0,c)}…`}function Ne({document:n,renderMarkdown:c,onToggleMarkdown:u}){const[a,x]=s.useState(!1),l=ve(n.content),h=n.content.length>200;return e.jsxs("div",{className:"document-card",children:[e.jsxs("div",{className:"document-card-header",children:[e.jsxs("div",{className:"document-card-key",children:[e.jsx(z,{size:14}),e.jsx("span",{className:"document-card-key-text",children:n.key}),e.jsxs("span",{className:"document-card-revision-badge",children:["v",n.revision]})]}),e.jsx("div",{className:"document-card-actions",children:e.jsx("button",{className:"btn btn-sm document-card-expand-btn",onClick:()=>x(i=>!i),title:a?"Collapse":"Expand","aria-label":a?"Collapse content":"Expand content",children:a?e.jsx(xe,{size:14}):e.jsx(X,{size:14})})})]}),e.jsxs("div",{className:"document-card-meta",children:[e.jsx("span",{className:"document-card-author",children:n.author}),e.jsx("span",{className:"document-card-separator",children:"·"}),e.jsx("span",{className:"document-card-date",children:_(n.updatedAt)})]}),e.jsxs("div",{className:`document-card-content${a?" document-card-content--expanded":""}`,children:[a?e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"document-card-content-header",children:e.jsx("button",{className:"btn btn-sm document-mode-toggle",onClick:u,"aria-label":c?"Switch to plain text":"Switch to markdown","aria-pressed":c,title:c?"Switch to plain text":"Switch to markdown",children:c?"Markdown":"Plain"})}),c?e.jsx("div",{className:"document-card-content-markdown",children:e.jsx("div",{className:"markdown-body",children:e.jsx(W,{remarkPlugins:[V],children:n.content})})}):e.jsx("pre",{className:"document-card-content-text",children:n.content})]}):e.jsx("p",{className:"document-card-preview",children:l}),h&&!a&&e.jsx("p",{className:"document-card-preview-truncated",children:"…"})]})]})}function Se({taskId:n,taskTitle:c,documents:u,onOpenTask:a,renderMarkdownStates:x,onToggleMarkdown:l}){const[h,i]=s.useState(!1);return e.jsxs("div",{className:"documents-group",children:[e.jsxs("div",{className:"documents-group-header",children:[e.jsxs("button",{className:"documents-group-toggle-btn",onClick:()=>i(o=>!o),"aria-expanded":h,"aria-label":`${h?"Collapse":"Expand"} documents for task ${n}`,children:[e.jsx("span",{className:"documents-group-toggle","aria-hidden":"true",children:h?e.jsx(X,{size:16}):e.jsx(je,{size:16})}),e.jsx("span",{className:"documents-group-task-id",children:n}),e.jsx("span",{className:"documents-group-task-title",children:c||"Untitled"})]}),e.jsxs("span",{className:"documents-group-count",children:[u.length," doc",u.length!==1?"s":""]}),e.jsx("button",{className:"documents-group-task-link",onClick:()=>a(n),"aria-label":`Open task ${n}: ${c||"Untitled"}`,children:"Open task"})]}),h&&e.jsx("div",{className:"documents-group-content",children:u.map(o=>e.jsx(Ne,{document:o,renderMarkdown:x.get(o.id)??!1,onToggleMarkdown:()=>l(o.id)},o.id))})]})}function ye({projectId:n,addToast:c,onOpenDetail:u}){const[a,x]=s.useState("project"),[l,h]=s.useState(""),[i,o]=s.useState(null),[p,k]=s.useState(!1),[b,f]=s.useState(null),[g,m]=s.useState(!1),[j,C]=s.useState(null),[E,L]=s.useState(!1),y=s.useRef(0),v=s.useRef(!1),[F,R]=s.useState(!1),[M,P]=s.useState(new Map),T=a==="tasks"?l.trim():"",{documents:N,loading:D,error:J,refresh:B}=we({projectId:n,searchQuery:T||void 0,includeProjectFiles:!1}),{files:S,loading:$,error:Y,refresh:O}=ke(n,{showHidden:p});s.useEffect(()=>{const t=()=>{L(window.innerWidth<=be)};return t(),window.addEventListener("resize",t),()=>{window.removeEventListener("resize",t)}},[]),s.useEffect(()=>{v.current=!1,x("project"),o(null),k(!1),f(null),C(null),m(!1),R(!1),P(new Map)},[n]),s.useEffect(()=>{v.current||D||$||(S.length>0?x("project"):N.length>0&&x("tasks"),v.current=!0)},[N.length,D,S.length,$]);const A=s.useMemo(()=>{const t=new Map;for(const r of N){const d=t.get(r.taskId)||[];t.set(r.taskId,[...d,r])}return Array.from(t.entries()).map(([r,d])=>{const w=[...d].sort((re,ce)=>ce.updatedAt.localeCompare(re.updatedAt));return{taskId:r,taskTitle:w[0]?.taskTitle,documents:w,latestUpdated:w[0]?.updatedAt??""}}).sort((r,d)=>d.latestUpdated.localeCompare(r.latestUpdated))},[N]),H=s.useMemo(()=>{const t=l.trim().toLowerCase();return t?S.filter(r=>{const d=r.path.toLowerCase(),w=r.name.toLowerCase();return d.includes(t)||w.includes(t)}):S},[S,l]);s.useEffect(()=>{if(!i)return;S.some(r=>r.path===i.path)||(o(null),f(null),C(null),m(!1))},[S,i]);const Z=s.useCallback(t=>{h(t.target.value)},[]),I=s.useCallback(()=>{h("")},[]),Q=s.useCallback(t=>{x(t)},[]),ee=s.useCallback(async t=>{try{const r=await le(t,n);u(r)}catch{c(`Failed to open task ${t}`,"error")}},[n,u,c]),se=s.useCallback(async t=>{o(t),m(!0),C(null),f(null);const r=y.current+1;y.current=r;try{const d=await ie("project",t.path,n);if(y.current!==r)return;f(d.content)}catch(d){if(y.current!==r)return;const w=d instanceof Error?d.message:`Failed to open ${t.path}`;C(w),c(w,"error")}finally{y.current===r&&m(!1)}},[n,c]),te=s.useCallback(()=>{o(null),f(null),C(null),m(!1)},[]),ne=s.useCallback(t=>{P(r=>{const d=new Map(r),w=d.get(t)??!1;return d.set(t,!w),d})},[]),U=a==="project"?Y:J,ae=s.useCallback(async()=>{if(a==="project"){await O();return}await B()},[a,O,B]),q=a==="project"?H.length:N.length,G=a==="project"?"Search project markdown files…":"Search task documents…";return e.jsxs("div",{className:"documents-view",children:[e.jsxs("div",{className:"documents-view-header",children:[e.jsxs("div",{className:"documents-view-title-row",children:[e.jsxs("h2",{className:"documents-view-title",children:[e.jsx(z,{size:20}),"Documents"]}),e.jsxs("span",{className:"documents-view-count",children:[q," result",q!==1?"s":""]})]}),e.jsxs("div",{className:"documents-controls-row",children:[e.jsxs("div",{className:"documents-tab-bar",role:"tablist","aria-label":"Documents sections",children:[e.jsxs("button",{className:`btn documents-tab${a==="project"?" active":""}`,role:"tab","aria-selected":a==="project","aria-label":"Show project markdown files",onClick:()=>Q("project"),children:["Project Files",e.jsx("span",{className:"documents-tab-count",children:S.length})]}),e.jsxs("button",{className:`btn documents-tab${a==="tasks"?" active":""}`,role:"tab","aria-selected":a==="tasks","aria-label":"Show task documents",onClick:()=>Q("tasks"),children:["Task Documents",e.jsx("span",{className:"documents-tab-count",children:A.length})]})]}),a==="project"&&e.jsxs("button",{className:"btn btn-sm documents-hidden-toggle",onClick:()=>k(t=>!t),"aria-pressed":p,"aria-label":p?"Hide hidden project files":"Show hidden project files",title:p?"Hide hidden files":"Show hidden files",children:[p?e.jsx(de,{size:14}):e.jsx(ue,{size:14}),p?"Hide Hidden":"Show Hidden"]}),e.jsxs("div",{className:"documents-search",children:[e.jsx(me,{size:16,className:"documents-search-icon"}),e.jsx("input",{type:"text",className:"documents-search-input",placeholder:G,value:l,onChange:Z,"aria-label":G}),l&&e.jsx("button",{className:"documents-search-clear",onClick:I,"aria-label":"Clear search",children:e.jsx(he,{size:16})})]})]})]}),e.jsx("div",{className:"documents-view-content",children:U?e.jsxs("div",{className:"documents-view-error",children:[e.jsxs("p",{children:["Failed to load ",a==="project"?"project files":"task documents",": ",U]}),e.jsxs("button",{className:"btn btn-primary",onClick:()=>void ae(),"aria-label":"Retry loading documents",children:[e.jsx(pe,{size:16}),"Retry"]})]}):a==="project"?$&&S.length===0?e.jsx("div",{className:"documents-view-loading",children:e.jsx("p",{children:"Loading project markdown files…"})}):H.length===0?e.jsx("div",{className:"documents-view-empty",children:l.trim()?e.jsxs("p",{children:['No project markdown files match "',l.trim(),'".']}):e.jsxs(e.Fragment,{children:[e.jsx(z,{size:48,className:"documents-view-empty-icon"}),e.jsx("p",{children:"No Markdown files found in this project."})]})}):e.jsxs("div",{className:`documents-project-layout${E?" documents-project-layout--mobile":""}`,children:[(!E||!i)&&e.jsx("aside",{className:"documents-view-sidebar","aria-label":"Project markdown files",children:e.jsx("ul",{className:"markdown-file-list",children:H.map(t=>{const r=i?.path===t.path;return e.jsx("li",{className:"markdown-file-list-item",children:e.jsxs("button",{className:`markdown-file-item${r?" markdown-file-item--selected":""}`,onClick:()=>void se(t),"aria-label":`Open ${t.path}`,"aria-current":r?"true":void 0,children:[e.jsx("span",{className:"markdown-file-item-name",children:t.name}),e.jsx("span",{className:"markdown-file-item-path",children:t.path}),e.jsxs("span",{className:"markdown-file-item-meta",children:[ge(t.size)," · ",_(t.mtime)]})]})},t.path)})})}),(!E||i)&&e.jsxs("section",{className:"documents-view-main","aria-label":"Project file content preview",children:[E&&i&&e.jsxs("button",{className:"btn btn-sm documents-mobile-back",onClick:te,"aria-label":"Back to project files list",children:[e.jsx(fe,{size:14}),"Back to files"]}),i?e.jsxs("div",{className:"documents-content-viewer",children:[e.jsxs("div",{className:"documents-content-header",children:[e.jsx("p",{className:"documents-file-path-header",children:i.path}),e.jsx("button",{className:"btn btn-sm document-mode-toggle",onClick:()=>R(t=>!t),"aria-label":F?"Switch to plain text":"Switch to markdown","aria-pressed":F,title:F?"Switch to plain text":"Switch to markdown",children:F?"Markdown":"Plain"})]}),g?e.jsx("p",{className:"documents-content-state",children:"Loading file content…"}):j?e.jsx("p",{className:"documents-content-state documents-content-state--error",children:j}):F?e.jsx("div",{className:"documents-content-markdown",children:e.jsx("div",{className:"markdown-body",children:e.jsx(W,{remarkPlugins:[V],children:b??""})})}):e.jsx("pre",{className:"document-card-content-text documents-content-viewer-text",children:b??""})]}):e.jsx("div",{className:"documents-view-empty",children:e.jsx("p",{children:"Select a Markdown file to view its content."})})]})]}):D&&N.length===0?e.jsx("div",{className:"documents-view-loading",children:e.jsx("p",{children:"Loading task documents…"})}):A.length===0?e.jsx("div",{className:"documents-view-empty",children:l.trim()?e.jsxs("p",{children:['No task documents match "',l.trim(),'".']}):e.jsxs(e.Fragment,{children:[e.jsx(z,{size:48,className:"documents-view-empty-icon"}),e.jsx("p",{children:"No task documents yet."}),e.jsx("p",{className:"documents-view-empty-hint",children:"Documents are created in task detail tabs."})]})}):e.jsx("div",{className:"documents-task-list-wrap",children:e.jsx("div",{className:"documents-view-list",children:A.map(({taskId:t,taskTitle:r,documents:d})=>e.jsx(Se,{taskId:t,taskTitle:r,documents:d,onOpenTask:ee,renderMarkdownStates:M,onToggleMarkdown:ne},t))})})})]})}export{ye as DocumentsView};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{r,j as s}from"./vendor-react-K0fH_qHe.js";import{h as os,i as vs,j as xs,t as fs,k as ps,l as ys,m as is,u as ws,n as y,X as ns,o as J,R as w,p as hs,q as Q,T as as,L as bs,P as us,s as js,v as ds,w as ks}from"./index-
|
|
1
|
+
import{r,j as s}from"./vendor-react-K0fH_qHe.js";import{h as os,i as vs,j as xs,t as fs,k as ps,l as ys,m as is,u as ws,n as y,X as ns,o as J,R as w,p as hs,q as Q,T as as,L as bs,P as us,s as js,v as ds,w as ks}from"./index-NFptaeUQ.js";import{U as rs}from"./users-Bu_ltePs.js";import"./vendor-xterm-DzcZoU0P.js";/**
|
|
2
2
|
* @license lucide-react v1.7.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|