From e3f95d6cfd7679a6418c82f2f3a70921fa8dd1c0 Mon Sep 17 00:00:00 2001 From: Jonathan Singer Date: Wed, 26 Aug 2026 14:24:06 -0400 Subject: [PATCH] render MCP tool calls with the connection look again --- strix/interface/tui/internal/render/mcp.go | 12 +++ .../interface/tui/internal/render/registry.go | 5 ++ .../tui/internal/render/render_test.go | 25 +++++- strix/interface/tui/live_view.py | 58 +++++++------ strix/interface/tui/runtime.py | 14 --- .../live/tool-renderers/McpRenderer.tsx | 22 ++++- .../components/live/tool-renderers/index.ts | 5 +- .../viewer/frontend/src/types/events.ts | 7 +- .../{index-C9c1WbvP.js => index-CYf9nnT3.js} | 2 +- strix/interface/viewer/static/index.html | 2 +- strix/tools/mcp/__init__.py | 4 +- strix/tools/mcp/agent_tools.py | 28 ++++-- strix/tools/mcp/client.py | 34 +++++++- strix/tools/mcp/naming.py | 59 +------------ tests/test_mcp_client.py | 87 ++++++++++++------- 15 files changed, 212 insertions(+), 152 deletions(-) rename strix/interface/viewer/static/assets/{index-C9c1WbvP.js => index-CYf9nnT3.js} (92%) diff --git a/strix/interface/tui/internal/render/mcp.go b/strix/interface/tui/internal/render/mcp.go index 24e0b42a..3d1f2c25 100644 --- a/strix/interface/tui/internal/render/mcp.go +++ b/strix/interface/tui/internal/render/mcp.go @@ -33,3 +33,15 @@ func renderMcpTool(connection, toolName string, args map[string]any, status stri b.WriteString(style.Render(icon)) return b.String() } + +// renderMcpInspect renders describe_mcp: a request to inspect one connection's +// catalog rather than a call to a tool on it. There is no underlying tool, so +// the connection is the whole subject and leads. Same icon and colors as a tool +// call so the two read as one family while scrolling a transcript. +func renderMcpInspect(connection, status string) string { + var b strings.Builder + b.WriteString(mcpIcon + Dim().Render("Inspecting MCP server ") + Bold(Mint).Render(connection) + "\n") + icon, style := statusIcon(status) + b.WriteString(style.Render(icon)) + return b.String() +} diff --git a/strix/interface/tui/internal/render/registry.go b/strix/interface/tui/internal/render/registry.go index 9e1ccdb3..ec58f781 100644 --- a/strix/interface/tui/internal/render/registry.go +++ b/strix/interface/tui/internal/render/registry.go @@ -57,6 +57,11 @@ func Tool(data map[string]any) string { // nothing here. The tag is only ever set from the connections the run made, // so it is the one thing that can tell such a call apart from a built-in. if connection := StringValue(data["mcp_connection"]); connection != "" { + // describe_mcp inspects a connection's catalog rather than calling a tool + // on it, so there is no underlying tool and the connection is the subject. + if name == "describe_mcp" { + return renderMcpInspect(connection, status) + } toolName := StringValue(data["mcp_tool"]) if toolName == "" { toolName = name diff --git a/strix/interface/tui/internal/render/render_test.go b/strix/interface/tui/internal/render/render_test.go index c326b0c0..2c2b5bcd 100644 --- a/strix/interface/tui/internal/render/render_test.go +++ b/strix/interface/tui/internal/render/render_test.go @@ -227,7 +227,9 @@ func TestGenericToolOmitsRawResult(t *testing.T) { } func TestMcpToolLeadsWithActionAndNamesTheServer(t *testing.T) { - data := tool("local_fs_read_file", map[string]any{"path": "/etc/hosts"}, "file body", "completed") + // call_mcp is the dispatch tool; the connection and the server's own tool + // name are tagged onto the event from its arguments. + data := tool("call_mcp", map[string]any{"path": "/etc/hosts"}, "file body", "completed") data["mcp_connection"] = "local_fs" data["mcp_tool"] = "read_file" @@ -244,11 +246,26 @@ func TestMcpToolLeadsWithActionAndNamesTheServer(t *testing.T) { } } -func TestMcpToolWithoutTaggedNameFallsBackToFullName(t *testing.T) { - data := tool("local_fs_read_file", nil, nil, "running") +func TestMcpToolWithoutTaggedToolFallsBackToDispatchName(t *testing.T) { + // A call_mcp whose underlying tool could not be read still renders as an MCP + // row, falling back to the dispatch tool name. + data := tool("call_mcp", nil, nil, "running") data["mcp_connection"] = "local_fs" - requireContains(t, ansi.Strip(Tool(data)), "local_fs_read_file", "In progress") + requireContains(t, ansi.Strip(Tool(data)), mcpIcon+"call_mcp", "local_fs", "In progress") +} + +func TestMcpDescribeInspectsConnection(t *testing.T) { + // describe_mcp inspects a connection; the connection is the subject and the + // dispatch tool name is not shown as if it were a server tool. + data := tool("describe_mcp", nil, nil, "completed") + data["mcp_connection"] = "local_fs" + + out := ansi.Strip(Tool(data)) + requireContains(t, out, mcpIcon, "Inspecting MCP server", "local_fs", "Done") + if strings.Contains(out, "describe_mcp") { + t.Fatalf("describe_mcp must read as inspecting the connection, not name the dispatch tool:\n%s", out) + } } func TestCollapseToolShellPreviewAndExpand(t *testing.T) { diff --git a/strix/interface/tui/live_view.py b/strix/interface/tui/live_view.py index a52c14be..3d984883 100644 --- a/strix/interface/tui/live_view.py +++ b/strix/interface/tui/live_view.py @@ -8,7 +8,6 @@ from typing import TYPE_CHECKING, Any if TYPE_CHECKING: - from collections.abc import Iterable from pathlib import Path from agents.tool import ToolOutputImage @@ -16,9 +15,10 @@ from agents.tool import ToolOutputImage from strix.core.paths import runtime_state_dir from strix.interface.tui.history import load_session_history -# Imported from the naming module rather than the mcp package so a projection -# never pulls in the MCP client and the agents SDK behind it. -from strix.tools.mcp.naming import resolve_mcp_tool + +# Every MCP call the model makes goes through one of two dispatch tools, so a +# call to a user's server is recognised by the tool's name alone. +_MCP_DISPATCH_TOOLS = frozenset({"call_mcp", "describe_mcp"}) class TuiLiveView: @@ -31,27 +31,30 @@ class TuiLiveView: self._user_instruction: str | None = None self._user_instruction_at: str | None = None self._user_instruction_shown = False - self._mcp_connections: tuple[str, ...] = () - def set_mcp_connections(self, names: Iterable[str]) -> None: - """The MCP servers this run connected, so its tool calls can name theirs. - - A server's tools are offered to the model under a name built from the - connection name and the tool's own name. That name cannot be split back - apart on its own, so tool calls are matched against these names instead. - """ - self._mcp_connections = tuple(str(name) for name in names) - - def _mcp_tool_fields(self, tool_name: str) -> dict[str, str]: + def _mcp_tool_fields(self, tool_name: str, args: dict[str, Any]) -> dict[str, str]: """Event fields naming the MCP server a tool call went out to, if any. - Empty for every built-in tool, which is what tells an interface to render - the call as one of its own rather than as a call to a user's server. + Every MCP call the model makes goes through one of two dispatch tools: + ``call_mcp`` runs a named tool on a connection, and ``describe_mcp`` + inspects a connection's catalog. The connection, and for ``call_mcp`` the + server's own name for the tool, ride in the call's arguments rather than + in the tool name, so they are read from there. Empty for every other tool, + which is what tells an interface to render the call as one of its own + rather than as a call to a user's server. """ - origin = resolve_mcp_tool(tool_name, self._mcp_connections) - if origin is None: + if tool_name not in _MCP_DISPATCH_TOOLS: return {} - return {"mcp_connection": origin.connection, "mcp_tool": origin.tool} + connection = args.get("connection") + if not isinstance(connection, str) or not connection: + return {} + # describe_mcp has no underlying tool; an empty tool tells both renderers + # to present the row as inspecting the connection itself. + tool = args.get("tool") if tool_name == "call_mcp" else "" + return { + "mcp_connection": connection, + "mcp_tool": tool if isinstance(tool, str) else "", + } def set_user_instruction(self, text: str | None, *, timestamp: str | None = None) -> None: """Open the transcript with what the user asked for. @@ -98,8 +101,7 @@ class TuiLiveView: def hydrate_from_run_dir(self, run_dir: Path) -> None: # Armed before the agents are added so the root agent's arrival puts the - # user's opening message ahead of the replayed history, and before the - # history is replayed so its MCP tool calls are attributed too. + # user's opening message ahead of the replayed history. self._load_run_record(run_dir) state_dir = runtime_state_dir(run_dir) agents_path = state_dir / "agents.json" @@ -128,16 +130,13 @@ class TuiLiveView: self._hydrate_sdk_session_history(run_dir, statuses.keys()) def _load_run_record(self, run_dir: Path) -> None: - """Take the user's opening message and the run's MCP servers off the record.""" + """Take the user's opening message off the record.""" try: record = json.loads((run_dir / "run.json").read_text(encoding="utf-8")) except (OSError, json.JSONDecodeError): return if not isinstance(record, dict): return - connections = record.get("mcp_connections") - if isinstance(connections, list): - self.set_mcp_connections(name for name in connections if isinstance(name, str)) instruction = record.get("user_instruction") if not isinstance(instruction, str): return @@ -348,7 +347,7 @@ class TuiLiveView: "status": "running", "agent_id": agent_id, "call_id": call_id, - **self._mcp_tool_fields(call["tool_name"]), + **self._mcp_tool_fields(call["tool_name"], call["args"]), } if existing is None: event = self._append_event(agent_id, "tool", tool_data, timestamp=timestamp) @@ -371,6 +370,10 @@ class TuiLiveView: event_key = (agent_id, call_id) event = self._tool_event_by_agent_and_call_id.get(event_key) if event is None: + # No prior call event to update, so its arguments are gone and the + # connection an MCP call went out to cannot be recovered. The matching + # call event, when there is one, already carries the MCP fields; this + # arrives only when the call was never projected, so it stays generic. event = self._append_event( agent_id, "tool", @@ -380,7 +383,6 @@ class TuiLiveView: "status": "completed", "agent_id": agent_id, "call_id": call_id, - **self._mcp_tool_fields(output["tool_name"]), }, timestamp=timestamp, ) diff --git a/strix/interface/tui/runtime.py b/strix/interface/tui/runtime.py index 6a49f72a..7e716628 100644 --- a/strix/interface/tui/runtime.py +++ b/strix/interface/tui/runtime.py @@ -207,23 +207,9 @@ class GoTuiRuntime: self.controller.notify_changed() def capture_event(self, agent_id: str, event: Any) -> None: - self._refresh_mcp_connections() self.live_view.ingest_sdk_event(agent_id, event) self.controller.notify_changed() - def _refresh_mcp_connections(self) -> None: - """Hand the projection the MCP servers the scan connected. - - The scan records them as it connects, which is before the agent can call - anything, and the projection needs them to say which server a tool call - went out to. Read on the way in rather than pushed, so no tool call can - be projected before they arrive. - """ - if self.report_state is None: - return - connections = self.report_state.run_record.get("mcp_connections") or [] - self.live_view.set_mcp_connections(connections) - async def _sync_agent_state(self) -> bool: parent_of, statuses, names, errors = await self.coordinator.graph_snapshot() changed = False diff --git a/strix/interface/viewer/frontend/src/components/live/tool-renderers/McpRenderer.tsx b/strix/interface/viewer/frontend/src/components/live/tool-renderers/McpRenderer.tsx index e17c268f..105ac77c 100644 --- a/strix/interface/viewer/frontend/src/components/live/tool-renderers/McpRenderer.tsx +++ b/strix/interface/viewer/frontend/src/components/live/tool-renderers/McpRenderer.tsx @@ -47,13 +47,29 @@ export default function McpRenderer({ const lines = argLines(args); const failed = status === "failed" || status === "error"; const error = failed ? errorText(result) : null; + // describe_mcp inspects a connection's catalog rather than calling a tool on + // it, so the connection is the subject and there is no underlying tool. + const inspecting = toolName === "describe_mcp"; return (
- {mcpTool || toolName} - via MCP server - {mcpConnection && {mcpConnection}} + {inspecting ? ( + <> + Inspecting MCP server + {mcpConnection && ( + {mcpConnection} + )} + + ) : ( + <> + + {mcpTool || toolName} + + via MCP server + {mcpConnection && {mcpConnection}} + + )}
{lines.length > 0 && ( diff --git a/strix/interface/viewer/frontend/src/components/live/tool-renderers/index.ts b/strix/interface/viewer/frontend/src/components/live/tool-renderers/index.ts index 4c7e088d..bda50125 100644 --- a/strix/interface/viewer/frontend/src/components/live/tool-renderers/index.ts +++ b/strix/interface/viewer/frontend/src/components/live/tool-renderers/index.ts @@ -181,8 +181,9 @@ function resolveCategory(toolName: string): ToolCategory | null { /** * A call to a tool from one of the user's MCP servers is placed by the - * connection it was tagged with, ahead of every name-keyed lookup below: its - * name belongs to that server and matches nothing in this table. + * connection it was tagged with, ahead of every name-keyed lookup below. Every + * MCP call goes through the `call_mcp` / `describe_mcp` dispatch tools, so the + * connection tag, not the tool name, is what routes it to the MCP renderer. */ export function getToolRenderer( toolName: string, diff --git a/strix/interface/viewer/frontend/src/types/events.ts b/strix/interface/viewer/frontend/src/types/events.ts index b58660e8..3f4f1133 100644 --- a/strix/interface/viewer/frontend/src/types/events.ts +++ b/strix/interface/viewer/frontend/src/types/events.ts @@ -101,9 +101,10 @@ export interface ToolRendererProps { status: "running" | "completed" | "failed" | "error"; /** * Set only on a call to a tool from an MCP server the user connected: the name - * they gave that connection, and the server's own name for the tool. The - * engine resolves both, because `toolName` is the two glued together and - * cannot be split back apart here. + * they gave that connection, and the server's own name for the tool. Every MCP + * call goes through the `call_mcp` / `describe_mcp` dispatch tools, so the + * engine reads both out of the call's arguments; `describe_mcp` inspects a + * connection and leaves `mcpTool` empty. */ mcpConnection?: string | null; mcpTool?: string | null; diff --git a/strix/interface/viewer/static/assets/index-C9c1WbvP.js b/strix/interface/viewer/static/assets/index-CYf9nnT3.js similarity index 92% rename from strix/interface/viewer/static/assets/index-C9c1WbvP.js rename to strix/interface/viewer/static/assets/index-CYf9nnT3.js index bac9288b..b6f6e45c 100644 --- a/strix/interface/viewer/static/assets/index-C9c1WbvP.js +++ b/strix/interface/viewer/static/assets/index-CYf9nnT3.js @@ -502,6 +502,6 @@ https://github.com/highlightjs/highlight.js/issues/2277`),Ht=ye,ft=Le),Qe===void ... more content available`:"")})})()]})}function D7({args:e,result:t}){const r=(e.method??"GET").toUpperCase(),a=e.url??"",s=e.headers,o=e.body,c=typeof o=="string"?o:"",d=t,f=d?d.error??null:null,h=d?d.status_code??null:null,p=d?d.response_time_ms??null:null,g=d?d.body:null,y=typeof g=="string"?g:null;return m.jsxs("div",{children:[m.jsx("span",{className:"text-purple-400/80 font-semibold text-sm",children:"request"}),m.jsxs("div",{className:"mt-1.5 font-mono text-[13px] space-y-0.5",children:[m.jsxs("div",{children:[m.jsx("span",{className:"text-[#555] select-none mr-1",children:">>"}),m.jsx("span",{className:`font-bold ${f2[r]??"text-[#888]"}`,children:r}),m.jsx("span",{className:"text-[#888] ml-1 break-all",children:Xr(a,180)})]}),s&&typeof s=="object"&&Object.entries(s).slice(0,5).map(([b,_])=>m.jsxs("div",{className:"text-[#555] pl-5",children:[b,": ",_p(String(_),150)]},b))]}),c&&m.jsx(wi,{className:"text-[#888]",children:wp(c,4)}),f&&m.jsx("div",{className:"text-red-400/70 text-[13px] mt-1.5",children:_p(f,150)}),h!=null&&m.jsxs("div",{className:"font-mono text-[13px] mt-1.5",children:[m.jsx("span",{className:"text-[#555] select-none mr-1",children:"<<"}),m.jsx("span",{className:`font-bold ${bg(h)}`,children:h}),p!=null&&m.jsxs("span",{className:"text-[#555] ml-2",children:[p,"ms"]})]}),y&&m.jsx(wi,{className:"text-[#666]",children:wp(y,6)})]})}function L7({args:e,result:t}){const r=e.request_id,a=e.modifications,s=t,o=s?s.status_code??null:null,c=s?s.response_time_ms??null:null,d=s?s.body:null,f=typeof d=="string"?d:null;return m.jsxs("div",{children:[m.jsxs("div",{className:"flex items-center gap-2",children:[m.jsx("span",{className:"text-purple-400/80 font-semibold text-sm",children:"repeating request"}),r!=null&&m.jsxs("span",{className:"text-[#888] text-[13px]",children:["#",r]})]}),a&&typeof a=="object"&&Object.keys(a).length>0&&m.jsx("div",{className:"mt-1.5 font-mono text-[13px] space-y-0.5",children:Object.entries(a).slice(0,5).map(([h,p])=>m.jsxs("div",{children:[m.jsxs("span",{className:"text-orange-400/60",children:[h,":"]})," ",m.jsx("span",{className:"text-[#777]",children:_p(typeof p=="string"?p:JSON.stringify(p),150)})]},h))}),o!=null&&m.jsxs("div",{className:"font-mono text-[13px] mt-1.5",children:[m.jsx("span",{className:"text-[#555] select-none mr-1",children:"<<"}),m.jsx("span",{className:`font-bold ${bg(o)}`,children:o}),c!=null&&m.jsxs("span",{className:"text-[#555] ml-2",children:[c,"ms"]})]}),f&&m.jsx(wi,{className:"text-[#666]",children:wp(f,5)})]})}const z7={get:"getting",list:"listing",create:"creating",update:"updating",delete:"deleting"};function I7({args:e}){const t=e.action??"",r=e.scope_name??"",a=z7[t]??(t||"managing");return m.jsxs("div",{className:"flex items-center gap-2",children:[m.jsxs("span",{className:"text-purple-400/80 font-semibold text-sm",children:[a," proxy scope"]}),r&&m.jsx("span",{className:"text-[#888] text-[13px]",children:Xr(r,50)})]})}function B7({args:e}){const t=e.parent_id;return m.jsxs("div",{className:"flex items-center gap-2",children:[m.jsx("span",{className:"text-purple-400/80 font-semibold text-sm",children:"listing sitemap"}),t&&m.jsxs("span",{className:"text-[#888] text-[13px]",children:["under #",Xr(String(t),20)]})]})}function U7({args:e}){const t=e.entry_id;return m.jsxs("div",{className:"flex items-center gap-2",children:[m.jsx("span",{className:"text-purple-400/80 font-semibold text-sm",children:"viewing sitemap entry"}),t&&m.jsxs("span",{className:"text-[#888] text-[13px]",children:["#",Xr(String(t),20)]})]})}function H7(e){switch(e.toolName){case"list_requests":return m.jsx(R7,{...e});case"view_request":return m.jsx(j7,{...e});case"send_request":return m.jsx(D7,{...e});case"repeat_request":return m.jsx(L7,{...e});case"scope_rules":return m.jsx(I7,{...e});case"list_sitemap":return m.jsx(B7,{...e});case"view_sitemap_entry":return m.jsx(U7,{...e});default:return m.jsx("span",{className:"text-purple-400/80 font-semibold text-sm",children:e.toolName.replace(/_/g," ")})}}function $7({args:e}){const t=e.thought??e.content??"";return t?m.jsxs("div",{children:[m.jsx("span",{className:"text-purple-400/80 font-semibold text-sm",children:"Agent is thinking"}),m.jsx("div",{className:"mt-1.5 italic text-[#888]",children:m.jsx(Yt,{text:t,maxLines:20})})]}):null}function q7({toolName:e,args:t}){if(e==="create_agent"){const r=t.name??t.agent_name??"",a=t.task??"";return m.jsxs("div",{children:[m.jsxs("div",{className:"flex items-center gap-2",children:[m.jsx("span",{className:"text-cyan-400/80 font-semibold text-sm",children:"spawning"}),r&&m.jsx("span",{className:"text-cyan-400 font-semibold text-sm",children:r})]}),a&&m.jsx("div",{className:"mt-1.5",children:m.jsx(Yt,{text:a,maxLines:15})})]})}if(e==="agent_finish"){const r=t.result_summary??"",a=t.success,s=t.findings,o=Array.isArray(s)?s:void 0;return m.jsxs("div",{children:[m.jsx("span",{className:`font-semibold text-sm ${a===!1?"text-red-400/80":"text-emerald-400/80"}`,children:a===!1?"Agent failed":"Agent completed"}),r&&m.jsx("div",{className:"mt-1.5",children:m.jsx(Yt,{text:r,maxLines:20})}),o&&o.length>0&&m.jsx("div",{className:"mt-1.5 space-y-0.5",children:o.map((c,d)=>m.jsxs("div",{className:"text-[13px] text-[#888]",children:[m.jsx("span",{className:"text-red-400/50 mr-1",children:"•"}),typeof c=="string"?c:JSON.stringify(c)]},d))})]})}if(e==="send_message_to_agent"){const r=t.message??"",a=t.target_agent_id??t.agent_id??"";return m.jsxs("div",{children:[m.jsxs("div",{className:"flex items-center gap-2",children:[m.jsx("span",{className:"text-cyan-400/80 font-semibold text-sm",children:"message"}),a&&m.jsxs("span",{className:"text-[#888] text-[13px]",children:["to ",a.slice(0,16)]})]}),r&&m.jsx("div",{className:"mt-1.5",children:m.jsx(Yt,{text:r,maxLines:20})})]})}if(e==="wait_for_agents"){const r=t.reason??"";return m.jsxs("div",{className:"flex items-center gap-2",children:[m.jsx("span",{className:"text-cyan-400/80 font-semibold text-sm",children:"waiting"}),r&&m.jsx("span",{className:"text-[#888] text-[13px] truncate",children:r})]})}if(e==="stop_agent"){const r=t.target_agent_id??"",a=t.cascade!==!1,s=t.reason??"";return m.jsxs("div",{children:[m.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[m.jsx("span",{className:"text-red-400/80 font-semibold text-sm",children:"stopping"}),r&&m.jsx("span",{className:"text-[#888] text-[13px]",children:r.slice(0,16)}),a&&m.jsx("span",{className:"text-[#555] text-[13px] italic",children:"+ descendants"})]}),s&&m.jsx("div",{className:"mt-1.5 text-[#888] text-[13px]",children:s})]})}return e==="view_agent_graph"?m.jsx("span",{className:"text-cyan-400/80 font-semibold text-sm",children:"viewing agents graph"}):m.jsx("span",{className:"text-cyan-400/80 font-semibold text-sm",children:e.replace(/_/g," ")})}function P7({args:e,result:t}){const r=e.query??e.search_query??"",a=t,s=a?a.content??null:null,o=a&&!a.success?a.message??null:null;return m.jsxs("div",{children:[m.jsx("span",{className:"text-amber-400/80 font-semibold text-sm",children:"Searching the web"}),r&&m.jsx("div",{className:"text-[#888] text-[13px] mt-0.5",children:r}),o&&m.jsx("div",{className:"text-red-400/70 text-[13px] mt-1.5",children:o}),s&&m.jsx("div",{className:"mt-2",children:m.jsx(Yt,{text:s,maxLines:15})})]})}const F7=50,h_=200,m_=25,p_=24,G7=/\x1b(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~]|\][^\x07]*\x07)/g,V7=/\.\.\. \[(stdout|stderr|result|output|error) truncated at \d+k? chars\]/g;function Y7(e){return e.replace(G7,"")}function Um(e){const t=Y7(e);return t.length>h_?t.slice(0,h_-3)+"...":t}function X7(e){return e.replace(V7,"").trim()}function K7(e){const t=e.split(` `);if(t.length<=F7)return t.map(Um).join(` `);const r=t.length-m_-p_;return[...t.slice(0,m_).map(Um),`... ${r} lines truncated ...`,...t.slice(-p_).map(Um)].join(` -`)}function Z7({args:e,result:t}){const r=e.action??"",a=e.code??e.script??"",s=t;let o=null;s&&typeof s=="object"?o=typeof s.stdout=="string"?s.stdout:null:typeof s=="string"&&(o=s);const c=r==="new_session"?"new session":r==="close"?"close session":r==="list_sessions"?"list sessions":null,d=o?K7(X7(o)):null;return m.jsxs("div",{children:[m.jsxs("div",{className:"flex items-center gap-2",children:[m.jsx("span",{className:"text-yellow-400/80 font-semibold text-sm",children:"Python"}),c&&m.jsx("span",{className:"text-[#888] text-[13px]",children:c})]}),a&&m.jsx(gg,{code:a,language:"python",collapsible:!0}),d&&m.jsx(wi,{className:"text-[#666]",children:d})]})}function Q7({args:e}){const t=e.targets,a=(Array.isArray(t)?t:[]).map(s=>typeof s=="object"&&s?s.original??null:null).filter(Boolean);return m.jsxs("div",{children:[m.jsxs("div",{className:"flex items-center gap-2",children:[m.jsx("span",{className:"text-emerald-400/80 font-semibold text-sm",children:"Starting penetration test"}),a.length===1&&m.jsxs("span",{className:"text-[#888] text-[13px]",children:["on ",a[0]]})]}),a.length>1&&m.jsx("div",{className:"mt-1.5 space-y-0.5",children:a.map((s,o)=>m.jsxs("div",{className:"text-[13px] text-[#888]",children:[m.jsx("span",{className:"text-[#555] mr-1",children:"•"}),s]},o))})]})}function W7({args:e}){const t=e.name??"Unknown Agent",r=e.task??"";return m.jsxs("div",{children:[m.jsxs("div",{className:"flex items-center gap-2",children:[m.jsx("span",{className:"text-[#888] text-[13px]",children:"subagent"}),m.jsx("span",{className:"text-purple-400 font-semibold text-sm",children:t})]}),r&&m.jsx("div",{className:"mt-1.5",children:m.jsx(Yt,{text:r,maxLines:15})})]})}function J7(e){return e.toolName==="subagent_start_info"?m.jsx(W7,{...e}):m.jsx(Q7,{...e})}function eU({args:e}){const t=e.executive_summary??"",r=e.methodology??"",a=e.technical_analysis??"",s=e.recommendations??"";return m.jsxs("div",{className:"space-y-3",children:[m.jsx("span",{className:"text-emerald-400/80 font-semibold text-sm",children:"Penetration test completed"}),t&&m.jsxs("div",{children:[m.jsx("span",{className:"text-emerald-400/60 text-sm font-semibold",children:"Executive Summary"}),m.jsx("div",{className:"mt-1",children:m.jsx(Yt,{text:t,maxLines:25})})]}),r&&m.jsxs("div",{children:[m.jsx("span",{className:"text-emerald-400/60 text-sm font-semibold",children:"Methodology"}),m.jsx("div",{className:"mt-1",children:m.jsx(Yt,{text:r,maxLines:25})})]}),a&&m.jsxs("div",{children:[m.jsx("span",{className:"text-emerald-400/60 text-sm font-semibold",children:"Technical Analysis"}),m.jsx("div",{className:"mt-1",children:m.jsx(Yt,{text:a,maxLines:25})})]}),s&&m.jsxs("div",{children:[m.jsx("span",{className:"text-emerald-400/60 text-sm font-semibold",children:"Recommendations"}),m.jsx("div",{className:"mt-1",children:m.jsx(Yt,{text:s,maxLines:25})})]}),!t&&!r&&!a&&!s&&m.jsx("div",{className:"text-[#555] text-xs",children:"Generating final report..."})]})}function tU({toolName:e,args:t,result:r}){if(e==="create_note"){const a=t.title??"",s=t.content??"",o=t.category??"general";return m.jsxs("div",{children:[m.jsxs("div",{className:"flex items-center gap-2",children:[m.jsx("span",{className:"text-amber-400/80 font-semibold text-sm",children:"note"}),m.jsxs("span",{className:"text-[#555] text-[13px]",children:["(",o,")"]})]}),a&&m.jsx("div",{className:"mt-1.5 text-[#999] text-[13px]",children:a}),s&&m.jsx("div",{className:"mt-1",children:m.jsx(ua,{text:s})})]})}if(e==="delete_note")return m.jsx("span",{className:"text-amber-400/80 font-semibold text-sm",children:"note removed"});if(e==="update_note"){const a=t.title??"",s=t.content??"";return m.jsxs("div",{children:[m.jsx("span",{className:"text-amber-400/80 font-semibold text-sm",children:"note updated"}),a&&m.jsx("div",{className:"mt-1.5 text-[#999] text-[13px]",children:a}),s&&m.jsx("div",{className:"mt-1",children:m.jsx(ua,{text:s})})]})}if(e==="get_note"){const a=r,s=a&&typeof a=="object"&&a.success?a.note:void 0;return m.jsxs("div",{children:[m.jsx("span",{className:"text-amber-400/80 font-semibold text-sm",children:"note read"}),s&&m.jsxs(m.Fragment,{children:[m.jsxs("div",{className:"mt-1.5 text-[#999] text-[13px]",children:[s.title??"(untitled)",m.jsxs("span",{className:"text-[#555] ml-1",children:["(",s.category??"general",")"]}),(s.by_you||s.agent_name)&&m.jsxs("span",{className:"text-[#666] ml-1 text-xs",children:["by ",s.by_you?"you":s.agent_name]})]}),s.content&&m.jsx("div",{className:"mt-1",children:m.jsx(ua,{text:s.content})})]})]})}if(e==="list_notes"){const a=r;let s=[];if(a&&typeof a=="object"&&a.success){const o=a.notes;s=Array.isArray(o)?o:[]}return m.jsxs("div",{children:[m.jsx("span",{className:"text-amber-400/80 font-semibold text-sm",children:"notes"}),s.length>0?m.jsx("div",{className:"mt-1.5 space-y-0.5",children:s.map((o,c)=>m.jsxs("div",{className:"text-[13px]",children:[m.jsx("span",{className:"text-[#555] mr-1",children:"-"}),m.jsx("span",{className:"text-[#999]",children:o.title??"(untitled)"}),m.jsxs("span",{className:"text-[#555] ml-1",children:["(",o.category??"general",")"]}),(o.by_you||o.agent_name)&&m.jsxs("span",{className:"text-[#666] ml-1 text-xs",children:["by ",o.by_you?"you":o.agent_name]}),o.content&&m.jsx("div",{className:"ml-3",children:m.jsx(ua,{text:o.content})})]},c))}):m.jsx("div",{className:"mt-1 text-[#555] text-xs",children:"No notes"})]})}return m.jsx("span",{className:"text-amber-400/80 font-semibold text-sm",children:"note"})}const nU={create_todo:{label:"Task added",Icon:Y_},list_todos:{label:"Plan",Icon:nC},update_todo:{label:"Task updated",Icon:nT},mark_todo_done:{label:"Task completed",Icon:H_},mark_todo_pending:{label:"Task reopened",Icon:fT},delete_todo:{label:"Task removed",Icon:CT}};function rU({status:e}){return e==="done"?m.jsx(H_,{className:"w-3.5 h-3.5 text-emerald-400/70 shrink-0"}):e==="in_progress"?m.jsx(mC,{className:"w-3.5 h-3.5 text-purple-400/70 shrink-0 animate-pulse"}):m.jsx($_,{className:"w-3.5 h-3.5 text-[#444] shrink-0"})}function iU({todos:e,highlightId:t}){return m.jsx("div",{className:"space-y-0",children:e.map((r,a)=>{const s=r.status??"pending",o=t&&r.id===t;return m.jsxs("div",{className:`flex items-start gap-2.5 py-1.5 px-2 -mx-2 rounded-md transition-colors ${o?"bg-purple-500/[0.08]":""}`,children:[m.jsx("div",{className:"mt-[1px]",children:m.jsx(rU,{status:s})}),m.jsx("span",{className:`text-[13px] leading-snug ${s==="done"?"text-[#555] line-through":s==="in_progress"?"text-[#bbb]":"text-[#999]"}`,children:r.title??"(untitled)"})]},r.id??a)})})}function aU({toolName:e,args:t,result:r}){const a=nU[e]??{label:"Plan",Icon:oT},s=a.Icon,o=r;if(typeof o=="string"&&o.trim())return m.jsxs("div",{children:[m.jsxs("div",{className:"flex items-center gap-2",children:[m.jsx(s,{className:"w-3.5 h-3.5 text-purple-400/60"}),m.jsx("span",{className:"text-purple-400/80 font-semibold text-sm",children:a.label})]}),m.jsx("div",{className:"mt-1.5 text-[#888] text-[13px]",children:o.trim()})]});let c=[],d=null,f;if(o&&typeof o=="object"){if(d=o.error??null,o.success){const p=o.todos;c=Array.isArray(p)?p:[]}f=o.id??t.todo_id??void 0}const h=e!=="list_todos"?f:void 0;return c.length===0&&!d?m.jsxs("div",{className:"flex items-center gap-2",children:[m.jsx(s,{className:"w-3.5 h-3.5 text-purple-400/60"}),m.jsx("span",{className:"text-purple-400/80 font-semibold text-sm",children:a.label})]}):m.jsxs("div",{children:[m.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[m.jsx(s,{className:"w-3.5 h-3.5 text-purple-400/60"}),m.jsx("span",{className:"text-purple-400/80 font-semibold text-sm",children:a.label})]}),d&&m.jsx("div",{className:"text-red-400/70 text-[13px] mb-2",children:d}),c.length>0&&m.jsx("div",{className:"rounded-lg border border-white/[0.06] bg-white/[0.015] px-3 py-2",children:m.jsx(iU,{todos:c,highlightId:h})})]})}function g_(e){if(e==null)return null;if(typeof e=="string")return e.trim()?e:null;if(typeof e=="object"){const t=e;if(typeof t.__raw=="string")return t.__raw;if(Object.keys(t).length===0)return null;try{return JSON.stringify(e,null,2)}catch{return String(e)}}return String(e)}function h2({toolName:e,args:t,result:r}){const a=g_(t),s=g_(r);return m.jsxs("div",{children:[m.jsx("span",{className:"text-[#888] font-semibold text-sm",children:e.replace(/_/g," ")}),a&&m.jsx(wi,{className:"text-[#777]",children:a}),s&&m.jsx(wi,{className:"text-[#666]",children:s})]})}function sU({args:e}){const t=e.skills,r=(Array.isArray(t)?t:String(t??"").split(",")).map(a=>String(a).trim()).filter(Boolean);return m.jsxs("div",{className:"flex items-center gap-2",children:[m.jsx("span",{className:"text-emerald-400/80 font-semibold text-sm",children:"Loading skill"}),r.length>0&&m.jsx("span",{className:"text-[#888] text-[13px]",children:r.join(", ")})]})}function lU({args:e}){const t=e.message??"";return t?m.jsxs("div",{children:[m.jsx(ua,{text:t}),m.jsx("div",{className:"mt-1.5 text-[#888] text-[13px]",children:"waiting for your reply"})]}):null}const oU={reported:{label:"reported",color:"text-orange-400",Icon:Nu},no_issue_found:{label:"no issue found",color:"text-emerald-400",Icon:Eu},ruled_out:{label:"ruled out",color:"text-emerald-400/70",Icon:Eu},not_applicable:{label:"not applicable",color:"text-[#777]",Icon:bC},needs_follow_up:{label:"needs follow-up",color:"text-yellow-400",Icon:gC}},cU=["reported","needs_follow_up","no_issue_found","ruled_out","not_applicable"];function mo(e){const t=(e??"").trim().toLowerCase();return oU[t]??{label:t?t.replace(/_/g," "):"unrecorded",color:"text-[#777]",Icon:$_}}const uU={record_coverage:"Coverage recorded",update_coverage:"Coverage updated",list_coverage:"Coverage"};function gu({toolName:e}){return m.jsxs("div",{className:"flex items-center gap-2",children:[m.jsx(q_,{className:"w-3.5 h-3.5 text-cyan-400/60"}),m.jsx("span",{className:"text-cyan-400/80 font-semibold text-sm",children:uU[e]??"Coverage"})]})}function dU({entry:e}){const{label:t,color:r,Icon:a}=mo(e.outcome),s=(e.previous_outcomes??[]).map(o=>mo(o).label).filter(Boolean);return m.jsxs("div",{className:"flex items-start gap-2.5 py-1.5",children:[m.jsx(a,{className:`w-3.5 h-3.5 shrink-0 mt-[2px] ${r}`}),m.jsxs("div",{className:"min-w-0",children:[m.jsxs("div",{className:"text-[13px] leading-snug",children:[m.jsx("span",{className:"text-[#bbb]",children:e.surface??"(unnamed surface)"}),e.risk_area&&m.jsxs("span",{className:"text-[#666]",children:[" · ",e.risk_area]})]}),m.jsxs("div",{className:"text-xs mt-0.5",children:[m.jsx("span",{className:r,children:t}),s.length>0&&m.jsxs("span",{className:"text-[#555]",children:[" (was ",s.join(" → "),")"]}),(e.by_you||e.agent_name)&&m.jsxs("span",{className:"text-[#555]",children:[" · ",e.by_you?"you":e.agent_name]})]}),e.evidence&&m.jsx("div",{className:"text-[#777] text-xs mt-1 leading-snug",children:e.evidence})]})]})}function fU({toolName:e,args:t,result:r}){const a=r;if(typeof a=="string"&&a.trim())return m.jsxs("div",{children:[m.jsx(gu,{toolName:e}),m.jsx("div",{className:"mt-1.5 text-[#888] text-[13px]",children:a.trim()})]});const s=a&&typeof a=="object"?a:null,o=t.surface??"",c=t.risk_area??"",d=t.evidence??"";if(s&&!s.success)return m.jsxs("div",{children:[m.jsx(gu,{toolName:e}),(o||c)&&m.jsxs("div",{className:"mt-1.5 text-[13px] text-[#bbb]",children:[o,c&&m.jsxs("span",{className:"text-[#666]",children:[" · ",c]})]}),m.jsx("div",{className:"mt-1 text-red-400/70 text-[13px]",children:s.error??"Coverage call failed"})]});if(e==="list_coverage"){const b=s==null?void 0:s.entries,_=Array.isArray(b)?b:[],E=(s==null?void 0:s.outcome_counts)??{},S=(s==null?void 0:s.total_count)??0;return m.jsxs("div",{children:[m.jsx(gu,{toolName:e}),Object.keys(E).length>0&&m.jsx("div",{className:"mt-2 flex items-center gap-3 flex-wrap",children:cU.filter(w=>E[w]).map(w=>{const{label:k,color:N}=mo(w);return m.jsxs("span",{className:`text-xs ${N}`,children:[k,": ",E[w]]},w)})}),_.length>0?m.jsx("div",{className:"mt-2 rounded-lg border border-white/[0.06] bg-white/[0.015] px-3 py-1 divide-y divide-white/[0.04]",children:_.map((w,k)=>m.jsx(dU,{entry:w},w.entry_id??k))}):m.jsx("div",{className:"mt-1.5 text-[#555] text-xs",children:S===0?"No surfaces recorded yet":"No surfaces match this filter"})]})}const f=(s==null?void 0:s.outcome)??"",h=(s==null?void 0:s.previous_outcome)??"",{label:p,color:g,Icon:y}=mo(f);return m.jsxs("div",{children:[m.jsx(gu,{toolName:e}),m.jsxs("div",{className:"mt-2 flex items-start gap-2.5",children:[m.jsx(y,{className:`w-3.5 h-3.5 shrink-0 mt-[2px] ${g}`}),m.jsxs("div",{className:"min-w-0",children:[m.jsxs("div",{className:"text-[13px] leading-snug text-[#bbb]",children:[o||(s!=null&&s.entry_id?`entry ${s.entry_id}`:"(unnamed surface)"),c&&m.jsxs("span",{className:"text-[#666]",children:[" · ",c]})]}),m.jsxs("div",{className:"text-xs mt-0.5",children:[h&&m.jsxs("span",{className:"text-[#666]",children:[mo(h).label," → "]}),m.jsx("span",{className:g,children:p})]}),d&&m.jsx("div",{className:"text-[#777] text-xs mt-1 leading-snug",children:d})]})]})]})}const hU={get_threat_model:{label:"Threat model",Icon:Vu},save_threat_model:{label:"Threat model saved",Icon:mT},amend_threat_model:{label:"Threat model amended",Icon:Y_}};function x_(e){const t=typeof e=="string"?e.trim():"";return!t||t==="unversioned"?"":t.slice(0,8)}function mU({toolName:e,args:t,result:r}){const a=hU[e]??{label:"Threat model",Icon:Vu},s=a.Icon,o=t.target??"",c=r,d=m.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[m.jsx(s,{className:"w-3.5 h-3.5 text-blue-400/60"}),m.jsx("span",{className:"text-blue-400/80 font-semibold text-sm",children:a.label}),o&&m.jsx("span",{className:"text-[#666] font-mono text-xs",children:o})]});if(typeof c=="string"&&c.trim())return m.jsxs("div",{children:[d,m.jsx("div",{className:"mt-1.5 text-[#888] text-[13px]",children:c.trim()})]});const f=c&&typeof c=="object"?c:null;if(f&&!f.success)return m.jsxs("div",{children:[d,m.jsx("div",{className:"mt-1.5 text-red-400/70 text-[13px]",children:f.error??"Threat model call failed"})]});if(e==="get_threat_model"){if(f&&!f.found)return m.jsxs("div",{children:[d,m.jsx("div",{className:"mt-1.5 text-[#555] text-xs",children:"No model cached for this target yet"})]});const y=f==null?void 0:f.amendments,b=Array.isArray(y)?y:[],_=x_(f==null?void 0:f.cached_revision);return m.jsxs("div",{children:[d,(f==null?void 0:f.stale)===!0&&m.jsxs("div",{className:"mt-1.5 flex items-center gap-1.5 text-yellow-400/80 text-xs",children:[m.jsx(Nu,{className:"w-3 h-3 shrink-0"}),m.jsxs("span",{children:["stale",_?` — written at ${_}`:""]})]}),b.length>0&&m.jsxs("div",{className:"mt-2",children:[m.jsxs("span",{className:"text-amber-400/70 text-xs font-semibold",children:[b.length," amendment",b.length===1?"":"s"]}),m.jsx("span",{className:"text-[#555] text-xs",children:" — later statements win"}),m.jsx("div",{className:"mt-1 space-y-1",children:b.map((E,S)=>m.jsxs("div",{className:"text-xs leading-snug",children:[m.jsx("span",{className:"text-[#666]",children:E.agent_name??"unknown agent"}),E.content&&m.jsxs("span",{className:"text-[#999]",children:[": ",E.content]})]},S))})]}),typeof(f==null?void 0:f.content)=="string"&&f.content.trim()&&m.jsx("div",{className:"mt-2",children:m.jsx(Yt,{text:f.content,maxLines:14})})]})}if(e==="amend_threat_model"){const y=t.addendum??"",b=f==null?void 0:f.amendment_count;return m.jsxs("div",{children:[d,b!=null&&m.jsxs("div",{className:"mt-1.5 text-[#666] text-xs",children:[b," amendment",b===1?"":"s"," on this model"]}),y&&m.jsx("div",{className:"mt-1.5",children:m.jsx(Yt,{text:y,maxLines:10})})]})}const h=(f==null?void 0:f.amendments_cleared)??0,p=x_(f==null?void 0:f.revision),g=t.content??"";return m.jsxs("div",{children:[d,p&&m.jsxs("div",{className:"mt-1.5 text-[#666] font-mono text-xs",children:["at ",p]}),h>0&&m.jsxs("div",{className:"mt-1.5 flex items-center gap-1.5 text-yellow-400/80 text-xs",children:[m.jsx(Nu,{className:"w-3 h-3 shrink-0"}),m.jsxs("span",{children:["cleared ",h," amendment",h===1?"":"s"]})]}),g&&m.jsx("div",{className:"mt-2",children:m.jsx(Yt,{text:g,maxLines:14})})]})}function pU(e){return!e||typeof e!="object"||Array.isArray(e)?[]:Object.entries(e).map(([t,r])=>{const a=typeof r=="string"?r:JSON.stringify(r);return`${t}: ${a??String(r)}`})}const b_=600;function gU(e){if(typeof e=="string"){const t=e.trim();return t?t.length>b_?`${t.slice(0,b_)}…`:t:null}return null}function xU({toolName:e,mcpTool:t,mcpConnection:r,args:a,result:s,status:o}){const c=pU(a),d=o==="failed"||o==="error",f=d?gU(s):null;return m.jsxs("div",{children:[m.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[m.jsx("span",{className:"font-mono text-teal-300 font-semibold text-sm",children:t||e}),m.jsx("span",{className:"text-[13px] text-[#555]",children:"via MCP server"}),r&&m.jsx("span",{className:"text-[13px] text-teal-400/80",children:r})]}),c.length>0&&m.jsx("div",{className:"mt-1 font-mono text-[13px] leading-relaxed",children:c.map(h=>m.jsx("div",{className:"text-[#777] break-all",children:h},h))}),m.jsxs("div",{className:"mt-1 text-[13px]",children:[o==="running"&&m.jsx("span",{className:"text-[#666]",children:"Running"}),o==="completed"&&m.jsx("span",{className:"text-emerald-400/80",children:"✓ Done"}),d&&m.jsx("span",{className:"text-red-400/80",children:"✗ Failed"})]}),f&&m.jsx("pre",{className:"mt-1 font-mono text-[13px] leading-relaxed whitespace-pre-wrap break-words text-red-400/70",children:f})]})}const Ga={terminal:{renderer:h7,icon:K_,color:"text-emerald-400"},python:{renderer:Z7,icon:EC,color:"text-yellow-400"},browser:{renderer:p7,icon:G_,color:"text-blue-400"},filesystem:{renderer:g7,icon:MC,color:"text-sky-400"},proxy:{renderer:H7,icon:z_,color:"text-purple-400",match:/request|sitemap|scope/},reporting:{renderer:A7,icon:bT,color:"text-red-400"},thinking:{renderer:$7,icon:B_,color:"text-purple-400"},agents:{renderer:q7,icon:Oo,color:"text-cyan-400",match:/agent/},search:{renderer:P7,icon:gT,color:"text-amber-400"},lifecycle:{renderer:J7,icon:F_,color:"text-emerald-400"},notes:{renderer:tU,icon:NT,color:"text-amber-400",match:/note/},skills:{renderer:sU,icon:Gm,color:"text-emerald-400"},todos:{renderer:aU,icon:YC,color:"text-purple-400",match:/todo/},coverage:{renderer:fU,icon:q_,color:"text-cyan-400",match:/coverage/},threatModel:{renderer:mU,icon:Vu,color:"text-blue-400",match:/threat_model/},telemetry:{renderer:h2,icon:Gm,color:"text-[#555]"},mcp:{renderer:xU,icon:V_,color:"text-teal-400"}},bU={terminal:["exec_command","write_stdin","terminal_execute"],python:["python_action"],browser:["browser_action"],filesystem:["apply_patch","view_image","str_replace_editor","list_files","search_files"],proxy:["list_requests","view_request","repeat_request","list_sitemap","view_sitemap_entry","scope_rules","send_request"],reporting:["create_vulnerability_report","list_reports","get_report"],thinking:["think"],agents:["create_agent","agent_finish","send_message_to_agent","wait_for_agents","view_agent_graph","stop_agent"],search:["web_search"],lifecycle:["scan_start_info","subagent_start_info","finish_scan","respond_to_user"],notes:["create_note","delete_note","update_note","list_notes","get_note"],skills:["load_skill"],todos:["create_todo","list_todos","update_todo","mark_todo_done","mark_todo_pending","delete_todo"],coverage:["record_coverage","update_coverage","list_coverage"],threatModel:["get_threat_model","save_threat_model","amend_threat_model"],telemetry:["sandbox_error_details","llm_error_details"],mcp:[]},yU=Object.fromEntries(Object.entries(bU).flatMap(([e,t])=>t.map(r=>[r,e]))),vU={finish_scan:eU,respond_to_user:lU,apply_patch:E7,view_image:k7,list_reports:f_,get_report:f_},_U={agent_finish:{icon:F_,color:"text-cyan-400"},send_message_to_agent:{icon:yh,color:"text-cyan-400"},wait_for_agents:{icon:yh,color:"text-cyan-400"},respond_to_user:{icon:yh,color:"text-emerald-400"},view_agent_graph:{icon:TC,color:"text-cyan-400"},stop_agent:{icon:I_,color:"text-red-400"},scan_start_info:{icon:Vu,color:"text-emerald-400"},subagent_start_info:{icon:Oo,color:"text-purple-400"},view_image:{icon:PC,color:"text-sky-400"}},wU=Ga.telemetry;function m2(e){var r;const t=yU[e];if(t)return t;for(const[a,s]of Object.entries(Ga))if((r=s.match)!=null&&r.test(e))return a;return null}function EU(e,t){if(t)return Ga.mcp.renderer;const r=vU[e];if(r)return r;const a=m2(e);return a?Ga[a].renderer:h2}function NU(e,t){if(t)return{icon:Ga.mcp.icon,color:Ga.mcp.color};const r=_U[e];if(r)return r;const a=m2(e),s=a?Ga[a]:wU;return{icon:s.icon,color:s.color}}const SU=30;function kU({role:e,content:t}){const r=e==="user"||e==="human";return m.jsxs("div",{children:[m.jsx("span",{className:`font-semibold text-sm ${r?"text-blue-400/80":"text-purple-400/80"}`,children:r?"User":"Thinking"}),m.jsx("div",{className:"mt-1.5 italic text-[#888]",children:m.jsx(Yt,{text:t,maxLines:SU})})]})}class CU extends ee.Component{constructor(t){super(t),this.state={hasError:!1}}static getDerivedStateFromError(){return{hasError:!0}}render(){return this.state.hasError?m.jsx("span",{className:"text-[#555] font-semibold text-sm",children:this.props.toolName.replace(/_/g," ")}):this.props.children}}function TU(e){const t=EU(e.toolName,e.mcpConnection);return m.jsx(CU,{toolName:e.toolName,children:m.jsx(t,{...e})})}function p2(e){if(e==null||typeof e!="string")return e;const t=e.trim();if(!t)return e;try{return JSON.parse(t)}catch{}try{const r=t.replace(/\bNone\b/g,"null").replace(/\bTrue\b/g,"true").replace(/\bFalse\b/g,"false").replace(/'/g,'"');return JSON.parse(r)}catch{return{__raw:e}}}function y_(e){return typeof e=="string"&&e?e:null}function g2(e){const t=p2(e);return t&&typeof t=="object"&&!Array.isArray(t)?t:t==null?{}:{__raw:typeof t=="string"?t:JSON.stringify(t)}}function v_(e){const t=/(\d+)$/.exec(e);return t?parseInt(t[1],10):0}function yg(e){var r;const t=(r=e.data)==null?void 0:r.role;return e.type==="chat"&&(t==="user"||t==="human")}function AU(e){var t;return yg(e)&&String(((t=e.data)==null?void 0:t.content)??"").startsWith("[Message from ")}function MU(e){const t=new Set;let r=!1;for(const a of e)if(yg(a)){if(AU(a)){t.add(a.id);continue}r||(r=!0,t.add(a.id))}return t}const OU={completed:"text-emerald-400 border-emerald-500/30 bg-emerald-500/10",running:"text-blue-400 border-blue-500/30 bg-blue-500/10",waiting:"text-yellow-400 border-yellow-500/30 bg-yellow-500/10",stopped:"text-[#aaa] border-[#333] bg-[#1a1a1a]",crashed:"text-red-400 border-red-500/30 bg-red-500/10",failed:"text-red-400 border-red-500/30 bg-red-500/10"};function RU(e){return e==="completed"?"completed":e==="running"?"running":e==="failed"||e==="crashed"?"failed":e}function jU(e,t){var d;const r=new Map;for(const f of e)if(f.parent_id){const h=r.get(f.parent_id)??[];h.push(f.id),r.set(f.parent_id,h)}const a=new Map,s=new Map,o=new Map;for(const f of t)if(f.type==="tool"){if(a.set(f.agent_id,(a.get(f.agent_id)??0)+1),((d=f.data)==null?void 0:d.tool_name)==="create_agent"){const h=g2(f.data.args),p=h.name??h.agent_name??"",g=h.task??"";p&&g&&o.set(p,g)}}else yg(f)||s.set(f.agent_id,(s.get(f.agent_id)??0)+1);const c=new Map;for(const f of e)c.set(f.id,{id:f.id,name:f.name,task:o.get(f.name)??"",status:RU(f.status),parentId:f.parent_id,children:r.get(f.id)??[],createdAt:f.created_at,toolCount:a.get(f.id)??0,messageCount:s.get(f.id)??0});return c}function DU({agent:e,events:t,showHeader:r=!0}){const a=ee.useMemo(()=>{const c=t.filter(f=>f.agent_id===e.id).sort((f,h)=>v_(f.id)-v_(h.id)),d=MU(c);return c.filter(f=>!d.has(f.id))},[t,e.id]),s=a.filter(c=>c.type==="tool").length,o=a.length-s;return m.jsxs("div",{children:[r&&m.jsxs(m.Fragment,{children:[m.jsxs("div",{className:"flex items-center gap-2 flex-wrap mb-1",children:[m.jsx("span",{className:"text-base font-semibold text-white truncate",children:e.name}),m.jsx("span",{className:`flex-shrink-0 text-xs font-medium capitalize px-2 py-0.5 rounded-full border ${OU[e.status]??"text-[#aaa] border-[#333] bg-[#1a1a1a]"}`,children:e.status}),m.jsx("span",{className:"font-mono text-xs text-[#555]",children:e.id})]}),m.jsxs("p",{className:"text-xs text-[#666] mb-4",children:[o," message",o===1?"":"s"," · ",s," tool call",s===1?"":"s"]})]}),a.length===0?m.jsx("p",{className:"text-sm text-[#666]",children:"No recorded activity for this agent."}):m.jsx("div",{className:"py-1",children:a.map((c,d)=>{var w,k,N,M,B,R,U,I;const f=d===a.length-1,h=c.type==="tool",p=h?String(((w=c.data)==null?void 0:w.tool_name)??"tool"):"",g=h?"":String(((k=c.data)==null?void 0:k.role)??"assistant"),y=y_((N=c.data)==null?void 0:N.mcp_connection),b=y_((M=c.data)==null?void 0:M.mcp_tool);let _,E;if(h){const X=NU(p,y);_=X.icon,E=X.color}else{const X=g==="user"||g==="human";_=X?Oo:B_,E=X?"text-blue-400":"text-purple-400"}const S=h?String(((B=c.data)==null?void 0:B.status)??"completed"):"completed";return m.jsxs("div",{className:"flex gap-3",children:[m.jsxs("div",{className:"flex flex-col items-center shrink-0",children:[m.jsx("div",{className:`w-[30px] h-[30px] rounded-full bg-black border flex items-center justify-center shrink-0 ${h&&S==="running"?"border-blue-500/40 animate-pulse":h&&S==="failed"?"border-red-500/30":"border-[#222]"}`,children:m.jsx(_,{className:`w-3.5 h-3.5 ${E}`})}),!f&&m.jsx("div",{className:"w-px flex-1 bg-[#1a1a1a] mt-1"})]}),m.jsx("div",{className:"flex-1 min-w-0 pt-[5px] pb-6",children:h?m.jsx(TU,{toolName:p,mcpConnection:y,mcpTool:b,args:g2((R=c.data)==null?void 0:R.args),result:p2((U=c.data)==null?void 0:U.result)??null,status:S}):m.jsx(kU,{role:g,content:String(((I=c.data)==null?void 0:I.content)??"")})})]},c.id)})})]})}class qu extends Error{constructor(t){super(t),this.name="RunParseError"}}const LU=["critical","high","medium","low"];function zU(e){const t=String(e??"").toLowerCase().trim();return LU.includes(t)?t:"low"}function IU(e){if(typeof e=="string"&&e.trim()){const t=e.trim().replace(" UTC","Z").replace(" ","T"),r=new Date(t);if(!Number.isNaN(r.getTime()))return r.toISOString();const a=new Date(e);if(!Number.isNaN(a.getTime()))return a.toISOString()}return new Date().toISOString()}function Ot(e){return typeof e=="string"&&e.length>0?e:null}function BU(e){return typeof e=="number"&&Number.isFinite(e)?e:null}function x2(e,t){try{return JSON.parse(e)}catch{throw new qu(`${t} isn't valid JSON. Make sure you selected a Strix run directory.`)}}function UU(e){const t=x2(e,"run.json");if(!t||typeof t!="object"||Array.isArray(t))throw new qu("run.json is not an object.");const r=t,a=[],s=r.targets_info;if(Array.isArray(s)){for(const b of s)if(b&&typeof b=="object"){const _=b.original;typeof _=="string"&&_&&a.push(_)}}const o=Ot(r.start_time),c=Ot(r.end_time);let d=null;if(o&&c){const b=new Date(o).getTime(),_=new Date(c).getTime();!Number.isNaN(b)&&!Number.isNaN(_)&&_>=b&&(d=Math.round((_-b)/1e3))}let f=null,h=null,p=null,g=null;const y=r.scan_results;if(y&&typeof y=="object"){const b=y;f=Ot(b.executive_summary),h=Ot(b.technical_analysis),p=Ot(b.methodology),g=Ot(b.recommendations)}return{runId:Ot(r.run_id),runName:Ot(r.run_name),targets:a,scanMode:Ot(r.scan_mode),status:Ot(r.status),startTime:o,endTime:c,durationSeconds:d,executiveSummary:f,technicalAnalysis:h,methodology:p,recommendations:g}}function HU(){return{pr_review_id:null,cve:null,cvss:null,potential_risk_saving:null,risk_saving_description:null,impact:null,endpoint:null,method:null,target:null,technical_analysis:null,poc_description:null,poc_script_code:null,code_diff:null,code_file:null,code_before:null,code_after:null,cwe:null,code_locations:null,remediation_steps:null,fix_pr_body:null,evidence:null,assumptions:null,fix_effort:null,cvss_breakdown:null,status_changed_at:null,status_changed_by:null,status_note:null,snoozed_until:null,reopened_at:null,reopened_by:null,original_severity:null,severity_changed_at:null,severity_changed_by:null,severity_override_reason:null,retest_of_vulnerability_id:null}}function $U(e,t,r){const a=e.cwe,s=typeof a=="string"&&a.trim()?[a.trim()]:Array.isArray(a)?a.filter(c=>typeof c=="string"&&c):null;return{...HU(),id:Ot(e.id)??`vuln-${t+1}`,scan_id:r,title:Ot(e.title)??"Untitled finding",description:Ot(e.description)??"",severity:zU(e.severity),status:"open",created_at:IU(e.timestamp),cve:Ot(e.cve),cvss:BU(e.cvss),impact:Ot(e.impact),endpoint:Ot(e.endpoint),method:Ot(e.method),target:Ot(e.target),technical_analysis:Ot(e.technical_analysis),poc_description:Ot(e.poc_description),poc_script_code:Ot(e.poc_script_code),cwe:s,code_locations:Array.isArray(e.code_locations)?e.code_locations:null,remediation_steps:Ot(e.remediation_steps),fix_pr_body:Ot(e.fix_pr_body),evidence:Ot(e.evidence),assumptions:Ot(e.assumptions),fix_effort:Ot(e.fix_effort)??null,cvss_breakdown:e.cvss_breakdown??null}}function qU(e,t=null){const r=x2(e,"vulnerabilities.json");if(!Array.isArray(r))throw new qu("vulnerabilities.json is not a JSON array.");return r.map((a,s)=>{if(!a||typeof a!="object")throw new qu(`vulnerabilities.json entry #${s+1} is not an object.`);return $U(a,s,t)})}function PU(e){const t={critical:0,high:0,medium:0,low:0};for(const r of e)t[r.severity]+=1;return t}async function es(e){const t=await fetch(e,{cache:"no-store"});if(!t.ok)throw new Error(`${e} responded ${t.status}`);return t.json()}function dd(e){return e?`?run=${encodeURIComponent(e)}`:""}async function b2(e){const t=await es("/api/run"+dd(e)),r=UU(JSON.stringify(t)),a=t.finished===!0;return{summary:r,raw:t,finished:a}}async function y2(e,t){const r=await es("/api/vulnerabilities"+dd(t));return qU(JSON.stringify(r),e)}async function FU(e){const t=await es("/api/report"+dd(e));return(t==null?void 0:t.markdown)??null}async function v2(e){const t=await es("/api/transcript"+dd(e));return{agents:Array.isArray(t==null?void 0:t.agents)?t.agents:[],events:Array.isArray(t==null?void 0:t.events)?t.events:[]}}async function __(e){const{summary:t,raw:r,finished:a}=await b2(e),[s,o,c]=await Promise.all([y2(t.runId,e).catch(()=>[]),FU(e).catch(()=>null),v2(e).catch(()=>({agents:[],events:[]}))]);return{summary:t,raw:r,finished:a,vulnerabilities:s,reportMarkdown:o,transcript:c}}async function il(e,t){const r=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t),cache:"no-store"});let a={};try{const s=await r.json();s&&typeof s=="object"&&(a=s)}catch{}return{ok:r.ok,status:r.status,data:a}}async function GU(){const e=await es("/api/runs");return{locked:(e==null?void 0:e.locked)??!0,count:typeof(e==null?void 0:e.count)=="number"?e.count:0,runs:Array.isArray(e==null?void 0:e.runs)?e.runs:[]}}async function VU(){const e=await es("/api/capabilities");return{can_steer:(e==null?void 0:e.can_steer)===!0}}async function YU(e,t){const{ok:r,data:a}=await il("/api/agents/steer",{agent_id:e,message:t});return r&&a.ok===!0?{ok:!0}:{ok:!1,error:String(a.error??"unavailable")}}async function XU(e,t){const{ok:r,data:a}=await il("/api/feedback",{message:e,email:t});return r&&a.ok===!0?{ok:!0}:{ok:!1,error:String(a.error??"unavailable")}}async function KU(){const e=await es("/api/auth/status");return{verified:(e==null?void 0:e.verified)===!0,email:(e==null?void 0:e.email)??null}}async function _2(e){const{ok:t,data:r}=await il("/api/auth/otp/start",{email:e});return t&&r.ok===!0?{ok:!0}:{ok:!1,error:String(r.error??"unavailable")}}async function w2(e,t){const{ok:r,data:a}=await il("/api/auth/otp/verify",{email:e,code:t});return r&&a.verified===!0?{verified:!0,email:String(a.email??e)}:{verified:!1,error:String(a.error??"invalid_code")}}async function ZU(){await il("/api/auth/forget",{})}async function QU(e){const{ok:t,data:r}=await il("/api/report/send",e?{run:e}:{});return t&&r.ok===!0?{ok:!0,password:String(r.password??""),filename:String(r.filename??"strix-report.pdf")}:{ok:!1,error:String(r.error??"unavailable")}}const Us="__root__";function E2({agents:e,fixedAgentId:t,className:r}){const a=ee.useRef(null),[s,o]=ee.useState(!1),[c,d]=ee.useState(!1),[f,h]=ee.useState(""),[p,g]=ee.useState(!1),[y,b]=ee.useState(null),_=t!=null,E=ee.useMemo(()=>e.find(z=>!z.parent_id)??e[0]??null,[e]),S=ee.useMemo(()=>e.filter(z=>z.parent_id&&z.status==="running"),[e]),[w,k]=ee.useState(Us),[N,M]=ee.useState(!1);ee.useEffect(()=>{w!==Us&&!S.some(z=>z.id===w)&&k(Us)},[w,S]);const{targetId:B,targetName:R}=ee.useMemo(()=>{if(_){const V=e.find(P=>P.id===t)??null;return{targetId:t??null,targetName:(V==null?void 0:V.name)??"this agent"}}if(w===Us)return{targetId:(E==null?void 0:E.id)??null,targetName:"Root agent"};const z=e.find(V=>V.id===w)??null;return{targetId:(z==null?void 0:z.id)??(E==null?void 0:E.id)??null,targetName:(z==null?void 0:z.name)??"Root agent"}},[e,t,_,E,w]),U=f.trim().length===0;ee.useLayoutEffect(()=>{const z=a.current;z&&(z.style.height="auto",z.style.height=`${z.scrollHeight}px`)},[f]);const I=ee.useCallback(()=>{o(!0),requestAnimationFrame(()=>{var z;return(z=a.current)==null?void 0:z.focus()})},[]),X=ee.useCallback(()=>{o(!1),d(!1),M(!1)},[]),j=ee.useCallback(async()=>{if(p)return;const z=f.trim();if(!z||!B)return;g(!0),b(null);const V=R,P=await YU(B,z);g(!1),P.ok?(h(""),b(`Sent to ${V}`),Tr("agent_steered")):P.error==="not_delivered"?b("Could not reach that agent (it may have finished)."):b("Could not send that message. Try again.")},[p,f,B,R]);return s?m.jsxs("div",{className:Mr("mt-4 rounded-2xl border border-white/[0.08] bg-[#050505] overflow-hidden transition-colors duration-300",c?"border-white/[0.18]":"hover:border-white/[0.12]",r),children:[m.jsxs("div",{className:"flex items-center justify-between gap-3 border-b border-white/[0.06] px-5 py-3",children:[m.jsxs("div",{className:"min-w-0",children:[m.jsxs("div",{className:"flex items-center gap-2",children:[m.jsx(Fm,{className:"h-4 w-4 text-[#666]"}),m.jsx("p",{className:"text-sm font-medium text-white",children:"Live prompt"})]}),m.jsx("p",{className:"mt-0.5 text-xs text-[#777]",children:"Connected"})]}),m.jsxs("div",{className:"flex shrink-0 items-center gap-2",children:[_?m.jsxs("div",{className:"rounded-full border border-white/[0.08] bg-white/[0.03] px-3 py-1 text-xs text-[#aaa]",children:["Target: ",m.jsx("span",{className:"text-white",children:R})]}):m.jsxs("div",{className:"flex items-center gap-1.5",children:[m.jsx("span",{className:"text-xs text-[#aaa]",children:"Target:"}),m.jsxs("div",{className:"relative",children:[m.jsxs("button",{type:"button",onClick:()=>M(z=>!z),onBlur:()=>requestAnimationFrame(()=>M(!1)),className:"inline-flex h-7 items-center gap-1 rounded-full border border-white/[0.08] bg-white/[0.03] px-3 text-xs text-white transition-colors hover:border-white/[0.16] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/20","aria-haspopup":"listbox","aria-expanded":N,children:[m.jsx("span",{className:"max-w-[140px] truncate",children:R}),m.jsx(po,{className:"h-3.5 w-3.5 text-[#999]"})]}),N&&m.jsxs("div",{className:"absolute right-0 z-10 mt-1 min-w-[160px] overflow-hidden rounded-lg border border-[#333] bg-[#0a0a0a] py-1 shadow-xl",role:"listbox",children:[m.jsx(w_,{label:"Root agent",active:w===Us,onSelect:()=>{k(Us),M(!1)}}),S.map(z=>m.jsx(w_,{label:z.name,active:w===z.id,onSelect:()=>{k(z.id),M(!1)}},z.id))]})]})]}),m.jsx("button",{type:"button",onClick:X,className:"inline-flex h-7 w-7 items-center justify-center rounded-full text-[#777] transition-colors hover:bg-white/[0.06] hover:text-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/20","aria-label":"Collapse live prompt composer",children:m.jsx(po,{className:"h-4 w-4"})})]})]}),m.jsx("div",{className:"px-5 pt-4 pb-3",children:m.jsx("textarea",{ref:a,rows:1,value:f,onChange:z=>h(z.target.value),onFocus:()=>d(!0),onBlur:()=>d(!1),onKeyDown:z=>{z.key==="Enter"&&!z.shiftKey&&(z.preventDefault(),j())},placeholder:"Send a live prompt to the running pentest…",maxLength:4e3,disabled:p,className:"block w-full resize-none border-0 bg-transparent p-0 text-[15px] leading-6 text-white placeholder:text-[#444] focus:outline-none disabled:opacity-60 max-h-[160px] overflow-y-auto"})}),m.jsxs("div",{className:"flex items-center justify-between gap-3 px-4 pb-4",children:[m.jsx("div",{className:"text-xs text-[#666]",children:y??"Press Enter to send."}),m.jsxs("button",{type:"button",onClick:z=>{z.stopPropagation(),j()},disabled:p||U,className:Mr("inline-flex h-10 min-w-[112px] items-center justify-center gap-2 rounded-full px-4 text-sm font-medium transition-colors",p||U?"bg-white/[0.08] text-[#666]":"bg-white text-black hover:bg-neutral-200"),children:[p?m.jsx(Ps,{className:"h-4 w-4 animate-spin"}):m.jsx(Yk,{className:"h-4 w-4",strokeWidth:2.5}),m.jsx("span",{children:"Send prompt"})]})]})]}):m.jsxs("button",{type:"button",onClick:I,className:Mr("mt-4 flex w-full items-center justify-between gap-3 rounded-2xl border border-white/[0.08] bg-[#050505] px-5 py-3 text-left transition-colors duration-300 hover:border-white/[0.12] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/20",r),"aria-expanded":!1,"aria-label":"Expand live prompt composer",children:[m.jsxs("div",{className:"flex min-w-0 items-center gap-2",children:[m.jsx(Fm,{className:"h-4 w-4 shrink-0 text-[#666]"}),m.jsx("span",{className:"truncate text-sm font-medium text-white",children:"Guide the agent"})]}),m.jsx(U_,{className:"h-4 w-4 shrink-0 text-[#777]"})]})}function w_({label:e,active:t,onSelect:r}){return m.jsx("button",{type:"button",role:"option","aria-selected":t,onMouseDown:a=>{a.preventDefault(),r()},className:Mr("block w-full truncate px-3 py-1.5 text-left text-xs transition-colors hover:bg-white/[0.06]",t?"text-white":"text-[#aaa]"),children:e})}const WU={completed:"bg-emerald-400",running:"bg-blue-400",waiting:"bg-yellow-400",stopped:"bg-[#888]",crashed:"bg-red-400",failed:"bg-red-400"},JU=80;function eH({open:e,agent:t,events:r,steerable:a,onClose:s}){const o=ee.useRef(null),c=ee.useRef(!1),[d,f]=ee.useState(e),[h,p]=ee.useState(e?"open":"closed"),[g,y]=ee.useState(!1),b=ee.useRef(t);ee.useEffect(()=>{t&&(b.current=t)},[t]);const _=t??b.current;ee.useEffect(()=>{if(e){f(!0),p("open");return}p("closed");const S=setTimeout(()=>f(!1),140);return()=>clearTimeout(S)},[e]),ee.useEffect(()=>{if(!d){y(!1);return}const S=requestAnimationFrame(()=>y(!0));return()=>cancelAnimationFrame(S)},[d]);const E=ee.useCallback(()=>{const S=o.current;S&&(c.current=S.scrollHeight-S.scrollTop-S.clientHeight{const S=o.current;!S||!c.current||requestAnimationFrame(()=>{S.scrollTo({top:S.scrollHeight,behavior:"smooth"})})},[r]),ee.useEffect(()=>{if(!d)return;const S=k=>{k.key==="Escape"&&s()};document.addEventListener("keydown",S);const w=document.body.style.overflow;return document.body.style.overflow="hidden",()=>{document.removeEventListener("keydown",S),document.body.style.overflow=w}},[d,s]),!d||!_?null:m.jsx("div",{"data-state":h,className:"agent-modal fixed inset-0 z-50 flex items-center justify-center bg-black/80 p-4 sm:p-8",onClick:s,role:"dialog","aria-modal":"true","aria-label":`Agent ${_.name}`,children:m.jsxs("div",{className:"relative flex h-[60vh] w-[calc(100vw-4rem)] max-w-6xl flex-col overflow-hidden rounded-xl border border-[#222] bg-[#0a0a0a] shadow-2xl",onClick:S=>S.stopPropagation(),children:[m.jsxs("div",{className:"flex items-center justify-between gap-3 border-b border-[#222] px-5 py-3.5",children:[m.jsxs("div",{className:"flex min-w-0 items-center gap-2",children:[m.jsx("span",{className:`h-2 w-2 flex-shrink-0 rounded-full ${WU[_.status]??"bg-[#888]"}`}),m.jsx("span",{className:"truncate text-sm font-semibold text-white",children:_.name}),m.jsx("span",{className:"flex-shrink-0 font-mono text-xs text-[#555]",children:_.id})]}),m.jsx("button",{type:"button",onClick:s,"aria-label":"Close",className:"flex-shrink-0 rounded-md p-1 text-[#888] transition-colors hover:bg-[#1a1a1a] hover:text-white",children:m.jsx(Sp,{className:"h-4 w-4"})})]}),m.jsx("div",{ref:o,onScroll:E,className:"flex-1 overflow-y-auto p-5",children:g&&m.jsx(DU,{agent:_,events:r,showHeader:!1})}),a&&m.jsx("div",{className:"border-t border-[#222] px-5 py-3",children:m.jsx(E2,{agents:[_],fixedAgentId:_.id,className:"mt-0"})})]})})}var N2={color:void 0,size:void 0,className:void 0,style:void 0,attr:void 0},E_=da.createContext&&da.createContext(N2),tH=["attr","size","title"];function nH(e,t){if(e==null)return{};var r,a,s=rH(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;ada.createElement(t.tag,Fu({key:r},t.attr),S2(t.child)))}function vg(e){return t=>da.createElement(lH,Pu({attr:Fu({},e.attr)},t),S2(e.child))}function lH(e){var t=r=>{var a=e.attr,s=e.size,o=e.title,c=nH(e,tH),d=s||r.size||"1em",f;return r.className&&(f=r.className),e.className&&(f=(f?f+" ":"")+e.className),da.createElement("svg",Pu({stroke:"currentColor",fill:"currentColor",strokeWidth:"0"},r.attr,a,c,{className:f,style:Fu(Fu({color:e.color||r.color},r.style),e.style),height:d,width:d,xmlns:"http://www.w3.org/2000/svg"}),o&&da.createElement("title",null,o),e.children)};return E_!==void 0?da.createElement(E_.Consumer,null,r=>t(r)):t(N2)}function oH(e){return vg({attr:{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},child:[{tag:"circle",attr:{cx:"5",cy:"6",r:"3"},child:[]},{tag:"path",attr:{d:"M5 9v12"},child:[]},{tag:"circle",attr:{cx:"19",cy:"18",r:"3"},child:[]},{tag:"path",attr:{d:"m15 9-3-3 3-3"},child:[]},{tag:"path",attr:{d:"M12 6h5a2 2 0 0 1 2 2v7"},child:[]}]})(e)}function cH(e){return vg({attr:{viewBox:"0 0 16 16",fill:"currentColor"},child:[{tag:"path",attr:{d:"M15 4.95703C15 4.58711 14.8563 4.24054 14.5949 3.97992L12.0096 1.39234C11.4879 0.86922 10.5788 0.86922 10.0571 1.39234L8 3.45119V3.32321C8 2.55068 7.37187 1.922 6.6 1.922H2.4C1.62813 1.922 1 2.55068 1 3.32321V13.5988C1 14.3713 1.62813 15 2.4 15H12.6667C13.4385 15 14.0667 14.3713 14.0667 13.5988V9.39514C14.0667 8.62261 13.4385 7.99393 12.6667 7.99393H12.5379L14.5949 5.93508C14.8553 5.67445 15 5.32602 15 4.95703ZM2.4 2.85521H6.6C6.85667 2.85521 7.06667 3.06446 7.06667 3.32228V7.99299H1.93333V3.32228C1.93333 3.06446 2.14333 2.85521 2.4 2.85521ZM1.93333 13.5979V8.92714H7.06667V14.0649H2.4C2.14333 14.0649 1.93333 13.8547 1.93333 13.5979ZM13.1333 9.39421V13.5979C13.1333 13.8547 12.9233 14.0649 12.6667 14.0649H8V8.92714H12.6667C12.9233 8.92714 13.1333 9.13638 13.1333 9.39421ZM8 7.99299V6.46287L9.5288 7.99299H8ZM13.9351 5.2737L11.3488 7.86221C11.1789 8.03223 10.8859 8.03223 10.716 7.86221L8.12973 5.2737C8.0448 5.18963 7.99813 5.07753 7.99813 4.95796C7.99813 4.83839 8.0448 4.7263 8.12973 4.64129L10.716 2.05278C10.8009 1.96777 10.9129 1.92106 11.0324 1.92106C11.1519 1.92106 11.2639 1.96777 11.3488 2.05278L13.9351 4.64129C14.02 4.72536 14.0667 4.83746 14.0667 4.95703C14.0667 5.0766 14.02 5.1887 13.9351 5.2737Z"},child:[]}]})(e)}function k2(e){return vg({attr:{viewBox:"0 0 512 512"},child:[{tag:"path",attr:{fill:"none",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"32",d:"M431 320.6c-1-3.6 1.2-8.6 3.3-12.2a34 34 0 0 1 2.1-3.1A162 162 0 0 0 464 215c.3-92.2-77.5-167-173.7-167-83.9 0-153.9 57.1-170.3 132.9a160.7 160.7 0 0 0-3.7 34.2c0 92.3 74.8 169.1 171 169.1 15.3 0 35.9-4.6 47.2-7.7s22.5-7.2 25.4-8.3a26.4 26.4 0 0 1 9.3-1.7 26 26 0 0 1 10.1 2l56.7 20.1a13.5 13.5 0 0 0 3.9 1 8 8 0 0 0 8-8 13 13 0 0 0-.5-2.7z"},child:[]},{tag:"path",attr:{fill:"none",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"32",d:"M66.46 232a146.23 146.23 0 0 0 6.39 152.67c2.31 3.49 3.61 6.19 3.21 8s-11.93 61.87-11.93 61.87a8 8 0 0 0 2.71 7.68A8.17 8.17 0 0 0 72 464a7.3 7.3 0 0 0 2.91-.6l56.21-22a15.7 15.7 0 0 1 12 .2c18.94 7.38 39.88 12 60.83 12A159.2 159.2 0 0 0 284 432.11"},child:[]}]})(e)}const uH=[{icon:LC,label:"PR security reviews"},{icon:_T,label:"Attack surface monitoring"},{icon:zT,label:"Real-time threat intelligence"},{icon:eC,label:"Scheduled pentesting"},{icon:RT,label:"One-click autofix"},{icon:V_,label:"Jira, Linear & Slack integrations"}];function dH({open:e,onClose:t,description:r,source:a="sidebar"}){const[s,o]=ee.useState(e),[c,d]=ee.useState(e?"open":"closed");return ee.useEffect(()=>{if(e){o(!0),d("open");return}d("closed");const f=setTimeout(()=>o(!1),200);return()=>clearTimeout(f)},[e]),ee.useEffect(()=>{if(!s)return;const f=p=>{p.key==="Escape"&&t()};document.addEventListener("keydown",f);const h=document.body.style.overflow;return document.body.style.overflow="hidden",()=>{document.removeEventListener("keydown",f),document.body.style.overflow=h}},[s,t]),s?m.jsx("div",{"data-state":c,className:"dialog-overlay fixed inset-0 z-50 flex items-center justify-center bg-black/80 p-4",onClick:t,role:"dialog","aria-modal":"true","aria-label":"Upgrade your plan",children:m.jsxs("div",{"data-state":c,className:"dialog-panel relative w-full max-w-md rounded-2xl border border-[#222] bg-black p-6 shadow-lg sm:rounded-lg",onClick:f=>f.stopPropagation(),children:[m.jsx("button",{type:"button",onClick:t,"aria-label":"Close",className:"absolute right-4 top-4 rounded-md p-1 text-[#888] transition-colors hover:bg-[#1a1a1a] hover:text-white",children:m.jsx(Sp,{className:"h-4 w-4"})}),m.jsxs("div",{children:[m.jsx("h2",{className:"text-lg text-white",children:"Available in Strix Cloud"}),r&&m.jsx("p",{className:"mt-2 text-base leading-relaxed text-[#e5e5e5]",children:r})]}),m.jsxs("div",{className:"space-y-4 pt-4",children:[m.jsxs("div",{className:"rounded-xl border border-[#333] bg-[#0a0a0a] p-4 sm:rounded-lg",children:[m.jsxs("div",{className:"mb-3 flex items-center gap-2",children:[m.jsx(Fm,{className:"h-4 w-4 text-blue-400"}),m.jsx("span",{className:"text-sm font-medium text-white",children:"Strix Cloud also includes"})]}),m.jsx("ul",{className:"space-y-2 text-sm text-[#888]",children:uH.map(f=>m.jsxs("li",{className:"flex items-center gap-2",children:[m.jsx(f.icon,{className:"h-3.5 w-3.5 text-[#555]"}),f.label]},f.label))})]}),m.jsxs("div",{className:"flex flex-col gap-2",children:[m.jsxs("a",{href:ha(Yu,"upgrade_try_free"),target:"_blank",rel:"noopener noreferrer",onClick:()=>jr("upgrade_try_free",a),className:"flex h-10 w-full items-center justify-center gap-2 rounded-lg bg-white px-4 text-sm font-semibold text-black transition-colors hover:bg-neutral-200",children:["Open Strix Cloud",m.jsx(oy,{className:"h-3.5 w-3.5"})]}),m.jsxs("a",{href:ha($T,"upgrade_view_plans"),target:"_blank",rel:"noopener noreferrer",onClick:()=>jr("upgrade_view_plans",a),className:"flex h-9 w-full items-center justify-center gap-1.5 rounded-lg border border-[#333] px-4 text-sm font-medium text-[#888] transition-colors hover:border-[#555] hover:text-white",children:["Learn more",m.jsx(oy,{className:"h-3 w-3"})]})]})]})]})}):null}const Hm=160,$m=260,io=400,fH=140,S_="strix_viewer_sidebar_width",k_="strix_viewer_sidebar_collapsed";function hH(e,t){try{const r=localStorage.getItem(e),a=r?parseInt(r,10):NaN;return Number.isFinite(a)?a:t}catch{return t}}function mH({view:e,onSelectView:t,issuesCount:r,agentCount:a,runCount:s,finished:o,verified:c,email:d,onOpenEmail:f,onOpenHistory:h,onForget:p}){var z;const[g,y]=ee.useState(()=>{const V=hH(S_,$m);return Math.min(io,Math.max(Hm,V))}),[b,_]=ee.useState(()=>{try{return localStorage.getItem(k_)==="1"}catch{return!1}}),[E,S]=ee.useState(!1),[w,k]=ee.useState(!1),[N,M]=ee.useState(null),B=ee.useRef(null),R=(V,P)=>{jr(V,"sidebar"),M(P)},U=ee.useCallback(V=>{y(V);try{localStorage.setItem(S_,String(V))}catch{}},[]),I=ee.useCallback(V=>{_(V);try{localStorage.setItem(k_,V?"1":"0")}catch{}},[]),X=ee.useCallback(()=>{I(!1),U($m)},[I,U]),j=ee.useCallback(V=>{V.preventDefault(),S(!0)},[]);return ee.useEffect(()=>{if(!E||b)return;const V=T=>{const $=T.clientX;$>=Hm&&$<=io?y($):$>io&&y(io)},P=T=>{const $=T.clientX;${window.removeEventListener("mousemove",V),window.removeEventListener("mouseup",P)}},[E,b,I,U]),ee.useEffect(()=>{if(!w)return;const V=P=>{B.current&&!B.current.contains(P.target)&&k(!1)};return document.addEventListener("mousedown",V),()=>document.removeEventListener("mousedown",V)},[w]),m.jsxs(m.Fragment,{children:[b&&m.jsx("div",{className:"fixed left-0 top-0 z-40 hidden h-full w-4 cursor-pointer transition-colors hover:bg-[rgba(255,255,255,0.08)] lg:block",onClick:X,title:"Expand sidebar"}),m.jsxs("aside",{className:Mr("sticky top-0 z-20 hidden h-screen flex-shrink-0 flex-col overflow-hidden border-r border-[rgba(255,255,255,0.08)] bg-black lg:flex",!E&&"transition-[width] duration-200 ease-out"),style:{width:b?0:g},children:[m.jsx("header",{className:"relative flex flex-col gap-1 pt-1 min-w-[160px]",children:m.jsx("div",{className:"flex flex-row py-1 px-2",children:m.jsxs("div",{className:"flex h-10 w-full flex-row items-center",children:[m.jsxs("a",{href:ha("https://app.strix.ai","logo"),target:"_blank",rel:"noopener noreferrer",onClick:()=>jr("logo","sidebar"),className:"flex flex-1 flex-row items-center gap-2 rounded-md py-2 pl-2.5 pr-1 min-w-0 transition-colors hover:bg-[rgba(255,255,255,0.06)]",title:"Open Strix Cloud",children:[m.jsx("span",{className:"flex flex-shrink-0 items-center justify-center rounded-full bg-gradient-to-br from-emerald-400 to-cyan-500",style:{width:20,height:20},children:m.jsx("span",{className:"text-[10px] font-semibold text-white",children:"S"})}),m.jsxs("span",{className:"flex flex-1 flex-row items-center gap-2 min-w-0",children:[m.jsx("span",{className:"truncate min-w-0 text-[14px] font-medium text-[#ededed]",children:"Strix"}),m.jsx("span",{className:"flex h-5 flex-shrink-0 items-center rounded px-2 text-[11px] font-medium text-[#888] bg-[rgba(255,255,255,0.08)]",children:"Local"})]})]}),m.jsx("a",{href:ha("https://app.strix.ai","logo"),target:"_blank",rel:"noopener noreferrer",onClick:()=>jr("logo","sidebar"),className:"flex flex-none items-center rounded-md px-1.5 py-2 transition-colors hover:bg-[rgba(255,255,255,0.06)]","aria-label":"Open Strix Cloud",children:m.jsx(cC,{className:"h-4 w-4 text-[#666]"})})]})})}),m.jsx("nav",{className:"relative min-w-[160px] flex-1 overflow-y-auto overflow-x-clip scrollbar-thin pb-10 pt-2",children:m.jsxs("div",{className:"relative flex flex-col gap-px px-2",children:[m.jsx(yi,{icon:m.jsx(pH,{}),label:"Pentest Overview",active:e==="overview",onClick:()=>t("overview")}),m.jsx(yi,{icon:m.jsx(Nu,{className:"h-4 w-4"}),label:"Issues",count:r>0?r:void 0,active:e==="issues",onClick:()=>t("issues")}),a>0&&m.jsx(yi,{icon:m.jsx(Oo,{className:"h-4 w-4"}),label:"Agents",count:a,active:e==="agents",onClick:()=>t("agents")}),m.jsx(yi,{icon:m.jsx(Ys,{className:"h-4 w-4"}),label:"Past runs",count:s>0?s:void 0,active:e==="history",onClick:h}),o&&m.jsx(yi,{icon:m.jsx(Np,{className:"h-4 w-4"}),label:"Export report",active:e==="email",onClick:f}),m.jsx(yi,{icon:m.jsx(k2,{className:"h-4 w-4"}),label:"Feedback & support",active:e==="feedback",onClick:()=>t("feedback")}),m.jsx("hr",{className:"mx-0 my-1 h-px w-full border-0 bg-[rgba(255,255,255,0.08)]"}),m.jsx(yi,{icon:m.jsx(oH,{className:"h-4 w-4"}),label:"PR Security Reviews",active:!1,onClick:()=>R("pr_reviews","Strix reviews every pull request and flags exploitable changes before they merge.")}),m.jsx(yi,{icon:m.jsx(cH,{className:"h-4 w-4"}),label:"Integrations",active:!1,onClick:()=>R("integrations","Sync findings to Jira, Linear, and Slack so fixes happen where your team already works.")}),m.jsx(yi,{icon:m.jsx(MT,{className:"h-4 w-4"}),label:"Members",active:!1,onClick:()=>R("members","Invite your team, set roles, and share findings and run history across your org.")})]})}),m.jsx("section",{className:"flex min-w-[160px] flex-col gap-0.5",ref:B,children:m.jsxs("div",{className:"relative p-2",children:[c&&d?m.jsxs("button",{onClick:()=>k(V=>!V),className:"relative flex w-full cursor-pointer items-center gap-2 rounded-md bg-transparent px-2.5 py-2 transition-colors hover:bg-[rgba(255,255,255,0.06)]",children:[m.jsx("span",{className:"flex flex-shrink-0 items-center justify-center rounded-full bg-gradient-to-br from-emerald-400 to-cyan-500",style:{width:20,height:20},children:m.jsx("span",{className:"text-[9px] font-semibold text-white",children:((z=d[0])==null?void 0:z.toUpperCase())||"U"})}),m.jsxs("span",{className:"flex min-w-0 flex-1 flex-col text-left",children:[m.jsx("span",{className:"truncate text-[13px] font-medium text-[#ededed]",children:d}),m.jsx("span",{className:"truncate text-[11px] text-[#555]",children:"Linked to this machine"})]})]}):m.jsxs("div",{className:"flex items-center gap-2 rounded-md px-2.5 py-2",children:[m.jsx("span",{className:"flex flex-shrink-0 items-center justify-center rounded-full bg-gradient-to-br from-emerald-400 to-cyan-500",style:{width:20,height:20},children:m.jsx("span",{className:"text-[9px] font-semibold text-white",children:"S"})}),m.jsx("span",{className:"flex min-w-0 flex-1 flex-col text-left",children:m.jsx("span",{className:"truncate text-[13px] font-medium text-[#ededed]",children:"Local viewer"})})]}),w&&c&&d&&m.jsxs("div",{className:"absolute bottom-full left-2 right-2 z-50 mb-1 overflow-hidden rounded-lg border border-[#333] bg-black shadow-xl",children:[m.jsxs("div",{className:"border-b border-[#333] px-3 py-2",children:[m.jsx("p",{className:"truncate text-[13px] font-medium text-white",children:"Linked email"}),m.jsx("p",{className:"truncate text-[11px] text-[#666]",children:d})]}),m.jsxs("button",{onClick:()=>{k(!1),p()},className:"flex w-full items-center gap-2 px-3 py-2 text-[13px] text-[#888] transition-colors hover:bg-[rgba(255,255,255,0.06)] hover:text-red-400",children:[m.jsx(WC,{className:"h-4 w-4"}),"Forget this email"]})]})]})}),m.jsx("div",{className:"group absolute right-0 top-0 z-30 h-full w-1 cursor-col-resize",onMouseDown:j,children:m.jsx("div",{className:Mr("absolute right-0 top-0 h-full w-px bg-[rgba(255,255,255,0.08)] transition-all duration-100",E?"w-0.5 bg-[rgba(255,255,255,0.3)]":"group-hover:bg-[rgba(255,255,255,0.2)]")})})]}),E&&m.jsx("div",{className:"fixed inset-0 z-10 cursor-col-resize"}),m.jsx(dH,{open:N!==null,description:N??"",source:"sidebar",onClose:()=>M(null)})]})}function yi({icon:e,label:t,active:r,onClick:a,count:s}){return m.jsxs("button",{onClick:a,className:Mr("group flex h-9 w-full origin-left flex-row items-center rounded-md transition-colors",r?"bg-[rgba(255,255,255,0.12)] text-white":"text-[#888] hover:bg-[rgba(255,255,255,0.06)] hover:text-[#ededed]"),children:[m.jsx("div",{className:"grid flex-none place-content-center",style:{width:36,height:36},children:e}),m.jsx("span",{className:"min-w-0 flex-1 truncate text-left text-[14px] font-medium",children:t}),s!=null&&m.jsx("span",{className:"mr-2 flex-none rounded-full border border-white/10 px-2 py-0.5 text-[10px] tabular-nums leading-none text-[#777]",children:s})]})}function pH(){return m.jsx("svg",{style:{width:16,height:16,color:"currentcolor"},viewBox:"0 0 16 16",fill:"currentColor",children:m.jsx("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M2.5 5.5V2.5H5.5V5.5H2.5ZM1 2C1 1.44772 1.44772 1 2 1H6C6.55228 1 7 1.44772 7 2V6C7 6.55228 6.55228 7 6 7H2C1.44772 7 1 6.55228 1 6V2ZM2.5 13.5V10.5H5.5V13.5H2.5ZM1 10C1 9.44772 1.44772 9 2 9H6C6.55228 9 7 9.44772 7 10V14C7 14.5523 6.55228 15 6 15H2C1.44772 15 1 14.5523 1 14V10ZM10.5 2.5V5.5H13.5V2.5H10.5ZM10 1C9.44772 1 9 1.44772 9 2V6C9 6.55228 9.44772 7 10 7H14C14.5523 7 15 6.55228 15 6V2C15 1.44772 14.5523 1 14 1H10ZM10.5 13.5V10.5H13.5V13.5H10.5ZM9 10C9 9.44772 9.44772 9 10 9H14C14.5523 9 15 9.44772 15 10V14C15 14.5523 14.5523 15 14 15H10C9.44772 15 9 14.5523 9 14V10Z"})})}const C_={work_email_required:"Please use your work email, not a personal one.",rate_limited:"Too many requests. Wait a minute and try again.",invalid_email:"That email does not look right. Check it and try again.",unavailable:"The email service is unavailable right now. Try again shortly."},gH=new Set(["gmail.com","googlemail.com","yahoo.com","ymail.com","outlook.com","hotmail.com","live.com","icloud.com","me.com","aol.com","proton.me","protonmail.com","gmx.com","mail.com"]);function xH({onVerified:e}){const[t,r]=ee.useState("email"),[a,s]=ee.useState(""),[o,c]=ee.useState(""),[d,f]=ee.useState(!1),[h,p]=ee.useState(null),[g,y]=ee.useState(null),b=async()=>{const E=a.trim();if(!E){p("Enter your email to continue.");return}const S=E.slice(E.lastIndexOf("@")+1).toLowerCase();if(gH.has(S)){Tr("work_email_required"),p(C_.work_email_required);return}f(!0),p(null);const w=await _2(E);f(!1),w.ok?(Tr("email_submitted",{purpose:"verify"}),y(`We sent a 6-digit code to ${E}.`),r("code")):(w.error==="work_email_required"&&Tr("work_email_required"),p(C_[w.error]??"Could not send a code. Try again."))},_=async()=>{const E=o.trim();if(E.length<4){p("Enter the 6-digit code from your email.");return}f(!0),p(null);const S=await w2(a.trim(),E);if(f(!1),!S.verified){p("That code did not match. Check it and try again.");return}Tr("email_verified",{purpose:"verify"}),e()};return m.jsxs("div",{className:"mx-auto mt-5 max-w-sm text-left",children:[h&&m.jsxs("div",{className:"mb-3 flex items-start gap-2 rounded-lg border border-red-500/30 bg-red-500/5 px-3 py-2",children:[m.jsx(Gu,{className:"mt-0.5 h-4 w-4 flex-shrink-0 text-red-400","aria-hidden":"true"}),m.jsx("p",{className:"text-xs text-red-300",children:h})]}),g&&!h&&m.jsx("p",{className:"mb-3 text-xs text-[#888]",children:g}),t==="email"?m.jsxs("form",{className:"space-y-3",onSubmit:E=>{E.preventDefault(),b()},children:[m.jsxs("label",{className:"block",children:[m.jsx("span",{className:"mb-1.5 block text-xs text-[#888]",children:"Your work email"}),m.jsx("input",{type:"email",autoFocus:!0,value:a,onChange:E=>s(E.target.value),placeholder:"you@company.com",className:"w-full rounded-lg bg-black px-3 py-2.5 text-sm text-white outline-none transition-colors focus:border-[#444]",style:{border:"1px solid #2a2a2a"}}),m.jsx("span",{className:"mt-1.5 block text-[11px] text-[#666]",children:"Use your work email."})]}),m.jsxs("button",{type:"submit",disabled:d,className:"flex w-full cursor-pointer items-center justify-center gap-2 rounded-lg bg-white px-4 py-2.5 text-sm font-semibold text-black transition-opacity hover:opacity-90 disabled:opacity-60",children:[d&&m.jsx(Ps,{className:"h-4 w-4 animate-spin","aria-hidden":"true"}),"Send me a code"]})]}):m.jsxs("form",{className:"space-y-3",onSubmit:E=>{E.preventDefault(),_()},children:[m.jsxs("label",{className:"block",children:[m.jsx("span",{className:"mb-1.5 block text-xs text-[#888]",children:"6-digit code"}),m.jsx("input",{inputMode:"numeric",autoFocus:!0,value:o,onChange:E=>c(E.target.value.replace(/\D/g,"").slice(0,6)),placeholder:"123456",className:"w-full rounded-lg bg-black px-3 py-2.5 text-center text-lg font-mono tracking-[0.4em] text-white outline-none transition-colors focus:border-[#444]",style:{border:"1px solid #2a2a2a"}})]}),m.jsxs("button",{type:"submit",disabled:d,className:"flex w-full cursor-pointer items-center justify-center gap-2 rounded-lg bg-white px-4 py-2.5 text-sm font-semibold text-black transition-opacity hover:opacity-90 disabled:opacity-60",children:[d&&m.jsx(Ps,{className:"h-4 w-4 animate-spin","aria-hidden":"true"}),"Verify"]}),m.jsx("button",{type:"button",onClick:()=>{r("email"),p(null),y(null)},className:"w-full cursor-pointer text-center text-xs text-[#666] transition-colors hover:text-[#aaa]",children:"Use a different email"})]})]})}const bH=[{key:"critical",dot:"bg-red-500",text:"text-red-500"},{key:"high",dot:"bg-orange-500",text:"text-orange-500"},{key:"medium",dot:"bg-yellow-500",text:"text-yellow-500"},{key:"low",dot:"bg-blue-500",text:"text-blue-500"}];function yH({counts:e}){const t=bH.filter(r=>e[r.key]>0);return t.length===0?m.jsx("span",{className:"text-xs text-[#555]",children:"No findings"}):m.jsx("div",{className:"flex items-center gap-3",children:t.map(r=>m.jsxs("div",{className:"flex items-center gap-1.5",children:[m.jsx("span",{className:`h-2 w-2 rounded-full ${r.dot}`,"aria-hidden":"true"}),m.jsx("span",{className:`text-xs tabular-nums ${r.text}`,children:e[r.key]})]},r.key))})}function vH(e){if(!e)return null;const t=e.trim().replace(" UTC","Z").replace(" ","T"),r=new Date(t);return Number.isNaN(r.getTime())?null:r.toLocaleString(void 0,{month:"short",day:"numeric",hour:"numeric",minute:"2-digit"})}function T_(e){if(!e)return null;const t=e.trim().replace(" UTC","Z").replace(" ","T"),r=new Date(t);if(Number.isNaN(r.getTime()))return null;const a=Date.now()-r.getTime(),s=Math.floor(a/6e4);if(s<1)return"just now";if(s<60)return`${s}m ago`;const o=Math.floor(s/60);if(o<24)return`${o}h ago`;const c=Math.floor(o/24);return c<7?`${c}d ago`:vH(e)}function _H({runs:e,activeRun:t,onSelectRun:r,onVerified:a}){const s=(e==null?void 0:e.count)??0,[o,c]=ee.useState(!1);return!e||e.locked?m.jsxs("div",{className:"rounded-xl border border-[#222] bg-[rgba(255,255,255,0.02)] p-8 text-center",children:[m.jsx("div",{className:"mx-auto mb-4 flex h-11 w-11 items-center justify-center rounded-xl",style:{border:"1px solid #2a2a2a",background:"rgba(255,255,255,0.04)"},children:m.jsx(Ys,{className:"h-5 w-5 text-[#888]","aria-hidden":"true"})}),m.jsx("h2",{className:"text-base font-semibold text-white",children:"Browse every run on this machine"}),m.jsxs("p",{className:"mx-auto mt-1.5 max-w-md text-sm text-[#888]",children:["You have ",s," past ",s===1?"run":"runs"," on this machine."]}),o?m.jsxs(m.Fragment,{children:[m.jsx("p",{className:"mx-auto mt-3 max-w-sm text-xs text-[#666]",children:"Verify your email with a one-time code to unlock the full history."}),m.jsx(xH,{onVerified:a})]}):m.jsx("button",{onClick:()=>{jr("history_unlock","past_runs"),c(!0)},className:"mt-4 cursor-pointer rounded-lg bg-white px-4 py-2 text-sm font-semibold text-black transition-opacity hover:opacity-90",children:"View runs"}),m.jsxs("p",{className:"mt-4 flex items-center justify-center gap-1.5 text-xs text-[#555]",children:[m.jsx(K_,{className:"h-3.5 w-3.5","aria-hidden":"true"}),"Or open one from the CLI with"," ",m.jsx("code",{className:"font-mono text-[#888]",children:"strix view "})]})]}):e.runs.length===0?m.jsx("div",{className:"rounded-xl border border-[#222] bg-[rgba(255,255,255,0.02)] p-8 text-center text-sm text-[#888]",children:"No past runs found on this machine yet."}):m.jsx("div",{className:"space-y-2",children:e.runs.map(d=>{const f=d.name===t,h=T_(d.start_time)??T_(d.end_time),p=yo(d.target,d.name);return m.jsxs("button",{onClick:()=>r(d.name),className:`animate-card-in group flex w-full cursor-pointer items-center gap-4 rounded-lg border px-4 py-3 text-left transition-colors ${f?"border-[#444] bg-[rgba(255,255,255,0.04)]":"border-[#222] bg-[rgba(255,255,255,0.02)] hover:border-[#444]"}`,children:[m.jsxs("div",{className:"min-w-0 flex-1",children:[m.jsxs("div",{className:"flex items-center gap-2",children:[m.jsx("span",{className:"truncate text-sm font-medium text-white",children:p}),f&&m.jsx("span",{className:"rounded-full px-1.5 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-emerald-400",style:{border:"1px solid rgba(16,185,129,0.3)"},children:"Active"})]}),m.jsxs("div",{className:"mt-0.5 flex flex-wrap items-center gap-x-2 gap-y-0.5 text-xs text-[#666]",children:[d.scan_mode&&m.jsx("span",{className:"capitalize",children:d.scan_mode}),d.scan_mode&&(h||d.status)&&m.jsx("span",{className:"text-[#333]",children:"·"}),h&&m.jsx("span",{children:h}),h&&d.status&&m.jsx("span",{className:"text-[#333]",children:"·"}),d.status&&m.jsx("span",{className:"capitalize",children:d.status})]})]}),m.jsx(yH,{counts:d.severity_counts}),m.jsx(sC,{className:"h-4 w-4 flex-shrink-0 text-[#555] transition-colors group-hover:text-[#aaa]","aria-hidden":"true"})]},d.name)})})}const A_={work_email_required:"Please use your work email, not a personal one.",rate_limited:"Too many requests. Wait a minute and try again.",invalid_email:"That email does not look right. Check it and try again.",unavailable:"The email service is unavailable right now. Try again shortly."},wH={forbidden:"This email was unsubscribed from Strix, so we cannot send to it.",too_large:"This report is too large to email. Try a smaller run.",unavailable:"The email service is unavailable right now. Try again shortly."},EH=new Set(["gmail.com","googlemail.com","yahoo.com","ymail.com","outlook.com","hotmail.com","live.com","icloud.com","me.com","aol.com","proton.me","protonmail.com","gmx.com","mail.com"]);function NH({activeRun:e,auth:t,purpose:r,skipDisclosure:a=!1,onAuthChanged:s,onExit:o}){const c=(t==null?void 0:t.verified)===!0,d=r==="verify",[f,h]=ee.useState(()=>d?"email":a?c?"sending":"email":"disclosure"),[p,g]=ee.useState((t==null?void 0:t.email)??""),[y,b]=ee.useState(""),[_,E]=ee.useState(!1),[S,w]=ee.useState(null),[k,N]=ee.useState(null),[M,B]=ee.useState(""),[R,U]=ee.useState(""),[I,X]=ee.useState(!1),[j,z]=ee.useState(""),V=ee.useRef(!1),P=async()=>{h("sending"),w(null);const Z=await QU(e);if(Z.ok){Tr("report_sent"),B(Z.password),U(Z.filename),h("password");return}if(Z.error==="reverify"||Z.error==="unverified"){N("Your verification expired. Enter your email to verify again."),h("email");return}w(wH[Z.error]??"Could not send the report. Try again."),h("disclosure")},T=()=>{w(null),N(null),c?P():h("email")};ee.useEffect(()=>{!d&&a&&c&&!V.current&&(V.current=!0,P())},[]);const $=async()=>{const Z=p.trim();if(!Z){w("Enter your email to continue.");return}const C=Z.slice(Z.lastIndexOf("@")+1).toLowerCase();if(EH.has(C)){Tr("work_email_required"),w(A_.work_email_required);return}E(!0),w(null);const D=await _2(Z);E(!1),D.ok?(Tr("email_submitted",{purpose:r}),N(`We sent a 6-digit code to ${Z}.`),h("code")):(D.error==="work_email_required"&&Tr("work_email_required"),w(A_[D.error]??"Could not send a code. Try again."))},O=async()=>{const Z=y.trim();if(Z.length<4){w("Enter the 6-digit code from your email.");return}E(!0),w(null);const C=await w2(p.trim(),Z);if(E(!1),!C.verified){w("That code did not match. Check it and try again.");return}Tr("email_verified",{purpose:r}),z(C.email),s(),d?o("history"):P()},H=async()=>{try{await navigator.clipboard.writeText(M),X(!0),setTimeout(()=>X(!1),1500)}catch{}},K=j||(t==null?void 0:t.email)||p.trim();return m.jsxs("div",{className:"mx-auto max-w-xl space-y-4",children:[m.jsxs("button",{onClick:()=>o(d?"history":"overview"),className:"cursor-pointer inline-flex items-center gap-1.5 text-sm text-[#888] transition-colors hover:text-white",children:[m.jsx(Ep,{className:"h-4 w-4"}),d?"Back to past runs":"Back to results"]}),m.jsxs("div",{className:"flex items-center gap-2",children:[m.jsx(Np,{className:"h-5 w-5 text-[#888]","aria-hidden":"true"}),m.jsx("h1",{className:"text-2xl font-semibold text-white",children:d?"Verify your email":"Export report to PDF"})]}),m.jsxs("div",{className:"w-full rounded-2xl bg-[rgba(255,255,255,0.02)] p-6",style:{border:"1px solid #2a2a2a"},children:[m.jsx("p",{className:"mb-4 text-xs text-[#666]",children:d?"We send a one-time code to confirm it is you.":"Verified by a one-time code sent to your email"}),S&&m.jsxs("div",{className:"mb-4 flex items-start gap-2 rounded-lg border border-red-500/30 bg-red-500/5 px-3 py-2",children:[m.jsx(Gu,{className:"mt-0.5 h-4 w-4 flex-shrink-0 text-red-400","aria-hidden":"true"}),m.jsx("p",{className:"text-xs text-red-300",children:S})]}),k&&!S&&f!=="password"&&m.jsx("p",{className:"mb-4 text-xs text-[#888]",children:k}),f==="disclosure"&&m.jsxs("div",{className:"space-y-4",children:[m.jsxs("div",{className:"space-y-2.5 rounded-lg p-3.5",style:{border:"1px solid #222",background:"rgba(255,255,255,0.02)"},children:[m.jsxs("div",{className:"flex items-start gap-2.5",children:[m.jsx(X_,{className:"mt-0.5 h-4 w-4 flex-shrink-0 text-emerald-400","aria-hidden":"true"}),m.jsxs("p",{className:"text-xs leading-relaxed text-[#aaa]",children:["We email an ",m.jsx("span",{className:"text-white",children:"encrypted PDF"}),". Nothing else leaves your machine."]})]}),m.jsxs("div",{className:"flex items-start gap-2.5",children:[m.jsx(ZC,{className:"mt-0.5 h-4 w-4 flex-shrink-0 text-[#888]","aria-hidden":"true"}),m.jsx("p",{className:"text-xs leading-relaxed text-[#aaa]",children:"Only you hold the password; Strix can't read it."})]})]}),m.jsx("button",{onClick:T,className:"w-full cursor-pointer rounded-lg bg-white px-4 py-2.5 text-sm font-semibold text-black transition-opacity hover:opacity-90",children:"Export report"}),c&&(t==null?void 0:t.email)&&m.jsxs("p",{className:"text-center text-xs text-[#666]",children:["Sending to ",t.email]})]}),f==="email"&&m.jsxs("form",{className:"space-y-4",onSubmit:Z=>{Z.preventDefault(),$()},children:[m.jsxs("label",{className:"block",children:[m.jsx("span",{className:"mb-1.5 block text-xs text-[#888]",children:"Your work email"}),m.jsx("input",{type:"email",autoFocus:!0,value:p,onChange:Z=>g(Z.target.value),placeholder:"you@company.com",className:"w-full rounded-lg bg-black px-3 py-2.5 text-sm text-white outline-none transition-colors focus:border-[#444]",style:{border:"1px solid #2a2a2a"}})]}),m.jsxs("button",{type:"submit",disabled:_,className:"flex w-full cursor-pointer items-center justify-center gap-2 rounded-lg bg-white px-4 py-2.5 text-sm font-semibold text-black transition-opacity hover:opacity-90 disabled:opacity-60",children:[_&&m.jsx(Ps,{className:"h-4 w-4 animate-spin","aria-hidden":"true"}),"Send me a code"]})]}),f==="code"&&m.jsxs("form",{className:"space-y-4",onSubmit:Z=>{Z.preventDefault(),O()},children:[m.jsxs("label",{className:"block",children:[m.jsx("span",{className:"mb-1.5 block text-xs text-[#888]",children:"6-digit code"}),m.jsx("input",{inputMode:"numeric",autoFocus:!0,value:y,onChange:Z=>b(Z.target.value.replace(/\D/g,"").slice(0,6)),placeholder:"123456",className:"w-full rounded-lg bg-black px-3 py-2.5 text-center text-lg font-mono tracking-[0.4em] text-white outline-none transition-colors focus:border-[#444]",style:{border:"1px solid #2a2a2a"}})]}),m.jsxs("button",{type:"submit",disabled:_,className:"flex w-full cursor-pointer items-center justify-center gap-2 rounded-lg bg-white px-4 py-2.5 text-sm font-semibold text-black transition-opacity hover:opacity-90 disabled:opacity-60",children:[_&&m.jsx(Ps,{className:"h-4 w-4 animate-spin","aria-hidden":"true"}),d?"Verify":"Verify and send"]}),m.jsx("button",{type:"button",onClick:()=>{h("email"),w(null),N(null)},className:"w-full cursor-pointer text-center text-xs text-[#666] transition-colors hover:text-[#aaa]",children:"Use a different email"})]}),f==="sending"&&m.jsxs("div",{className:"flex flex-col items-center gap-3 py-8",children:[m.jsx(Ps,{className:"h-6 w-6 animate-spin text-white","aria-hidden":"true"}),m.jsx("p",{className:"text-sm text-[#aaa]",children:"Generating and encrypting locally..."})]}),f==="password"&&m.jsxs("div",{className:"space-y-4",children:[m.jsxs("div",{className:"flex items-start gap-2.5 rounded-lg border border-emerald-500/30 bg-emerald-500/5 px-3 py-2.5",children:[m.jsx(Vs,{className:"mt-0.5 h-4 w-4 flex-shrink-0 text-emerald-400","aria-hidden":"true"}),m.jsxs("p",{className:"text-xs text-emerald-200",children:["Sent to ",K,". Open the attached PDF with this password."]})]}),m.jsxs("div",{children:[m.jsx("span",{className:"mb-1.5 block text-xs text-[#888]",children:"Your one-time password"}),m.jsxs("div",{className:"flex items-center gap-2 rounded-lg bg-black p-3",style:{border:"1px solid #2a2a2a"},children:[m.jsx("code",{className:"flex-1 break-all font-mono text-base text-white",children:M}),m.jsxs("button",{onClick:H,className:"flex cursor-pointer items-center gap-1 rounded-md px-2 py-1 text-xs text-[#aaa] transition-colors hover:bg-[rgba(255,255,255,0.06)] hover:text-white",style:{border:"1px solid #2a2a2a"},children:[I?m.jsx(Vs,{className:"h-3.5 w-3.5"}):m.jsx(go,{className:"h-3.5 w-3.5"}),I?"Copied":"Copy"]})]}),m.jsxs("p",{className:"mt-2 text-xs text-[#666]",children:["Save this now. Strix never stores it, so we cannot show it again. File:"," ",m.jsx("span",{className:"font-mono text-[#888]",children:R})]})]}),m.jsx("button",{onClick:()=>o("overview"),className:"w-full cursor-pointer rounded-lg px-4 py-2.5 text-sm font-semibold text-white transition-colors hover:bg-[rgba(255,255,255,0.06)]",style:{border:"1px solid #2a2a2a"},children:"Done"})]})]})]})}function la(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}function ao(e){return Array.isArray(e)?e:[]}function nr(e){return typeof e=="string"&&e.trim()?e:null}function Ba(e){return typeof e=="number"&&Number.isFinite(e)?e:null}function SH(e){return e.replace(/_/g," ")}function M_(e){return e&&e.charAt(0).toUpperCase()+e.slice(1)}function kH(e){if(e==null||e<0)return"n/a";const t=Math.floor(e/3600),r=Math.floor(e%3600/60),a=e%60;return t?`${t}h ${r}m ${a}s`:r?`${r}m ${a}s`:`${a}s`}function En({label:e,children:t}){return m.jsxs("div",{className:"grid grid-cols-[7rem_1fr] gap-3 items-baseline",children:[m.jsx("dt",{className:"text-[11px] uppercase tracking-wide text-[#666]",children:e}),m.jsx("dd",{className:"min-w-0 break-words text-sm text-[#ddd]",children:t})]})}function CH({raw:e,durationSeconds:t}){const[r,a]=ee.useState(!0),s=ao(e.targets_info).map(P=>{const T=la(P),$=nr(T.original)??nr(la(T.details).target_url)??"unknown target",O=nr(T.type);return{display:$,type:O?SH(O):null}}),o=nr(e.instruction),c=M_(nr(e.scan_mode)),d=nr(e.scope_mode),f=la(e.diff_scope),h=f.active===!0,p=nr(f.mode),g=nr(e.diff_base),y=e.non_interactive===!0,b=ao(e.local_sources).map(P=>{if(typeof P=="string")return P;const T=la(P);return nr(T.source_path)??nr(T.target_path)??""}).filter(Boolean),_=M_(nr(e.status));let E=d??"auto";h&&(E+=` (diff${p?`: ${p}`:""}${g?` vs ${g}`:""})`);const S=la(e.llm_usage),w=Object.keys(S).length>0,k=ao(S.agents).map(la),N=Array.from(new Set(k.map(P=>nr(P.model)).filter(P=>!!P))),M=Ba(S.requests),B=Ba(S.input_tokens),R=Ba(la(ao(S.input_tokens_details)[0]).cached_tokens),U=Ba(S.output_tokens),I=Ba(la(ao(S.output_tokens_details)[0]).reasoning_tokens),X=Ba(S.total_tokens),j=Ba(S.cost),z=nr(e.auth_mode)==="subscription",V=(P,T)=>m.jsxs("span",{className:"text-[#666]",children:[" (",Ls(P)," ",T,")"]});return m.jsxs("div",{className:"rounded-xl border border-[#222] bg-[rgba(255,255,255,0.02)] p-5",children:[m.jsxs("button",{type:"button",onClick:()=>a(P=>!P),"aria-expanded":r,className:"flex w-full cursor-pointer items-center gap-2 text-left",children:[m.jsx(GC,{className:"h-4 w-4 text-[#888]","aria-hidden":"true"}),m.jsx("h2",{className:"text-sm font-semibold text-white",children:"Run details"}),r?m.jsx(U_,{className:"ml-auto h-4 w-4 text-[#666]","aria-hidden":"true"}):m.jsx(po,{className:"ml-auto h-4 w-4 text-[#666]","aria-hidden":"true"})]}),r&&m.jsxs("div",{className:"mt-4 grid grid-cols-1 gap-x-8 gap-y-6 md:grid-cols-2",children:[m.jsxs("section",{children:[m.jsx("h3",{className:"mb-3 text-[11px] font-semibold uppercase tracking-wide text-[#555]",children:"Configuration"}),m.jsxs("dl",{className:"space-y-2.5",children:[s.length>0&&m.jsx(En,{label:"Targets",children:m.jsx("div",{className:"space-y-1",children:s.map((P,T)=>m.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[m.jsx("span",{className:"font-mono text-[#ddd]",children:P.display}),P.type&&m.jsx("span",{className:"rounded-full border border-[#2a2a2a] px-1.5 py-0.5 text-[10px] text-[#888]",children:P.type})]},T))})}),m.jsx(En,{label:"Instruction",children:o?m.jsx("span",{className:"whitespace-pre-wrap",children:o}):m.jsx("span",{className:"text-[#666]",children:"None"})}),c&&m.jsx(En,{label:"Pentest mode",children:c}),m.jsx(En,{label:"Scope",children:E}),m.jsx(En,{label:"Mode",children:y?"Non-interactive":"Interactive"}),b.length>0&&m.jsx(En,{label:"Local sources",children:m.jsx("div",{className:"space-y-0.5 font-mono text-[#ddd]",children:b.map((P,T)=>m.jsx("div",{children:P},T))})}),_&&m.jsx(En,{label:"Status",children:_})]})]}),m.jsxs("section",{children:[m.jsx("h3",{className:"mb-3 text-[11px] font-semibold uppercase tracking-wide text-[#555]",children:"Usage & cost"}),w?m.jsxs("dl",{className:"space-y-2.5 tabular-nums",children:[m.jsx(En,{label:"Model",children:N.length?N.join(", "):"n/a"}),z&&m.jsx(En,{label:"Provider",children:m.jsx("span",{className:"inline-flex items-center gap-1.5",children:m.jsx("span",{className:"rounded-full border border-[#22c55e]/40 bg-[#22c55e]/10 px-2 py-0.5 text-[11px] text-[#22c55e]",children:"ChatGPT subscription"})})}),m.jsx(En,{label:"Run time",children:kH(t)}),M!=null&&m.jsx(En,{label:"Requests",children:Ls(M)}),B!=null&&m.jsxs(En,{label:"Input tokens",children:[Ls(B),R!=null&&V(R,"cached")]}),U!=null&&m.jsxs(En,{label:"Output tokens",children:[Ls(U),I!=null&&V(I,"reasoning")]}),X!=null&&m.jsx(En,{label:"Total tokens",children:Ls(X)}),z?m.jsxs(En,{label:"Cost",children:[m.jsx("span",{className:"text-[#22c55e]",children:"$0.00"}),m.jsx("span",{className:"text-[#666]",children:" (subscription)"})]}):j!=null&&m.jsxs(En,{label:"Cost",children:["$",j.toFixed(2)]}),k.length>0&&m.jsx(En,{label:"Agents",children:Ls(k.length)})]}):m.jsx("p",{className:"text-sm text-[#666]",children:"Not available yet."})]})]})]})}const O_="strix_viewer_trust_dismissed";function TH({message:e}){const[t,r]=ee.useState(()=>{try{return localStorage.getItem(O_)==="1"}catch{return!1}});if(t)return null;const a=()=>{try{localStorage.setItem(O_,"1")}catch{}r(!0)};return m.jsx("div",{className:"fixed bottom-3 left-3 z-[60] max-w-xs rounded-lg bg-[#0a0a0a] p-3 shadow-2xl",style:{border:"1px solid #2a2a2a"},role:"status",children:m.jsxs("div",{className:"flex gap-2.5",children:[m.jsx(X_,{className:"mt-0.5 h-4 w-4 flex-shrink-0 text-emerald-400","aria-hidden":"true"}),m.jsx("p",{className:"text-xs leading-relaxed text-[#aaa]",children:e}),m.jsx("button",{onClick:a,"aria-label":"Dismiss",className:"-mr-0.5 -mt-0.5 flex-shrink-0 cursor-pointer rounded p-0.5 text-[#666] transition-colors hover:text-white",children:m.jsx(Sp,{className:"h-3.5 w-3.5"})})]})})}const AH=5e3,R_={invalid_email:"That email doesn't look right.",invalid_message:"Please write a little more.",unavailable:"Couldn't send that just now. Try again."};function MH({defaultEmail:e,onExit:t}){const[r,a]=ee.useState(""),[s,o]=ee.useState(e??""),[c,d]=ee.useState("form"),[f,h]=ee.useState(null),p=r.trim().length>0&&s.trim().length>0&&c!=="sending",g=async()=>{if(!p)return;d("sending"),h(null);const y=await XU(r.trim(),s.trim());if(y.ok){d("sent");return}d("form"),h(R_[y.error]??R_.unavailable)};return m.jsxs("div",{className:"mx-auto max-w-xl space-y-4",children:[m.jsxs("button",{onClick:()=>t("overview"),className:"cursor-pointer inline-flex items-center gap-1.5 text-sm text-[#888] transition-colors hover:text-white",children:[m.jsx(Ep,{className:"h-4 w-4"}),"Back to results"]}),m.jsxs("div",{className:"flex items-center gap-2",children:[m.jsx(k2,{className:"h-5 w-5 text-[#888]","aria-hidden":"true"}),m.jsx("h1",{className:"text-2xl font-semibold text-white",children:"Feedback & support"})]}),m.jsx("div",{className:"w-full rounded-2xl bg-[rgba(255,255,255,0.02)] p-6",style:{border:"1px solid #2a2a2a"},children:c==="sent"?m.jsxs("div",{className:"flex items-start gap-3",children:[m.jsx(Eu,{className:"mt-0.5 h-5 w-5 flex-shrink-0 text-emerald-400","aria-hidden":"true"}),m.jsxs("div",{className:"min-w-0",children:[m.jsx("p",{className:"text-sm font-semibold text-white",children:"Thanks, we got it."}),m.jsx("p",{className:"mt-1 text-xs text-[#888]",children:"We read every message. If it needs a reply, we'll reach out to the email you gave."}),m.jsx("button",{onClick:()=>{a(""),d("form")},className:"mt-4 cursor-pointer text-xs text-[#888] transition-colors hover:text-white",children:"Send more feedback"})]})]}):m.jsxs(m.Fragment,{children:[m.jsx("p",{className:"mb-4 text-xs text-[#666]",children:"Bugs, feature requests, or anything else. Tell us what's on your mind."}),f&&m.jsxs("div",{className:"mb-4 flex items-start gap-2 rounded-lg border border-red-500/30 bg-red-500/5 px-3 py-2",children:[m.jsx(Gu,{className:"mt-0.5 h-4 w-4 flex-shrink-0 text-red-400","aria-hidden":"true"}),m.jsx("p",{className:"text-xs text-red-300",children:f})]}),m.jsxs("label",{className:"block",children:[m.jsx("span",{className:"mb-1.5 block text-xs text-[#888]",children:"Your feedback"}),m.jsx("textarea",{autoFocus:!0,value:r,maxLength:AH,onChange:y=>a(y.target.value),rows:5,placeholder:"What's working, what's not, what you'd love to see…",className:"w-full resize-y rounded-lg border border-[#2a2a2a] bg-black px-3 py-2.5 text-sm text-white outline-none transition-colors focus:border-white/50 focus:ring-2 focus:ring-white/10"})]}),m.jsxs("label",{className:"mt-4 block",children:[m.jsx("span",{className:"mb-1.5 block text-xs text-[#888]",children:"Your work email"}),m.jsx("input",{type:"email",value:s,onChange:y=>o(y.target.value),placeholder:"you@company.com",className:"w-full rounded-lg border border-[#2a2a2a] bg-black px-3 py-2.5 text-sm text-white outline-none transition-colors focus:border-white/50 focus:ring-2 focus:ring-white/10"})]}),m.jsx("button",{onClick:()=>void g(),disabled:!p,className:"mt-4 flex w-full cursor-pointer items-center justify-center gap-2 rounded-lg bg-white px-4 py-2.5 text-sm font-semibold text-black transition-opacity hover:opacity-90 disabled:opacity-60",children:c==="sending"?"Sending…":"Send feedback"})]})})]})}function OH({text:e,children:t,className:r=""}){const[a,s]=ee.useState(!1);return m.jsxs("span",{className:`relative inline-flex ${r}`,onMouseEnter:()=>s(!0),onMouseLeave:()=>s(!1),onFocus:()=>s(!0),onBlur:()=>s(!1),children:[t,a&&m.jsx("span",{role:"tooltip",className:"pointer-events-none absolute bottom-full left-1/2 z-50 mb-2 w-max max-w-[240px] -translate-x-1/2 rounded-md px-2.5 py-1.5 text-xs text-[#ddd] shadow-lg",style:{border:"1px solid #2a2a2a",background:"#0a0a0a"},children:e})]})}function C2({label:e,desc:t,slug:r,icon:a,surface:s}){return m.jsx(OH,{text:t,children:m.jsxs("a",{href:ha(Yu,r),target:"_blank",rel:"noopener noreferrer",onClick:()=>jr(r,s),className:"group inline-flex items-center gap-2 rounded-lg border border-[#222] bg-[rgba(255,255,255,0.02)] px-3 py-2 text-sm text-[#aaa] transition-colors hover:border-[#444] hover:text-white",children:[m.jsx(a,{className:"h-4 w-4 text-[#888] transition-colors group-hover:text-white","aria-hidden":"true"}),m.jsx("span",{children:e})]})})}const RH="Your findings stay on your machine. They're rendered here locally in your browser and never uploaded or stored by Strix.",j_=["critical","high","medium","low"],jH=500;function DH(){const[e,t]=ee.useState(null),[r,a]=ee.useState(null),[s,o]=ee.useState(null),[c,d]=ee.useState(null),[f,h]=ee.useState("overview"),[p,g]=ee.useState(null),[y,b]=ee.useState(null),[_,E]=ee.useState("report"),[S,w]=ee.useState(!1),[k,N]=ee.useState(!1),M=ee.useCallback(async()=>{try{g(await KU())}catch{}},[]),B=ee.useCallback(async()=>{try{b(await GU())}catch{}},[]);ee.useEffect(()=>{M(),B(),VU().then(C=>N(C.can_steer)).catch(()=>{})},[M,B]);const R=ee.useRef(!1);ee.useEffect(()=>{let C=!1,D;R.current=!1;const Y=()=>{D=setTimeout(L,jH)},L=async()=>{if(!C)try{const{summary:G,raw:q,finished:Q}=await b2(e);if(C)return;if(Q&&!R.current){R.current=!0;const te=await __(e);C||a(te);return}const[J,W]=await Promise.all([v2(e).catch(()=>({agents:[],events:[]})),y2(G.runId,e).catch(()=>[])]);if(C)return;a(te=>({summary:G,raw:q,finished:Q,transcript:J,vulnerabilities:W,reportMarkdown:(te==null?void 0:te.reportMarkdown)??null})),Y()}catch(G){if(C)return;o(G instanceof Error?G.message:"Could not load run data."),Y()}};return(async()=>{try{const G=await __(e);if(C)return;a(G),G.finished?R.current=!0:Y()}catch(G){if(C)return;o(G instanceof Error?G.message:"Could not load run data."),Y()}})(),()=>{C=!0,D&&clearTimeout(D)}},[e]);const U=ee.useMemo(()=>r?PU(r.vulnerabilities):null,[r]),I=(r==null?void 0:r.vulnerabilities.find(C=>C.id===c))??null,X=(r==null?void 0:r.transcript.agents.length)??0,j=(p==null?void 0:p.verified)===!0,z=ee.useRef(!1);ee.useEffect(()=>{z.current=!1},[e]),ee.useEffect(()=>{z.current||!r||(r.finished?(z.current=!0,h("overview")):X>0&&(z.current=!0,h("agents")))},[r,X]);const V=ee.useCallback(C=>{z.current=!0,h(C)},[]),P=ee.useCallback(C=>{t(C),d(null),a(null),o(null),z.current=!1},[]),T=ee.useCallback((C,D)=>{jr("email_report",D),E("report"),w(C),V("email")},[V]),$=ee.useCallback(()=>T(!1,"sidebar"),[T]),O=ee.useCallback(()=>T(!0,"overview"),[T]),H=ee.useCallback(()=>{B(),V("history")},[B,V]),K=ee.useCallback(async()=>{await M(),await B()},[M,B]),Z=ee.useCallback(async()=>{await ZU(),await M(),await B()},[M,B]);return m.jsxs("div",{className:"min-h-screen bg-black text-white flex",children:[m.jsx(mH,{view:f,onSelectView:C=>{d(null),C==="history"?H():V(C)},issuesCount:(r==null?void 0:r.vulnerabilities.length)??0,agentCount:X,runCount:(y==null?void 0:y.count)??0,finished:(r==null?void 0:r.finished)??!1,verified:j,email:(p==null?void 0:p.email)??null,onOpenEmail:$,onOpenHistory:H,onForget:()=>void Z()}),m.jsxs("div",{className:"flex-1 min-w-0",children:[m.jsx("div",{className:"border-b border-[#222]",children:m.jsxs("div",{className:"max-w-[88rem] mx-auto px-3 sm:px-6 py-4 flex items-center gap-1.5",children:[m.jsxs("a",{href:ha("https://app.strix.ai","logo"),target:"_blank",rel:"noopener noreferrer",onClick:()=>jr("logo","topbar"),className:"flex items-center gap-1.5 opacity-90 transition-opacity hover:opacity-100 lg:hidden",title:"Open Strix Cloud",children:[m.jsx("img",{src:"./logo.png",alt:"Strix",className:"w-10 h-8 object-cover"}),m.jsx("div",{className:"text-base text-white font-medium tracking-tight",children:"Strix"})]}),r&&m.jsx(zH,{finished:r.finished}),m.jsxs("div",{className:"ml-auto flex items-center gap-3",children:[j&&y&&!y.locked&&y.runs.length>0&&m.jsx(LH,{runs:y,activeRun:e,launchedName:yo((r==null?void 0:r.summary.targets[0])??null,(r==null?void 0:r.summary.runName)??(r==null?void 0:r.summary.runId)??"Current run"),onSelect:P}),m.jsxs("a",{href:ha(Yu,"run_in_cloud"),target:"_blank",rel:"noopener noreferrer",onClick:()=>jr("run_in_cloud","topbar"),className:"inline-flex items-center gap-1 rounded-lg bg-white px-3 py-1.5 text-xs font-semibold text-black transition-opacity hover:opacity-90",children:["Run in the cloud",m.jsx(z_,{className:"w-3 h-3","aria-hidden":"true"})]})]})]})}),m.jsxs("div",{className:"max-w-[88rem] mx-auto px-3 sm:px-6 py-8 sm:py-12 space-y-6",children:[s&&!r&&f!=="history"&&f!=="email"&&m.jsxs("div",{className:"rounded-lg px-4 py-3 flex gap-3 items-start border border-red-500/30 bg-red-500/5",children:[m.jsx(Gu,{className:"w-5 h-5 flex-shrink-0 mt-0.5 text-red-400","aria-hidden":"true"}),m.jsx("p",{className:"text-sm text-red-300",children:s})]}),m.jsx("div",{className:"animate-page-in space-y-6",children:f==="email"?m.jsx(NH,{activeRun:e,auth:p,purpose:_,skipDisclosure:S,onAuthChanged:()=>{M(),B()},onExit:C=>h(C==="history"?"history":"overview")}):f==="feedback"?m.jsx(MH,{defaultEmail:(p==null?void 0:p.email)??null,onExit:C=>h(C)}):f==="history"?m.jsxs("div",{className:"space-y-4",children:[m.jsxs("div",{className:"flex items-center gap-2",children:[m.jsx(Ys,{className:"w-5 h-5 text-[#888]","aria-hidden":"true"}),m.jsx("h1",{className:"text-2xl font-semibold text-white",children:"Past runs"})]}),m.jsx(_H,{runs:y,activeRun:e,onSelectRun:P,onVerified:()=>void K()})]}):!r&&!s?m.jsxs("div",{className:"rounded-xl border border-[#222] bg-[rgba(255,255,255,0.02)] p-10 text-center",children:[m.jsx("div",{className:"w-6 h-6 mx-auto mb-3 rounded-full border-2 border-[#333] border-t-white animate-spin"}),m.jsx("p",{className:"text-sm text-[#888]",children:"Loading run data…"})]}):r&&U?m.jsxs(m.Fragment,{children:[m.jsx(BH,{summary:r.summary}),m.jsxs("div",{className:"flex gap-5 border-b border-[#2a2a2a] lg:hidden",children:[m.jsx(Pm,{active:f==="overview",onClick:()=>V("overview"),children:"Pentest Overview"}),m.jsxs(Pm,{active:f==="issues",onClick:()=>V("issues"),children:["Issues",r.vulnerabilities.length>0?` (${r.vulnerabilities.length})`:""]}),X>0&&m.jsxs(Pm,{active:f==="agents",onClick:()=>V("agents"),children:["Agents (",X,")"]})]}),f==="overview"?m.jsx(PH,{summary:r.summary,counts:U,total:r.vulnerabilities.length,reportMarkdown:r.reportMarkdown,raw:r.raw,finished:r.finished,onOpenEmail:O}):f==="agents"&&X>0?m.jsx(FH,{run:r,canSteer:k}):I?m.jsxs("div",{className:"space-y-4",children:[m.jsxs("button",{onClick:()=>d(null),className:"cursor-pointer inline-flex items-center gap-1.5 text-sm text-[#888] hover:text-white transition-colors",children:[m.jsx(Ep,{className:"w-4 h-4"})," Back to all findings"]}),m.jsx(mD,{vulnerability:I})]}):m.jsx(UH,{vulnerabilities:r.vulnerabilities,finished:r.finished,onSelect:C=>d(C)})]}):null},`${e??"launched"}:${f}:${c??""}`)]})]}),m.jsx(TH,{message:RH})]})}function LH({runs:e,activeRun:t,launchedName:r,onSelect:a}){const[s,o]=ee.useState(!1),c=e.runs.find(f=>f.name===t),d=c?yo(c.target,c.name):r;return m.jsxs("div",{className:"relative",children:[m.jsxs("button",{onClick:()=>o(f=>!f),onBlur:()=>setTimeout(()=>o(!1),150),"aria-label":"Switch pentest",className:"flex items-center gap-2 rounded-lg border border-[#3a3a3a] bg-[rgba(255,255,255,0.05)] px-3 py-2 text-sm text-white transition-colors hover:border-[#555] hover:bg-[rgba(255,255,255,0.09)]",children:[m.jsx(Ys,{className:"h-4 w-4 flex-shrink-0 text-[#888]","aria-hidden":"true"}),m.jsx("span",{className:"flex-shrink-0 text-[#888]",children:"Pentest"}),m.jsx("span",{className:"max-w-[260px] truncate font-medium",children:d}),m.jsx(po,{className:"h-4 w-4 flex-shrink-0 text-[#aaa]","aria-hidden":"true"})]}),s&&m.jsxs("div",{className:"absolute right-0 z-50 mt-2 max-h-96 w-96 overflow-y-auto rounded-xl py-1.5 shadow-2xl",style:{border:"1px solid #3a3a3a",background:"#0a0a0a"},children:[m.jsx("div",{className:"border-b border-[#222] px-3 py-2 text-[11px] font-semibold uppercase tracking-wide text-[#666]",children:"Switch pentest"}),e.runs.map(f=>{const h=f.name===t;return m.jsxs("button",{onMouseDown:()=>a(f.name),className:`flex w-full items-center gap-2 px-3 py-2.5 text-left text-sm transition-colors hover:bg-[rgba(255,255,255,0.06)] ${h?"bg-[rgba(255,255,255,0.04)] text-white":"text-[#aaa]"}`,children:[m.jsxs("span",{className:"min-w-0 flex-1",children:[m.jsx("span",{className:"block truncate font-medium",children:yo(f.target,f.name)}),f.target&&m.jsx("span",{className:"block truncate font-mono text-xs text-[#666]",children:f.target})]}),h&&m.jsx("span",{className:"h-2 w-2 flex-shrink-0 rounded-full bg-emerald-400"})]},f.name)})]})]})}function zH({finished:e}){return e?m.jsxs("span",{className:"ml-3 inline-flex items-center gap-1.5 text-xs text-[#888]",children:[m.jsx("span",{className:"w-1.5 h-1.5 rounded-full bg-[#555]"}),"Complete"]}):m.jsxs("span",{className:"ml-3 inline-flex items-center gap-1.5 text-xs text-emerald-400",children:[m.jsxs("span",{className:"relative flex h-1.5 w-1.5",children:[m.jsx("span",{className:"absolute inline-flex h-full w-full rounded-full bg-emerald-400 opacity-75 animate-ping"}),m.jsx("span",{className:"relative inline-flex h-1.5 w-1.5 rounded-full bg-emerald-400"})]}),"Live"]})}function IH(e){if(e==null)return null;if(e<60)return`${e}s`;const t=Math.floor(e/60);return t<60?`${t}m`:`${Math.floor(t/60)}h ${t%60}m`}function BH({summary:e}){const t=IH(e.durationSeconds);return m.jsxs("div",{children:[m.jsx("h1",{className:"text-2xl font-semibold text-white",children:yo(e.targets[0]??null,e.runName??e.runId??"Pentest results")}),m.jsxs("div",{className:"mt-1 flex flex-wrap items-center gap-x-3 gap-y-1 text-sm text-[#888]",children:[e.targets.length>0&&m.jsx("span",{className:"font-mono text-[#aaa]",children:e.targets.join(", ")}),e.scanMode&&m.jsx(qm,{label:e.scanMode}),t&&m.jsx(qm,{label:t}),e.status&&m.jsx(qm,{label:e.status})]})]})}function qm({label:e}){return m.jsxs(m.Fragment,{children:[m.jsx("span",{className:"text-[#333]",children:"·"}),m.jsx("span",{className:"capitalize",children:e})]})}function UH({vulnerabilities:e,finished:t,onSelect:r}){const a=[...e].sort((s,o)=>j_.indexOf(s.severity)-j_.indexOf(o.severity));return a.length===0?m.jsxs("div",{className:"space-y-4",children:[m.jsx("div",{className:"rounded-xl border border-[#222] bg-[rgba(255,255,255,0.02)] p-8 text-center text-sm text-[#888]",children:t?"No findings in this run.":"No findings yet. The pentest is still running…"}),t&&m.jsxs("div",{className:"rounded-xl border border-[#222] bg-[rgba(255,255,255,0.02)] p-5",children:[m.jsx("p",{className:"text-sm font-medium text-white",children:"Stay ahead of new exposures"}),m.jsx("p",{className:"mt-0.5 mb-3 text-xs text-[#666]",children:"Attack surface monitoring catches new exposures for your org over time."}),m.jsx(C2,{label:"Attack surface monitoring",desc:"Continuous coverage for your whole org.",slug:"asm",surface:"empty_state",icon:sT})]})]}):m.jsx("div",{className:"space-y-2",children:a.map(s=>m.jsxs("button",{onClick:()=>r(s.id),className:"animate-card-in cursor-pointer w-full text-left rounded-lg border border-[#222] hover:border-[#444] bg-[rgba(255,255,255,0.02)] px-4 py-3 transition-colors flex items-center gap-3",children:[m.jsx("span",{className:`w-2.5 h-2.5 rounded-full flex-shrink-0 ${kp(s.severity)}`,"aria-hidden":"true"}),m.jsxs("span",{className:"flex-1 min-w-0",children:[m.jsx("span",{className:"block text-sm font-medium text-white truncate",children:s.title}),s.target&&m.jsx("span",{className:"block text-xs text-[#666] font-mono truncate",children:s.target})]}),m.jsx("span",{className:`text-xs font-semibold px-2 py-0.5 rounded-full border capitalize ${Z_[s.severity]}`,children:s.severity})]},s.id))})}function HH(e){return e.replace(/^\s*#{1,6}[ \t]+.*(?:\r?\n)+/,"").trimStart()}function $H(e){const t=[];let r=null;for(const a of e.split(` +`)}function Z7({args:e,result:t}){const r=e.action??"",a=e.code??e.script??"",s=t;let o=null;s&&typeof s=="object"?o=typeof s.stdout=="string"?s.stdout:null:typeof s=="string"&&(o=s);const c=r==="new_session"?"new session":r==="close"?"close session":r==="list_sessions"?"list sessions":null,d=o?K7(X7(o)):null;return m.jsxs("div",{children:[m.jsxs("div",{className:"flex items-center gap-2",children:[m.jsx("span",{className:"text-yellow-400/80 font-semibold text-sm",children:"Python"}),c&&m.jsx("span",{className:"text-[#888] text-[13px]",children:c})]}),a&&m.jsx(gg,{code:a,language:"python",collapsible:!0}),d&&m.jsx(wi,{className:"text-[#666]",children:d})]})}function Q7({args:e}){const t=e.targets,a=(Array.isArray(t)?t:[]).map(s=>typeof s=="object"&&s?s.original??null:null).filter(Boolean);return m.jsxs("div",{children:[m.jsxs("div",{className:"flex items-center gap-2",children:[m.jsx("span",{className:"text-emerald-400/80 font-semibold text-sm",children:"Starting penetration test"}),a.length===1&&m.jsxs("span",{className:"text-[#888] text-[13px]",children:["on ",a[0]]})]}),a.length>1&&m.jsx("div",{className:"mt-1.5 space-y-0.5",children:a.map((s,o)=>m.jsxs("div",{className:"text-[13px] text-[#888]",children:[m.jsx("span",{className:"text-[#555] mr-1",children:"•"}),s]},o))})]})}function W7({args:e}){const t=e.name??"Unknown Agent",r=e.task??"";return m.jsxs("div",{children:[m.jsxs("div",{className:"flex items-center gap-2",children:[m.jsx("span",{className:"text-[#888] text-[13px]",children:"subagent"}),m.jsx("span",{className:"text-purple-400 font-semibold text-sm",children:t})]}),r&&m.jsx("div",{className:"mt-1.5",children:m.jsx(Yt,{text:r,maxLines:15})})]})}function J7(e){return e.toolName==="subagent_start_info"?m.jsx(W7,{...e}):m.jsx(Q7,{...e})}function eU({args:e}){const t=e.executive_summary??"",r=e.methodology??"",a=e.technical_analysis??"",s=e.recommendations??"";return m.jsxs("div",{className:"space-y-3",children:[m.jsx("span",{className:"text-emerald-400/80 font-semibold text-sm",children:"Penetration test completed"}),t&&m.jsxs("div",{children:[m.jsx("span",{className:"text-emerald-400/60 text-sm font-semibold",children:"Executive Summary"}),m.jsx("div",{className:"mt-1",children:m.jsx(Yt,{text:t,maxLines:25})})]}),r&&m.jsxs("div",{children:[m.jsx("span",{className:"text-emerald-400/60 text-sm font-semibold",children:"Methodology"}),m.jsx("div",{className:"mt-1",children:m.jsx(Yt,{text:r,maxLines:25})})]}),a&&m.jsxs("div",{children:[m.jsx("span",{className:"text-emerald-400/60 text-sm font-semibold",children:"Technical Analysis"}),m.jsx("div",{className:"mt-1",children:m.jsx(Yt,{text:a,maxLines:25})})]}),s&&m.jsxs("div",{children:[m.jsx("span",{className:"text-emerald-400/60 text-sm font-semibold",children:"Recommendations"}),m.jsx("div",{className:"mt-1",children:m.jsx(Yt,{text:s,maxLines:25})})]}),!t&&!r&&!a&&!s&&m.jsx("div",{className:"text-[#555] text-xs",children:"Generating final report..."})]})}function tU({toolName:e,args:t,result:r}){if(e==="create_note"){const a=t.title??"",s=t.content??"",o=t.category??"general";return m.jsxs("div",{children:[m.jsxs("div",{className:"flex items-center gap-2",children:[m.jsx("span",{className:"text-amber-400/80 font-semibold text-sm",children:"note"}),m.jsxs("span",{className:"text-[#555] text-[13px]",children:["(",o,")"]})]}),a&&m.jsx("div",{className:"mt-1.5 text-[#999] text-[13px]",children:a}),s&&m.jsx("div",{className:"mt-1",children:m.jsx(ua,{text:s})})]})}if(e==="delete_note")return m.jsx("span",{className:"text-amber-400/80 font-semibold text-sm",children:"note removed"});if(e==="update_note"){const a=t.title??"",s=t.content??"";return m.jsxs("div",{children:[m.jsx("span",{className:"text-amber-400/80 font-semibold text-sm",children:"note updated"}),a&&m.jsx("div",{className:"mt-1.5 text-[#999] text-[13px]",children:a}),s&&m.jsx("div",{className:"mt-1",children:m.jsx(ua,{text:s})})]})}if(e==="get_note"){const a=r,s=a&&typeof a=="object"&&a.success?a.note:void 0;return m.jsxs("div",{children:[m.jsx("span",{className:"text-amber-400/80 font-semibold text-sm",children:"note read"}),s&&m.jsxs(m.Fragment,{children:[m.jsxs("div",{className:"mt-1.5 text-[#999] text-[13px]",children:[s.title??"(untitled)",m.jsxs("span",{className:"text-[#555] ml-1",children:["(",s.category??"general",")"]}),(s.by_you||s.agent_name)&&m.jsxs("span",{className:"text-[#666] ml-1 text-xs",children:["by ",s.by_you?"you":s.agent_name]})]}),s.content&&m.jsx("div",{className:"mt-1",children:m.jsx(ua,{text:s.content})})]})]})}if(e==="list_notes"){const a=r;let s=[];if(a&&typeof a=="object"&&a.success){const o=a.notes;s=Array.isArray(o)?o:[]}return m.jsxs("div",{children:[m.jsx("span",{className:"text-amber-400/80 font-semibold text-sm",children:"notes"}),s.length>0?m.jsx("div",{className:"mt-1.5 space-y-0.5",children:s.map((o,c)=>m.jsxs("div",{className:"text-[13px]",children:[m.jsx("span",{className:"text-[#555] mr-1",children:"-"}),m.jsx("span",{className:"text-[#999]",children:o.title??"(untitled)"}),m.jsxs("span",{className:"text-[#555] ml-1",children:["(",o.category??"general",")"]}),(o.by_you||o.agent_name)&&m.jsxs("span",{className:"text-[#666] ml-1 text-xs",children:["by ",o.by_you?"you":o.agent_name]}),o.content&&m.jsx("div",{className:"ml-3",children:m.jsx(ua,{text:o.content})})]},c))}):m.jsx("div",{className:"mt-1 text-[#555] text-xs",children:"No notes"})]})}return m.jsx("span",{className:"text-amber-400/80 font-semibold text-sm",children:"note"})}const nU={create_todo:{label:"Task added",Icon:Y_},list_todos:{label:"Plan",Icon:nC},update_todo:{label:"Task updated",Icon:nT},mark_todo_done:{label:"Task completed",Icon:H_},mark_todo_pending:{label:"Task reopened",Icon:fT},delete_todo:{label:"Task removed",Icon:CT}};function rU({status:e}){return e==="done"?m.jsx(H_,{className:"w-3.5 h-3.5 text-emerald-400/70 shrink-0"}):e==="in_progress"?m.jsx(mC,{className:"w-3.5 h-3.5 text-purple-400/70 shrink-0 animate-pulse"}):m.jsx($_,{className:"w-3.5 h-3.5 text-[#444] shrink-0"})}function iU({todos:e,highlightId:t}){return m.jsx("div",{className:"space-y-0",children:e.map((r,a)=>{const s=r.status??"pending",o=t&&r.id===t;return m.jsxs("div",{className:`flex items-start gap-2.5 py-1.5 px-2 -mx-2 rounded-md transition-colors ${o?"bg-purple-500/[0.08]":""}`,children:[m.jsx("div",{className:"mt-[1px]",children:m.jsx(rU,{status:s})}),m.jsx("span",{className:`text-[13px] leading-snug ${s==="done"?"text-[#555] line-through":s==="in_progress"?"text-[#bbb]":"text-[#999]"}`,children:r.title??"(untitled)"})]},r.id??a)})})}function aU({toolName:e,args:t,result:r}){const a=nU[e]??{label:"Plan",Icon:oT},s=a.Icon,o=r;if(typeof o=="string"&&o.trim())return m.jsxs("div",{children:[m.jsxs("div",{className:"flex items-center gap-2",children:[m.jsx(s,{className:"w-3.5 h-3.5 text-purple-400/60"}),m.jsx("span",{className:"text-purple-400/80 font-semibold text-sm",children:a.label})]}),m.jsx("div",{className:"mt-1.5 text-[#888] text-[13px]",children:o.trim()})]});let c=[],d=null,f;if(o&&typeof o=="object"){if(d=o.error??null,o.success){const p=o.todos;c=Array.isArray(p)?p:[]}f=o.id??t.todo_id??void 0}const h=e!=="list_todos"?f:void 0;return c.length===0&&!d?m.jsxs("div",{className:"flex items-center gap-2",children:[m.jsx(s,{className:"w-3.5 h-3.5 text-purple-400/60"}),m.jsx("span",{className:"text-purple-400/80 font-semibold text-sm",children:a.label})]}):m.jsxs("div",{children:[m.jsxs("div",{className:"flex items-center gap-2 mb-2",children:[m.jsx(s,{className:"w-3.5 h-3.5 text-purple-400/60"}),m.jsx("span",{className:"text-purple-400/80 font-semibold text-sm",children:a.label})]}),d&&m.jsx("div",{className:"text-red-400/70 text-[13px] mb-2",children:d}),c.length>0&&m.jsx("div",{className:"rounded-lg border border-white/[0.06] bg-white/[0.015] px-3 py-2",children:m.jsx(iU,{todos:c,highlightId:h})})]})}function g_(e){if(e==null)return null;if(typeof e=="string")return e.trim()?e:null;if(typeof e=="object"){const t=e;if(typeof t.__raw=="string")return t.__raw;if(Object.keys(t).length===0)return null;try{return JSON.stringify(e,null,2)}catch{return String(e)}}return String(e)}function h2({toolName:e,args:t,result:r}){const a=g_(t),s=g_(r);return m.jsxs("div",{children:[m.jsx("span",{className:"text-[#888] font-semibold text-sm",children:e.replace(/_/g," ")}),a&&m.jsx(wi,{className:"text-[#777]",children:a}),s&&m.jsx(wi,{className:"text-[#666]",children:s})]})}function sU({args:e}){const t=e.skills,r=(Array.isArray(t)?t:String(t??"").split(",")).map(a=>String(a).trim()).filter(Boolean);return m.jsxs("div",{className:"flex items-center gap-2",children:[m.jsx("span",{className:"text-emerald-400/80 font-semibold text-sm",children:"Loading skill"}),r.length>0&&m.jsx("span",{className:"text-[#888] text-[13px]",children:r.join(", ")})]})}function lU({args:e}){const t=e.message??"";return t?m.jsxs("div",{children:[m.jsx(ua,{text:t}),m.jsx("div",{className:"mt-1.5 text-[#888] text-[13px]",children:"waiting for your reply"})]}):null}const oU={reported:{label:"reported",color:"text-orange-400",Icon:Nu},no_issue_found:{label:"no issue found",color:"text-emerald-400",Icon:Eu},ruled_out:{label:"ruled out",color:"text-emerald-400/70",Icon:Eu},not_applicable:{label:"not applicable",color:"text-[#777]",Icon:bC},needs_follow_up:{label:"needs follow-up",color:"text-yellow-400",Icon:gC}},cU=["reported","needs_follow_up","no_issue_found","ruled_out","not_applicable"];function mo(e){const t=(e??"").trim().toLowerCase();return oU[t]??{label:t?t.replace(/_/g," "):"unrecorded",color:"text-[#777]",Icon:$_}}const uU={record_coverage:"Coverage recorded",update_coverage:"Coverage updated",list_coverage:"Coverage"};function gu({toolName:e}){return m.jsxs("div",{className:"flex items-center gap-2",children:[m.jsx(q_,{className:"w-3.5 h-3.5 text-cyan-400/60"}),m.jsx("span",{className:"text-cyan-400/80 font-semibold text-sm",children:uU[e]??"Coverage"})]})}function dU({entry:e}){const{label:t,color:r,Icon:a}=mo(e.outcome),s=(e.previous_outcomes??[]).map(o=>mo(o).label).filter(Boolean);return m.jsxs("div",{className:"flex items-start gap-2.5 py-1.5",children:[m.jsx(a,{className:`w-3.5 h-3.5 shrink-0 mt-[2px] ${r}`}),m.jsxs("div",{className:"min-w-0",children:[m.jsxs("div",{className:"text-[13px] leading-snug",children:[m.jsx("span",{className:"text-[#bbb]",children:e.surface??"(unnamed surface)"}),e.risk_area&&m.jsxs("span",{className:"text-[#666]",children:[" · ",e.risk_area]})]}),m.jsxs("div",{className:"text-xs mt-0.5",children:[m.jsx("span",{className:r,children:t}),s.length>0&&m.jsxs("span",{className:"text-[#555]",children:[" (was ",s.join(" → "),")"]}),(e.by_you||e.agent_name)&&m.jsxs("span",{className:"text-[#555]",children:[" · ",e.by_you?"you":e.agent_name]})]}),e.evidence&&m.jsx("div",{className:"text-[#777] text-xs mt-1 leading-snug",children:e.evidence})]})]})}function fU({toolName:e,args:t,result:r}){const a=r;if(typeof a=="string"&&a.trim())return m.jsxs("div",{children:[m.jsx(gu,{toolName:e}),m.jsx("div",{className:"mt-1.5 text-[#888] text-[13px]",children:a.trim()})]});const s=a&&typeof a=="object"?a:null,o=t.surface??"",c=t.risk_area??"",d=t.evidence??"";if(s&&!s.success)return m.jsxs("div",{children:[m.jsx(gu,{toolName:e}),(o||c)&&m.jsxs("div",{className:"mt-1.5 text-[13px] text-[#bbb]",children:[o,c&&m.jsxs("span",{className:"text-[#666]",children:[" · ",c]})]}),m.jsx("div",{className:"mt-1 text-red-400/70 text-[13px]",children:s.error??"Coverage call failed"})]});if(e==="list_coverage"){const b=s==null?void 0:s.entries,_=Array.isArray(b)?b:[],E=(s==null?void 0:s.outcome_counts)??{},S=(s==null?void 0:s.total_count)??0;return m.jsxs("div",{children:[m.jsx(gu,{toolName:e}),Object.keys(E).length>0&&m.jsx("div",{className:"mt-2 flex items-center gap-3 flex-wrap",children:cU.filter(w=>E[w]).map(w=>{const{label:k,color:N}=mo(w);return m.jsxs("span",{className:`text-xs ${N}`,children:[k,": ",E[w]]},w)})}),_.length>0?m.jsx("div",{className:"mt-2 rounded-lg border border-white/[0.06] bg-white/[0.015] px-3 py-1 divide-y divide-white/[0.04]",children:_.map((w,k)=>m.jsx(dU,{entry:w},w.entry_id??k))}):m.jsx("div",{className:"mt-1.5 text-[#555] text-xs",children:S===0?"No surfaces recorded yet":"No surfaces match this filter"})]})}const f=(s==null?void 0:s.outcome)??"",h=(s==null?void 0:s.previous_outcome)??"",{label:p,color:g,Icon:y}=mo(f);return m.jsxs("div",{children:[m.jsx(gu,{toolName:e}),m.jsxs("div",{className:"mt-2 flex items-start gap-2.5",children:[m.jsx(y,{className:`w-3.5 h-3.5 shrink-0 mt-[2px] ${g}`}),m.jsxs("div",{className:"min-w-0",children:[m.jsxs("div",{className:"text-[13px] leading-snug text-[#bbb]",children:[o||(s!=null&&s.entry_id?`entry ${s.entry_id}`:"(unnamed surface)"),c&&m.jsxs("span",{className:"text-[#666]",children:[" · ",c]})]}),m.jsxs("div",{className:"text-xs mt-0.5",children:[h&&m.jsxs("span",{className:"text-[#666]",children:[mo(h).label," → "]}),m.jsx("span",{className:g,children:p})]}),d&&m.jsx("div",{className:"text-[#777] text-xs mt-1 leading-snug",children:d})]})]})]})}const hU={get_threat_model:{label:"Threat model",Icon:Vu},save_threat_model:{label:"Threat model saved",Icon:mT},amend_threat_model:{label:"Threat model amended",Icon:Y_}};function x_(e){const t=typeof e=="string"?e.trim():"";return!t||t==="unversioned"?"":t.slice(0,8)}function mU({toolName:e,args:t,result:r}){const a=hU[e]??{label:"Threat model",Icon:Vu},s=a.Icon,o=t.target??"",c=r,d=m.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[m.jsx(s,{className:"w-3.5 h-3.5 text-blue-400/60"}),m.jsx("span",{className:"text-blue-400/80 font-semibold text-sm",children:a.label}),o&&m.jsx("span",{className:"text-[#666] font-mono text-xs",children:o})]});if(typeof c=="string"&&c.trim())return m.jsxs("div",{children:[d,m.jsx("div",{className:"mt-1.5 text-[#888] text-[13px]",children:c.trim()})]});const f=c&&typeof c=="object"?c:null;if(f&&!f.success)return m.jsxs("div",{children:[d,m.jsx("div",{className:"mt-1.5 text-red-400/70 text-[13px]",children:f.error??"Threat model call failed"})]});if(e==="get_threat_model"){if(f&&!f.found)return m.jsxs("div",{children:[d,m.jsx("div",{className:"mt-1.5 text-[#555] text-xs",children:"No model cached for this target yet"})]});const y=f==null?void 0:f.amendments,b=Array.isArray(y)?y:[],_=x_(f==null?void 0:f.cached_revision);return m.jsxs("div",{children:[d,(f==null?void 0:f.stale)===!0&&m.jsxs("div",{className:"mt-1.5 flex items-center gap-1.5 text-yellow-400/80 text-xs",children:[m.jsx(Nu,{className:"w-3 h-3 shrink-0"}),m.jsxs("span",{children:["stale",_?` — written at ${_}`:""]})]}),b.length>0&&m.jsxs("div",{className:"mt-2",children:[m.jsxs("span",{className:"text-amber-400/70 text-xs font-semibold",children:[b.length," amendment",b.length===1?"":"s"]}),m.jsx("span",{className:"text-[#555] text-xs",children:" — later statements win"}),m.jsx("div",{className:"mt-1 space-y-1",children:b.map((E,S)=>m.jsxs("div",{className:"text-xs leading-snug",children:[m.jsx("span",{className:"text-[#666]",children:E.agent_name??"unknown agent"}),E.content&&m.jsxs("span",{className:"text-[#999]",children:[": ",E.content]})]},S))})]}),typeof(f==null?void 0:f.content)=="string"&&f.content.trim()&&m.jsx("div",{className:"mt-2",children:m.jsx(Yt,{text:f.content,maxLines:14})})]})}if(e==="amend_threat_model"){const y=t.addendum??"",b=f==null?void 0:f.amendment_count;return m.jsxs("div",{children:[d,b!=null&&m.jsxs("div",{className:"mt-1.5 text-[#666] text-xs",children:[b," amendment",b===1?"":"s"," on this model"]}),y&&m.jsx("div",{className:"mt-1.5",children:m.jsx(Yt,{text:y,maxLines:10})})]})}const h=(f==null?void 0:f.amendments_cleared)??0,p=x_(f==null?void 0:f.revision),g=t.content??"";return m.jsxs("div",{children:[d,p&&m.jsxs("div",{className:"mt-1.5 text-[#666] font-mono text-xs",children:["at ",p]}),h>0&&m.jsxs("div",{className:"mt-1.5 flex items-center gap-1.5 text-yellow-400/80 text-xs",children:[m.jsx(Nu,{className:"w-3 h-3 shrink-0"}),m.jsxs("span",{children:["cleared ",h," amendment",h===1?"":"s"]})]}),g&&m.jsx("div",{className:"mt-2",children:m.jsx(Yt,{text:g,maxLines:14})})]})}function pU(e){return!e||typeof e!="object"||Array.isArray(e)?[]:Object.entries(e).map(([t,r])=>{const a=typeof r=="string"?r:JSON.stringify(r);return`${t}: ${a??String(r)}`})}const b_=600;function gU(e){if(typeof e=="string"){const t=e.trim();return t?t.length>b_?`${t.slice(0,b_)}…`:t:null}return null}function xU({toolName:e,mcpTool:t,mcpConnection:r,args:a,result:s,status:o}){const c=pU(a),d=o==="failed"||o==="error",f=d?gU(s):null,h=e==="describe_mcp";return m.jsxs("div",{children:[m.jsx("div",{className:"flex items-center gap-2 flex-wrap",children:h?m.jsxs(m.Fragment,{children:[m.jsx("span",{className:"text-[13px] text-[#555]",children:"Inspecting MCP server"}),r&&m.jsx("span",{className:"font-mono text-teal-300 font-semibold text-sm",children:r})]}):m.jsxs(m.Fragment,{children:[m.jsx("span",{className:"font-mono text-teal-300 font-semibold text-sm",children:t||e}),m.jsx("span",{className:"text-[13px] text-[#555]",children:"via MCP server"}),r&&m.jsx("span",{className:"text-[13px] text-teal-400/80",children:r})]})}),c.length>0&&m.jsx("div",{className:"mt-1 font-mono text-[13px] leading-relaxed",children:c.map(p=>m.jsx("div",{className:"text-[#777] break-all",children:p},p))}),m.jsxs("div",{className:"mt-1 text-[13px]",children:[o==="running"&&m.jsx("span",{className:"text-[#666]",children:"Running"}),o==="completed"&&m.jsx("span",{className:"text-emerald-400/80",children:"✓ Done"}),d&&m.jsx("span",{className:"text-red-400/80",children:"✗ Failed"})]}),f&&m.jsx("pre",{className:"mt-1 font-mono text-[13px] leading-relaxed whitespace-pre-wrap break-words text-red-400/70",children:f})]})}const Ga={terminal:{renderer:h7,icon:K_,color:"text-emerald-400"},python:{renderer:Z7,icon:EC,color:"text-yellow-400"},browser:{renderer:p7,icon:G_,color:"text-blue-400"},filesystem:{renderer:g7,icon:MC,color:"text-sky-400"},proxy:{renderer:H7,icon:z_,color:"text-purple-400",match:/request|sitemap|scope/},reporting:{renderer:A7,icon:bT,color:"text-red-400"},thinking:{renderer:$7,icon:B_,color:"text-purple-400"},agents:{renderer:q7,icon:Oo,color:"text-cyan-400",match:/agent/},search:{renderer:P7,icon:gT,color:"text-amber-400"},lifecycle:{renderer:J7,icon:F_,color:"text-emerald-400"},notes:{renderer:tU,icon:NT,color:"text-amber-400",match:/note/},skills:{renderer:sU,icon:Gm,color:"text-emerald-400"},todos:{renderer:aU,icon:YC,color:"text-purple-400",match:/todo/},coverage:{renderer:fU,icon:q_,color:"text-cyan-400",match:/coverage/},threatModel:{renderer:mU,icon:Vu,color:"text-blue-400",match:/threat_model/},telemetry:{renderer:h2,icon:Gm,color:"text-[#555]"},mcp:{renderer:xU,icon:V_,color:"text-teal-400"}},bU={terminal:["exec_command","write_stdin","terminal_execute"],python:["python_action"],browser:["browser_action"],filesystem:["apply_patch","view_image","str_replace_editor","list_files","search_files"],proxy:["list_requests","view_request","repeat_request","list_sitemap","view_sitemap_entry","scope_rules","send_request"],reporting:["create_vulnerability_report","list_reports","get_report"],thinking:["think"],agents:["create_agent","agent_finish","send_message_to_agent","wait_for_agents","view_agent_graph","stop_agent"],search:["web_search"],lifecycle:["scan_start_info","subagent_start_info","finish_scan","respond_to_user"],notes:["create_note","delete_note","update_note","list_notes","get_note"],skills:["load_skill"],todos:["create_todo","list_todos","update_todo","mark_todo_done","mark_todo_pending","delete_todo"],coverage:["record_coverage","update_coverage","list_coverage"],threatModel:["get_threat_model","save_threat_model","amend_threat_model"],telemetry:["sandbox_error_details","llm_error_details"],mcp:[]},yU=Object.fromEntries(Object.entries(bU).flatMap(([e,t])=>t.map(r=>[r,e]))),vU={finish_scan:eU,respond_to_user:lU,apply_patch:E7,view_image:k7,list_reports:f_,get_report:f_},_U={agent_finish:{icon:F_,color:"text-cyan-400"},send_message_to_agent:{icon:yh,color:"text-cyan-400"},wait_for_agents:{icon:yh,color:"text-cyan-400"},respond_to_user:{icon:yh,color:"text-emerald-400"},view_agent_graph:{icon:TC,color:"text-cyan-400"},stop_agent:{icon:I_,color:"text-red-400"},scan_start_info:{icon:Vu,color:"text-emerald-400"},subagent_start_info:{icon:Oo,color:"text-purple-400"},view_image:{icon:PC,color:"text-sky-400"}},wU=Ga.telemetry;function m2(e){var r;const t=yU[e];if(t)return t;for(const[a,s]of Object.entries(Ga))if((r=s.match)!=null&&r.test(e))return a;return null}function EU(e,t){if(t)return Ga.mcp.renderer;const r=vU[e];if(r)return r;const a=m2(e);return a?Ga[a].renderer:h2}function NU(e,t){if(t)return{icon:Ga.mcp.icon,color:Ga.mcp.color};const r=_U[e];if(r)return r;const a=m2(e),s=a?Ga[a]:wU;return{icon:s.icon,color:s.color}}const SU=30;function kU({role:e,content:t}){const r=e==="user"||e==="human";return m.jsxs("div",{children:[m.jsx("span",{className:`font-semibold text-sm ${r?"text-blue-400/80":"text-purple-400/80"}`,children:r?"User":"Thinking"}),m.jsx("div",{className:"mt-1.5 italic text-[#888]",children:m.jsx(Yt,{text:t,maxLines:SU})})]})}class CU extends ee.Component{constructor(t){super(t),this.state={hasError:!1}}static getDerivedStateFromError(){return{hasError:!0}}render(){return this.state.hasError?m.jsx("span",{className:"text-[#555] font-semibold text-sm",children:this.props.toolName.replace(/_/g," ")}):this.props.children}}function TU(e){const t=EU(e.toolName,e.mcpConnection);return m.jsx(CU,{toolName:e.toolName,children:m.jsx(t,{...e})})}function p2(e){if(e==null||typeof e!="string")return e;const t=e.trim();if(!t)return e;try{return JSON.parse(t)}catch{}try{const r=t.replace(/\bNone\b/g,"null").replace(/\bTrue\b/g,"true").replace(/\bFalse\b/g,"false").replace(/'/g,'"');return JSON.parse(r)}catch{return{__raw:e}}}function y_(e){return typeof e=="string"&&e?e:null}function g2(e){const t=p2(e);return t&&typeof t=="object"&&!Array.isArray(t)?t:t==null?{}:{__raw:typeof t=="string"?t:JSON.stringify(t)}}function v_(e){const t=/(\d+)$/.exec(e);return t?parseInt(t[1],10):0}function yg(e){var r;const t=(r=e.data)==null?void 0:r.role;return e.type==="chat"&&(t==="user"||t==="human")}function AU(e){var t;return yg(e)&&String(((t=e.data)==null?void 0:t.content)??"").startsWith("[Message from ")}function MU(e){const t=new Set;let r=!1;for(const a of e)if(yg(a)){if(AU(a)){t.add(a.id);continue}r||(r=!0,t.add(a.id))}return t}const OU={completed:"text-emerald-400 border-emerald-500/30 bg-emerald-500/10",running:"text-blue-400 border-blue-500/30 bg-blue-500/10",waiting:"text-yellow-400 border-yellow-500/30 bg-yellow-500/10",stopped:"text-[#aaa] border-[#333] bg-[#1a1a1a]",crashed:"text-red-400 border-red-500/30 bg-red-500/10",failed:"text-red-400 border-red-500/30 bg-red-500/10"};function RU(e){return e==="completed"?"completed":e==="running"?"running":e==="failed"||e==="crashed"?"failed":e}function jU(e,t){var d;const r=new Map;for(const f of e)if(f.parent_id){const h=r.get(f.parent_id)??[];h.push(f.id),r.set(f.parent_id,h)}const a=new Map,s=new Map,o=new Map;for(const f of t)if(f.type==="tool"){if(a.set(f.agent_id,(a.get(f.agent_id)??0)+1),((d=f.data)==null?void 0:d.tool_name)==="create_agent"){const h=g2(f.data.args),p=h.name??h.agent_name??"",g=h.task??"";p&&g&&o.set(p,g)}}else yg(f)||s.set(f.agent_id,(s.get(f.agent_id)??0)+1);const c=new Map;for(const f of e)c.set(f.id,{id:f.id,name:f.name,task:o.get(f.name)??"",status:RU(f.status),parentId:f.parent_id,children:r.get(f.id)??[],createdAt:f.created_at,toolCount:a.get(f.id)??0,messageCount:s.get(f.id)??0});return c}function DU({agent:e,events:t,showHeader:r=!0}){const a=ee.useMemo(()=>{const c=t.filter(f=>f.agent_id===e.id).sort((f,h)=>v_(f.id)-v_(h.id)),d=MU(c);return c.filter(f=>!d.has(f.id))},[t,e.id]),s=a.filter(c=>c.type==="tool").length,o=a.length-s;return m.jsxs("div",{children:[r&&m.jsxs(m.Fragment,{children:[m.jsxs("div",{className:"flex items-center gap-2 flex-wrap mb-1",children:[m.jsx("span",{className:"text-base font-semibold text-white truncate",children:e.name}),m.jsx("span",{className:`flex-shrink-0 text-xs font-medium capitalize px-2 py-0.5 rounded-full border ${OU[e.status]??"text-[#aaa] border-[#333] bg-[#1a1a1a]"}`,children:e.status}),m.jsx("span",{className:"font-mono text-xs text-[#555]",children:e.id})]}),m.jsxs("p",{className:"text-xs text-[#666] mb-4",children:[o," message",o===1?"":"s"," · ",s," tool call",s===1?"":"s"]})]}),a.length===0?m.jsx("p",{className:"text-sm text-[#666]",children:"No recorded activity for this agent."}):m.jsx("div",{className:"py-1",children:a.map((c,d)=>{var w,k,N,M,B,R,U,I;const f=d===a.length-1,h=c.type==="tool",p=h?String(((w=c.data)==null?void 0:w.tool_name)??"tool"):"",g=h?"":String(((k=c.data)==null?void 0:k.role)??"assistant"),y=y_((N=c.data)==null?void 0:N.mcp_connection),b=y_((M=c.data)==null?void 0:M.mcp_tool);let _,E;if(h){const X=NU(p,y);_=X.icon,E=X.color}else{const X=g==="user"||g==="human";_=X?Oo:B_,E=X?"text-blue-400":"text-purple-400"}const S=h?String(((B=c.data)==null?void 0:B.status)??"completed"):"completed";return m.jsxs("div",{className:"flex gap-3",children:[m.jsxs("div",{className:"flex flex-col items-center shrink-0",children:[m.jsx("div",{className:`w-[30px] h-[30px] rounded-full bg-black border flex items-center justify-center shrink-0 ${h&&S==="running"?"border-blue-500/40 animate-pulse":h&&S==="failed"?"border-red-500/30":"border-[#222]"}`,children:m.jsx(_,{className:`w-3.5 h-3.5 ${E}`})}),!f&&m.jsx("div",{className:"w-px flex-1 bg-[#1a1a1a] mt-1"})]}),m.jsx("div",{className:"flex-1 min-w-0 pt-[5px] pb-6",children:h?m.jsx(TU,{toolName:p,mcpConnection:y,mcpTool:b,args:g2((R=c.data)==null?void 0:R.args),result:p2((U=c.data)==null?void 0:U.result)??null,status:S}):m.jsx(kU,{role:g,content:String(((I=c.data)==null?void 0:I.content)??"")})})]},c.id)})})]})}class qu extends Error{constructor(t){super(t),this.name="RunParseError"}}const LU=["critical","high","medium","low"];function zU(e){const t=String(e??"").toLowerCase().trim();return LU.includes(t)?t:"low"}function IU(e){if(typeof e=="string"&&e.trim()){const t=e.trim().replace(" UTC","Z").replace(" ","T"),r=new Date(t);if(!Number.isNaN(r.getTime()))return r.toISOString();const a=new Date(e);if(!Number.isNaN(a.getTime()))return a.toISOString()}return new Date().toISOString()}function Ot(e){return typeof e=="string"&&e.length>0?e:null}function BU(e){return typeof e=="number"&&Number.isFinite(e)?e:null}function x2(e,t){try{return JSON.parse(e)}catch{throw new qu(`${t} isn't valid JSON. Make sure you selected a Strix run directory.`)}}function UU(e){const t=x2(e,"run.json");if(!t||typeof t!="object"||Array.isArray(t))throw new qu("run.json is not an object.");const r=t,a=[],s=r.targets_info;if(Array.isArray(s)){for(const b of s)if(b&&typeof b=="object"){const _=b.original;typeof _=="string"&&_&&a.push(_)}}const o=Ot(r.start_time),c=Ot(r.end_time);let d=null;if(o&&c){const b=new Date(o).getTime(),_=new Date(c).getTime();!Number.isNaN(b)&&!Number.isNaN(_)&&_>=b&&(d=Math.round((_-b)/1e3))}let f=null,h=null,p=null,g=null;const y=r.scan_results;if(y&&typeof y=="object"){const b=y;f=Ot(b.executive_summary),h=Ot(b.technical_analysis),p=Ot(b.methodology),g=Ot(b.recommendations)}return{runId:Ot(r.run_id),runName:Ot(r.run_name),targets:a,scanMode:Ot(r.scan_mode),status:Ot(r.status),startTime:o,endTime:c,durationSeconds:d,executiveSummary:f,technicalAnalysis:h,methodology:p,recommendations:g}}function HU(){return{pr_review_id:null,cve:null,cvss:null,potential_risk_saving:null,risk_saving_description:null,impact:null,endpoint:null,method:null,target:null,technical_analysis:null,poc_description:null,poc_script_code:null,code_diff:null,code_file:null,code_before:null,code_after:null,cwe:null,code_locations:null,remediation_steps:null,fix_pr_body:null,evidence:null,assumptions:null,fix_effort:null,cvss_breakdown:null,status_changed_at:null,status_changed_by:null,status_note:null,snoozed_until:null,reopened_at:null,reopened_by:null,original_severity:null,severity_changed_at:null,severity_changed_by:null,severity_override_reason:null,retest_of_vulnerability_id:null}}function $U(e,t,r){const a=e.cwe,s=typeof a=="string"&&a.trim()?[a.trim()]:Array.isArray(a)?a.filter(c=>typeof c=="string"&&c):null;return{...HU(),id:Ot(e.id)??`vuln-${t+1}`,scan_id:r,title:Ot(e.title)??"Untitled finding",description:Ot(e.description)??"",severity:zU(e.severity),status:"open",created_at:IU(e.timestamp),cve:Ot(e.cve),cvss:BU(e.cvss),impact:Ot(e.impact),endpoint:Ot(e.endpoint),method:Ot(e.method),target:Ot(e.target),technical_analysis:Ot(e.technical_analysis),poc_description:Ot(e.poc_description),poc_script_code:Ot(e.poc_script_code),cwe:s,code_locations:Array.isArray(e.code_locations)?e.code_locations:null,remediation_steps:Ot(e.remediation_steps),fix_pr_body:Ot(e.fix_pr_body),evidence:Ot(e.evidence),assumptions:Ot(e.assumptions),fix_effort:Ot(e.fix_effort)??null,cvss_breakdown:e.cvss_breakdown??null}}function qU(e,t=null){const r=x2(e,"vulnerabilities.json");if(!Array.isArray(r))throw new qu("vulnerabilities.json is not a JSON array.");return r.map((a,s)=>{if(!a||typeof a!="object")throw new qu(`vulnerabilities.json entry #${s+1} is not an object.`);return $U(a,s,t)})}function PU(e){const t={critical:0,high:0,medium:0,low:0};for(const r of e)t[r.severity]+=1;return t}async function es(e){const t=await fetch(e,{cache:"no-store"});if(!t.ok)throw new Error(`${e} responded ${t.status}`);return t.json()}function dd(e){return e?`?run=${encodeURIComponent(e)}`:""}async function b2(e){const t=await es("/api/run"+dd(e)),r=UU(JSON.stringify(t)),a=t.finished===!0;return{summary:r,raw:t,finished:a}}async function y2(e,t){const r=await es("/api/vulnerabilities"+dd(t));return qU(JSON.stringify(r),e)}async function FU(e){const t=await es("/api/report"+dd(e));return(t==null?void 0:t.markdown)??null}async function v2(e){const t=await es("/api/transcript"+dd(e));return{agents:Array.isArray(t==null?void 0:t.agents)?t.agents:[],events:Array.isArray(t==null?void 0:t.events)?t.events:[]}}async function __(e){const{summary:t,raw:r,finished:a}=await b2(e),[s,o,c]=await Promise.all([y2(t.runId,e).catch(()=>[]),FU(e).catch(()=>null),v2(e).catch(()=>({agents:[],events:[]}))]);return{summary:t,raw:r,finished:a,vulnerabilities:s,reportMarkdown:o,transcript:c}}async function il(e,t){const r=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t),cache:"no-store"});let a={};try{const s=await r.json();s&&typeof s=="object"&&(a=s)}catch{}return{ok:r.ok,status:r.status,data:a}}async function GU(){const e=await es("/api/runs");return{locked:(e==null?void 0:e.locked)??!0,count:typeof(e==null?void 0:e.count)=="number"?e.count:0,runs:Array.isArray(e==null?void 0:e.runs)?e.runs:[]}}async function VU(){const e=await es("/api/capabilities");return{can_steer:(e==null?void 0:e.can_steer)===!0}}async function YU(e,t){const{ok:r,data:a}=await il("/api/agents/steer",{agent_id:e,message:t});return r&&a.ok===!0?{ok:!0}:{ok:!1,error:String(a.error??"unavailable")}}async function XU(e,t){const{ok:r,data:a}=await il("/api/feedback",{message:e,email:t});return r&&a.ok===!0?{ok:!0}:{ok:!1,error:String(a.error??"unavailable")}}async function KU(){const e=await es("/api/auth/status");return{verified:(e==null?void 0:e.verified)===!0,email:(e==null?void 0:e.email)??null}}async function _2(e){const{ok:t,data:r}=await il("/api/auth/otp/start",{email:e});return t&&r.ok===!0?{ok:!0}:{ok:!1,error:String(r.error??"unavailable")}}async function w2(e,t){const{ok:r,data:a}=await il("/api/auth/otp/verify",{email:e,code:t});return r&&a.verified===!0?{verified:!0,email:String(a.email??e)}:{verified:!1,error:String(a.error??"invalid_code")}}async function ZU(){await il("/api/auth/forget",{})}async function QU(e){const{ok:t,data:r}=await il("/api/report/send",e?{run:e}:{});return t&&r.ok===!0?{ok:!0,password:String(r.password??""),filename:String(r.filename??"strix-report.pdf")}:{ok:!1,error:String(r.error??"unavailable")}}const Us="__root__";function E2({agents:e,fixedAgentId:t,className:r}){const a=ee.useRef(null),[s,o]=ee.useState(!1),[c,d]=ee.useState(!1),[f,h]=ee.useState(""),[p,g]=ee.useState(!1),[y,b]=ee.useState(null),_=t!=null,E=ee.useMemo(()=>e.find(z=>!z.parent_id)??e[0]??null,[e]),S=ee.useMemo(()=>e.filter(z=>z.parent_id&&z.status==="running"),[e]),[w,k]=ee.useState(Us),[N,M]=ee.useState(!1);ee.useEffect(()=>{w!==Us&&!S.some(z=>z.id===w)&&k(Us)},[w,S]);const{targetId:B,targetName:R}=ee.useMemo(()=>{if(_){const V=e.find(P=>P.id===t)??null;return{targetId:t??null,targetName:(V==null?void 0:V.name)??"this agent"}}if(w===Us)return{targetId:(E==null?void 0:E.id)??null,targetName:"Root agent"};const z=e.find(V=>V.id===w)??null;return{targetId:(z==null?void 0:z.id)??(E==null?void 0:E.id)??null,targetName:(z==null?void 0:z.name)??"Root agent"}},[e,t,_,E,w]),U=f.trim().length===0;ee.useLayoutEffect(()=>{const z=a.current;z&&(z.style.height="auto",z.style.height=`${z.scrollHeight}px`)},[f]);const I=ee.useCallback(()=>{o(!0),requestAnimationFrame(()=>{var z;return(z=a.current)==null?void 0:z.focus()})},[]),X=ee.useCallback(()=>{o(!1),d(!1),M(!1)},[]),j=ee.useCallback(async()=>{if(p)return;const z=f.trim();if(!z||!B)return;g(!0),b(null);const V=R,P=await YU(B,z);g(!1),P.ok?(h(""),b(`Sent to ${V}`),Tr("agent_steered")):P.error==="not_delivered"?b("Could not reach that agent (it may have finished)."):b("Could not send that message. Try again.")},[p,f,B,R]);return s?m.jsxs("div",{className:Mr("mt-4 rounded-2xl border border-white/[0.08] bg-[#050505] overflow-hidden transition-colors duration-300",c?"border-white/[0.18]":"hover:border-white/[0.12]",r),children:[m.jsxs("div",{className:"flex items-center justify-between gap-3 border-b border-white/[0.06] px-5 py-3",children:[m.jsxs("div",{className:"min-w-0",children:[m.jsxs("div",{className:"flex items-center gap-2",children:[m.jsx(Fm,{className:"h-4 w-4 text-[#666]"}),m.jsx("p",{className:"text-sm font-medium text-white",children:"Live prompt"})]}),m.jsx("p",{className:"mt-0.5 text-xs text-[#777]",children:"Connected"})]}),m.jsxs("div",{className:"flex shrink-0 items-center gap-2",children:[_?m.jsxs("div",{className:"rounded-full border border-white/[0.08] bg-white/[0.03] px-3 py-1 text-xs text-[#aaa]",children:["Target: ",m.jsx("span",{className:"text-white",children:R})]}):m.jsxs("div",{className:"flex items-center gap-1.5",children:[m.jsx("span",{className:"text-xs text-[#aaa]",children:"Target:"}),m.jsxs("div",{className:"relative",children:[m.jsxs("button",{type:"button",onClick:()=>M(z=>!z),onBlur:()=>requestAnimationFrame(()=>M(!1)),className:"inline-flex h-7 items-center gap-1 rounded-full border border-white/[0.08] bg-white/[0.03] px-3 text-xs text-white transition-colors hover:border-white/[0.16] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/20","aria-haspopup":"listbox","aria-expanded":N,children:[m.jsx("span",{className:"max-w-[140px] truncate",children:R}),m.jsx(po,{className:"h-3.5 w-3.5 text-[#999]"})]}),N&&m.jsxs("div",{className:"absolute right-0 z-10 mt-1 min-w-[160px] overflow-hidden rounded-lg border border-[#333] bg-[#0a0a0a] py-1 shadow-xl",role:"listbox",children:[m.jsx(w_,{label:"Root agent",active:w===Us,onSelect:()=>{k(Us),M(!1)}}),S.map(z=>m.jsx(w_,{label:z.name,active:w===z.id,onSelect:()=>{k(z.id),M(!1)}},z.id))]})]})]}),m.jsx("button",{type:"button",onClick:X,className:"inline-flex h-7 w-7 items-center justify-center rounded-full text-[#777] transition-colors hover:bg-white/[0.06] hover:text-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/20","aria-label":"Collapse live prompt composer",children:m.jsx(po,{className:"h-4 w-4"})})]})]}),m.jsx("div",{className:"px-5 pt-4 pb-3",children:m.jsx("textarea",{ref:a,rows:1,value:f,onChange:z=>h(z.target.value),onFocus:()=>d(!0),onBlur:()=>d(!1),onKeyDown:z=>{z.key==="Enter"&&!z.shiftKey&&(z.preventDefault(),j())},placeholder:"Send a live prompt to the running pentest…",maxLength:4e3,disabled:p,className:"block w-full resize-none border-0 bg-transparent p-0 text-[15px] leading-6 text-white placeholder:text-[#444] focus:outline-none disabled:opacity-60 max-h-[160px] overflow-y-auto"})}),m.jsxs("div",{className:"flex items-center justify-between gap-3 px-4 pb-4",children:[m.jsx("div",{className:"text-xs text-[#666]",children:y??"Press Enter to send."}),m.jsxs("button",{type:"button",onClick:z=>{z.stopPropagation(),j()},disabled:p||U,className:Mr("inline-flex h-10 min-w-[112px] items-center justify-center gap-2 rounded-full px-4 text-sm font-medium transition-colors",p||U?"bg-white/[0.08] text-[#666]":"bg-white text-black hover:bg-neutral-200"),children:[p?m.jsx(Ps,{className:"h-4 w-4 animate-spin"}):m.jsx(Yk,{className:"h-4 w-4",strokeWidth:2.5}),m.jsx("span",{children:"Send prompt"})]})]})]}):m.jsxs("button",{type:"button",onClick:I,className:Mr("mt-4 flex w-full items-center justify-between gap-3 rounded-2xl border border-white/[0.08] bg-[#050505] px-5 py-3 text-left transition-colors duration-300 hover:border-white/[0.12] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/20",r),"aria-expanded":!1,"aria-label":"Expand live prompt composer",children:[m.jsxs("div",{className:"flex min-w-0 items-center gap-2",children:[m.jsx(Fm,{className:"h-4 w-4 shrink-0 text-[#666]"}),m.jsx("span",{className:"truncate text-sm font-medium text-white",children:"Guide the agent"})]}),m.jsx(U_,{className:"h-4 w-4 shrink-0 text-[#777]"})]})}function w_({label:e,active:t,onSelect:r}){return m.jsx("button",{type:"button",role:"option","aria-selected":t,onMouseDown:a=>{a.preventDefault(),r()},className:Mr("block w-full truncate px-3 py-1.5 text-left text-xs transition-colors hover:bg-white/[0.06]",t?"text-white":"text-[#aaa]"),children:e})}const WU={completed:"bg-emerald-400",running:"bg-blue-400",waiting:"bg-yellow-400",stopped:"bg-[#888]",crashed:"bg-red-400",failed:"bg-red-400"},JU=80;function eH({open:e,agent:t,events:r,steerable:a,onClose:s}){const o=ee.useRef(null),c=ee.useRef(!1),[d,f]=ee.useState(e),[h,p]=ee.useState(e?"open":"closed"),[g,y]=ee.useState(!1),b=ee.useRef(t);ee.useEffect(()=>{t&&(b.current=t)},[t]);const _=t??b.current;ee.useEffect(()=>{if(e){f(!0),p("open");return}p("closed");const S=setTimeout(()=>f(!1),140);return()=>clearTimeout(S)},[e]),ee.useEffect(()=>{if(!d){y(!1);return}const S=requestAnimationFrame(()=>y(!0));return()=>cancelAnimationFrame(S)},[d]);const E=ee.useCallback(()=>{const S=o.current;S&&(c.current=S.scrollHeight-S.scrollTop-S.clientHeight{const S=o.current;!S||!c.current||requestAnimationFrame(()=>{S.scrollTo({top:S.scrollHeight,behavior:"smooth"})})},[r]),ee.useEffect(()=>{if(!d)return;const S=k=>{k.key==="Escape"&&s()};document.addEventListener("keydown",S);const w=document.body.style.overflow;return document.body.style.overflow="hidden",()=>{document.removeEventListener("keydown",S),document.body.style.overflow=w}},[d,s]),!d||!_?null:m.jsx("div",{"data-state":h,className:"agent-modal fixed inset-0 z-50 flex items-center justify-center bg-black/80 p-4 sm:p-8",onClick:s,role:"dialog","aria-modal":"true","aria-label":`Agent ${_.name}`,children:m.jsxs("div",{className:"relative flex h-[60vh] w-[calc(100vw-4rem)] max-w-6xl flex-col overflow-hidden rounded-xl border border-[#222] bg-[#0a0a0a] shadow-2xl",onClick:S=>S.stopPropagation(),children:[m.jsxs("div",{className:"flex items-center justify-between gap-3 border-b border-[#222] px-5 py-3.5",children:[m.jsxs("div",{className:"flex min-w-0 items-center gap-2",children:[m.jsx("span",{className:`h-2 w-2 flex-shrink-0 rounded-full ${WU[_.status]??"bg-[#888]"}`}),m.jsx("span",{className:"truncate text-sm font-semibold text-white",children:_.name}),m.jsx("span",{className:"flex-shrink-0 font-mono text-xs text-[#555]",children:_.id})]}),m.jsx("button",{type:"button",onClick:s,"aria-label":"Close",className:"flex-shrink-0 rounded-md p-1 text-[#888] transition-colors hover:bg-[#1a1a1a] hover:text-white",children:m.jsx(Sp,{className:"h-4 w-4"})})]}),m.jsx("div",{ref:o,onScroll:E,className:"flex-1 overflow-y-auto p-5",children:g&&m.jsx(DU,{agent:_,events:r,showHeader:!1})}),a&&m.jsx("div",{className:"border-t border-[#222] px-5 py-3",children:m.jsx(E2,{agents:[_],fixedAgentId:_.id,className:"mt-0"})})]})})}var N2={color:void 0,size:void 0,className:void 0,style:void 0,attr:void 0},E_=da.createContext&&da.createContext(N2),tH=["attr","size","title"];function nH(e,t){if(e==null)return{};var r,a,s=rH(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;ada.createElement(t.tag,Fu({key:r},t.attr),S2(t.child)))}function vg(e){return t=>da.createElement(lH,Pu({attr:Fu({},e.attr)},t),S2(e.child))}function lH(e){var t=r=>{var a=e.attr,s=e.size,o=e.title,c=nH(e,tH),d=s||r.size||"1em",f;return r.className&&(f=r.className),e.className&&(f=(f?f+" ":"")+e.className),da.createElement("svg",Pu({stroke:"currentColor",fill:"currentColor",strokeWidth:"0"},r.attr,a,c,{className:f,style:Fu(Fu({color:e.color||r.color},r.style),e.style),height:d,width:d,xmlns:"http://www.w3.org/2000/svg"}),o&&da.createElement("title",null,o),e.children)};return E_!==void 0?da.createElement(E_.Consumer,null,r=>t(r)):t(N2)}function oH(e){return vg({attr:{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"},child:[{tag:"circle",attr:{cx:"5",cy:"6",r:"3"},child:[]},{tag:"path",attr:{d:"M5 9v12"},child:[]},{tag:"circle",attr:{cx:"19",cy:"18",r:"3"},child:[]},{tag:"path",attr:{d:"m15 9-3-3 3-3"},child:[]},{tag:"path",attr:{d:"M12 6h5a2 2 0 0 1 2 2v7"},child:[]}]})(e)}function cH(e){return vg({attr:{viewBox:"0 0 16 16",fill:"currentColor"},child:[{tag:"path",attr:{d:"M15 4.95703C15 4.58711 14.8563 4.24054 14.5949 3.97992L12.0096 1.39234C11.4879 0.86922 10.5788 0.86922 10.0571 1.39234L8 3.45119V3.32321C8 2.55068 7.37187 1.922 6.6 1.922H2.4C1.62813 1.922 1 2.55068 1 3.32321V13.5988C1 14.3713 1.62813 15 2.4 15H12.6667C13.4385 15 14.0667 14.3713 14.0667 13.5988V9.39514C14.0667 8.62261 13.4385 7.99393 12.6667 7.99393H12.5379L14.5949 5.93508C14.8553 5.67445 15 5.32602 15 4.95703ZM2.4 2.85521H6.6C6.85667 2.85521 7.06667 3.06446 7.06667 3.32228V7.99299H1.93333V3.32228C1.93333 3.06446 2.14333 2.85521 2.4 2.85521ZM1.93333 13.5979V8.92714H7.06667V14.0649H2.4C2.14333 14.0649 1.93333 13.8547 1.93333 13.5979ZM13.1333 9.39421V13.5979C13.1333 13.8547 12.9233 14.0649 12.6667 14.0649H8V8.92714H12.6667C12.9233 8.92714 13.1333 9.13638 13.1333 9.39421ZM8 7.99299V6.46287L9.5288 7.99299H8ZM13.9351 5.2737L11.3488 7.86221C11.1789 8.03223 10.8859 8.03223 10.716 7.86221L8.12973 5.2737C8.0448 5.18963 7.99813 5.07753 7.99813 4.95796C7.99813 4.83839 8.0448 4.7263 8.12973 4.64129L10.716 2.05278C10.8009 1.96777 10.9129 1.92106 11.0324 1.92106C11.1519 1.92106 11.2639 1.96777 11.3488 2.05278L13.9351 4.64129C14.02 4.72536 14.0667 4.83746 14.0667 4.95703C14.0667 5.0766 14.02 5.1887 13.9351 5.2737Z"},child:[]}]})(e)}function k2(e){return vg({attr:{viewBox:"0 0 512 512"},child:[{tag:"path",attr:{fill:"none",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"32",d:"M431 320.6c-1-3.6 1.2-8.6 3.3-12.2a34 34 0 0 1 2.1-3.1A162 162 0 0 0 464 215c.3-92.2-77.5-167-173.7-167-83.9 0-153.9 57.1-170.3 132.9a160.7 160.7 0 0 0-3.7 34.2c0 92.3 74.8 169.1 171 169.1 15.3 0 35.9-4.6 47.2-7.7s22.5-7.2 25.4-8.3a26.4 26.4 0 0 1 9.3-1.7 26 26 0 0 1 10.1 2l56.7 20.1a13.5 13.5 0 0 0 3.9 1 8 8 0 0 0 8-8 13 13 0 0 0-.5-2.7z"},child:[]},{tag:"path",attr:{fill:"none",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"32",d:"M66.46 232a146.23 146.23 0 0 0 6.39 152.67c2.31 3.49 3.61 6.19 3.21 8s-11.93 61.87-11.93 61.87a8 8 0 0 0 2.71 7.68A8.17 8.17 0 0 0 72 464a7.3 7.3 0 0 0 2.91-.6l56.21-22a15.7 15.7 0 0 1 12 .2c18.94 7.38 39.88 12 60.83 12A159.2 159.2 0 0 0 284 432.11"},child:[]}]})(e)}const uH=[{icon:LC,label:"PR security reviews"},{icon:_T,label:"Attack surface monitoring"},{icon:zT,label:"Real-time threat intelligence"},{icon:eC,label:"Scheduled pentesting"},{icon:RT,label:"One-click autofix"},{icon:V_,label:"Jira, Linear & Slack integrations"}];function dH({open:e,onClose:t,description:r,source:a="sidebar"}){const[s,o]=ee.useState(e),[c,d]=ee.useState(e?"open":"closed");return ee.useEffect(()=>{if(e){o(!0),d("open");return}d("closed");const f=setTimeout(()=>o(!1),200);return()=>clearTimeout(f)},[e]),ee.useEffect(()=>{if(!s)return;const f=p=>{p.key==="Escape"&&t()};document.addEventListener("keydown",f);const h=document.body.style.overflow;return document.body.style.overflow="hidden",()=>{document.removeEventListener("keydown",f),document.body.style.overflow=h}},[s,t]),s?m.jsx("div",{"data-state":c,className:"dialog-overlay fixed inset-0 z-50 flex items-center justify-center bg-black/80 p-4",onClick:t,role:"dialog","aria-modal":"true","aria-label":"Upgrade your plan",children:m.jsxs("div",{"data-state":c,className:"dialog-panel relative w-full max-w-md rounded-2xl border border-[#222] bg-black p-6 shadow-lg sm:rounded-lg",onClick:f=>f.stopPropagation(),children:[m.jsx("button",{type:"button",onClick:t,"aria-label":"Close",className:"absolute right-4 top-4 rounded-md p-1 text-[#888] transition-colors hover:bg-[#1a1a1a] hover:text-white",children:m.jsx(Sp,{className:"h-4 w-4"})}),m.jsxs("div",{children:[m.jsx("h2",{className:"text-lg text-white",children:"Available in Strix Cloud"}),r&&m.jsx("p",{className:"mt-2 text-base leading-relaxed text-[#e5e5e5]",children:r})]}),m.jsxs("div",{className:"space-y-4 pt-4",children:[m.jsxs("div",{className:"rounded-xl border border-[#333] bg-[#0a0a0a] p-4 sm:rounded-lg",children:[m.jsxs("div",{className:"mb-3 flex items-center gap-2",children:[m.jsx(Fm,{className:"h-4 w-4 text-blue-400"}),m.jsx("span",{className:"text-sm font-medium text-white",children:"Strix Cloud also includes"})]}),m.jsx("ul",{className:"space-y-2 text-sm text-[#888]",children:uH.map(f=>m.jsxs("li",{className:"flex items-center gap-2",children:[m.jsx(f.icon,{className:"h-3.5 w-3.5 text-[#555]"}),f.label]},f.label))})]}),m.jsxs("div",{className:"flex flex-col gap-2",children:[m.jsxs("a",{href:ha(Yu,"upgrade_try_free"),target:"_blank",rel:"noopener noreferrer",onClick:()=>jr("upgrade_try_free",a),className:"flex h-10 w-full items-center justify-center gap-2 rounded-lg bg-white px-4 text-sm font-semibold text-black transition-colors hover:bg-neutral-200",children:["Open Strix Cloud",m.jsx(oy,{className:"h-3.5 w-3.5"})]}),m.jsxs("a",{href:ha($T,"upgrade_view_plans"),target:"_blank",rel:"noopener noreferrer",onClick:()=>jr("upgrade_view_plans",a),className:"flex h-9 w-full items-center justify-center gap-1.5 rounded-lg border border-[#333] px-4 text-sm font-medium text-[#888] transition-colors hover:border-[#555] hover:text-white",children:["Learn more",m.jsx(oy,{className:"h-3 w-3"})]})]})]})]})}):null}const Hm=160,$m=260,io=400,fH=140,S_="strix_viewer_sidebar_width",k_="strix_viewer_sidebar_collapsed";function hH(e,t){try{const r=localStorage.getItem(e),a=r?parseInt(r,10):NaN;return Number.isFinite(a)?a:t}catch{return t}}function mH({view:e,onSelectView:t,issuesCount:r,agentCount:a,runCount:s,finished:o,verified:c,email:d,onOpenEmail:f,onOpenHistory:h,onForget:p}){var z;const[g,y]=ee.useState(()=>{const V=hH(S_,$m);return Math.min(io,Math.max(Hm,V))}),[b,_]=ee.useState(()=>{try{return localStorage.getItem(k_)==="1"}catch{return!1}}),[E,S]=ee.useState(!1),[w,k]=ee.useState(!1),[N,M]=ee.useState(null),B=ee.useRef(null),R=(V,P)=>{jr(V,"sidebar"),M(P)},U=ee.useCallback(V=>{y(V);try{localStorage.setItem(S_,String(V))}catch{}},[]),I=ee.useCallback(V=>{_(V);try{localStorage.setItem(k_,V?"1":"0")}catch{}},[]),X=ee.useCallback(()=>{I(!1),U($m)},[I,U]),j=ee.useCallback(V=>{V.preventDefault(),S(!0)},[]);return ee.useEffect(()=>{if(!E||b)return;const V=T=>{const $=T.clientX;$>=Hm&&$<=io?y($):$>io&&y(io)},P=T=>{const $=T.clientX;${window.removeEventListener("mousemove",V),window.removeEventListener("mouseup",P)}},[E,b,I,U]),ee.useEffect(()=>{if(!w)return;const V=P=>{B.current&&!B.current.contains(P.target)&&k(!1)};return document.addEventListener("mousedown",V),()=>document.removeEventListener("mousedown",V)},[w]),m.jsxs(m.Fragment,{children:[b&&m.jsx("div",{className:"fixed left-0 top-0 z-40 hidden h-full w-4 cursor-pointer transition-colors hover:bg-[rgba(255,255,255,0.08)] lg:block",onClick:X,title:"Expand sidebar"}),m.jsxs("aside",{className:Mr("sticky top-0 z-20 hidden h-screen flex-shrink-0 flex-col overflow-hidden border-r border-[rgba(255,255,255,0.08)] bg-black lg:flex",!E&&"transition-[width] duration-200 ease-out"),style:{width:b?0:g},children:[m.jsx("header",{className:"relative flex flex-col gap-1 pt-1 min-w-[160px]",children:m.jsx("div",{className:"flex flex-row py-1 px-2",children:m.jsxs("div",{className:"flex h-10 w-full flex-row items-center",children:[m.jsxs("a",{href:ha("https://app.strix.ai","logo"),target:"_blank",rel:"noopener noreferrer",onClick:()=>jr("logo","sidebar"),className:"flex flex-1 flex-row items-center gap-2 rounded-md py-2 pl-2.5 pr-1 min-w-0 transition-colors hover:bg-[rgba(255,255,255,0.06)]",title:"Open Strix Cloud",children:[m.jsx("span",{className:"flex flex-shrink-0 items-center justify-center rounded-full bg-gradient-to-br from-emerald-400 to-cyan-500",style:{width:20,height:20},children:m.jsx("span",{className:"text-[10px] font-semibold text-white",children:"S"})}),m.jsxs("span",{className:"flex flex-1 flex-row items-center gap-2 min-w-0",children:[m.jsx("span",{className:"truncate min-w-0 text-[14px] font-medium text-[#ededed]",children:"Strix"}),m.jsx("span",{className:"flex h-5 flex-shrink-0 items-center rounded px-2 text-[11px] font-medium text-[#888] bg-[rgba(255,255,255,0.08)]",children:"Local"})]})]}),m.jsx("a",{href:ha("https://app.strix.ai","logo"),target:"_blank",rel:"noopener noreferrer",onClick:()=>jr("logo","sidebar"),className:"flex flex-none items-center rounded-md px-1.5 py-2 transition-colors hover:bg-[rgba(255,255,255,0.06)]","aria-label":"Open Strix Cloud",children:m.jsx(cC,{className:"h-4 w-4 text-[#666]"})})]})})}),m.jsx("nav",{className:"relative min-w-[160px] flex-1 overflow-y-auto overflow-x-clip scrollbar-thin pb-10 pt-2",children:m.jsxs("div",{className:"relative flex flex-col gap-px px-2",children:[m.jsx(yi,{icon:m.jsx(pH,{}),label:"Pentest Overview",active:e==="overview",onClick:()=>t("overview")}),m.jsx(yi,{icon:m.jsx(Nu,{className:"h-4 w-4"}),label:"Issues",count:r>0?r:void 0,active:e==="issues",onClick:()=>t("issues")}),a>0&&m.jsx(yi,{icon:m.jsx(Oo,{className:"h-4 w-4"}),label:"Agents",count:a,active:e==="agents",onClick:()=>t("agents")}),m.jsx(yi,{icon:m.jsx(Ys,{className:"h-4 w-4"}),label:"Past runs",count:s>0?s:void 0,active:e==="history",onClick:h}),o&&m.jsx(yi,{icon:m.jsx(Np,{className:"h-4 w-4"}),label:"Export report",active:e==="email",onClick:f}),m.jsx(yi,{icon:m.jsx(k2,{className:"h-4 w-4"}),label:"Feedback & support",active:e==="feedback",onClick:()=>t("feedback")}),m.jsx("hr",{className:"mx-0 my-1 h-px w-full border-0 bg-[rgba(255,255,255,0.08)]"}),m.jsx(yi,{icon:m.jsx(oH,{className:"h-4 w-4"}),label:"PR Security Reviews",active:!1,onClick:()=>R("pr_reviews","Strix reviews every pull request and flags exploitable changes before they merge.")}),m.jsx(yi,{icon:m.jsx(cH,{className:"h-4 w-4"}),label:"Integrations",active:!1,onClick:()=>R("integrations","Sync findings to Jira, Linear, and Slack so fixes happen where your team already works.")}),m.jsx(yi,{icon:m.jsx(MT,{className:"h-4 w-4"}),label:"Members",active:!1,onClick:()=>R("members","Invite your team, set roles, and share findings and run history across your org.")})]})}),m.jsx("section",{className:"flex min-w-[160px] flex-col gap-0.5",ref:B,children:m.jsxs("div",{className:"relative p-2",children:[c&&d?m.jsxs("button",{onClick:()=>k(V=>!V),className:"relative flex w-full cursor-pointer items-center gap-2 rounded-md bg-transparent px-2.5 py-2 transition-colors hover:bg-[rgba(255,255,255,0.06)]",children:[m.jsx("span",{className:"flex flex-shrink-0 items-center justify-center rounded-full bg-gradient-to-br from-emerald-400 to-cyan-500",style:{width:20,height:20},children:m.jsx("span",{className:"text-[9px] font-semibold text-white",children:((z=d[0])==null?void 0:z.toUpperCase())||"U"})}),m.jsxs("span",{className:"flex min-w-0 flex-1 flex-col text-left",children:[m.jsx("span",{className:"truncate text-[13px] font-medium text-[#ededed]",children:d}),m.jsx("span",{className:"truncate text-[11px] text-[#555]",children:"Linked to this machine"})]})]}):m.jsxs("div",{className:"flex items-center gap-2 rounded-md px-2.5 py-2",children:[m.jsx("span",{className:"flex flex-shrink-0 items-center justify-center rounded-full bg-gradient-to-br from-emerald-400 to-cyan-500",style:{width:20,height:20},children:m.jsx("span",{className:"text-[9px] font-semibold text-white",children:"S"})}),m.jsx("span",{className:"flex min-w-0 flex-1 flex-col text-left",children:m.jsx("span",{className:"truncate text-[13px] font-medium text-[#ededed]",children:"Local viewer"})})]}),w&&c&&d&&m.jsxs("div",{className:"absolute bottom-full left-2 right-2 z-50 mb-1 overflow-hidden rounded-lg border border-[#333] bg-black shadow-xl",children:[m.jsxs("div",{className:"border-b border-[#333] px-3 py-2",children:[m.jsx("p",{className:"truncate text-[13px] font-medium text-white",children:"Linked email"}),m.jsx("p",{className:"truncate text-[11px] text-[#666]",children:d})]}),m.jsxs("button",{onClick:()=>{k(!1),p()},className:"flex w-full items-center gap-2 px-3 py-2 text-[13px] text-[#888] transition-colors hover:bg-[rgba(255,255,255,0.06)] hover:text-red-400",children:[m.jsx(WC,{className:"h-4 w-4"}),"Forget this email"]})]})]})}),m.jsx("div",{className:"group absolute right-0 top-0 z-30 h-full w-1 cursor-col-resize",onMouseDown:j,children:m.jsx("div",{className:Mr("absolute right-0 top-0 h-full w-px bg-[rgba(255,255,255,0.08)] transition-all duration-100",E?"w-0.5 bg-[rgba(255,255,255,0.3)]":"group-hover:bg-[rgba(255,255,255,0.2)]")})})]}),E&&m.jsx("div",{className:"fixed inset-0 z-10 cursor-col-resize"}),m.jsx(dH,{open:N!==null,description:N??"",source:"sidebar",onClose:()=>M(null)})]})}function yi({icon:e,label:t,active:r,onClick:a,count:s}){return m.jsxs("button",{onClick:a,className:Mr("group flex h-9 w-full origin-left flex-row items-center rounded-md transition-colors",r?"bg-[rgba(255,255,255,0.12)] text-white":"text-[#888] hover:bg-[rgba(255,255,255,0.06)] hover:text-[#ededed]"),children:[m.jsx("div",{className:"grid flex-none place-content-center",style:{width:36,height:36},children:e}),m.jsx("span",{className:"min-w-0 flex-1 truncate text-left text-[14px] font-medium",children:t}),s!=null&&m.jsx("span",{className:"mr-2 flex-none rounded-full border border-white/10 px-2 py-0.5 text-[10px] tabular-nums leading-none text-[#777]",children:s})]})}function pH(){return m.jsx("svg",{style:{width:16,height:16,color:"currentcolor"},viewBox:"0 0 16 16",fill:"currentColor",children:m.jsx("path",{fillRule:"evenodd",clipRule:"evenodd",d:"M2.5 5.5V2.5H5.5V5.5H2.5ZM1 2C1 1.44772 1.44772 1 2 1H6C6.55228 1 7 1.44772 7 2V6C7 6.55228 6.55228 7 6 7H2C1.44772 7 1 6.55228 1 6V2ZM2.5 13.5V10.5H5.5V13.5H2.5ZM1 10C1 9.44772 1.44772 9 2 9H6C6.55228 9 7 9.44772 7 10V14C7 14.5523 6.55228 15 6 15H2C1.44772 15 1 14.5523 1 14V10ZM10.5 2.5V5.5H13.5V2.5H10.5ZM10 1C9.44772 1 9 1.44772 9 2V6C9 6.55228 9.44772 7 10 7H14C14.5523 7 15 6.55228 15 6V2C15 1.44772 14.5523 1 14 1H10ZM10.5 13.5V10.5H13.5V13.5H10.5ZM9 10C9 9.44772 9.44772 9 10 9H14C14.5523 9 15 9.44772 15 10V14C15 14.5523 14.5523 15 14 15H10C9.44772 15 9 14.5523 9 14V10Z"})})}const C_={work_email_required:"Please use your work email, not a personal one.",rate_limited:"Too many requests. Wait a minute and try again.",invalid_email:"That email does not look right. Check it and try again.",unavailable:"The email service is unavailable right now. Try again shortly."},gH=new Set(["gmail.com","googlemail.com","yahoo.com","ymail.com","outlook.com","hotmail.com","live.com","icloud.com","me.com","aol.com","proton.me","protonmail.com","gmx.com","mail.com"]);function xH({onVerified:e}){const[t,r]=ee.useState("email"),[a,s]=ee.useState(""),[o,c]=ee.useState(""),[d,f]=ee.useState(!1),[h,p]=ee.useState(null),[g,y]=ee.useState(null),b=async()=>{const E=a.trim();if(!E){p("Enter your email to continue.");return}const S=E.slice(E.lastIndexOf("@")+1).toLowerCase();if(gH.has(S)){Tr("work_email_required"),p(C_.work_email_required);return}f(!0),p(null);const w=await _2(E);f(!1),w.ok?(Tr("email_submitted",{purpose:"verify"}),y(`We sent a 6-digit code to ${E}.`),r("code")):(w.error==="work_email_required"&&Tr("work_email_required"),p(C_[w.error]??"Could not send a code. Try again."))},_=async()=>{const E=o.trim();if(E.length<4){p("Enter the 6-digit code from your email.");return}f(!0),p(null);const S=await w2(a.trim(),E);if(f(!1),!S.verified){p("That code did not match. Check it and try again.");return}Tr("email_verified",{purpose:"verify"}),e()};return m.jsxs("div",{className:"mx-auto mt-5 max-w-sm text-left",children:[h&&m.jsxs("div",{className:"mb-3 flex items-start gap-2 rounded-lg border border-red-500/30 bg-red-500/5 px-3 py-2",children:[m.jsx(Gu,{className:"mt-0.5 h-4 w-4 flex-shrink-0 text-red-400","aria-hidden":"true"}),m.jsx("p",{className:"text-xs text-red-300",children:h})]}),g&&!h&&m.jsx("p",{className:"mb-3 text-xs text-[#888]",children:g}),t==="email"?m.jsxs("form",{className:"space-y-3",onSubmit:E=>{E.preventDefault(),b()},children:[m.jsxs("label",{className:"block",children:[m.jsx("span",{className:"mb-1.5 block text-xs text-[#888]",children:"Your work email"}),m.jsx("input",{type:"email",autoFocus:!0,value:a,onChange:E=>s(E.target.value),placeholder:"you@company.com",className:"w-full rounded-lg bg-black px-3 py-2.5 text-sm text-white outline-none transition-colors focus:border-[#444]",style:{border:"1px solid #2a2a2a"}}),m.jsx("span",{className:"mt-1.5 block text-[11px] text-[#666]",children:"Use your work email."})]}),m.jsxs("button",{type:"submit",disabled:d,className:"flex w-full cursor-pointer items-center justify-center gap-2 rounded-lg bg-white px-4 py-2.5 text-sm font-semibold text-black transition-opacity hover:opacity-90 disabled:opacity-60",children:[d&&m.jsx(Ps,{className:"h-4 w-4 animate-spin","aria-hidden":"true"}),"Send me a code"]})]}):m.jsxs("form",{className:"space-y-3",onSubmit:E=>{E.preventDefault(),_()},children:[m.jsxs("label",{className:"block",children:[m.jsx("span",{className:"mb-1.5 block text-xs text-[#888]",children:"6-digit code"}),m.jsx("input",{inputMode:"numeric",autoFocus:!0,value:o,onChange:E=>c(E.target.value.replace(/\D/g,"").slice(0,6)),placeholder:"123456",className:"w-full rounded-lg bg-black px-3 py-2.5 text-center text-lg font-mono tracking-[0.4em] text-white outline-none transition-colors focus:border-[#444]",style:{border:"1px solid #2a2a2a"}})]}),m.jsxs("button",{type:"submit",disabled:d,className:"flex w-full cursor-pointer items-center justify-center gap-2 rounded-lg bg-white px-4 py-2.5 text-sm font-semibold text-black transition-opacity hover:opacity-90 disabled:opacity-60",children:[d&&m.jsx(Ps,{className:"h-4 w-4 animate-spin","aria-hidden":"true"}),"Verify"]}),m.jsx("button",{type:"button",onClick:()=>{r("email"),p(null),y(null)},className:"w-full cursor-pointer text-center text-xs text-[#666] transition-colors hover:text-[#aaa]",children:"Use a different email"})]})]})}const bH=[{key:"critical",dot:"bg-red-500",text:"text-red-500"},{key:"high",dot:"bg-orange-500",text:"text-orange-500"},{key:"medium",dot:"bg-yellow-500",text:"text-yellow-500"},{key:"low",dot:"bg-blue-500",text:"text-blue-500"}];function yH({counts:e}){const t=bH.filter(r=>e[r.key]>0);return t.length===0?m.jsx("span",{className:"text-xs text-[#555]",children:"No findings"}):m.jsx("div",{className:"flex items-center gap-3",children:t.map(r=>m.jsxs("div",{className:"flex items-center gap-1.5",children:[m.jsx("span",{className:`h-2 w-2 rounded-full ${r.dot}`,"aria-hidden":"true"}),m.jsx("span",{className:`text-xs tabular-nums ${r.text}`,children:e[r.key]})]},r.key))})}function vH(e){if(!e)return null;const t=e.trim().replace(" UTC","Z").replace(" ","T"),r=new Date(t);return Number.isNaN(r.getTime())?null:r.toLocaleString(void 0,{month:"short",day:"numeric",hour:"numeric",minute:"2-digit"})}function T_(e){if(!e)return null;const t=e.trim().replace(" UTC","Z").replace(" ","T"),r=new Date(t);if(Number.isNaN(r.getTime()))return null;const a=Date.now()-r.getTime(),s=Math.floor(a/6e4);if(s<1)return"just now";if(s<60)return`${s}m ago`;const o=Math.floor(s/60);if(o<24)return`${o}h ago`;const c=Math.floor(o/24);return c<7?`${c}d ago`:vH(e)}function _H({runs:e,activeRun:t,onSelectRun:r,onVerified:a}){const s=(e==null?void 0:e.count)??0,[o,c]=ee.useState(!1);return!e||e.locked?m.jsxs("div",{className:"rounded-xl border border-[#222] bg-[rgba(255,255,255,0.02)] p-8 text-center",children:[m.jsx("div",{className:"mx-auto mb-4 flex h-11 w-11 items-center justify-center rounded-xl",style:{border:"1px solid #2a2a2a",background:"rgba(255,255,255,0.04)"},children:m.jsx(Ys,{className:"h-5 w-5 text-[#888]","aria-hidden":"true"})}),m.jsx("h2",{className:"text-base font-semibold text-white",children:"Browse every run on this machine"}),m.jsxs("p",{className:"mx-auto mt-1.5 max-w-md text-sm text-[#888]",children:["You have ",s," past ",s===1?"run":"runs"," on this machine."]}),o?m.jsxs(m.Fragment,{children:[m.jsx("p",{className:"mx-auto mt-3 max-w-sm text-xs text-[#666]",children:"Verify your email with a one-time code to unlock the full history."}),m.jsx(xH,{onVerified:a})]}):m.jsx("button",{onClick:()=>{jr("history_unlock","past_runs"),c(!0)},className:"mt-4 cursor-pointer rounded-lg bg-white px-4 py-2 text-sm font-semibold text-black transition-opacity hover:opacity-90",children:"View runs"}),m.jsxs("p",{className:"mt-4 flex items-center justify-center gap-1.5 text-xs text-[#555]",children:[m.jsx(K_,{className:"h-3.5 w-3.5","aria-hidden":"true"}),"Or open one from the CLI with"," ",m.jsx("code",{className:"font-mono text-[#888]",children:"strix view "})]})]}):e.runs.length===0?m.jsx("div",{className:"rounded-xl border border-[#222] bg-[rgba(255,255,255,0.02)] p-8 text-center text-sm text-[#888]",children:"No past runs found on this machine yet."}):m.jsx("div",{className:"space-y-2",children:e.runs.map(d=>{const f=d.name===t,h=T_(d.start_time)??T_(d.end_time),p=yo(d.target,d.name);return m.jsxs("button",{onClick:()=>r(d.name),className:`animate-card-in group flex w-full cursor-pointer items-center gap-4 rounded-lg border px-4 py-3 text-left transition-colors ${f?"border-[#444] bg-[rgba(255,255,255,0.04)]":"border-[#222] bg-[rgba(255,255,255,0.02)] hover:border-[#444]"}`,children:[m.jsxs("div",{className:"min-w-0 flex-1",children:[m.jsxs("div",{className:"flex items-center gap-2",children:[m.jsx("span",{className:"truncate text-sm font-medium text-white",children:p}),f&&m.jsx("span",{className:"rounded-full px-1.5 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-emerald-400",style:{border:"1px solid rgba(16,185,129,0.3)"},children:"Active"})]}),m.jsxs("div",{className:"mt-0.5 flex flex-wrap items-center gap-x-2 gap-y-0.5 text-xs text-[#666]",children:[d.scan_mode&&m.jsx("span",{className:"capitalize",children:d.scan_mode}),d.scan_mode&&(h||d.status)&&m.jsx("span",{className:"text-[#333]",children:"·"}),h&&m.jsx("span",{children:h}),h&&d.status&&m.jsx("span",{className:"text-[#333]",children:"·"}),d.status&&m.jsx("span",{className:"capitalize",children:d.status})]})]}),m.jsx(yH,{counts:d.severity_counts}),m.jsx(sC,{className:"h-4 w-4 flex-shrink-0 text-[#555] transition-colors group-hover:text-[#aaa]","aria-hidden":"true"})]},d.name)})})}const A_={work_email_required:"Please use your work email, not a personal one.",rate_limited:"Too many requests. Wait a minute and try again.",invalid_email:"That email does not look right. Check it and try again.",unavailable:"The email service is unavailable right now. Try again shortly."},wH={forbidden:"This email was unsubscribed from Strix, so we cannot send to it.",too_large:"This report is too large to email. Try a smaller run.",unavailable:"The email service is unavailable right now. Try again shortly."},EH=new Set(["gmail.com","googlemail.com","yahoo.com","ymail.com","outlook.com","hotmail.com","live.com","icloud.com","me.com","aol.com","proton.me","protonmail.com","gmx.com","mail.com"]);function NH({activeRun:e,auth:t,purpose:r,skipDisclosure:a=!1,onAuthChanged:s,onExit:o}){const c=(t==null?void 0:t.verified)===!0,d=r==="verify",[f,h]=ee.useState(()=>d?"email":a?c?"sending":"email":"disclosure"),[p,g]=ee.useState((t==null?void 0:t.email)??""),[y,b]=ee.useState(""),[_,E]=ee.useState(!1),[S,w]=ee.useState(null),[k,N]=ee.useState(null),[M,B]=ee.useState(""),[R,U]=ee.useState(""),[I,X]=ee.useState(!1),[j,z]=ee.useState(""),V=ee.useRef(!1),P=async()=>{h("sending"),w(null);const Z=await QU(e);if(Z.ok){Tr("report_sent"),B(Z.password),U(Z.filename),h("password");return}if(Z.error==="reverify"||Z.error==="unverified"){N("Your verification expired. Enter your email to verify again."),h("email");return}w(wH[Z.error]??"Could not send the report. Try again."),h("disclosure")},T=()=>{w(null),N(null),c?P():h("email")};ee.useEffect(()=>{!d&&a&&c&&!V.current&&(V.current=!0,P())},[]);const $=async()=>{const Z=p.trim();if(!Z){w("Enter your email to continue.");return}const C=Z.slice(Z.lastIndexOf("@")+1).toLowerCase();if(EH.has(C)){Tr("work_email_required"),w(A_.work_email_required);return}E(!0),w(null);const D=await _2(Z);E(!1),D.ok?(Tr("email_submitted",{purpose:r}),N(`We sent a 6-digit code to ${Z}.`),h("code")):(D.error==="work_email_required"&&Tr("work_email_required"),w(A_[D.error]??"Could not send a code. Try again."))},O=async()=>{const Z=y.trim();if(Z.length<4){w("Enter the 6-digit code from your email.");return}E(!0),w(null);const C=await w2(p.trim(),Z);if(E(!1),!C.verified){w("That code did not match. Check it and try again.");return}Tr("email_verified",{purpose:r}),z(C.email),s(),d?o("history"):P()},H=async()=>{try{await navigator.clipboard.writeText(M),X(!0),setTimeout(()=>X(!1),1500)}catch{}},K=j||(t==null?void 0:t.email)||p.trim();return m.jsxs("div",{className:"mx-auto max-w-xl space-y-4",children:[m.jsxs("button",{onClick:()=>o(d?"history":"overview"),className:"cursor-pointer inline-flex items-center gap-1.5 text-sm text-[#888] transition-colors hover:text-white",children:[m.jsx(Ep,{className:"h-4 w-4"}),d?"Back to past runs":"Back to results"]}),m.jsxs("div",{className:"flex items-center gap-2",children:[m.jsx(Np,{className:"h-5 w-5 text-[#888]","aria-hidden":"true"}),m.jsx("h1",{className:"text-2xl font-semibold text-white",children:d?"Verify your email":"Export report to PDF"})]}),m.jsxs("div",{className:"w-full rounded-2xl bg-[rgba(255,255,255,0.02)] p-6",style:{border:"1px solid #2a2a2a"},children:[m.jsx("p",{className:"mb-4 text-xs text-[#666]",children:d?"We send a one-time code to confirm it is you.":"Verified by a one-time code sent to your email"}),S&&m.jsxs("div",{className:"mb-4 flex items-start gap-2 rounded-lg border border-red-500/30 bg-red-500/5 px-3 py-2",children:[m.jsx(Gu,{className:"mt-0.5 h-4 w-4 flex-shrink-0 text-red-400","aria-hidden":"true"}),m.jsx("p",{className:"text-xs text-red-300",children:S})]}),k&&!S&&f!=="password"&&m.jsx("p",{className:"mb-4 text-xs text-[#888]",children:k}),f==="disclosure"&&m.jsxs("div",{className:"space-y-4",children:[m.jsxs("div",{className:"space-y-2.5 rounded-lg p-3.5",style:{border:"1px solid #222",background:"rgba(255,255,255,0.02)"},children:[m.jsxs("div",{className:"flex items-start gap-2.5",children:[m.jsx(X_,{className:"mt-0.5 h-4 w-4 flex-shrink-0 text-emerald-400","aria-hidden":"true"}),m.jsxs("p",{className:"text-xs leading-relaxed text-[#aaa]",children:["We email an ",m.jsx("span",{className:"text-white",children:"encrypted PDF"}),". Nothing else leaves your machine."]})]}),m.jsxs("div",{className:"flex items-start gap-2.5",children:[m.jsx(ZC,{className:"mt-0.5 h-4 w-4 flex-shrink-0 text-[#888]","aria-hidden":"true"}),m.jsx("p",{className:"text-xs leading-relaxed text-[#aaa]",children:"Only you hold the password; Strix can't read it."})]})]}),m.jsx("button",{onClick:T,className:"w-full cursor-pointer rounded-lg bg-white px-4 py-2.5 text-sm font-semibold text-black transition-opacity hover:opacity-90",children:"Export report"}),c&&(t==null?void 0:t.email)&&m.jsxs("p",{className:"text-center text-xs text-[#666]",children:["Sending to ",t.email]})]}),f==="email"&&m.jsxs("form",{className:"space-y-4",onSubmit:Z=>{Z.preventDefault(),$()},children:[m.jsxs("label",{className:"block",children:[m.jsx("span",{className:"mb-1.5 block text-xs text-[#888]",children:"Your work email"}),m.jsx("input",{type:"email",autoFocus:!0,value:p,onChange:Z=>g(Z.target.value),placeholder:"you@company.com",className:"w-full rounded-lg bg-black px-3 py-2.5 text-sm text-white outline-none transition-colors focus:border-[#444]",style:{border:"1px solid #2a2a2a"}})]}),m.jsxs("button",{type:"submit",disabled:_,className:"flex w-full cursor-pointer items-center justify-center gap-2 rounded-lg bg-white px-4 py-2.5 text-sm font-semibold text-black transition-opacity hover:opacity-90 disabled:opacity-60",children:[_&&m.jsx(Ps,{className:"h-4 w-4 animate-spin","aria-hidden":"true"}),"Send me a code"]})]}),f==="code"&&m.jsxs("form",{className:"space-y-4",onSubmit:Z=>{Z.preventDefault(),O()},children:[m.jsxs("label",{className:"block",children:[m.jsx("span",{className:"mb-1.5 block text-xs text-[#888]",children:"6-digit code"}),m.jsx("input",{inputMode:"numeric",autoFocus:!0,value:y,onChange:Z=>b(Z.target.value.replace(/\D/g,"").slice(0,6)),placeholder:"123456",className:"w-full rounded-lg bg-black px-3 py-2.5 text-center text-lg font-mono tracking-[0.4em] text-white outline-none transition-colors focus:border-[#444]",style:{border:"1px solid #2a2a2a"}})]}),m.jsxs("button",{type:"submit",disabled:_,className:"flex w-full cursor-pointer items-center justify-center gap-2 rounded-lg bg-white px-4 py-2.5 text-sm font-semibold text-black transition-opacity hover:opacity-90 disabled:opacity-60",children:[_&&m.jsx(Ps,{className:"h-4 w-4 animate-spin","aria-hidden":"true"}),d?"Verify":"Verify and send"]}),m.jsx("button",{type:"button",onClick:()=>{h("email"),w(null),N(null)},className:"w-full cursor-pointer text-center text-xs text-[#666] transition-colors hover:text-[#aaa]",children:"Use a different email"})]}),f==="sending"&&m.jsxs("div",{className:"flex flex-col items-center gap-3 py-8",children:[m.jsx(Ps,{className:"h-6 w-6 animate-spin text-white","aria-hidden":"true"}),m.jsx("p",{className:"text-sm text-[#aaa]",children:"Generating and encrypting locally..."})]}),f==="password"&&m.jsxs("div",{className:"space-y-4",children:[m.jsxs("div",{className:"flex items-start gap-2.5 rounded-lg border border-emerald-500/30 bg-emerald-500/5 px-3 py-2.5",children:[m.jsx(Vs,{className:"mt-0.5 h-4 w-4 flex-shrink-0 text-emerald-400","aria-hidden":"true"}),m.jsxs("p",{className:"text-xs text-emerald-200",children:["Sent to ",K,". Open the attached PDF with this password."]})]}),m.jsxs("div",{children:[m.jsx("span",{className:"mb-1.5 block text-xs text-[#888]",children:"Your one-time password"}),m.jsxs("div",{className:"flex items-center gap-2 rounded-lg bg-black p-3",style:{border:"1px solid #2a2a2a"},children:[m.jsx("code",{className:"flex-1 break-all font-mono text-base text-white",children:M}),m.jsxs("button",{onClick:H,className:"flex cursor-pointer items-center gap-1 rounded-md px-2 py-1 text-xs text-[#aaa] transition-colors hover:bg-[rgba(255,255,255,0.06)] hover:text-white",style:{border:"1px solid #2a2a2a"},children:[I?m.jsx(Vs,{className:"h-3.5 w-3.5"}):m.jsx(go,{className:"h-3.5 w-3.5"}),I?"Copied":"Copy"]})]}),m.jsxs("p",{className:"mt-2 text-xs text-[#666]",children:["Save this now. Strix never stores it, so we cannot show it again. File:"," ",m.jsx("span",{className:"font-mono text-[#888]",children:R})]})]}),m.jsx("button",{onClick:()=>o("overview"),className:"w-full cursor-pointer rounded-lg px-4 py-2.5 text-sm font-semibold text-white transition-colors hover:bg-[rgba(255,255,255,0.06)]",style:{border:"1px solid #2a2a2a"},children:"Done"})]})]})]})}function la(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}function ao(e){return Array.isArray(e)?e:[]}function nr(e){return typeof e=="string"&&e.trim()?e:null}function Ba(e){return typeof e=="number"&&Number.isFinite(e)?e:null}function SH(e){return e.replace(/_/g," ")}function M_(e){return e&&e.charAt(0).toUpperCase()+e.slice(1)}function kH(e){if(e==null||e<0)return"n/a";const t=Math.floor(e/3600),r=Math.floor(e%3600/60),a=e%60;return t?`${t}h ${r}m ${a}s`:r?`${r}m ${a}s`:`${a}s`}function En({label:e,children:t}){return m.jsxs("div",{className:"grid grid-cols-[7rem_1fr] gap-3 items-baseline",children:[m.jsx("dt",{className:"text-[11px] uppercase tracking-wide text-[#666]",children:e}),m.jsx("dd",{className:"min-w-0 break-words text-sm text-[#ddd]",children:t})]})}function CH({raw:e,durationSeconds:t}){const[r,a]=ee.useState(!0),s=ao(e.targets_info).map(P=>{const T=la(P),$=nr(T.original)??nr(la(T.details).target_url)??"unknown target",O=nr(T.type);return{display:$,type:O?SH(O):null}}),o=nr(e.instruction),c=M_(nr(e.scan_mode)),d=nr(e.scope_mode),f=la(e.diff_scope),h=f.active===!0,p=nr(f.mode),g=nr(e.diff_base),y=e.non_interactive===!0,b=ao(e.local_sources).map(P=>{if(typeof P=="string")return P;const T=la(P);return nr(T.source_path)??nr(T.target_path)??""}).filter(Boolean),_=M_(nr(e.status));let E=d??"auto";h&&(E+=` (diff${p?`: ${p}`:""}${g?` vs ${g}`:""})`);const S=la(e.llm_usage),w=Object.keys(S).length>0,k=ao(S.agents).map(la),N=Array.from(new Set(k.map(P=>nr(P.model)).filter(P=>!!P))),M=Ba(S.requests),B=Ba(S.input_tokens),R=Ba(la(ao(S.input_tokens_details)[0]).cached_tokens),U=Ba(S.output_tokens),I=Ba(la(ao(S.output_tokens_details)[0]).reasoning_tokens),X=Ba(S.total_tokens),j=Ba(S.cost),z=nr(e.auth_mode)==="subscription",V=(P,T)=>m.jsxs("span",{className:"text-[#666]",children:[" (",Ls(P)," ",T,")"]});return m.jsxs("div",{className:"rounded-xl border border-[#222] bg-[rgba(255,255,255,0.02)] p-5",children:[m.jsxs("button",{type:"button",onClick:()=>a(P=>!P),"aria-expanded":r,className:"flex w-full cursor-pointer items-center gap-2 text-left",children:[m.jsx(GC,{className:"h-4 w-4 text-[#888]","aria-hidden":"true"}),m.jsx("h2",{className:"text-sm font-semibold text-white",children:"Run details"}),r?m.jsx(U_,{className:"ml-auto h-4 w-4 text-[#666]","aria-hidden":"true"}):m.jsx(po,{className:"ml-auto h-4 w-4 text-[#666]","aria-hidden":"true"})]}),r&&m.jsxs("div",{className:"mt-4 grid grid-cols-1 gap-x-8 gap-y-6 md:grid-cols-2",children:[m.jsxs("section",{children:[m.jsx("h3",{className:"mb-3 text-[11px] font-semibold uppercase tracking-wide text-[#555]",children:"Configuration"}),m.jsxs("dl",{className:"space-y-2.5",children:[s.length>0&&m.jsx(En,{label:"Targets",children:m.jsx("div",{className:"space-y-1",children:s.map((P,T)=>m.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[m.jsx("span",{className:"font-mono text-[#ddd]",children:P.display}),P.type&&m.jsx("span",{className:"rounded-full border border-[#2a2a2a] px-1.5 py-0.5 text-[10px] text-[#888]",children:P.type})]},T))})}),m.jsx(En,{label:"Instruction",children:o?m.jsx("span",{className:"whitespace-pre-wrap",children:o}):m.jsx("span",{className:"text-[#666]",children:"None"})}),c&&m.jsx(En,{label:"Pentest mode",children:c}),m.jsx(En,{label:"Scope",children:E}),m.jsx(En,{label:"Mode",children:y?"Non-interactive":"Interactive"}),b.length>0&&m.jsx(En,{label:"Local sources",children:m.jsx("div",{className:"space-y-0.5 font-mono text-[#ddd]",children:b.map((P,T)=>m.jsx("div",{children:P},T))})}),_&&m.jsx(En,{label:"Status",children:_})]})]}),m.jsxs("section",{children:[m.jsx("h3",{className:"mb-3 text-[11px] font-semibold uppercase tracking-wide text-[#555]",children:"Usage & cost"}),w?m.jsxs("dl",{className:"space-y-2.5 tabular-nums",children:[m.jsx(En,{label:"Model",children:N.length?N.join(", "):"n/a"}),z&&m.jsx(En,{label:"Provider",children:m.jsx("span",{className:"inline-flex items-center gap-1.5",children:m.jsx("span",{className:"rounded-full border border-[#22c55e]/40 bg-[#22c55e]/10 px-2 py-0.5 text-[11px] text-[#22c55e]",children:"ChatGPT subscription"})})}),m.jsx(En,{label:"Run time",children:kH(t)}),M!=null&&m.jsx(En,{label:"Requests",children:Ls(M)}),B!=null&&m.jsxs(En,{label:"Input tokens",children:[Ls(B),R!=null&&V(R,"cached")]}),U!=null&&m.jsxs(En,{label:"Output tokens",children:[Ls(U),I!=null&&V(I,"reasoning")]}),X!=null&&m.jsx(En,{label:"Total tokens",children:Ls(X)}),z?m.jsxs(En,{label:"Cost",children:[m.jsx("span",{className:"text-[#22c55e]",children:"$0.00"}),m.jsx("span",{className:"text-[#666]",children:" (subscription)"})]}):j!=null&&m.jsxs(En,{label:"Cost",children:["$",j.toFixed(2)]}),k.length>0&&m.jsx(En,{label:"Agents",children:Ls(k.length)})]}):m.jsx("p",{className:"text-sm text-[#666]",children:"Not available yet."})]})]})]})}const O_="strix_viewer_trust_dismissed";function TH({message:e}){const[t,r]=ee.useState(()=>{try{return localStorage.getItem(O_)==="1"}catch{return!1}});if(t)return null;const a=()=>{try{localStorage.setItem(O_,"1")}catch{}r(!0)};return m.jsx("div",{className:"fixed bottom-3 left-3 z-[60] max-w-xs rounded-lg bg-[#0a0a0a] p-3 shadow-2xl",style:{border:"1px solid #2a2a2a"},role:"status",children:m.jsxs("div",{className:"flex gap-2.5",children:[m.jsx(X_,{className:"mt-0.5 h-4 w-4 flex-shrink-0 text-emerald-400","aria-hidden":"true"}),m.jsx("p",{className:"text-xs leading-relaxed text-[#aaa]",children:e}),m.jsx("button",{onClick:a,"aria-label":"Dismiss",className:"-mr-0.5 -mt-0.5 flex-shrink-0 cursor-pointer rounded p-0.5 text-[#666] transition-colors hover:text-white",children:m.jsx(Sp,{className:"h-3.5 w-3.5"})})]})})}const AH=5e3,R_={invalid_email:"That email doesn't look right.",invalid_message:"Please write a little more.",unavailable:"Couldn't send that just now. Try again."};function MH({defaultEmail:e,onExit:t}){const[r,a]=ee.useState(""),[s,o]=ee.useState(e??""),[c,d]=ee.useState("form"),[f,h]=ee.useState(null),p=r.trim().length>0&&s.trim().length>0&&c!=="sending",g=async()=>{if(!p)return;d("sending"),h(null);const y=await XU(r.trim(),s.trim());if(y.ok){d("sent");return}d("form"),h(R_[y.error]??R_.unavailable)};return m.jsxs("div",{className:"mx-auto max-w-xl space-y-4",children:[m.jsxs("button",{onClick:()=>t("overview"),className:"cursor-pointer inline-flex items-center gap-1.5 text-sm text-[#888] transition-colors hover:text-white",children:[m.jsx(Ep,{className:"h-4 w-4"}),"Back to results"]}),m.jsxs("div",{className:"flex items-center gap-2",children:[m.jsx(k2,{className:"h-5 w-5 text-[#888]","aria-hidden":"true"}),m.jsx("h1",{className:"text-2xl font-semibold text-white",children:"Feedback & support"})]}),m.jsx("div",{className:"w-full rounded-2xl bg-[rgba(255,255,255,0.02)] p-6",style:{border:"1px solid #2a2a2a"},children:c==="sent"?m.jsxs("div",{className:"flex items-start gap-3",children:[m.jsx(Eu,{className:"mt-0.5 h-5 w-5 flex-shrink-0 text-emerald-400","aria-hidden":"true"}),m.jsxs("div",{className:"min-w-0",children:[m.jsx("p",{className:"text-sm font-semibold text-white",children:"Thanks, we got it."}),m.jsx("p",{className:"mt-1 text-xs text-[#888]",children:"We read every message. If it needs a reply, we'll reach out to the email you gave."}),m.jsx("button",{onClick:()=>{a(""),d("form")},className:"mt-4 cursor-pointer text-xs text-[#888] transition-colors hover:text-white",children:"Send more feedback"})]})]}):m.jsxs(m.Fragment,{children:[m.jsx("p",{className:"mb-4 text-xs text-[#666]",children:"Bugs, feature requests, or anything else. Tell us what's on your mind."}),f&&m.jsxs("div",{className:"mb-4 flex items-start gap-2 rounded-lg border border-red-500/30 bg-red-500/5 px-3 py-2",children:[m.jsx(Gu,{className:"mt-0.5 h-4 w-4 flex-shrink-0 text-red-400","aria-hidden":"true"}),m.jsx("p",{className:"text-xs text-red-300",children:f})]}),m.jsxs("label",{className:"block",children:[m.jsx("span",{className:"mb-1.5 block text-xs text-[#888]",children:"Your feedback"}),m.jsx("textarea",{autoFocus:!0,value:r,maxLength:AH,onChange:y=>a(y.target.value),rows:5,placeholder:"What's working, what's not, what you'd love to see…",className:"w-full resize-y rounded-lg border border-[#2a2a2a] bg-black px-3 py-2.5 text-sm text-white outline-none transition-colors focus:border-white/50 focus:ring-2 focus:ring-white/10"})]}),m.jsxs("label",{className:"mt-4 block",children:[m.jsx("span",{className:"mb-1.5 block text-xs text-[#888]",children:"Your work email"}),m.jsx("input",{type:"email",value:s,onChange:y=>o(y.target.value),placeholder:"you@company.com",className:"w-full rounded-lg border border-[#2a2a2a] bg-black px-3 py-2.5 text-sm text-white outline-none transition-colors focus:border-white/50 focus:ring-2 focus:ring-white/10"})]}),m.jsx("button",{onClick:()=>void g(),disabled:!p,className:"mt-4 flex w-full cursor-pointer items-center justify-center gap-2 rounded-lg bg-white px-4 py-2.5 text-sm font-semibold text-black transition-opacity hover:opacity-90 disabled:opacity-60",children:c==="sending"?"Sending…":"Send feedback"})]})})]})}function OH({text:e,children:t,className:r=""}){const[a,s]=ee.useState(!1);return m.jsxs("span",{className:`relative inline-flex ${r}`,onMouseEnter:()=>s(!0),onMouseLeave:()=>s(!1),onFocus:()=>s(!0),onBlur:()=>s(!1),children:[t,a&&m.jsx("span",{role:"tooltip",className:"pointer-events-none absolute bottom-full left-1/2 z-50 mb-2 w-max max-w-[240px] -translate-x-1/2 rounded-md px-2.5 py-1.5 text-xs text-[#ddd] shadow-lg",style:{border:"1px solid #2a2a2a",background:"#0a0a0a"},children:e})]})}function C2({label:e,desc:t,slug:r,icon:a,surface:s}){return m.jsx(OH,{text:t,children:m.jsxs("a",{href:ha(Yu,r),target:"_blank",rel:"noopener noreferrer",onClick:()=>jr(r,s),className:"group inline-flex items-center gap-2 rounded-lg border border-[#222] bg-[rgba(255,255,255,0.02)] px-3 py-2 text-sm text-[#aaa] transition-colors hover:border-[#444] hover:text-white",children:[m.jsx(a,{className:"h-4 w-4 text-[#888] transition-colors group-hover:text-white","aria-hidden":"true"}),m.jsx("span",{children:e})]})})}const RH="Your findings stay on your machine. They're rendered here locally in your browser and never uploaded or stored by Strix.",j_=["critical","high","medium","low"],jH=500;function DH(){const[e,t]=ee.useState(null),[r,a]=ee.useState(null),[s,o]=ee.useState(null),[c,d]=ee.useState(null),[f,h]=ee.useState("overview"),[p,g]=ee.useState(null),[y,b]=ee.useState(null),[_,E]=ee.useState("report"),[S,w]=ee.useState(!1),[k,N]=ee.useState(!1),M=ee.useCallback(async()=>{try{g(await KU())}catch{}},[]),B=ee.useCallback(async()=>{try{b(await GU())}catch{}},[]);ee.useEffect(()=>{M(),B(),VU().then(C=>N(C.can_steer)).catch(()=>{})},[M,B]);const R=ee.useRef(!1);ee.useEffect(()=>{let C=!1,D;R.current=!1;const Y=()=>{D=setTimeout(L,jH)},L=async()=>{if(!C)try{const{summary:G,raw:q,finished:Q}=await b2(e);if(C)return;if(Q&&!R.current){R.current=!0;const te=await __(e);C||a(te);return}const[J,W]=await Promise.all([v2(e).catch(()=>({agents:[],events:[]})),y2(G.runId,e).catch(()=>[])]);if(C)return;a(te=>({summary:G,raw:q,finished:Q,transcript:J,vulnerabilities:W,reportMarkdown:(te==null?void 0:te.reportMarkdown)??null})),Y()}catch(G){if(C)return;o(G instanceof Error?G.message:"Could not load run data."),Y()}};return(async()=>{try{const G=await __(e);if(C)return;a(G),G.finished?R.current=!0:Y()}catch(G){if(C)return;o(G instanceof Error?G.message:"Could not load run data."),Y()}})(),()=>{C=!0,D&&clearTimeout(D)}},[e]);const U=ee.useMemo(()=>r?PU(r.vulnerabilities):null,[r]),I=(r==null?void 0:r.vulnerabilities.find(C=>C.id===c))??null,X=(r==null?void 0:r.transcript.agents.length)??0,j=(p==null?void 0:p.verified)===!0,z=ee.useRef(!1);ee.useEffect(()=>{z.current=!1},[e]),ee.useEffect(()=>{z.current||!r||(r.finished?(z.current=!0,h("overview")):X>0&&(z.current=!0,h("agents")))},[r,X]);const V=ee.useCallback(C=>{z.current=!0,h(C)},[]),P=ee.useCallback(C=>{t(C),d(null),a(null),o(null),z.current=!1},[]),T=ee.useCallback((C,D)=>{jr("email_report",D),E("report"),w(C),V("email")},[V]),$=ee.useCallback(()=>T(!1,"sidebar"),[T]),O=ee.useCallback(()=>T(!0,"overview"),[T]),H=ee.useCallback(()=>{B(),V("history")},[B,V]),K=ee.useCallback(async()=>{await M(),await B()},[M,B]),Z=ee.useCallback(async()=>{await ZU(),await M(),await B()},[M,B]);return m.jsxs("div",{className:"min-h-screen bg-black text-white flex",children:[m.jsx(mH,{view:f,onSelectView:C=>{d(null),C==="history"?H():V(C)},issuesCount:(r==null?void 0:r.vulnerabilities.length)??0,agentCount:X,runCount:(y==null?void 0:y.count)??0,finished:(r==null?void 0:r.finished)??!1,verified:j,email:(p==null?void 0:p.email)??null,onOpenEmail:$,onOpenHistory:H,onForget:()=>void Z()}),m.jsxs("div",{className:"flex-1 min-w-0",children:[m.jsx("div",{className:"border-b border-[#222]",children:m.jsxs("div",{className:"max-w-[88rem] mx-auto px-3 sm:px-6 py-4 flex items-center gap-1.5",children:[m.jsxs("a",{href:ha("https://app.strix.ai","logo"),target:"_blank",rel:"noopener noreferrer",onClick:()=>jr("logo","topbar"),className:"flex items-center gap-1.5 opacity-90 transition-opacity hover:opacity-100 lg:hidden",title:"Open Strix Cloud",children:[m.jsx("img",{src:"./logo.png",alt:"Strix",className:"w-10 h-8 object-cover"}),m.jsx("div",{className:"text-base text-white font-medium tracking-tight",children:"Strix"})]}),r&&m.jsx(zH,{finished:r.finished}),m.jsxs("div",{className:"ml-auto flex items-center gap-3",children:[j&&y&&!y.locked&&y.runs.length>0&&m.jsx(LH,{runs:y,activeRun:e,launchedName:yo((r==null?void 0:r.summary.targets[0])??null,(r==null?void 0:r.summary.runName)??(r==null?void 0:r.summary.runId)??"Current run"),onSelect:P}),m.jsxs("a",{href:ha(Yu,"run_in_cloud"),target:"_blank",rel:"noopener noreferrer",onClick:()=>jr("run_in_cloud","topbar"),className:"inline-flex items-center gap-1 rounded-lg bg-white px-3 py-1.5 text-xs font-semibold text-black transition-opacity hover:opacity-90",children:["Run in the cloud",m.jsx(z_,{className:"w-3 h-3","aria-hidden":"true"})]})]})]})}),m.jsxs("div",{className:"max-w-[88rem] mx-auto px-3 sm:px-6 py-8 sm:py-12 space-y-6",children:[s&&!r&&f!=="history"&&f!=="email"&&m.jsxs("div",{className:"rounded-lg px-4 py-3 flex gap-3 items-start border border-red-500/30 bg-red-500/5",children:[m.jsx(Gu,{className:"w-5 h-5 flex-shrink-0 mt-0.5 text-red-400","aria-hidden":"true"}),m.jsx("p",{className:"text-sm text-red-300",children:s})]}),m.jsx("div",{className:"animate-page-in space-y-6",children:f==="email"?m.jsx(NH,{activeRun:e,auth:p,purpose:_,skipDisclosure:S,onAuthChanged:()=>{M(),B()},onExit:C=>h(C==="history"?"history":"overview")}):f==="feedback"?m.jsx(MH,{defaultEmail:(p==null?void 0:p.email)??null,onExit:C=>h(C)}):f==="history"?m.jsxs("div",{className:"space-y-4",children:[m.jsxs("div",{className:"flex items-center gap-2",children:[m.jsx(Ys,{className:"w-5 h-5 text-[#888]","aria-hidden":"true"}),m.jsx("h1",{className:"text-2xl font-semibold text-white",children:"Past runs"})]}),m.jsx(_H,{runs:y,activeRun:e,onSelectRun:P,onVerified:()=>void K()})]}):!r&&!s?m.jsxs("div",{className:"rounded-xl border border-[#222] bg-[rgba(255,255,255,0.02)] p-10 text-center",children:[m.jsx("div",{className:"w-6 h-6 mx-auto mb-3 rounded-full border-2 border-[#333] border-t-white animate-spin"}),m.jsx("p",{className:"text-sm text-[#888]",children:"Loading run data…"})]}):r&&U?m.jsxs(m.Fragment,{children:[m.jsx(BH,{summary:r.summary}),m.jsxs("div",{className:"flex gap-5 border-b border-[#2a2a2a] lg:hidden",children:[m.jsx(Pm,{active:f==="overview",onClick:()=>V("overview"),children:"Pentest Overview"}),m.jsxs(Pm,{active:f==="issues",onClick:()=>V("issues"),children:["Issues",r.vulnerabilities.length>0?` (${r.vulnerabilities.length})`:""]}),X>0&&m.jsxs(Pm,{active:f==="agents",onClick:()=>V("agents"),children:["Agents (",X,")"]})]}),f==="overview"?m.jsx(PH,{summary:r.summary,counts:U,total:r.vulnerabilities.length,reportMarkdown:r.reportMarkdown,raw:r.raw,finished:r.finished,onOpenEmail:O}):f==="agents"&&X>0?m.jsx(FH,{run:r,canSteer:k}):I?m.jsxs("div",{className:"space-y-4",children:[m.jsxs("button",{onClick:()=>d(null),className:"cursor-pointer inline-flex items-center gap-1.5 text-sm text-[#888] hover:text-white transition-colors",children:[m.jsx(Ep,{className:"w-4 h-4"})," Back to all findings"]}),m.jsx(mD,{vulnerability:I})]}):m.jsx(UH,{vulnerabilities:r.vulnerabilities,finished:r.finished,onSelect:C=>d(C)})]}):null},`${e??"launched"}:${f}:${c??""}`)]})]}),m.jsx(TH,{message:RH})]})}function LH({runs:e,activeRun:t,launchedName:r,onSelect:a}){const[s,o]=ee.useState(!1),c=e.runs.find(f=>f.name===t),d=c?yo(c.target,c.name):r;return m.jsxs("div",{className:"relative",children:[m.jsxs("button",{onClick:()=>o(f=>!f),onBlur:()=>setTimeout(()=>o(!1),150),"aria-label":"Switch pentest",className:"flex items-center gap-2 rounded-lg border border-[#3a3a3a] bg-[rgba(255,255,255,0.05)] px-3 py-2 text-sm text-white transition-colors hover:border-[#555] hover:bg-[rgba(255,255,255,0.09)]",children:[m.jsx(Ys,{className:"h-4 w-4 flex-shrink-0 text-[#888]","aria-hidden":"true"}),m.jsx("span",{className:"flex-shrink-0 text-[#888]",children:"Pentest"}),m.jsx("span",{className:"max-w-[260px] truncate font-medium",children:d}),m.jsx(po,{className:"h-4 w-4 flex-shrink-0 text-[#aaa]","aria-hidden":"true"})]}),s&&m.jsxs("div",{className:"absolute right-0 z-50 mt-2 max-h-96 w-96 overflow-y-auto rounded-xl py-1.5 shadow-2xl",style:{border:"1px solid #3a3a3a",background:"#0a0a0a"},children:[m.jsx("div",{className:"border-b border-[#222] px-3 py-2 text-[11px] font-semibold uppercase tracking-wide text-[#666]",children:"Switch pentest"}),e.runs.map(f=>{const h=f.name===t;return m.jsxs("button",{onMouseDown:()=>a(f.name),className:`flex w-full items-center gap-2 px-3 py-2.5 text-left text-sm transition-colors hover:bg-[rgba(255,255,255,0.06)] ${h?"bg-[rgba(255,255,255,0.04)] text-white":"text-[#aaa]"}`,children:[m.jsxs("span",{className:"min-w-0 flex-1",children:[m.jsx("span",{className:"block truncate font-medium",children:yo(f.target,f.name)}),f.target&&m.jsx("span",{className:"block truncate font-mono text-xs text-[#666]",children:f.target})]}),h&&m.jsx("span",{className:"h-2 w-2 flex-shrink-0 rounded-full bg-emerald-400"})]},f.name)})]})]})}function zH({finished:e}){return e?m.jsxs("span",{className:"ml-3 inline-flex items-center gap-1.5 text-xs text-[#888]",children:[m.jsx("span",{className:"w-1.5 h-1.5 rounded-full bg-[#555]"}),"Complete"]}):m.jsxs("span",{className:"ml-3 inline-flex items-center gap-1.5 text-xs text-emerald-400",children:[m.jsxs("span",{className:"relative flex h-1.5 w-1.5",children:[m.jsx("span",{className:"absolute inline-flex h-full w-full rounded-full bg-emerald-400 opacity-75 animate-ping"}),m.jsx("span",{className:"relative inline-flex h-1.5 w-1.5 rounded-full bg-emerald-400"})]}),"Live"]})}function IH(e){if(e==null)return null;if(e<60)return`${e}s`;const t=Math.floor(e/60);return t<60?`${t}m`:`${Math.floor(t/60)}h ${t%60}m`}function BH({summary:e}){const t=IH(e.durationSeconds);return m.jsxs("div",{children:[m.jsx("h1",{className:"text-2xl font-semibold text-white",children:yo(e.targets[0]??null,e.runName??e.runId??"Pentest results")}),m.jsxs("div",{className:"mt-1 flex flex-wrap items-center gap-x-3 gap-y-1 text-sm text-[#888]",children:[e.targets.length>0&&m.jsx("span",{className:"font-mono text-[#aaa]",children:e.targets.join(", ")}),e.scanMode&&m.jsx(qm,{label:e.scanMode}),t&&m.jsx(qm,{label:t}),e.status&&m.jsx(qm,{label:e.status})]})]})}function qm({label:e}){return m.jsxs(m.Fragment,{children:[m.jsx("span",{className:"text-[#333]",children:"·"}),m.jsx("span",{className:"capitalize",children:e})]})}function UH({vulnerabilities:e,finished:t,onSelect:r}){const a=[...e].sort((s,o)=>j_.indexOf(s.severity)-j_.indexOf(o.severity));return a.length===0?m.jsxs("div",{className:"space-y-4",children:[m.jsx("div",{className:"rounded-xl border border-[#222] bg-[rgba(255,255,255,0.02)] p-8 text-center text-sm text-[#888]",children:t?"No findings in this run.":"No findings yet. The pentest is still running…"}),t&&m.jsxs("div",{className:"rounded-xl border border-[#222] bg-[rgba(255,255,255,0.02)] p-5",children:[m.jsx("p",{className:"text-sm font-medium text-white",children:"Stay ahead of new exposures"}),m.jsx("p",{className:"mt-0.5 mb-3 text-xs text-[#666]",children:"Attack surface monitoring catches new exposures for your org over time."}),m.jsx(C2,{label:"Attack surface monitoring",desc:"Continuous coverage for your whole org.",slug:"asm",surface:"empty_state",icon:sT})]})]}):m.jsx("div",{className:"space-y-2",children:a.map(s=>m.jsxs("button",{onClick:()=>r(s.id),className:"animate-card-in cursor-pointer w-full text-left rounded-lg border border-[#222] hover:border-[#444] bg-[rgba(255,255,255,0.02)] px-4 py-3 transition-colors flex items-center gap-3",children:[m.jsx("span",{className:`w-2.5 h-2.5 rounded-full flex-shrink-0 ${kp(s.severity)}`,"aria-hidden":"true"}),m.jsxs("span",{className:"flex-1 min-w-0",children:[m.jsx("span",{className:"block text-sm font-medium text-white truncate",children:s.title}),s.target&&m.jsx("span",{className:"block text-xs text-[#666] font-mono truncate",children:s.target})]}),m.jsx("span",{className:`text-xs font-semibold px-2 py-0.5 rounded-full border capitalize ${Z_[s.severity]}`,children:s.severity})]},s.id))})}function HH(e){return e.replace(/^\s*#{1,6}[ \t]+.*(?:\r?\n)+/,"").trimStart()}function $H(e){const t=[];let r=null;for(const a of e.split(` `)){const s=a.match(/^#{1,6}\s+(.*)$/);if(s){const o=s[1].trim().toLowerCase();if(o===r)continue;r=o}else a.trim()!==""&&(r=null);t.push(a)}return t.join(` `)}function qH({onOpenEmail:e}){return m.jsx("button",{onClick:e,className:"group w-full cursor-pointer rounded-xl border border-emerald-500/25 bg-emerald-500/[0.06] p-4 text-left transition-colors hover:border-emerald-500/40",children:m.jsxs("div",{className:"flex items-center gap-3",children:[m.jsx("div",{className:"flex h-9 w-9 flex-shrink-0 items-center justify-center rounded-lg",style:{border:"1px solid rgba(16,185,129,0.3)",background:"rgba(16,185,129,0.08)"},children:m.jsx(Np,{className:"h-4 w-4 text-emerald-400","aria-hidden":"true"})}),m.jsxs("div",{className:"min-w-0 flex-1",children:[m.jsx("p",{className:"text-sm font-semibold text-white",children:"Email an encrypted PDF report of this run"}),m.jsx("p",{className:"mt-0.5 text-xs text-[#888]",children:"Encrypted with a key only you can see, email verified with a one-time code before sending."})]}),m.jsx("span",{className:"flex-shrink-0 rounded-lg bg-white px-3 py-1.5 text-xs font-semibold text-black transition-opacity group-hover:opacity-90",children:"Export report to PDF"})]})})}function PH({summary:e,counts:t,total:r,reportMarkdown:a,raw:s,finished:o,onOpenEmail:c}){const d=[["Executive Summary",e.executiveSummary],["Technical Analysis",e.technicalAnalysis],["Methodology",e.methodology],["Recommendations",e.recommendations]].filter(([,f])=>!!f).map(([f,h])=>({title:f,content:HH(h)}));return m.jsxs("div",{className:"space-y-6",children:[m.jsx("div",{className:"animate-card-in",children:m.jsx(CH,{raw:s,durationSeconds:e.durationSeconds})}),r>0&&m.jsx("div",{className:"animate-card-in rounded-xl border border-[#222] bg-[rgba(255,255,255,0.02)] p-5",children:m.jsx(pD,{findings:{total:r,...t}})}),o&&m.jsx("div",{className:"animate-card-in",children:m.jsx(qH,{onOpenEmail:c})}),d.length>0?m.jsx("div",{className:"animate-card-in rounded-xl border border-[#222] bg-[rgba(255,255,255,0.02)] p-5 space-y-8",children:d.map(f=>m.jsx(oa,{title:f.title,content:f.content},f.title))}):a?m.jsx("div",{className:"animate-card-in rounded-xl border border-[#222] bg-[rgba(255,255,255,0.02)] p-5",children:m.jsx(oa,{content:$H(a)})}):r===0&&m.jsx("p",{className:"text-sm text-[#888]",children:"No summary available for this run yet."})]})}function Pm({active:e,onClick:t,children:r}){return m.jsxs("button",{onClick:t,className:`cursor-pointer relative pb-2.5 text-sm font-semibold transition-colors ${e?"text-white":"text-[#666] hover:text-white"}`,children:[r,e&&m.jsx("span",{className:"absolute bottom-0 inset-x-0 h-0.5 bg-white rounded-full"})]})}function FH({run:e,canSteer:t}){const{agents:r,events:a}=e.transcript,s=ee.useMemo(()=>jU(r,a),[r,a]),[o,c]=ee.useState(null),d=o?r.find(h=>h.id===o)??null:null,f=t&&!e.finished;return m.jsxs("div",{className:"space-y-5",children:[m.jsxs("div",{className:"rounded-xl border border-[#222] bg-[rgba(255,255,255,0.02)] p-5",children:[m.jsxs("div",{className:"flex items-center gap-2",children:[m.jsx(Oo,{className:"w-4 h-4 text-[#888]","aria-hidden":"true"}),m.jsx("h2",{className:"text-sm font-semibold text-white",children:"Agent graph"}),m.jsxs("span",{className:"text-xs text-[#666]",children:[r.length," agent",r.length===1?"":"s"]})]}),m.jsx("p",{className:"mt-1 mb-4 text-xs text-[#666]",children:"Click an agent to open its full transcript."}),m.jsx("div",{className:"h-[480px] rounded-lg border border-[#1a1a1a] overflow-hidden",children:m.jsx(i7,{agents:s,selectedAgentId:o,onSelectAgent:h=>c(h),eventsLoaded:!0,eventsEmpty:s.size===0,scanCompleted:e.finished})})]}),f&&m.jsx(E2,{agents:r}),m.jsxs("div",{className:"rounded-xl border border-[#222] bg-[rgba(255,255,255,0.02)] p-5",children:[m.jsx("p",{className:"text-sm font-semibold text-white",children:"Run this pentest with more depth"}),m.jsx("p",{className:"mt-0.5 text-xs text-[#666]",children:"Re-run this pentest on managed infra in the cloud."}),m.jsx("div",{className:"mt-3 flex flex-wrap gap-2.5",children:m.jsx(C2,{label:"Re-run in Strix Pro with more depth",desc:"Run this pentest on managed infra with more depth.",slug:"live_scan",surface:"agents",icon:uT})})]}),m.jsx(eH,{open:d!==null,agent:d,events:a,steerable:f,onClose:()=>c(null)})]})}Bk.createRoot(document.getElementById("root")).render(m.jsx(ee.StrictMode,{children:m.jsx(DH,{})})); diff --git a/strix/interface/viewer/static/index.html b/strix/interface/viewer/static/index.html index 22fad9fc..73057a7e 100644 --- a/strix/interface/viewer/static/index.html +++ b/strix/interface/viewer/static/index.html @@ -6,7 +6,7 @@ Strix Results - + diff --git a/strix/tools/mcp/__init__.py b/strix/tools/mcp/__init__.py index 1cd25aae..78f8eaaf 100644 --- a/strix/tools/mcp/__init__.py +++ b/strix/tools/mcp/__init__.py @@ -10,7 +10,7 @@ from strix.tools.mcp.config import ( McpConnectionConfig, ) from strix.tools.mcp.loader import load_user_mcp_configs -from strix.tools.mcp.naming import McpToolOrigin, namespaced_tool_name, resolve_mcp_tool +from strix.tools.mcp.naming import namespaced_tool_name from strix.tools.mcp.registry import ( MCP_REGISTRY_CONTEXT_KEY, McpConnectionEntry, @@ -29,12 +29,10 @@ __all__ = [ "McpConnectionEntry", "McpConnectionSummary", "McpRegistry", - "McpToolOrigin", "call_mcp", "connect_mcp_servers", "describe_mcp", "load_user_mcp_configs", "mcp_inventory_context", "namespaced_tool_name", - "resolve_mcp_tool", ] diff --git a/strix/tools/mcp/agent_tools.py b/strix/tools/mcp/agent_tools.py index 780092dd..76801efd 100644 --- a/strix/tools/mcp/agent_tools.py +++ b/strix/tools/mcp/agent_tools.py @@ -97,10 +97,11 @@ async def call_mcp( Args: connection: The connection name exactly as shown in the MCP inventory. tool: The tool name, exactly as reported by ``describe_mcp``. - arguments: The tool's arguments as an object of names to values, or - omitted/empty for a tool that takes none. ``arguments`` is passed - through as-is, so its shape is whatever ``describe_mcp`` showed for - the tool rather than a shape this tool fixes in advance. + arguments: The tool's arguments as a JSON object of names to values (for + example ``{"path": "app.py"}``), or omitted/empty for a tool that + takes none. Pass an object, not a stringified one. Its shape is + whatever ``describe_mcp`` showed for the tool rather than a shape this + tool fixes in advance. """ registry = _registry_from_ctx(ctx) if registry is None or not registry: @@ -108,11 +109,22 @@ async def call_mcp( entry = registry.get(connection) if entry is None: return _unknown_connection(connection, registry) + invalid_arguments = ( + f"Invalid arguments for {connection!r}.{tool}: expected a JSON object of " + "argument names to values, or none. Call describe_mcp for the input schema." + ) + if isinstance(arguments, str): + # The ``arguments`` parameter is schema-less (an open object is not + # expressible as a strict tool schema), so some models serialize it as a + # JSON string instead of a bare object. Accept a string that decodes to an + # object so a correct call is not rejected over its encoding. + stripped = arguments.strip() + try: + arguments = json.loads(stripped) if stripped else {} + except json.JSONDecodeError: + return invalid_arguments if arguments is not None and not isinstance(arguments, dict): - return ( - f"Invalid arguments for {connection!r}.{tool}: expected a JSON object of " - "argument names to values, or none. Call describe_mcp for the input schema." - ) + return invalid_arguments available = await entry.server.list_tools() valid_names = {mcp_tool.name for mcp_tool in available} if tool not in valid_names: diff --git a/strix/tools/mcp/client.py b/strix/tools/mcp/client.py index df0b94df..2ba5cd6a 100644 --- a/strix/tools/mcp/client.py +++ b/strix/tools/mcp/client.py @@ -17,6 +17,8 @@ from __future__ import annotations import contextlib import json import logging +import os +from pathlib import Path from typing import TYPE_CHECKING, Any, NamedTuple, cast from agents.mcp import ( @@ -27,6 +29,7 @@ from agents.mcp import ( MCPServerStreamableHttpParams, create_static_tool_filter, ) +from mcp.client.stdio import stdio_client if TYPE_CHECKING: @@ -72,6 +75,35 @@ def _auth_headers(config: McpConnectionConfig) -> dict[str, str]: return {"Authorization": f"Bearer {auth.token}"} +@contextlib.asynccontextmanager +async def _quiet_stdio_streams(params: Any) -> Any: + """Run a stdio MCP server with its stderr sent to the void. + + A stdio MCP server chats on stderr as it boots (the filesystem server, for + one, prints ``Allowed directories: [ ... ]``). The mcp library forwards that + stderr to the parent's ``sys.stderr`` by default, which is the terminal the + TUI is drawing on, so the banner corrupts the display. Pointing ``errlog`` at + ``os.devnull`` drops that chatter. Connection failures are unaffected: they + still raise from ``connect`` and are logged by :func:`connect_mcp_servers`. + """ + with Path(os.devnull).open("w", encoding="utf-8") as errlog: + async with stdio_client(params, errlog=errlog) as streams: + yield streams + + +class _QuietMCPServerStdio(MCPServerStdio): + """``MCPServerStdio`` whose subprocess stderr is kept off the terminal. + + The SDK's ``create_streams`` calls ``stdio_client(self.params)`` with no + ``errlog``, so the subprocess stderr defaults to ``sys.stderr`` and paints + server banners over the running TUI. Overriding it lets us redirect that + stream; everything else about the stdio transport is unchanged. + """ + + def create_streams(self) -> Any: + return _quiet_stdio_streams(self.params) + + def _build_server(config: McpConnectionConfig) -> MCPServer: """Construct (but do not connect) the SDK server for one connection. @@ -92,7 +124,7 @@ def _build_server(config: McpConnectionConfig) -> MCPServer: "args": config.args, "env": config.env, } - return MCPServerStdio( + return _QuietMCPServerStdio( params=stdio_params, name=config.name, tool_filter=tool_filter, diff --git a/strix/tools/mcp/naming.py b/strix/tools/mcp/naming.py index 818c34b2..dff2726c 100644 --- a/strix/tools/mcp/naming.py +++ b/strix/tools/mcp/naming.py @@ -1,18 +1,13 @@ -"""How an MCP server's tools are named for the model, and how to read that back. +"""How an MCP server's tools are named for the model. -Kept apart from the client, and stdlib-only, so the interfaces can resolve which -connection a tool call went to without importing the MCP client (and through it -the agents SDK and every registered tool). +Kept apart from the client, and stdlib-only, so a caller can build the +model-facing name for a connection's tool without importing the MCP client (and +through it the agents SDK and every registered tool). """ from __future__ import annotations import re -from typing import TYPE_CHECKING, NamedTuple - - -if TYPE_CHECKING: - from collections.abc import Iterable # A tool name offered to a model has to be letters, digits, underscores or @@ -32,49 +27,3 @@ def namespaced_tool_name(connection: str, tool: str) -> str: which tool is invoked. """ return _INVALID_TOOL_NAME_CHARS.sub("_", f"{connection}_{tool}") - - -class McpToolOrigin(NamedTuple): - """Where a model-facing tool name came from, for showing the user. - - ``connection`` is the name the user gave the connection in their config, so - it reads the way they wrote it. ``tool`` is what is left of the model-facing - name once the connection prefix is removed, which is the server's own name - for the tool and the part a reader cares about. - """ - - connection: str - tool: str - - -def resolve_mcp_tool(tool_name: str, connections: Iterable[str]) -> McpToolOrigin | None: - """Split a model-facing tool name against the run's connections, or ``None``. - - Matched against the connections the run actually made rather than by - splitting the name on the separator: the connection name and the server's own - tool name can both contain underscores, so a split is ambiguous and would - attribute calls to a connection that does not exist. Each connection name is - sanitized the same way :func:`namespaced_tool_name` sanitizes it before - comparing, so a connection whose name has characters a model-facing name - cannot carry still matches. - - The longest match wins, so one connection whose name is a prefix of another's - still resolves to the right one. The character after the prefix has to be a - separator rather than more of a name, which any non-alphanumeric satisfies, - so this holds whichever separator :func:`namespaced_tool_name` uses. - """ - best: McpToolOrigin | None = None - best_length = 0 - for connection in connections: - prefix = _INVALID_TOOL_NAME_CHARS.sub("_", connection) - if not prefix or len(tool_name) <= len(prefix) or not tool_name.startswith(prefix): - continue - if tool_name[len(prefix)].isalnum(): - continue - if len(prefix) > best_length: - # Past the prefix and its single separator character is the tool's - # own name; if a server named a tool nothing but separators, fall - # back to the whole name so the row still says something. - tool = tool_name[len(prefix) + 1 :] or tool_name - best, best_length = McpToolOrigin(connection, tool), len(prefix) - return best diff --git a/tests/test_mcp_client.py b/tests/test_mcp_client.py index 18eb91e2..3f097497 100644 --- a/tests/test_mcp_client.py +++ b/tests/test_mcp_client.py @@ -31,7 +31,6 @@ from strix.tools.mcp import ( load_user_mcp_configs, mcp_inventory_context, namespaced_tool_name, - resolve_mcp_tool, ) from strix.tools.mcp import client as mcp_client @@ -417,6 +416,40 @@ async def test_call_mcp_defaults_missing_arguments_to_empty_object() -> None: assert server.calls == [("ping", {})] +@pytest.mark.asyncio +async def test_call_mcp_coerces_json_string_arguments() -> None: + # Some models serialize the schema-less ``arguments`` object as a JSON string; + # a correct call must not be rejected over that encoding. + registry = McpRegistry() + server = FakeMCPServer("fs", [_mcp_tool("read_file")]) + registry.add(name="fs", server=server, purpose=None, tool_count=1) + + out = await call_mcp.on_invoke_tool( + _ctx(registry), + json.dumps( + {"connection": "fs", "tool": "read_file", "arguments": '{"path": "/etc/hosts"}'} + ), + ) + + assert server.calls == [("read_file", {"path": "/etc/hosts"})] + assert out == {"type": "text", "text": "routed:read_file"} + + +@pytest.mark.asyncio +async def test_call_mcp_errors_on_unparseable_string_arguments() -> None: + registry = McpRegistry() + server = FakeMCPServer("fs", [_mcp_tool("read_file")]) + registry.add(name="fs", server=server, purpose=None, tool_count=1) + + out = await call_mcp.on_invoke_tool( + _ctx(registry), + json.dumps({"connection": "fs", "tool": "read_file", "arguments": "not json"}), + ) + + assert "expected a JSON object" in out + assert server.calls == [] + + @pytest.mark.asyncio async def test_call_mcp_errors_on_unknown_connection() -> None: registry = McpRegistry() @@ -685,31 +718,9 @@ async def test_connect_cleans_up_when_cancelled_mid_connect( # --- reading a tool call back to the server it went out to ------------------- -# resolve_mcp_tool / namespaced_tool_name stay in strix.tools.mcp.naming: the -# TUI reads them to attribute a call to its connection, and call_mcp builds the -# result_transform label with namespaced_tool_name. - - -def test_resolve_mcp_tool_splits_against_the_run_connections() -> None: - assert resolve_mcp_tool("local_fs_read_file", ["github", "local_fs"]) == ( - "local_fs", - "read_file", - ) - - -def test_resolve_mcp_tool_prefers_the_longest_matching_connection() -> None: - assert resolve_mcp_tool("files_main_list", ["files", "files_main"]) == ("files_main", "list") - - -def test_resolve_mcp_tool_matches_a_connection_name_it_had_to_sanitize() -> None: - tool_name = namespaced_tool_name("my server", "db.query") - - assert resolve_mcp_tool(tool_name, ["my server"]) == ("my server", "db_query") - - -def test_resolve_mcp_tool_ignores_tools_that_are_not_a_connection_s() -> None: - assert resolve_mcp_tool("exec_command", ["local_fs"]) is None - assert resolve_mcp_tool("local_fsx", ["local_fs"]) is None +# namespaced_tool_name stays in strix.tools.mcp.naming so call_mcp can build the +# result_transform label. The connection a call went out to is read off the +# call's arguments by the TUI projection, not off the tool name. def test_namespaced_name_is_a_valid_tool_name() -> None: @@ -721,13 +732,16 @@ def test_namespaced_name_is_a_valid_tool_name() -> None: assert re.fullmatch(r"[a-zA-Z0-9_-]{1,128}", name) -def test_projected_tool_call_names_the_server_it_went_out_to() -> None: +def test_projected_call_mcp_names_the_server_and_tool_from_its_args() -> None: view = TuiLiveView() - view.set_mcp_connections(["local_fs"]) view._record_tool_call_data( "agent-1", - {"call_id": "c1", "tool_name": "local_fs_read_file", "args": {"path": "/etc/hosts"}}, + { + "call_id": "c1", + "tool_name": "call_mcp", + "args": {"connection": "local_fs", "tool": "read_file", "arguments": {"path": "/x"}}, + }, ) view._record_tool_call_data( "agent-1", @@ -737,3 +751,18 @@ def test_projected_tool_call_names_the_server_it_went_out_to() -> None: mcp_call, built_in = (event["data"] for event in view.events) assert (mcp_call["mcp_connection"], mcp_call["mcp_tool"]) == ("local_fs", "read_file") assert "mcp_connection" not in built_in + + +def test_projected_describe_mcp_names_the_connection_with_no_tool() -> None: + view = TuiLiveView() + + view._record_tool_call_data( + "agent-1", + {"call_id": "c1", "tool_name": "describe_mcp", "args": {"connection": "local_fs"}}, + ) + + (describe,) = (event["data"] for event in view.events) + # An empty tool is what tells both renderers to present the row as inspecting + # the connection rather than as a call to a tool on it. + assert describe["mcp_connection"] == "local_fs" + assert describe["mcp_tool"] == ""