@runfusion/fusion 0.8.2 → 0.8.4

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.
Files changed (48) hide show
  1. package/dist/bin.js +1714 -840
  2. package/dist/client/assets/{AgentDetailView-B6wfIQ9j.js → AgentDetailView-C_DD03d6.js} +1 -1
  3. package/dist/client/assets/{AgentsView-Fcym0XCw.js → AgentsView-CsEX_Fsi.js} +3 -3
  4. package/dist/client/assets/ChatView-DhudD-jT.js +1 -0
  5. package/dist/client/assets/{DevServerView-CmMS4D6V.js → DevServerView-CNItMoga.js} +1 -1
  6. package/dist/client/assets/DirectoryPicker-BqcVbDZX.js +1 -0
  7. package/dist/client/assets/{DocumentsView-C4HDkN_0.js → DocumentsView-zpHkjZdf.js} +1 -1
  8. package/dist/client/assets/{InsightsView-Egu71gmh.css → InsightsView-6LHF7OdE.css} +1 -1
  9. package/dist/client/assets/InsightsView-CgguV1au.js +11 -0
  10. package/dist/client/assets/{MemoryView-DPYGW09y.js → MemoryView-BWXP8uGT.js} +1 -1
  11. package/dist/client/assets/{NodesView-DsM-c8RF.js → NodesView-DP_O4ae0.js} +1 -1
  12. package/dist/client/assets/{PiExtensionsManager-DHgMjjRE.js → PiExtensionsManager-DGEPbF0y.js} +3 -3
  13. package/dist/client/assets/{PluginManager-N-7Sw_tE.js → PluginManager-4TehPpcf.js} +1 -1
  14. package/dist/client/assets/{RoadmapsView-BgX79uYM.js → RoadmapsView-DNaToPqN.js} +2 -2
  15. package/dist/client/assets/SettingsModal-BluRnKGd.js +31 -0
  16. package/dist/client/assets/{SettingsModal-BIKEMPwb.js → SettingsModal-C-RjolQ5.js} +1 -1
  17. package/dist/client/assets/SettingsModal-C7gPLBaR.css +1 -0
  18. package/dist/client/assets/{SetupWizardModal-D2m0i9Io.js → SetupWizardModal-BQoo_AvX.js} +1 -1
  19. package/dist/client/assets/{SkillsView-Eb1Mngnt.js → SkillsView-AS8Cr_Md.js} +1 -1
  20. package/dist/client/assets/{TodoView-BN8FQYyp.js → TodoView-nWOpOg3R.js} +2 -2
  21. package/dist/client/assets/{folder-open-BqZBHfoZ.js → folder-open-D0LfE0ZP.js} +1 -1
  22. package/dist/client/assets/index-D6xr8Oa2.css +1 -0
  23. package/dist/client/assets/index-heCcln3Z.js +656 -0
  24. package/dist/client/assets/{list-checks-D2EURsP0.js → list-checks-D1faMe1o.js} +1 -1
  25. package/dist/client/assets/{star-CNQlAD8p.js → star-B_uA5YGG.js} +1 -1
  26. package/dist/client/assets/{upload-uoxlYkig.js → upload-DPQ3hWf0.js} +1 -1
  27. package/dist/client/assets/{users-BLvidusm.js → users-CEcYlrZO.js} +1 -1
  28. package/dist/client/index.html +2 -2
  29. package/dist/client/version.json +1 -1
  30. package/dist/extension.js +1033 -372
  31. package/dist/pi-claude-cli/package.json +1 -1
  32. package/dist/pi-claude-cli/src/__tests__/control-handler.test.ts +39 -66
  33. package/dist/pi-claude-cli/src/__tests__/process-manager.test.ts +7 -9
  34. package/dist/pi-claude-cli/src/__tests__/provider.test.ts +73 -148
  35. package/dist/pi-claude-cli/src/__tests__/setup-test-isolation.test.ts +2 -0
  36. package/dist/pi-claude-cli/src/__tests__/setup-test-isolation.ts +8 -0
  37. package/dist/pi-claude-cli/src/control-handler.ts +22 -8
  38. package/dist/pi-claude-cli/src/process-manager.ts +10 -3
  39. package/dist/pi-claude-cli/src/prompt-builder.ts +2 -1
  40. package/dist/pi-claude-cli/src/provider.ts +10 -2
  41. package/package.json +1 -1
  42. package/dist/client/assets/ChatView-DEckS3f3.js +0 -1
  43. package/dist/client/assets/DirectoryPicker-CQtE-YyA.js +0 -1
  44. package/dist/client/assets/InsightsView-oNQ7h5e8.js +0 -11
  45. package/dist/client/assets/SettingsModal-C4EwtN6K.js +0 -31
  46. package/dist/client/assets/SettingsModal-D5hLoLXp.css +0 -1
  47. package/dist/client/assets/index-D2fXOwWF.css +0 -1
  48. package/dist/client/assets/index-DlHPhpDu.js +0 -656
@@ -42,7 +42,6 @@ import {
42
42
  } from "./process-manager.js";
43
43
  import { parseLine } from "./stream-parser.js";
44
44
  import { createEventBridge } from "./event-bridge.js";
45
- import { handleControlRequest } from "./control-handler.js";
46
45
  import { mapThinkingEffort } from "./thinking-config.js";
47
46
  import { isPiKnownClaudeTool } from "./tool-mapping.js";
48
47
  /**
@@ -161,6 +160,7 @@ export function streamViaCli(
161
160
 
162
161
  // Write user message to subprocess stdin
163
162
  writeUserMessage(proc, prompt);
163
+ debugLog("user message written to stdin, stdin.end() called");
164
164
 
165
165
  // Create event bridge (before endStreamWithError so bridge is in scope)
166
166
  const bridge = createEventBridge(stream, model);
@@ -227,6 +227,7 @@ export function streamViaCli(
227
227
 
228
228
  // Track tool_use blocks for break-early decision at message_stop
229
229
  let sawBuiltInOrCustomTool = false;
230
+ let firstLineReceived = false;
230
231
  // Guard against buffered readline lines firing after rl.close()
231
232
  let broken = false;
232
233
 
@@ -247,6 +248,7 @@ export function streamViaCli(
247
248
  // Handle subprocess close -- surface crashes with stderr and exit code
248
249
  proc.on("close", (code: number | null, _signal: string | null) => {
249
250
  clearTimeout(inactivityTimer);
251
+ debugLog(`subprocess closed: code=${code} signal=${_signal}`);
250
252
  if (broken) return; // Break-early kill, expected
251
253
  const stderr = getStderr().trim();
252
254
  if (stderr) {
@@ -267,6 +269,10 @@ export function streamViaCli(
267
269
  // NOTE: Using 'line' event instead of `for await` because the async
268
270
  // iterator batches lines, breaking real-time streaming to pi.
269
271
  rl.on("line", (line: string) => {
272
+ if (!firstLineReceived) {
273
+ firstLineReceived = true;
274
+ debugLog("first stdout line received from Claude CLI");
275
+ }
270
276
  if (broken) return; // Guard: ignore buffered lines after break-early
271
277
 
272
278
  // Reset inactivity timer on each line of output
@@ -319,7 +325,9 @@ export function streamViaCli(
319
325
  return; // Don't process further -- done event already pushed by event bridge
320
326
  }
321
327
  } else if (msg.type === "control_request") {
322
- handleControlRequest(msg, proc!.stdin!);
328
+ debugLog(
329
+ `unexpected control_request received (stdin already closed): ${msg.request_id}`,
330
+ );
323
331
  } else if (msg.type === "result") {
324
332
  if (msg.subtype === "error") {
325
333
  endStreamWithError(msg.error ?? "Unknown error from Claude CLI");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@runfusion/fusion",
3
- "version": "0.8.2",
3
+ "version": "0.8.4",
4
4
  "license": "MIT",
5
5
  "description": "Fusion CLI: HTTP API server, daemon, dashboard launcher, and task tooling for the Fusion AI coding agent.",
6
6
  "homepage": "https://github.com/Runfusion/Fusion#readme",
@@ -1 +0,0 @@
1
- import{r as s,j as e}from"./vendor-react-K0fH_qHe.js";import{i as ze,ay as gt,g as ft,az as pt,a as xt,aA as St,aB as bt,aC as vt,aD as wt,aE as kt,aF as Nt,s as Ct,aG as Mt,aH as jt,aI as yt,f as Tt,a7 as At,a8 as $t,y as Le,S as Et,M as Ke,ak as Pt,aJ as Dt,B as je,a4 as Ue,a5 as qe,aK as Rt,aL as Lt,aM as _t,aN as zt,aO as It,aP as Ft,h as Ot,k as Ht}from"./index-DlHPhpDu.js";import"./vendor-xterm-DzcZoU0P.js";const _e="kb-chat-active-session";function Vt(n){const i=n?.toolCalls;if(!Array.isArray(i))return;const c=i.map(l=>{if(!l||typeof l!="object")return null;const r=l,f=typeof r.toolName=="string"?r.toolName:"";if(!f)return null;const v=r.args;return{toolName:f,...v&&typeof v=="object"?{args:v}:{},isError:!!r.isError,result:r.result,status:"completed"}}).filter(l=>l!==null);return c.length>0?c:void 0}function Je(n){return{id:n.id,sessionId:n.sessionId,role:n.role,content:n.content,thinkingOutput:n.thinkingOutput,toolCalls:Vt(n.metadata),createdAt:n.createdAt}}function Bt(n){const[i,c]=s.useState([]),[l,r]=s.useState(null),[f,v]=s.useState(!0),[j,w]=s.useState([]),[X,I]=s.useState(!1),[F,L]=s.useState(!1),[oe,E]=s.useState(""),[O,T]=s.useState(""),[pe,P]=s.useState([]),[p,D]=s.useState(""),[Z,K]=s.useState(""),[A,H]=s.useState(!0),[U,ne]=s.useState(new Map),N=s.useRef(null),q=s.useRef(!1),J=s.useRef(""),xe=s.useRef(i),V=s.useRef(l),ke=s.useRef(F);xe.current=i,V.current=l,ke.current=F,s.useEffect(()=>{J.current=p},[p]);const ae=s.useRef(new Set),ee=s.useRef(0),Ne=s.useRef(n);Ne.current!==n&&(Ne.current=n,ee.current++),s.useEffect(()=>{const u=ee.current;ze(void 0,n).then(m=>{if(ee.current!==u)return;const h=new Map;for(const k of m)h.set(k.id,k);ne(h)}).catch(()=>{})},[n]);const te=s.useCallback(async()=>{v(!0);try{const m=[...(await gt(n)).sessions].sort((h,k)=>new Date(k.updatedAt).getTime()-new Date(h.updatedAt).getTime());c(m)}catch{}finally{v(!1)}},[n]);s.useEffect(()=>{te()},[te]);const Q=s.useRef(()=>{});s.useEffect(()=>{if(f)return;const u=ft(_e,n);u&&i.find(h=>h.id===u)&&Q.current(u)},[f,i,n]);const _=s.useCallback(async(u,m)=>{I(!0);try{const h=await pt(u,{limit:50,...m},n),k=h.messages.map(Je);m?.offset&&m.offset>0?w(W=>[...k,...W]):w(k),H(h.messages.length>=50)}catch{}finally{I(!1)}},[n]),de=s.useCallback(u=>{N.current&&(N.current.close(),N.current=null);const m=i.find(h=>h.id===u);r(m||null),E(""),T(""),P([]),L(!1),H(!0),u?_(u):w([]),u?xt(_e,u,n):St(_e,n)},[i,_,n]);Q.current=de;const ue=s.useCallback(async u=>{const m=await bt(u,n),h={id:m.session.id,title:m.session.title,agentId:m.session.agentId,status:m.session.status,modelProvider:m.session.modelProvider,modelId:m.session.modelId,createdAt:m.session.createdAt,updatedAt:m.session.updatedAt};return c(k=>[h,...k]),r(h),w([]),E(""),T(""),P([]),L(!1),H(!0),h},[n]),he=s.useCallback(async u=>{await vt(u,{status:"archived"},n),c(m=>m.filter(h=>h.id!==u)),l?.id===u&&(r(null),w([]))},[l,n]),ie=s.useCallback(async u=>{l?.id===u&&N.current&&(N.current.close(),N.current=null),await wt(u,n),c(m=>m.filter(h=>h.id!==u)),l?.id===u&&(r(null),w([]))},[l,n]),me=s.useCallback(async()=>{!l||!A||await _(l.id,{offset:j.length})},[l,A,_,j.length]),se=s.useCallback(()=>{l&&(q.current=!0,N.current?.close(),N.current=null,kt(l.id,n).catch(()=>{}),L(!1),E(""),T(""),P([]))},[l,n]),B=s.useCallback(()=>{J.current="",D("")},[]),G=s.useCallback(u=>{if(!l)return;if(F){J.current=u,D(u);return}q.current=!1,N.current&&(N.current.close(),N.current=null);const m=`temp-${Date.now()}`,h={id:m,sessionId:l.id,role:"user",content:u,createdAt:new Date().toISOString()};w(x=>[...x,h]),E(""),T(""),P([]),L(!0);let k="",W="",M=[];const be={onThinking:x=>{W+=x,T(W)},onText:x=>{k+=x,E(k)},onToolStart:x=>{M=[...M,{toolName:x.toolName,args:x.args,isError:!1,status:"running"}],P(M)},onToolEnd:x=>{const d=[...M];for(let S=d.length-1;S>=0;S--){const b=d[S];if(b?.toolName===x.toolName&&b.status==="running"){d[S]={...b,status:"completed",isError:x.isError,result:x.result},M=d,P(d);return}}M=[...d,{toolName:x.toolName,isError:x.isError,result:x.result,status:"completed"}],P(M)},onDone:x=>{const d={id:x.messageId||`msg-${Date.now()}`,sessionId:l.id,role:"assistant",content:k,thinkingOutput:W,toolCalls:M.length>0?M:void 0,createdAt:new Date().toISOString()};ae.current.add(d.id),w(b=>[...b,d]),E(""),T(""),P([]),L(!1),N.current=null,setTimeout(()=>{ae.current.delete(d.id)},1e3),te();const S=J.current.trim();S&&(J.current="",D(""),G(S))},onError:x=>{if(w(d=>d.filter(S=>S.id!==m)),E(""),T(""),P([]),L(!1),N.current=null,console.error("[useChat] Stream error:",x),!q.current){const d=J.current.trim();d&&(J.current="",D(""),G(d))}}};N.current=Nt(l.id,u,be,n)},[l,F,n,te]),Se=Z?i.filter(u=>u.title?.toLowerCase().includes(Z.toLowerCase())||u.agentId.toLowerCase().includes(Z.toLowerCase())):i;return s.useEffect(()=>{const u=ee.current,m=n?`?projectId=${encodeURIComponent(n)}`:"",h=()=>ee.current!==u,k=S=>{if(h())return;const b=JSON.parse(S.data);c(g=>g.some(R=>R.id===b.id)?g:[b,...g])},W=S=>{if(h())return;const b=JSON.parse(S.data);c(g=>[...g.map(C=>C.id===b.id?b:C)]),V.current?.id===b.id&&r(b)},M=S=>{if(h())return;const{id:b}=JSON.parse(S.data);c(g=>g.filter(R=>R.id!==b)),V.current?.id===b&&(r(null),w([]))},be=S=>{if(h())return;const b=JSON.parse(S.data),g=Je(b);ae.current.has(g.id)||V.current?.id===g.sessionId&&!ke.current&&w(R=>R.some(C=>C.id===g.id)?R:[...R,g])},x=S=>{if(h())return;const{id:b}=JSON.parse(S.data);w(g=>g.filter(R=>R.id!==b))};return Ct(`/api/events${m}`,{events:{"chat:session:created":k,"chat:session:updated":W,"chat:session:deleted":M,"chat:message:added":be,"chat:message:deleted":x}})},[n]),s.useEffect(()=>()=>{N.current&&(N.current.close(),N.current=null)},[]),{sessions:i,activeSession:l,sessionsLoading:f,messages:j,messagesLoading:X,isStreaming:F,streamingText:oe,streamingThinking:O,streamingToolCalls:pe,pendingMessage:p,selectSession:de,createSession:ue,archiveSession:he,deleteSession:ie,sendMessage:G,stopStreaming:se,clearPendingMessage:B,loadMoreMessages:me,hasMoreMessages:A,searchQuery:Z,setSearchQuery:K,filteredSessions:Se,refreshSessions:te,agentsMap:U}}function Qe(n){const i=new Date(n),l=new Date().getTime()-i.getTime(),r=Math.floor(l/1e3),f=Math.floor(r/60),v=Math.floor(f/60),j=Math.floor(v/24);return r<60?"just now":f<60?`${f}m ago`:v<24?`${v}h ago`:j<7?`${j}d ago`:i.toLocaleDateString()}function We(n,i){if(!n||!i)return null;const c=i.toLowerCase();if(c.includes("claude")){let r=i.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 r=r.replace(/\s+/g," "),r.length>30?r.slice(0,30)+"…":r}if(c.includes("gpt")||c.includes("openai")){const r=i.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 r.length>30?r.slice(0,30)+"…":r}if(c.includes("gemini")){const r=i.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 r.length>30?r.slice(0,30)+"…":r}const l=i.replace(/-/g," ").replace(/^\w/,r=>r.toUpperCase()).replace(/\s+/g," ").trim();return l.length>30?l.slice(0,30)+"…":l}function ye(n,i){return n.length>i?`${n.slice(0,i)}…`:n}function Gt(n){if(!n)return null;const i=Object.entries(n);return i.length===0?null:i.map(([c,l])=>{let r="";if(typeof l=="string")r=l;else try{r=JSON.stringify(l)}catch{r=String(l)}return`${c}=${ye(r,50)}`}).join(", ")}function Kt(n){if(n===void 0)return null;if(typeof n=="string")return ye(n,200);try{return ye(JSON.stringify(n),200)}catch{return ye(String(n),200)}}function Ye(n){return!n||n.length===0?null:e.jsxs("div",{className:"chat-tool-calls","data-testid":"chat-tool-calls",children:[e.jsxs("div",{className:"chat-tool-calls-header",children:[e.jsx(Ft,{size:12,"aria-hidden":"true"}),e.jsx("span",{children:"Tool calls"})]}),n.map((i,c)=>{const l=i.status==="running",r=i.status==="completed"&&i.isError,f=Gt(i.args),v=Kt(i.result),j=l?f:v?`result: ${v}`:f?`args: ${f}`:null,w=l?"running":r?"error":"completed";return e.jsxs("details",{className:`chat-tool-call${l?" chat-tool-call--running":""}${r?" chat-tool-call--error":""}`,open:l,children:[e.jsxs("summary",{children:[e.jsx("span",{className:"chat-tool-call-status-dot","aria-hidden":"true"}),e.jsx("span",{className:"chat-tool-call-name",children:i.toolName}),j&&e.jsx("span",{className:"chat-tool-call-preview",title:j,children:j}),e.jsx("span",{className:"chat-tool-call-status-text",children:w})]}),e.jsxs("div",{className:"chat-tool-call-content",children:[f&&e.jsxs("div",{className:"chat-tool-call-row",children:[e.jsx("span",{className:"chat-tool-call-label",children:"args"}),e.jsx("span",{className:"chat-tool-call-value",children:f})]}),v&&e.jsxs("div",{className:`chat-tool-call-row${r?" chat-tool-call-row--error":""}`,children:[e.jsx("span",{className:"chat-tool-call-label",children:"result"}),e.jsx("span",{className:"chat-tool-call-value",children:v})]})]})]},`${i.toolName}-${c}`)})]})}const Ut={pre:({children:n,...i})=>e.jsx("pre",{...i,className:"chat-markdown-pre",children:n}),table:({children:n,...i})=>e.jsx("table",{...i,className:"chat-markdown-table",children:n})},Te="__fn_agent__";function Xe(n){const i=/(^|[\s])\/([^\s]*)$/.exec(n);if(!i)return null;const c=i[1]??"",l=i[2]??"",r=i.index+c.length;return{filter:l,start:r,end:n.length}}function qt(n,i){const c=n.slice(0,i),l=/(^|[\s\n])@([\w-]*)$/.exec(c);if(!l)return null;const r=l[2]??"",f=c.length-r.length-1;return{filter:r,start:f,end:i}}function Jt({projectId:n,onClose:i,onCreate:c}){const[l,r]=s.useState("agent"),[f,v]=s.useState([]),[j,w]=s.useState(!0),[X,I]=s.useState(""),[F,L]=s.useState([]),[oe,E]=s.useState(!0),[O,T]=s.useState("");s.useEffect(()=>{let p=!1;return w(!0),ze(void 0,n).then(D=>{p||v(D)}).catch(()=>{p||v([])}).finally(()=>{p||w(!1)}),()=>{p=!0}},[n]),s.useEffect(()=>{E(!0),Ot().then(p=>{L(p.models)}).catch(()=>{L([])}).finally(()=>{E(!1)})},[]);const pe=p=>{if(p.preventDefault(),l==="agent"){if(!X)return;c({agentId:X});return}if(!O)return;const D=O.indexOf("/");if(D<=0)return;const Z=O.slice(0,D),K=O.slice(D+1);c({agentId:Te,modelProvider:Z,modelId:K})},P=l==="agent"?!X:!O;return e.jsx("div",{className:"chat-new-dialog-backdrop",onClick:i,role:"dialog","aria-modal":"true",children:e.jsxs("div",{className:"chat-new-dialog",onClick:p=>p.stopPropagation(),children:[e.jsx("h3",{children:"New Chat"}),e.jsxs("div",{className:"chat-new-dialog-mode-toggle","data-testid":"chat-new-dialog-mode-toggle",children:[e.jsx("button",{type:"button",className:`chat-new-dialog-mode-btn${l==="agent"?" chat-new-dialog-mode-btn--active":""}`,"data-testid":"chat-new-dialog-mode-agent",onClick:()=>{r("agent"),T("")},children:"Agent"}),e.jsx("button",{type:"button",className:`chat-new-dialog-mode-btn${l==="model"?" chat-new-dialog-mode-btn--active":""}`,"data-testid":"chat-new-dialog-mode-model",onClick:()=>{r("model"),I("")},children:"Model"})]}),e.jsxs("form",{onSubmit:pe,children:[l==="agent"&&e.jsxs("label",{className:"chat-new-dialog-model-label",children:["Agent",j?e.jsx("div",{className:"chat-new-dialog-loading",children:"Loading agents..."}):f.length===0?e.jsx("div",{className:"chat-new-dialog-empty",children:"No agents available"}):e.jsx("div",{className:"chat-new-dialog-agent-list",children:f.map(p=>e.jsxs("button",{type:"button",className:`chat-new-dialog-agent-item${X===p.id?" chat-new-dialog-agent-item--selected":""}`,onClick:()=>I(p.id),"data-testid":`agent-option-${p.id}`,children:[e.jsx(je,{size:16}),e.jsx("span",{className:"chat-new-dialog-agent-name",children:p.name}),e.jsx("span",{className:"chat-new-dialog-agent-role",children:p.role})]},p.id))})]}),l==="model"&&e.jsx("div",{className:"chat-new-dialog-model-dropdown","data-testid":"chat-new-dialog-model-section",children:oe?e.jsx("div",{className:"chat-new-dialog-loading",children:"Loading models..."}):e.jsx(Ht,{models:F,value:O,onChange:T,label:"Model",placeholder:"Select a model"})}),e.jsxs("div",{className:"chat-new-dialog-actions",children:[e.jsx("button",{type:"button",className:"btn btn-sm",onClick:i,children:"Cancel"}),e.jsx("button",{type:"submit",className:"btn btn-sm btn-primary",disabled:P,children:"Create"})]})]})]})})}function Zt({projectId:n,addToast:i}){const{activeSession:c,sessionsLoading:l,messages:r,messagesLoading:f,isStreaming:v,streamingText:j,streamingThinking:w,streamingToolCalls:X,selectSession:I,createSession:F,archiveSession:L,deleteSession:oe,sendMessage:E,stopStreaming:O,pendingMessage:T,clearPendingMessage:pe,searchQuery:P,setSearchQuery:p,filteredSessions:D}=Bt(n),[Z,K]=s.useState(!1),[A,H]=s.useState(""),[U,ne]=s.useState(null),[N,q]=s.useState(null),[J,xe]=s.useState(!0),[V,ke]=s.useState(new Map),[ae,ee]=s.useState([]),[Ne,te]=s.useState(!0),[Q,_]=s.useState(!1),[de,ue]=s.useState(""),[he,ie]=s.useState(0),[me,se]=s.useState(""),[B,G]=s.useState(!1),[Se,u]=s.useState(0),[m,h]=s.useState(-1),[k,W]=s.useState(()=>new Set),[,M]=s.useState(!1),[be,x]=s.useState({top:0,left:0}),d=Mt({projectId:n}),S=s.useCallback(t=>{if(!t||!d.mentionActive)return;const a=t.getBoundingClientRect();x({top:a.top-260,left:a.left+8})},[d.mentionActive]),b=s.useRef(null),g=s.useRef(null),R=s.useRef(null),C=s.useRef(null),ve=s.useRef(0),le=jt()==="mobile",{keyboardOverlap:Ce,viewportHeight:Ie}=yt({enabled:le&&!!c}),Ze=Ce>0?{"--keyboard-overlap":`${Ce}px`,...Ie!==null?{"--vv-height":`${Ie}px`}:{}}:{},z=s.useMemo(()=>{const t=de.trim().toLowerCase();return(t?ae.filter(o=>o.name.toLowerCase().includes(t)):ae).slice(0,10)},[ae,de]),ge=s.useMemo(()=>Array.from(V.values()),[V]),re=s.useMemo(()=>{const t=me.trim().toLowerCase();return t?ge.filter(a=>a.name.toLowerCase().includes(t)):ge},[ge,me]),Fe=s.useMemo(()=>{const t=new Map;for(const a of ge)t.set(a.name.toLowerCase(),a);return t},[ge]);s.useEffect(()=>{ie(0)},[z]),s.useEffect(()=>{u(0)},[me,B]),s.useEffect(()=>()=>{g.current!==null&&window.clearTimeout(g.current)},[]),s.useEffect(()=>{b.current?.scrollIntoView({behavior:"smooth"})},[r,j]),s.useEffect(()=>{if(Ce<=0)return;const t=R.current;t&&(t.scrollTop=t.scrollHeight)},[Ce]),s.useEffect(()=>{const t=()=>ne(null);if(U)return document.addEventListener("click",t),()=>document.removeEventListener("click",t)},[U]),s.useEffect(()=>{let t=!1;const a=n;return ze(void 0,n).then(o=>{if(t||a!==n)return;const y=new Map;for(const $ of o)y.set($.id,$);ke(y)}).catch(()=>{}),()=>{t=!0}},[n]),s.useEffect(()=>{let t=!1;return te(!0),Tt(n).then(a=>{t||ee(a)}).catch(()=>{t||ee([])}).finally(()=>{t||te(!1)}),()=>{t=!0}},[n]);const et=s.useCallback(async t=>{try{await F(t),K(!1),le&&xe(!1)}catch{i("Failed to create chat session","error")}},[F,i,le]),Ae=s.useCallback(()=>{const t=A.trim();!t||!c||(H(""),_(!1),ue(""),G(!1),se(""),h(-1),E(t))},[A,c,E]),$e=s.useCallback(t=>{H(a=>{const o=Xe(a);if(!o)return a;const y=`/skill:${t.name} `,$=a.slice(0,o.start)+y+a.slice(o.end);return window.requestAnimationFrame(()=>{C.current&&(C.current.style.height="auto",C.current.style.height=`${Math.min(C.current.scrollHeight,120)}px`,C.current.focus())}),$}),_(!1),ue(""),ie(0)},[]),Ee=s.useCallback(t=>{const a=C.current;if(!a||m<0)return;const o=a.selectionStart??ve.current,y=a.selectionEnd??o,$=Math.max(o,y),we=Math.min(m,$),ce=`${`@${t.name.replace(/\s+/g,"_")}`} `,Re=A.slice(0,we)+ce+A.slice($),fe=we+ce.length;H(Re),G(!1),se(""),u(0),h(-1),window.requestAnimationFrame(()=>{C.current&&(C.current.style.height="auto",C.current.style.height=`${Math.min(C.current.scrollHeight,120)}px`,C.current.focus(),C.current.setSelectionRange(fe,fe))})},[m,A]),tt=s.useCallback(t=>{const a=/@([\w-]+)/g,o=[];let y=0,$=a.exec(t);for(;$;){const[we,Ge=""]=$,ce=$.index;ce>y&&o.push(t.slice(y,ce));const Re=Ge.replace(/_/g," ").toLowerCase(),fe=Fe.get(Re);fe?o.push(e.jsxs("span",{className:"chat-mention-chip",children:["@",fe.name.replace(/\s+/g,"_")]},`${fe.id}-${ce}`)):o.push(we),y=ce+we.length,$=a.exec(t)}return y<t.length&&o.push(t.slice(y)),o.length===0?t:o},[Fe]),st=s.useCallback(t=>{if(ve.current=t.currentTarget.selectionStart??ve.current,d.mentionActive&&d.files.length>0){if(d.handleKeyDown(t,A),t.key==="Enter"||t.key==="Tab"){const a=d.files[d.selectedIndex];if(a){const o=d.selectFile(a,A);H(o),d.dismissMention(),M(!1)}}return}if(B&&t.key==="ArrowDown"){t.preventDefault(),re.length>0&&u(a=>(a+1)%re.length);return}if(B&&t.key==="ArrowUp"){t.preventDefault(),re.length>0&&u(a=>a===0?re.length-1:a-1);return}if(B&&t.key==="Enter"){t.preventDefault();const a=re[Se]??re[0];a&&Ee(a);return}if(B&&t.key==="Escape"){t.preventDefault(),G(!1),se(""),h(-1);return}if(Q&&t.key==="ArrowDown"){t.preventDefault(),z.length>0&&ie(a=>(a+1)%z.length);return}if(Q&&t.key==="ArrowUp"){t.preventDefault(),z.length>0&&ie(a=>a===0?z.length-1:a-1);return}if(Q&&(t.key==="Enter"||t.key==="Tab")&&z.length>0){t.preventDefault();const a=z[he]??z[0];a&&$e(a);return}if(Q&&t.key==="Escape"){t.preventDefault(),_(!1);return}t.key==="Enter"&&!t.shiftKey&&(t.preventDefault(),Ae())},[B,re,Se,Ee,Q,z,he,$e,Ae,d,A]),Me=s.useCallback((t,a)=>{const o=qt(t,a);if(o){G(!0),se(o.filter),h(o.start);return}G(!1),se(""),h(-1)},[]),nt=s.useCallback(t=>{const a=t.target,o=a.value,y=a.selectionStart??o.length;ve.current=y,H(o);const $=Xe(o);$?(_(!0),ue($.filter)):(_(!1),ue("")),Me(o,y),d.detectMention(o,y),M(d.mentionActive),d.mentionActive&&S(a),a.style.height="auto",a.style.height=`${Math.min(a.scrollHeight,120)}px`},[Me]),Pe=s.useCallback(t=>{const a=t.currentTarget,o=a.selectionStart??a.value.length;ve.current=o,Me(a.value,o),d.detectMention(a.value,o),M(d.mentionActive),d.mentionActive&&S(a)},[Me,d,S]),at=s.useCallback(t=>{t.key!=="Escape"&&Pe(t)},[Pe]),it=s.useCallback(()=>{g.current!==null&&window.clearTimeout(g.current),g.current=window.setTimeout(()=>{_(!1),G(!1),se(""),h(-1),M(!1),d.dismissMention(),g.current=null},120)},[d]),lt=s.useCallback(()=>{g.current!==null&&(window.clearTimeout(g.current),g.current=null)},[]),rt=s.useCallback(async t=>{ne(null);try{await L(t),i("Conversation archived","success")}catch{i("Failed to archive conversation","error")}},[L,i]),ct=s.useCallback(async t=>{q(null),ne(null);try{await oe(t),i("Conversation deleted","success")}catch{i("Failed to delete conversation","error")}},[oe,i]),ot=s.useCallback(t=>{I(t),le&&xe(!1)},[I,le]),dt=s.useCallback(()=>{I(""),xe(!0)},[I]),ut=()=>e.jsxs("div",{className:"chat-empty-state",children:[e.jsx(It,{size:48,strokeWidth:1.5}),e.jsx("h2",{children:"Start a new conversation"}),e.jsxs("button",{className:"btn btn-primary",onClick:()=>K(!0),children:[e.jsx(Le,{size:16}),"New Chat"]})]}),Y=We(c?.modelProvider,c?.modelId),Oe=c?.agentId===Te?Y??"Fusion":c?.title||V.get(c?.agentId??"")?.name||c?.agentId||"Chat",ht=!!(Y&&Y!==Oe),De=V.get(c?.agentId??"")?.name||(c?.agentId===Te?Y??"Fusion":c?.agentId?.slice(0,30)??"Fusion"),He=!!(Y&&Y!==De),mt=T.length>50?`${T.slice(0,50)}…`:T,Ve=s.useCallback(t=>{W(a=>{const o=new Set(a);return o.has(t)?o.delete(t):o.add(t),o})},[]),Be=s.useCallback((t,a=!1)=>a?e.jsx("div",{className:"chat-message-content chat-message-content--plain",children:t}):e.jsx("div",{className:"chat-message-content chat-message-content--markdown",children:e.jsx(At,{remarkPlugins:[$t],components:Ut,children:t})}),[]);return e.jsxs("div",{className:"chat-view",children:[e.jsxs("div",{className:`chat-sidebar${J?"":" chat-sidebar--hidden"}`,children:[e.jsx("div",{className:"chat-sidebar-header",children:e.jsxs("button",{className:"btn btn-sm btn-primary",onClick:()=>K(!0),"data-testid":"chat-new-btn",children:[e.jsx(Le,{size:14}),"New Chat"]})}),e.jsx("div",{className:"chat-sidebar-search",children:e.jsxs("div",{className:"chat-sidebar-search-wrapper",children:[e.jsx(Et,{size:14,className:"chat-sidebar-search-icon"}),e.jsx("input",{type:"text",className:"chat-sidebar-search",placeholder:"Search conversations...",value:P,onChange:t=>p(t.target.value),"data-testid":"chat-search-input"})]})}),e.jsx("div",{className:"chat-session-list chat-sidebar-list",children:l?e.jsx("div",{style:{padding:"12px",color:"var(--text-secondary)",fontSize:"13px"},children:"Loading..."}):D.length===0?e.jsx("div",{style:{padding:"12px",color:"var(--text-secondary)",fontSize:"13px"},children:"No conversations yet"}):D.map(t=>e.jsxs("div",{className:`chat-session-item${c?.id===t.id?" chat-session-item--active":""}`,onClick:()=>ot(t.id),onContextMenu:a=>{a.preventDefault(),ne({sessionId:t.id,x:a.clientX,y:a.clientY})},"data-testid":`chat-session-${t.id}`,children:[e.jsx("button",{className:"chat-session-delete-btn",onClick:a=>{a.stopPropagation(),q(t.id)},"data-testid":"chat-session-delete-btn","aria-label":"Delete conversation",children:e.jsx(Ke,{size:14})}),e.jsx("div",{className:"chat-session-title",children:t.title||"Untitled"}),e.jsx("div",{className:"chat-session-preview",children:t.lastMessagePreview||"No messages"}),e.jsxs("div",{className:"chat-session-meta",children:[e.jsx("span",{children:V.get(t.agentId)?.name||(t.agentId===Te?We(t.modelProvider,t.modelId)??"Fusion":t.agentId.slice(0,30))}),e.jsx("span",{children:t.updatedAt?Qe(t.updatedAt):""})]})]},t.id))}),e.jsx("div",{className:"chat-sidebar-footer",children:e.jsxs("button",{className:"btn btn-sm btn-primary chat-sidebar-footer-btn",onClick:()=>K(!0),"data-testid":"chat-new-btn-mobile",children:[e.jsx(Le,{size:14}),"New Chat"]})})]}),U&&e.jsxs("div",{className:"chat-session-context-menu",style:{top:U.y,left:U.x},onClick:t=>t.stopPropagation(),children:[e.jsxs("button",{onClick:()=>rt(U.sessionId),"data-testid":"chat-context-archive",children:[e.jsx(Pt,{size:14}),"Archive"]}),e.jsxs("button",{onClick:()=>{ne(null),q(U.sessionId)},"data-testid":"chat-context-delete",children:[e.jsx(Ke,{size:14}),"Delete"]})]}),N&&e.jsx("div",{className:"chat-new-dialog-backdrop",onClick:()=>q(null),children:e.jsxs("div",{className:"chat-new-dialog",onClick:t=>t.stopPropagation(),children:[e.jsx("h3",{children:"Delete Conversation?"}),e.jsx("p",{style:{fontSize:"14px",color:"var(--text-secondary)",marginBottom:"16px"},children:"This action cannot be undone. All messages in this conversation will be permanently deleted."}),e.jsxs("div",{className:"chat-new-dialog-actions",children:[e.jsx("button",{className:"btn btn-sm",onClick:()=>q(null),children:"Cancel"}),e.jsx("button",{className:"btn btn-sm btn-danger",onClick:()=>void ct(N),children:"Delete"})]})]})}),e.jsxs("div",{className:"chat-thread",style:Ze,children:[(c||!le)&&e.jsxs("div",{className:"chat-thread-header",children:[le&&c&&e.jsx("button",{className:"btn-icon",onClick:dt,"data-testid":"chat-back-btn",children:e.jsx(Dt,{size:16})}),e.jsx(je,{size:16}),e.jsx("span",{className:"chat-thread-header-title",children:Oe}),ht&&e.jsx("span",{className:"chat-model-tag",children:Y})]}),e.jsxs("div",{className:"chat-messages",ref:R,children:[f?e.jsx("div",{style:{color:"var(--text-secondary)",fontSize:"13px"},children:"Loading messages..."}):r.length===0&&!c?ut():r.length===0&&c?e.jsx("div",{style:{color:"var(--text-secondary)",fontSize:"13px"},children:"No messages yet. Start the conversation!"}):e.jsxs(e.Fragment,{children:[r.map(t=>{const a=t.role==="assistant",o=k.has(t.id);return e.jsxs("div",{className:`chat-message chat-message--${t.role}`,"data-testid":`chat-message-${t.id}`,children:[a&&e.jsxs("div",{className:"chat-message-avatar",children:[e.jsx(je,{size:14}),e.jsx("span",{children:De}),He&&e.jsx("span",{className:"chat-model-tag",children:Y}),e.jsx("button",{type:"button",className:`chat-message-render-toggle${o?" chat-message-render-toggle--plain":""}`,"data-testid":"chat-message-render-toggle","aria-label":o?"Show rendered markdown":"Show plain text",onClick:()=>Ve(t.id),children:o?e.jsx(Ue,{size:14}):e.jsx(qe,{size:14})})]}),a?Be(t.content,o):e.jsx("div",{className:"chat-message-content",children:tt(t.content)}),Ye(t.toolCalls),t.thinkingOutput&&e.jsxs("details",{className:"chat-message-thinking",children:[e.jsx("summary",{children:"Thinking"}),e.jsx("pre",{className:"chat-message-thinking-content",children:t.thinkingOutput})]}),e.jsx("div",{className:"chat-message-time",children:Qe(t.createdAt)})]},t.id)}),v&&e.jsxs("div",{className:"chat-message chat-message--assistant chat-message--streaming",children:[e.jsxs("div",{className:"chat-message-avatar",children:[e.jsx(je,{size:14}),e.jsx("span",{children:De}),He&&e.jsx("span",{className:"chat-model-tag",children:Y}),e.jsx("button",{type:"button",className:`chat-message-render-toggle${k.has("__streaming__")?" chat-message-render-toggle--plain":""}`,"data-testid":"chat-message-render-toggle","aria-label":k.has("__streaming__")?"Show rendered markdown":"Show plain text",onClick:()=>Ve("__streaming__"),children:k.has("__streaming__")?e.jsx(Ue,{size:14}):e.jsx(qe,{size:14})})]}),j?Be(j,k.has("__streaming__")):e.jsx("div",{className:"chat-message-content chat-message-content--waiting",children:w?"Thinking…":"Connecting…"}),Ye(X),w&&e.jsxs("details",{className:"chat-message-thinking",children:[e.jsx("summary",{children:"Thinking"}),e.jsx("pre",{className:"chat-message-thinking-content",children:w})]}),e.jsxs("div",{className:"chat-typing-indicator",children:[e.jsx("span",{}),e.jsx("span",{}),e.jsx("span",{})]})]})]}),e.jsx("div",{ref:b})]}),c&&e.jsxs("div",{className:"chat-input-area",children:[Q&&e.jsx("div",{className:"chat-skill-menu","data-testid":"chat-skill-menu",role:"listbox","aria-label":"Skill suggestions",children:Ne?e.jsx("div",{className:"chat-skill-menu-empty",children:"Loading skills…"}):z.length===0?e.jsx("div",{className:"chat-skill-menu-empty",children:de?"No skills found":"No skills available"}):z.map((t,a)=>e.jsxs("button",{type:"button",role:"option","aria-selected":a===he,className:`chat-skill-menu-item${a===he?" chat-skill-menu-item--highlighted":""}`,onMouseDown:o=>o.preventDefault(),onMouseEnter:()=>ie(a),onClick:()=>$e(t),children:[e.jsx("span",{className:"chat-skill-menu-item-name",children:t.name}),e.jsx("span",{className:"chat-skill-menu-item-description",title:t.relativePath,children:t.relativePath})]},t.id))}),e.jsxs("div",{className:"chat-input-wrapper",children:[e.jsx("textarea",{ref:C,className:"chat-input-textarea",placeholder:"Type a message...",value:A,onChange:nt,onKeyDown:st,onKeyUp:at,onClick:Pe,onBlur:it,onFocus:lt,rows:1,"data-testid":"chat-input"}),e.jsx(Rt,{agents:ge,filter:me,highlightedIndex:Se,visible:B,onSelect:Ee,position:"below"}),e.jsx(Lt,{visible:d.mentionActive&&!B,position:be,files:d.files,selectedIndex:d.selectedIndex,onSelect:t=>{const a=d.selectFile(t,A);H(a),d.dismissMention(),M(!1),C.current?.focus()},loading:d.loading}),T&&e.jsxs("div",{className:"chat-pending-message","data-testid":"chat-pending-indicator",children:[e.jsx("span",{children:`Queued: ${mt}`}),e.jsx("button",{type:"button",className:"chat-pending-message-dismiss","aria-label":"Dismiss queued message","data-testid":"chat-pending-dismiss",onClick:pe,children:"×"})]})]}),v?e.jsx("button",{className:"chat-input-stop",onClick:O,"aria-label":"Stop generation","data-testid":"chat-stop-btn",children:e.jsx(_t,{size:14})}):e.jsx("button",{className:"chat-input-send",onClick:()=>void Ae(),disabled:!A.trim(),"data-testid":"chat-send-btn",children:e.jsx(zt,{size:16})})]})]}),Z&&e.jsx(Jt,{projectId:n,onClose:()=>K(!1),onCreate:et})]})}export{Zt as ChatView};
@@ -1 +0,0 @@
1
- import{r as i,j as r}from"./vendor-react-K0fH_qHe.js";import{dt as f,cz as m,H as y,a9 as g,a4 as P,a5 as H,L as C,ag as O}from"./index-DlHPhpDu.js";import{F as z}from"./folder-open-BqZBHfoZ.js";function B({value:d,onChange:l,placeholder:x,onInputKeyDown:j,nodeId:h,localNodeId:p}){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 f(s,c,h,p);n(b=>({...b,loading:!1,currentPath:t.currentPath,parentPath:t.parentPath,entries:t.entries}))}catch(t){n(b=>({...b,loading:!1,error:t instanceof Error?t.message:"Failed to browse directory"}))}},[h,p]),k=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(d||void 0,e.showHidden)},[e.isOpen,e.loading,e.entries.length,e.error,d,e.showHidden,a,h,p]);const o=i.useCallback(s=>{a(s,e.showHidden)},[a,e.showHidden]),w=i.useCallback(()=>{l(e.currentPath),n(s=>({...s,isOpen:!1}))},[e.currentPath,l]),N=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 u=e.currentPath?e.currentPath.split("/").filter(Boolean):[];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:d,onChange:s=>l(s.target.value),onKeyDown:j,placeholder:x||"/path/to/your/project"}),r.jsxs("button",{type:"button",className:"btn btn-secondary btn-sm directory-picker-browse-btn",onClick:k,"aria-label":e.isOpen?"Close directory browser":"Browse directories",children:[e.isOpen?r.jsx(z,{size:16}):r.jsx(m,{size:16}),r.jsx("span",{children:"Browse"})]})]}),e.isOpen&&r.jsxs("div",{className:"directory-picker-browser",role:"tree","aria-label":"Directory browser",children:[r.jsxs("div",{className:"directory-picker-breadcrumbs",children:[r.jsx("button",{type:"button",className:"directory-picker-breadcrumb",onClick:()=>o("/"),title:"Root",children:"/"}),u.map((s,c)=>{const t="/"+u.slice(0,c+1).join("/");return r.jsxs("span",{className:"directory-picker-breadcrumb-item",children:[r.jsx(y,{size:12,className:"directory-picker-breadcrumb-sep"}),r.jsx("button",{type:"button",className:"directory-picker-breadcrumb",onClick:()=>o(t),title:t,children:s})]},t)})]}),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:()=>o(e.parentPath),"aria-label":"Go to parent directory",title:"Parent directory",children:[r.jsx(g,{size:14}),r.jsx("span",{children:"Up"})]}),r.jsxs("button",{type:"button",className:"btn btn-sm btn-secondary directory-picker-hidden-toggle",onClick:N,"aria-label":e.showHidden?"Hide hidden directories":"Show hidden directories",title:e.showHidden?"Hide hidden":"Show hidden",children:[e.showHidden?r.jsx(P,{size:14}):r.jsx(H,{size:14}),r.jsx("span",{children:e.showHidden?"Hide hidden":"Show hidden"})]})]}),e.loading?r.jsxs("div",{className:"directory-picker-loading",children:[r.jsx(C,{size:20,className:"animate-spin"}),r.jsx("span",{children:"Loading…"})]}):e.error?r.jsxs("div",{className:"directory-picker-error",children:[r.jsx(O,{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:()=>o(s.path),role:"treeitem",title:s.path,children:[r.jsx(m,{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:w,children:"Select"})]})]})]})}export{B as D};
@@ -1,11 +0,0 @@
1
- import{r as c,j as s}from"./vendor-react-K0fH_qHe.js";import{c as U,aa as Q,ab as V,ac as W,ad as X,ae as J,af as x,X as T,R as j,C as q,ag as F,ah as G,ai as K,y as B,aj as Z,ak as ss,al as P}from"./index-DlHPhpDu.js";import{U as _}from"./users-BLvidusm.js";import"./vendor-xterm-DzcZoU0P.js";/**
2
- * @license lucide-react v1.7.0 - ISC
3
- *
4
- * This source code is licensed under the ISC license.
5
- * See the LICENSE file in the root directory of this source tree.
6
- */const es=[["path",{d:"M12 10h.01",key:"1nrarc"}],["path",{d:"M12 14h.01",key:"1etili"}],["path",{d:"M12 6h.01",key:"1vi96p"}],["path",{d:"M16 10h.01",key:"1m94wz"}],["path",{d:"M16 14h.01",key:"1gbofw"}],["path",{d:"M16 6h.01",key:"1x0f13"}],["path",{d:"M8 10h.01",key:"19clt8"}],["path",{d:"M8 14h.01",key:"6423bh"}],["path",{d:"M8 6h.01",key:"1dz90k"}],["path",{d:"M9 22v-3a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v3",key:"cabbwy"}],["rect",{x:"4",y:"2",width:"16",height:"20",rx:"2",key:"1uxh74"}]],ts=U("building",es);/**
7
- * @license lucide-react v1.7.0 - ISC
8
- *
9
- * This source code is licensed under the ISC license.
10
- * See the LICENSE file in the root directory of this source tree.
11
- */const is=[["path",{d:"M3 3v16a2 2 0 0 0 2 2h16",key:"c24i48"}],["path",{d:"m19 9-5 5-4-4-3 3",key:"2osh9i"}]],as=U("chart-line",is),A=["architecture","quality","workflow","performance","reliability","security","ux","testability","documentation","dependency","features","competitive_analysis","research","trends","other"],O={quality:"Quality",performance:"Performance",architecture:"Architecture",security:"Security",reliability:"Reliability",ux:"User Experience",testability:"Testability",documentation:"Documentation",dependency:"Dependencies",workflow:"Workflow",other:"Other",features:"Features",competitive_analysis:"Competitive Analysis",research:"Research",trends:"Trends"};function ns(h){const[l,b]=c.useState(()=>A.map(t=>({category:t,label:O[t]??t,items:[],isLoading:!1,error:null}))),[k,S]=c.useState(!0),[N,v]=c.useState(null),[u,w]=c.useState(null),[M,C]=c.useState(!1),[I,p]=c.useState(null),[R,f]=c.useState(new Map),[z,y]=c.useState(new Map),m=c.useCallback(async()=>{S(!0),v(null);try{const t=await Q({status:void 0,limit:1e3},h),a=new Map;for(const i of A)a.set(i,[]);for(const i of t.insights)if(i.status!=="dismissed"){const r=a.get(i.category)??[];a.set(i.category,[...r,i])}b(A.map(i=>({category:i,label:O[i]??i,items:a.get(i)??[],isLoading:!1,error:null})));const e=await V(h);e.runs.length>0&&w(e.runs[0])}catch(t){const a=t instanceof Error?t.message:"Failed to fetch insights";v(a)}finally{S(!1)}},[h]),o=c.useCallback(async()=>{C(!0),p(null);try{const t=await W("manual",void 0,h);w(t),t.status==="completed"?await m():t.status==="failed"&&t.error&&p(t.error)}catch(t){const a=t instanceof Error?t.message:"Failed to generate insights";throw p(a),t}finally{C(!1)}},[h,m]),g=c.useCallback(async t=>{f(a=>{const e=new Map(a);return e.set(t,{running:!0,error:null}),e});try{await X(t,h),b(a=>a.map(e=>({...e,items:e.items.filter(i=>i.id!==t)}))),f(a=>{const e=new Map(a);return e.set(t,{running:!1,error:null}),e})}catch(a){const e=a instanceof Error?a.message:"Failed to dismiss insight";throw f(i=>{const r=new Map(i);return r.set(t,{running:!1,error:e}),r}),a}},[h]),d=c.useCallback(async t=>{y(a=>{const e=new Map(a);return e.set(t,{running:!0,error:null}),e});try{const a=await J(t,h);return y(e=>{const i=new Map(e);return i.set(t,{running:!1,error:null}),i}),{title:a.suggestedTitle,description:a.suggestedDescription}}catch(a){const e=a instanceof Error?a.message:"Failed to create task";throw y(i=>{const r=new Map(i);return r.set(t,{running:!1,error:e}),r}),a}},[h]),E=c.useMemo(()=>l.reduce((t,a)=>t+a.items.length,0),[l]),D=c.useMemo(()=>0,[l]);return c.useMemo(()=>{m()},[]),{sections:l,loading:k,error:N,latestRun:u,isRunInFlight:M,runError:I,refresh:m,runInsights:o,dismiss:g,createTask:d,dismissStates:R,createTaskStates:z,totalCount:E,dismissedCount:D}}const rs={architecture:ts,quality:q,workflow:P,performance:G,reliability:j,security:F,ux:_,testability:ss,documentation:Z,dependency:B,features:K,competitive_analysis:_,research:as,trends:G,other:x};function ds({projectId:h,addToast:l,onClose:b,onCreateTask:k}){const{sections:S,loading:N,error:v,latestRun:u,isRunInFlight:w,runError:M,refresh:C,runInsights:I,dismiss:p,createTask:R,dismissStates:f,createTaskStates:z,totalCount:y}=ns(h),[m,o]=c.useState(null),[g,d]=c.useState("info");c.useEffect(()=>{if(m){const e=setTimeout(()=>o(null),5e3);return()=>clearTimeout(e)}},[m]);const E=c.useCallback(async()=>{try{o("Generating insights..."),d("info"),await I(),o("Insight generation started"),d("success"),l("Insight generation started","success")}catch(e){const i=e instanceof Error?e.message:"Failed to start generation";o(i),d("error"),l(i,"error")}},[I,l]),D=c.useCallback(async(e,i)=>{try{o(`Dismissing "${i}"...`),d("info"),await p(e),o(`Dismissed "${i}"`),d("success"),l(`Insight dismissed: ${i}`,"success")}catch(r){const n=r instanceof Error?r.message:"Failed to dismiss insight";o(n),d("error"),l(n,"error")}},[p,l]),t=c.useCallback(async(e,i)=>{try{o(`Creating task from "${i}"...`),d("info");const r=await R(e);r&&k&&k(r.title,r.description),o(`Task created from "${i}"`),d("success"),l(`Task created: ${r?.title??i}`,"success")}catch(r){const n=r instanceof Error?r.message:"Failed to create task";o(n),d("error"),l(n,"error")}},[R,k,l]),a=e=>{const i=rs[e.category]??x,r=e.items.some(n=>f.get(n.id)?.running||z.get(n.id)?.running)??!1;return s.jsxs("section",{className:"insights-section","data-testid":`insights-section-${e.category}`,children:[s.jsx("div",{className:"insights-section-header",children:s.jsxs("div",{className:"insights-section-title",children:[s.jsx(i,{size:18,className:"insights-section-icon"}),s.jsx("h3",{children:e.label}),s.jsx("span",{className:"insights-section-count",children:e.items.length})]})}),s.jsx("div",{className:"insights-section-content",children:e.items.length===0?s.jsx("div",{className:"insights-empty-section","data-testid":`insights-empty-${e.category}`,children:s.jsx("p",{children:"No insights in this category"})}):s.jsx("ul",{className:"insights-list",children:e.items.map(n=>{const Y=f.get(n.id),H=z.get(n.id),L=Y?.running??!1,$=H?.running??!1;return s.jsxs("li",{className:"insight-item","data-insight-id":n.id,children:[s.jsxs("div",{className:"insight-item-header",children:[s.jsx("h4",{className:"insight-item-title",children:n.title}),s.jsxs("div",{className:"insight-item-actions",children:[s.jsx("button",{className:"btn btn-sm btn-icon",onClick:()=>void t(n.id,n.title),disabled:$||r,title:"Create task from this insight","aria-label":"Create task from this insight","data-testid":`create-task-${n.id}`,children:$?s.jsx(j,{size:14,className:"spin"}):s.jsx(B,{size:14})}),s.jsx("button",{className:"btn btn-sm btn-icon",onClick:()=>void D(n.id,n.title),disabled:L||r,title:"Dismiss this insight","aria-label":"Dismiss this insight","data-testid":`dismiss-${n.id}`,children:L?s.jsx(j,{size:14,className:"spin"}):s.jsx(T,{size:14})})]})]}),n.content&&s.jsx("p",{className:"insight-item-content",children:n.content}),s.jsxs("div",{className:"insight-item-meta",children:[s.jsx("span",{className:`insight-item-status insight-item-status--${n.status}`,children:n.status}),n.createdAt&&s.jsxs("span",{className:"insight-item-date",children:[s.jsx(P,{size:12}),new Date(n.createdAt).toLocaleDateString()]})]})]},n.id)})})})]},e.category)};return s.jsxs("div",{className:"insights-view","data-testid":"insights-view",children:[s.jsxs("div",{className:"insights-view-header",children:[s.jsxs("div",{className:"insights-view-title",children:[s.jsxs("h2",{children:[s.jsx(x,{size:20}),"Insights"]}),s.jsxs("span",{className:"insights-view-count",children:[y," total"]})]}),s.jsxs("div",{className:"insights-view-actions",children:[b&&s.jsx("button",{className:"btn btn-icon insights-view-close",onClick:b,"aria-label":"Close insights view",children:s.jsx(T,{size:16})}),s.jsxs("button",{className:"btn btn-sm",onClick:()=>void C(),disabled:N,"aria-label":"Refresh insights","data-testid":"refresh-insights",children:[s.jsx(j,{size:14,className:N?"spin":""}),"Refresh"]}),s.jsx("button",{className:"btn btn-primary btn-sm",onClick:()=>void E(),disabled:w,"aria-label":"Generate new insights","data-testid":"run-insights",children:w?s.jsxs(s.Fragment,{children:[s.jsx(j,{size:14,className:"spin"}),"Generating..."]}):s.jsxs(s.Fragment,{children:[s.jsx(x,{size:14}),"Generate Insights"]})})]})]}),s.jsx("div",{className:"insights-status-region","aria-live":"polite","data-testid":"insights-status",children:m&&s.jsxs("div",{className:`insights-status-message insights-status-message--${g}`,role:g==="error"?"alert":void 0,children:[g==="success"&&s.jsx(q,{size:16}),g==="error"&&s.jsx(F,{size:16}),g==="info"&&s.jsx(x,{size:16}),s.jsx("span",{children:m})]})}),M&&s.jsxs("div",{className:"insights-error-callout",role:"alert","data-testid":"run-error",children:[s.jsx(F,{size:16}),s.jsx("span",{children:M})]}),u&&s.jsx("div",{className:"insights-run-info","data-testid":"latest-run",children:s.jsxs("span",{className:"insights-run-status",children:["Latest run: ",u.status,u.status==="completed"&&s.jsxs(s.Fragment,{children:[" — ",u.insightsCreated," created, ",u.insightsUpdated," updated"]}),u.status==="failed"&&u.error&&s.jsxs(s.Fragment,{children:[" — ",u.error]})]})}),N?s.jsxs("div",{className:"insights-loading","data-testid":"insights-loading",children:[s.jsx(j,{size:24,className:"spin"}),s.jsx("p",{children:"Loading insights..."})]}):v?s.jsxs("div",{className:"insights-error","data-testid":"insights-error",children:[s.jsx(F,{size:24}),s.jsx("p",{children:v}),s.jsx("button",{className:"btn btn-sm",onClick:()=>void C(),children:"Retry"})]}):y===0?s.jsxs("div",{className:"insights-empty","data-testid":"insights-empty",children:[s.jsx(x,{size:48}),s.jsx("h3",{children:"No insights yet"}),s.jsx("p",{children:"Generate insights to get AI-powered recommendations for your project."}),s.jsxs("button",{className:"btn btn-primary",onClick:()=>void E(),children:[s.jsx(x,{size:14}),"Generate First Insights"]})]}):s.jsx("div",{className:"insights-sections",children:S.map(a)})]})}export{ds as InsightsView};