@runfusion/fusion 0.31.0 → 0.32.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/dist/bin.js +78395 -59001
  2. package/dist/client/.vite/manifest.json +549 -0
  3. package/dist/client/assets/{AgentDetailView-Dx7T1-gM.js → AgentDetailView-CnFf_eBZ.js} +3 -3
  4. package/dist/client/assets/{AgentPermissionPolicyEditor-Cbd6SG_T.css → AgentPermissionPolicyEditor-CGxjOr6G.css} +1 -1
  5. package/dist/client/assets/{AgentPermissionPolicyEditor-Ia7QkynK.js → AgentPermissionPolicyEditor-Cmkt9Z01.js} +2 -2
  6. package/dist/client/assets/{AgentsView-DBbdPWV-.js → AgentsView-LkVv9hph.js} +3 -3
  7. package/dist/client/assets/ChatView-DYjECCRG.js +1 -0
  8. package/dist/client/assets/{DevServerView-DotHOFZt.js → DevServerView-D7legPr1.js} +1 -1
  9. package/dist/client/assets/{DevServerView-DlZpuAnj.css → DevServerView-VTQY28P7.css} +1 -1
  10. package/dist/client/assets/{DirectoryPicker-CIj3ZGKv.js → DirectoryPicker-DctpCNrd.js} +1 -1
  11. package/dist/client/assets/DocumentsView-DORp5JjC.js +1 -0
  12. package/dist/client/assets/EvalsView-CYVJ1pbc.js +1 -0
  13. package/dist/client/assets/{ExperimentalAgentOnboardingModal-U7fXDhhN.js → ExperimentalAgentOnboardingModal-BULVNAiq.js} +1 -1
  14. package/dist/client/assets/GoalsView-Cg136Jcn.css +1 -0
  15. package/dist/client/assets/GoalsView-bmpZKOI_.js +1 -0
  16. package/dist/client/assets/{InsightsView-B0J4mhzV.css → InsightsView-C9-mqVvf.css} +1 -1
  17. package/dist/client/assets/InsightsView-mmtem0RU.js +11 -0
  18. package/dist/client/assets/{MemoryView-D-HLtRrr.js → MemoryView-HVpO1fCH.js} +2 -2
  19. package/dist/client/assets/{NodesView-w3ms-XX2.js → NodesView-CM0eoCP8.js} +3 -3
  20. package/dist/client/assets/{PiExtensionsManager-DFAZAfNn.js → PiExtensionsManager-Cyfas2VT.js} +2 -2
  21. package/dist/client/assets/{PluginManager-DN1VG7Qm.js → PluginManager-C7QDE3Lk.js} +1 -1
  22. package/dist/client/assets/ReliabilityView-C1C1j1SD.js +1 -0
  23. package/dist/client/assets/ReliabilityView-D9AsVv5l.css +1 -0
  24. package/dist/client/assets/ResearchView-Bn2WxwnQ.js +1 -0
  25. package/dist/client/assets/SecretsView-BFhVwJu6.css +1 -0
  26. package/dist/client/assets/SecretsView-DgrrgzFc.js +1 -0
  27. package/dist/client/assets/SettingsModal-BCZrCLl3.js +31 -0
  28. package/dist/client/assets/{SettingsModal-sp7SNwS9.css → SettingsModal-BZBV2kLr.css} +1 -1
  29. package/dist/client/assets/{SettingsModal-1Y8N6MkL.css → SettingsModal-DZrJ5PFH.css} +1 -1
  30. package/dist/client/assets/{SettingsModal-BRRPoxku.js → SettingsModal-YCJM5is3.js} +1 -1
  31. package/dist/client/assets/{SetupWizardModal-B4eA3bpz.js → SetupWizardModal-BT-mj3VD.js} +1 -1
  32. package/dist/client/assets/{SkillsView-DZIfZoF5.js → SkillsView-Db7dYpqd.js} +1 -1
  33. package/dist/client/assets/{StashRecoveryView-mKXYsqam.js → StashRecoveryView-CSYYcWux.js} +1 -1
  34. package/dist/client/assets/TodoView-zqCqfy26.js +6 -0
  35. package/dist/client/assets/{dashboard-view-DOY8-BIx.js → dashboard-view-PpcsMDvN.js} +1 -1
  36. package/dist/client/assets/{folder-open-C_fxRMq1.js → folder-open-mxsFQlAX.js} +1 -1
  37. package/dist/client/assets/index-Ba-F8c1g.js +732 -0
  38. package/dist/client/assets/index-D4HhaIOp.css +1 -0
  39. package/dist/client/assets/{upload-xjku_93-.js → upload-j7JjaJzG.js} +1 -1
  40. package/dist/client/assets/{users-CbALDtDk.js → users-DZ_0WcB6.js} +1 -1
  41. package/dist/client/index.html +15 -27
  42. package/dist/client/version.json +1 -1
  43. package/dist/droid-cli/package.json +1 -1
  44. package/dist/extension.js +51638 -35198
  45. package/dist/pi-claude-cli/package.json +1 -1
  46. package/dist/plugins/fusion-plugin-cli-printing-press/package.json +1 -1
  47. package/dist/plugins/fusion-plugin-cursor-runtime/package.json +1 -1
  48. package/dist/plugins/fusion-plugin-dependency-graph/package.json +1 -1
  49. package/dist/plugins/fusion-plugin-droid-runtime/package.json +1 -1
  50. package/dist/plugins/fusion-plugin-hermes-runtime/package.json +1 -1
  51. package/dist/plugins/fusion-plugin-openclaw-runtime/package.json +1 -1
  52. package/dist/plugins/fusion-plugin-paperclip-runtime/package.json +1 -1
  53. package/dist/plugins/fusion-plugin-reports/package.json +1 -1
  54. package/dist/plugins/fusion-plugin-roadmap/package.json +1 -1
  55. package/dist/plugins/fusion-plugin-whatsapp-chat/package.json +1 -1
  56. package/package.json +1 -1
  57. package/skill/fusion/SKILL.md +1 -1
  58. package/skill/fusion/references/cli-commands.md +1 -1
  59. package/skill/fusion/references/engine-tools.md +1 -0
  60. package/skill/fusion/references/extension-tools.md +12 -2
  61. package/skill/fusion/references/fusion-capabilities.md +3 -2
  62. package/skill/fusion/workflows/task-management.md +1 -1
  63. package/dist/client/assets/ChatView-DYpoWnCc.js +0 -1
  64. package/dist/client/assets/DocumentsView-Dt27gDYa.js +0 -1
  65. package/dist/client/assets/EvalsView-HfWTc8Uv.js +0 -1
  66. package/dist/client/assets/InsightsView-C8bsAlMv.js +0 -11
  67. package/dist/client/assets/ReliabilityView-D0Rtd7pX.css +0 -1
  68. package/dist/client/assets/ReliabilityView-DAuqE-zi.js +0 -1
  69. package/dist/client/assets/ResearchView-YoxEFtNB.js +0 -1
  70. package/dist/client/assets/SettingsModal-B86XhYB1.js +0 -31
  71. package/dist/client/assets/TodoView-C6sLLEQu.js +0 -6
  72. package/dist/client/assets/index-DTFPgu6_.js +0 -695
  73. package/dist/client/assets/index-DdvAZIzj.css +0 -1
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion/pi-claude-cli",
3
- "version": "0.31.0",
3
+ "version": "0.32.0",
4
4
  "description": "Fusion vendored fork: pi coding-agent extension that routes LLM calls through the Claude Code CLI. Forked from rchern/pi-claude-cli (MIT). See UPSTREAM.md.",
5
5
  "license": "MIT",
6
6
  "private": true,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/cli-printing-press",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "type": "module",
5
5
  "description": "CLI Printing Press plugin package for Fusion",
6
6
  "private": true,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/cursor-runtime",
3
- "version": "0.1.10",
3
+ "version": "0.1.11",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/dependency-graph",
3
- "version": "0.1.22",
3
+ "version": "0.1.23",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/droid-runtime",
3
- "version": "0.1.17",
3
+ "version": "0.1.18",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/hermes-runtime",
3
- "version": "0.2.41",
3
+ "version": "0.2.42",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/openclaw-runtime",
3
- "version": "0.2.41",
3
+ "version": "0.2.42",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/paperclip-runtime",
3
- "version": "0.2.41",
3
+ "version": "0.2.42",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/reports",
3
- "version": "0.1.10",
3
+ "version": "0.1.11",
4
4
  "type": "module",
5
5
  "description": "Reports plugin for Fusion",
6
6
  "private": true,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/roadmap",
3
- "version": "0.1.10",
3
+ "version": "0.1.11",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/whatsapp-chat",
3
- "version": "0.1.10",
3
+ "version": "0.1.11",
4
4
  "type": "module",
5
5
  "description": "WhatsApp Web (Baileys) chat bridge for Fusion agents",
6
6
  "keywords": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@runfusion/fusion",
3
- "version": "0.31.0",
3
+ "version": "0.32.0",
4
4
  "license": "MIT",
5
5
  "description": "Fusion CLI: HTTP API server, daemon, dashboard launcher, and task tooling for the Fusion AI coding agent.",
6
6
  "homepage": "https://github.com/Runfusion/Fusion#readme",
@@ -33,7 +33,7 @@ Mission → Milestone → Slice → Feature → Task
33
33
  - **Agent tools** — `fn_agent_stop`, `fn_agent_start`, `fn_agent_create`, `fn_agent_delete`, `fn_list_agents`, `fn_delegate_task`, `fn_agent_show`, `fn_agent_org_chart`
34
34
  - **Skills tools** — `fn_skills_search`, `fn_skills_install`
35
35
  - **Insight tools** — `fn_insight_list`, `fn_insight_show`, `fn_insight_run_list`, `fn_insight_run_show`
36
- - **Other tools** — `fn_web_fetch`, `fn_research_run`, `fn_research_list`, `fn_research_get`, `fn_research_cancel`, `fn_research_retry`, `fn_experiment_finalize`
36
+ - **Other tools** — `fn_web_fetch`, `fn_secret_get`, `fn_research_run`, `fn_research_list`, `fn_research_get`, `fn_research_cancel`, `fn_research_retry`, `fn_experiment_finalize`
37
37
  <!-- END: tool-categories -->
38
38
  - **Dashboard** — Use `/fn` command to start/stop the dashboard
39
39
 
@@ -27,7 +27,7 @@ fn task duplicate FN-001 # Copy task to triage
27
27
  fn task refine FN-001 --feedback "..." # Create follow-up task
28
28
  fn task archive FN-001 # Move done → archived
29
29
  fn task unarchive FN-001 # Move archived → done
30
- fn task delete FN-001 [--force] # Permanently delete
30
+ fn task delete FN-001 [--force] # Soft delete (recoverable via DB)
31
31
  fn task retry FN-001 # Retry failed task → todo
32
32
  fn task comment FN-001 "text" # Add general comment
33
33
  fn task comments FN-001 # List task comments
@@ -41,6 +41,7 @@ These tools are **not** part of the user-invokable extension surface. They are i
41
41
  | Tool | Purpose | Parameters |
42
42
  |---|---|---|
43
43
  | `fn_task_list` | List active tasks during specification (duplicate check, discovery) | none |
44
+ | `fn_task_search` | Keyword search tasks (including done/archived by default) for duplicate detection | `query` (string), `limit?` (number), `includeDone?` (boolean), `includeArchived?` (boolean) |
44
45
  | `fn_task_get` | Fetch full task detail including PROMPT.md | `id` (string) |
45
46
  | `fn_review_spec` | Spawn spec reviewer and return `APPROVE`/`REVISE`/`RETHINK`/`UNAVAILABLE` | none |
46
47
 
@@ -21,7 +21,7 @@ Create a new task on the Fusion task board. The task enters the planning column
21
21
 
22
22
  ### fn_task_update
23
23
 
24
- Update fields on an existing task. Supports modifying the title, description, dependencies, and assigned agent after task creation.
24
+ Update fields on an existing task. Supports modifying the title, description, dependencies, assigned agent, and priority after task creation.
25
25
 
26
26
  | Parameter | Type | Required | Description |
27
27
  |-----------|------|----------|-------------|
@@ -31,6 +31,7 @@ Update fields on an existing task. Supports modifying the title, description, de
31
31
  | `depends` | array | — | New dependency list — replaces existing dependencies (e.g. ['FN-001', 'FN-002']) |
32
32
  | `agentId` | union | — | Agent ID to assign this task to, or null to clear (e.g. 'agent-abc123') |
33
33
  | `nodeId` | union | — | Node ID override for this task, or null to clear |
34
+ | `priority` | string(enum) | — | Task priority (low, normal, high, urgent) |
34
35
 
35
36
  ### fn_task_list
36
37
 
@@ -117,7 +118,7 @@ Unarchive an archived task (move from archived → done). Restores the task to t
117
118
 
118
119
  ### fn_task_delete
119
120
 
120
- Permanently delete a task from the Fusion board. Tasks are deleted immediately and cannot be recovered.
121
+ Soft-delete a task from active Fusion board views. The task row and artifacts are preserved, and the task ID remains reserved for potential operator recovery.
121
122
 
122
123
  | Parameter | Type | Required | Description |
123
124
  |-----------|------|----------|-------------|
@@ -427,6 +428,15 @@ Lightweight URL fetch (no JS rendering). Use agent-browser skill for JS-heavy pa
427
428
  | `timeoutMs` | number | — | Timeout in milliseconds (default: 30000) |
428
429
  | `maxBytes` | number | — | Max bytes to return (default: 512000) |
429
430
 
431
+ ### fn_secret_get
432
+
433
+ Read a secret by key using per-secret access policy.
434
+
435
+ | Parameter | Type | Required | Description |
436
+ |-----------|------|----------|-------------|
437
+ | `key` | string | ✓ | Secret key |
438
+ | `scope` | union | — | Optional scope |
439
+
430
440
  ### fn_research_run
431
441
 
432
442
  Cited-research pipeline: create a bounded search/fetch/synthesis run (not an autonomous experiment loop) and optionally wait for completion.
@@ -13,7 +13,7 @@ All skill/extension tool invocations in this catalog use the public `fn_*` names
13
13
  | Tool | Purpose |
14
14
  |------|---------|
15
15
  | `fn_task_create` | Create a new task on the Fusion task board. The task enters the planning column where the AI planning agent will plan it into a full prompt with steps, file scope, and acceptance criteria. |
16
- | `fn_task_update` | Update fields on an existing task. Supports modifying the title, description, dependencies, and assigned agent after task creation. |
16
+ | `fn_task_update` | Update fields on an existing task. Supports modifying the title, description, dependencies, assigned agent, and priority after task creation. |
17
17
  | `fn_task_list` | List all tasks on the Fusion board, grouped by column. |
18
18
  | `fn_task_show` | Show full details for a task including steps, progress, and log entries. |
19
19
  | `fn_task_attach` | Attach a file to a task. Supports images (png, jpg, gif, webp) and text files (txt, log, json, yaml, yml, toml, csv, xml). |
@@ -24,12 +24,13 @@ All skill/extension tool invocations in this catalog use the public `fn_*` names
24
24
  | `fn_task_refine` | Request a refinement of a completed or in-review task. Creates a new follow-up task in planning that references the original task as a dependency. Use this when a done or in-review task needs additional work, improvements, or follow-up changes. |
25
25
  | `fn_task_archive` | Archive a done task (move from done → archived). Archived tasks are preserved for historical reference but moved out of the main board view. |
26
26
  | `fn_task_unarchive` | Unarchive an archived task (move from archived → done). Restores the task to the done column. |
27
- | `fn_task_delete` | Permanently delete a task from the Fusion board. Tasks are deleted immediately and cannot be recovered. |
27
+ | `fn_task_delete` | Soft-delete a task from active Fusion board views. The task row and artifacts are preserved, and the task ID remains reserved for potential operator recovery. |
28
28
  | `fn_task_import_github` | Import GitHub issues as Fusion tasks. Fetches open issues from a repository and creates tasks in the planning column. Each task includes the issue title and body with a link to the source issue. |
29
29
  | `fn_task_import_github_issue` | Import a specific GitHub issue as a Fusion task. Fetches the issue by number and creates a single task in the planning column with the issue title and body. |
30
30
  | `fn_task_browse_github_issues` | List open GitHub issues from a repository to browse before importing. Returns issue numbers, titles, and URLs for selection. Use with fn_task_import_github_issue to import specific issues by number. |
31
31
  | `fn_task_plan` | Create a task via AI-guided planning mode — interactive conversation to refine your idea into a well-specified task. |
32
32
  | `fn_web_fetch` | Lightweight URL fetch (no JS rendering). Use agent-browser skill for JS-heavy pages. URL to fetch (http/https) Optional extraction hint for downstream summarization Timeout in milliseconds (default: 30000) Max bytes to return (default: 512000) |
33
+ | `fn_secret_get` | Read a secret by key using per-secret access policy. |
33
34
  | `fn_research_run` | Cited-research pipeline: create a bounded search/fetch/synthesis run (not an autonomous experiment loop) and optionally wait for completion. |
34
35
  | `fn_research_list` | Cited-research pipeline: list recent search/fetch/synthesis runs (not experiment-loop sessions). |
35
36
  | `fn_research_get` | Cited-research pipeline: get one run with structured findings and citations (not experiment-loop state). |
@@ -67,7 +67,7 @@ Use `fn_task_show` with the task ID:
67
67
  | Refine completed task | `fn_task_refine` | Creates follow-up task with dependency on original |
68
68
  | Archive done task | `fn_task_archive` | Moves from done → archived |
69
69
  | Restore archived task | `fn_task_unarchive` | Moves from archived → done |
70
- | Delete task | `fn_task_delete` | Permanentcannot be undone |
70
+ | Delete task | `fn_task_delete` | Soft delete hides from active views; ID stays reserved; archive cleanup is the only hard-removal path |
71
71
 
72
72
  **Attaching files:**
73
73
 
@@ -1 +0,0 @@
1
- import{r as n,a as en,j as t,R as tn}from"./vendor-react-K0fH_qHe.js";import{i as yt,b5 as fs,t as Es,b6 as sn,b7 as gs,b8 as nn,w as Kt,b9 as qe,ba as an,bb as rn,bc as on,bd as cn,be as ln,bf as ps,bg as dn,s as Ds,bh as un,bi as mn,bj as _t,bk as hn,bl as fn,bm as gn,bn as pn,k as $s,bo as bn,bp as vn,p as xn,bq as yn,br as wn,u as Sn,bs as Cn,ac as Is,ad as Ps,bt as Nn,bu as kn,S as jn,Y as Ut,P as it,J as at,ap as Mn,bv as bs,bw as vs,bx as xs,B as ot,a as ys,a9 as Rn,aa as An,aW as xt,by as Tn,bz as En,aT as Dn,bA as ws,bB as $n,T as In,bC as Ss,bD as Pn,h as Ln,j as Cs,m as Fn}from"./index-DTFPgu6_.js";import"./vendor-xterm-DzcZoU0P.js";import"./vendor-codemirror-jBKmHyH0.js";const Ot="kb-chat-active-session";function Ns(s){const r=typeof s=="string"?s.trim():"",l=r.indexOf("/");return!r||l<=0||l>=r.length-1?{}:{modelProvider:r.slice(0,l),modelId:r.slice(l+1)}}function zn(s){const r=s?.toolCalls;if(!Array.isArray(r))return;const l=r.map(i=>{if(!i||typeof i!="object")return null;const u=i,x=typeof u.toolName=="string"?u.toolName:"";if(!x)return null;const R=u.args;return{toolName:x,...R&&typeof R=="object"?{args:R}:{},isError:!!u.isError,result:u.result,status:"completed"}}).filter(i=>i!==null);return l.length>0?l:void 0}function _n(s){const r=s?.fallback;if(!r||typeof r!="object")return;const l=r,i=typeof l.primaryModel=="string"?l.primaryModel:"",u=typeof l.fallbackModel=="string"?l.fallbackModel:"",x=l.triggerPoint;if(!(!i||!u||x!=="session-creation"&&x!=="prompt-time"))return{primaryModel:i,fallbackModel:u,triggerPoint:x}}function Un(s){const r=s?.failureInfo;if(!r||typeof r!="object")return;const l=r,i=typeof l.summary=="string"?l.summary.trim():"";if(!i)return;const u=(()=>{const x=l.reference;if(!x||typeof x!="object")return;const R=x,E=typeof R.kind=="string"?R.kind.trim():"",D=typeof R.id=="string"?R.id.trim():"";if(!(!E||!D))return{kind:E,id:D,...typeof R.label=="string"&&R.label.trim()?{label:R.label.trim()}:{}}})();return{summary:i,...typeof l.errorClass=="string"&&l.errorClass.trim()?{errorClass:l.errorClass.trim()}:{},...typeof l.code=="string"&&l.code.trim()?{code:l.code.trim()}:{},...typeof l.detail=="string"&&l.detail.trim()?{detail:l.detail.trim()}:{},...u?{reference:u}:{}}}function ks(s){return typeof s=="string"?{summary:s.trim()||"Failed to get response"}:{summary:typeof s.summary=="string"&&s.summary.trim()?s.summary.trim():"Failed to get response",...typeof s.errorClass=="string"&&s.errorClass.trim()?{errorClass:s.errorClass.trim()}:{},...typeof s.code=="string"&&s.code.trim()?{code:s.code.trim()}:{},...typeof s.detail=="string"&&s.detail.trim()?{detail:s.detail.trim()}:{},...s.reference?{reference:s.reference}:{}}}function Ht(s){return{id:s.id,sessionId:s.sessionId,role:s.role,content:s.content,thinkingOutput:s.thinkingOutput,toolCalls:zn(s.metadata),fallbackInfo:_n(s.metadata),failureInfo:Un(s.metadata),attachments:s.attachments,createdAt:s.createdAt}}function On(s,r){const[l,i]=n.useState([]),[u,x]=n.useState(null),[R,E]=n.useState(!0),[D,C]=n.useState([]),[Q,S]=n.useState(!1),[L,g]=n.useState(!1),[ee,N]=n.useState(""),[_,b]=n.useState(""),[M,A]=n.useState([]),[T,$]=n.useState(""),[J,Y]=n.useState(""),[z,h]=n.useState(!0),[p,o]=n.useState(new Map),c=n.useRef(null),m=n.useRef(!1),y=n.useRef(""),k=n.useRef(null),Z=n.useRef(l),F=n.useRef(u),G=n.useRef(L);Z.current=l,F.current=u,G.current=L,n.useEffect(()=>{y.current=T},[T]);const ke=n.useRef(new Set),ue=n.useRef(0),ve=n.useRef(s);ve.current!==s&&(ve.current=s,ue.current++),n.useEffect(()=>{const f=ue.current;yt(void 0,s).then(v=>{if(ue.current!==f)return;const w=new Map;for(const P of v)w.set(P.id,P);o(w)}).catch(()=>{})},[s]);const ie=n.useCallback(async()=>{E(!0);try{const v=[...(await fs(s)).sessions].sort((w,P)=>new Date(P.updatedAt).getTime()-new Date(w.updatedAt).getTime());i(v)}catch{}finally{E(!1)}},[s]);n.useEffect(()=>{ie()},[ie]);const Ue=n.useRef(()=>{}),Fe=n.useRef(!1);n.useEffect(()=>{Fe.current=!1},[s]),n.useEffect(()=>{if(R||Fe.current||F.current)return;const f=Es(Ot,s);if(!f){Fe.current=!0;return}const v=l.find(w=>w.id===f);if(v){Fe.current=!0,Ue.current(f,v);return}Fe.current=!0},[R,l,s]);const te=n.useCallback(async(f,v)=>{S(!0);try{const w=await sn(f,{limit:50,...v},s),P=w.messages.map(Ht);v?.offset&&v.offset>0?C(se=>[...P,...se]):C(P),h(w.messages.length>=50)}catch{}finally{S(!1)}},[s]),me=n.useCallback(()=>{k.current?.(),k.current=null,y.current="",$(""),N(""),b(""),A([]),g(!1)},[]),wt=n.useCallback(()=>{y.current="",$("")},[]),ne=n.useCallback(()=>{const f=y.current.trim();f&&(y.current="",$(""),ze.current(f))},[]),oe=n.useCallback((f,v,w)=>{if(c.current||!f)return!0;m.current=!1,v&&(N(v.streamingText),b(v.streamingThinking),A(v.toolCalls)),g(!0);const{handlers:P}=gs({sessionId:f,tempUserMessageId:"",setStreamingText:N,setStreamingThinking:b,setStreamingToolCalls:A,cancelStreamingFlushesRef:k,addToast:w?.silent?void 0:r,onFallbackSession:(H,ae)=>{const U=Ns(H.fallbackModel);i(K=>K.map(W=>W.id===ae?{...W,...U}:W)),x(K=>K&&K.id===ae?{...K,...U}:K)},onDone:()=>{N(""),b(""),A([]),g(!1),G.current=!1,c.current=null,te(f),ne()},onError:H=>{N(""),b(""),A([]),g(!1),G.current=!1,c.current=null;const ae=ks(H);w?.silent||r?.(ae.summary,"error"),te(f),ne()}}),se=nn(f,P,s,{...typeof v?.replayFromEventId=="number"?{lastEventId:v.replayFromEventId}:{}});return c.current=se,!0},[r,te,s,ne]),Oe=n.useCallback((f,v)=>{const w=F.current?.id??null;if(f&&w===f&&!v)return;c.current&&(c.current.close(),c.current=null);const P=v??l.find(se=>se.id===f);x(P||null),me(),h(!0),f?te(f):C([]),P?.isGenerating&&oe(P.id,P.inFlightGeneration),f?Kt(Ot,f,s):qe(Ot,s)},[oe,l,te,s,me]);Ue.current=Oe;const ct=n.useCallback(async f=>{const v=await an(f,s);c.current&&(c.current.close(),c.current=null);const w={id:v.session.id,title:v.session.title,agentId:v.session.agentId,status:v.session.status,modelProvider:v.session.modelProvider,modelId:v.session.modelId,createdAt:v.session.createdAt,updatedAt:v.session.updatedAt};return i(P=>P.some(se=>se.id===w.id)?P:[w,...P]),me(),Oe(w.id,w),C([]),w},[s,me,Oe]),je=n.useCallback(async f=>{await rn(f,{status:"archived"},s),i(v=>v.filter(w=>w.id!==f)),u?.id===f&&(x(null),C([]))},[u,s]),Me=n.useCallback(async f=>{u?.id===f&&c.current&&(c.current.close(),c.current=null),await on(f,s),i(v=>v.filter(w=>w.id!==f)),u?.id===f&&(x(null),C([]))},[u,s]),Je=n.useCallback(async()=>{!u||!z||await te(u.id,{offset:D.length})},[u,z,te,D.length]),He=n.useCallback(()=>{u&&(m.current=!0,k.current?.(),k.current=null,c.current?.close(),c.current=null,cn(u.id,s).catch(()=>{}),g(!1),N(""),b(""),A([]))},[u,s]),ze=n.useRef(()=>{}),Re=ln(),xe=n.useCallback(async f=>{try{await ie();const v=await ps(f,s);F.current?.id===f&&x(w=>!w||w.id!==f?w:{...w,...v.session}),v.session.isGenerating?(N(""),b(""),A([]),g(!0),G.current=!0,oe(f,v.session.inFlightGeneration,{silent:!0})):(N(""),b(""),A([]),g(!1),G.current=!1,await te(f))}catch{}},[oe,te,s,ie]),ye=n.useCallback((f,v)=>{if(!u)return;if(G.current){y.current=f,$(f);return}m.current=!1,c.current&&(c.current.close(),c.current=null);const w=`temp-${Date.now()}`,P={id:w,sessionId:u.id,role:"user",content:f,createdAt:new Date().toISOString()};C(H=>[...H,P]),N(""),b(""),A([]),g(!0);const{handlers:se}=gs({sessionId:u.id,tempUserMessageId:w,setStreamingText:N,setStreamingThinking:b,setStreamingToolCalls:A,cancelStreamingFlushesRef:k,addToast:r,onFallbackSession:(H,ae)=>{const U=Ns(H.fallbackModel);i(K=>K.map(W=>W.id===ae?{...W,...U}:W)),x(K=>K&&K.id===ae?{...K,...U}:K)},onDone:({messageId:H,message:ae,accumulated:U})=>{const K=ae?Ht(ae):{id:H||`msg-${Date.now()}`,sessionId:u.id,role:"assistant",content:U.text,thinkingOutput:U.thinking,toolCalls:U.toolCalls.length>0?U.toolCalls:void 0,fallbackInfo:U.fallbackInfo,createdAt:new Date().toISOString()};ke.current.add(K.id),C(W=>[...W,K]),N(""),b(""),A([]),g(!1),G.current=!1,c.current=null,setTimeout(()=>{ke.current.delete(K.id)},1e3),ie(),ne()},onError:(H,ae)=>{const U=ks(H),K=typeof H=="string"?H:U.summary,W=un(K);C(V=>{const O=V.filter(q=>q.id!==ae);return W?O:[...O,{id:`error-${Date.now()}`,sessionId:u.id,role:"assistant",content:U.summary,failureInfo:U,createdAt:new Date().toISOString()}]}),N(""),b(""),A([]),g(!1),G.current=!1,c.current=null,console.error("[useChat] Stream error:",H),W?(console.info("[useChat] Suppressed tab-suspension stream error:",H),u?.id&&(N(""),b(""),A([]),g(!0),G.current=!0,xe(u.id))):(r?.(U.summary,"error"),ie()),m.current||ne()}});c.current=dn(u.id,f,se,v,s)},[u,s,ie,r,oe,xe,ne]);ze.current=ye;const fe=J?l.filter(f=>f.title?.toLowerCase().includes(J.toLowerCase())||f.agentId.toLowerCase().includes(J.toLowerCase())):l;return n.useEffect(()=>{if(!F.current?.isGenerating||(c.current||oe(F.current.id,F.current.inFlightGeneration),!G.current||c.current||!F.current))return;const f=setInterval(async()=>{if(!G.current||c.current||!F.current){clearInterval(f);return}try{(await fs(s)).sessions.find(P=>P.id===F.current?.id)?.isGenerating||(clearInterval(f),await te(F.current.id),N(""),b(""),A([]),g(!1),G.current=!1,ne())}catch{}},3e3);return()=>clearInterval(f)},[oe,te,s,u,ne]),n.useEffect(()=>Re.onBecameVisible(()=>{const v=F.current;if(!v||c.current)return;const w=ue.current;ps(v.id,s).then(P=>{if(!(ue.current!==w||c.current)){if(P.session.isGenerating){N(""),b(""),A([]),g(!0),G.current=!0,oe(v.id,P.session.inFlightGeneration,{silent:!0});return}G.current&&(N(""),b(""),A([]),g(!1),G.current=!1,ne(),te(v.id))}}).catch(()=>{})}),[oe,te,s,Re,ne]),n.useEffect(()=>{const f=ue.current,v=s?`?projectId=${encodeURIComponent(s)}`:"",w=()=>ue.current!==f,P=W=>{if(w())return;const V=JSON.parse(W.data);i(O=>O.some(q=>q.id===V.id)?O:[V,...O])},se=W=>{if(w())return;const V=JSON.parse(W.data);i(O=>[...O.map(re=>re.id===V.id?V:re)]),F.current?.id===V.id&&(x(V),V.isGenerating&&!c.current&&oe(V.id,V.inFlightGeneration))},H=W=>{if(w())return;const{id:V}=JSON.parse(W.data);i(O=>O.filter(q=>q.id!==V)),F.current?.id===V&&(x(null),C([]))},ae=W=>{if(w())return;const V=JSON.parse(W.data),O=Ht(V);if(!ke.current.has(O.id)){if(F.current?.id===O.sessionId&&G.current&&!c.current&&O.role==="assistant"){C(q=>q.some(re=>re.id===O.id)?q:[...q,O]),N(""),b(""),A([]),g(!1),G.current=!1,ne();return}F.current?.id===O.sessionId&&!G.current&&C(q=>{if(q.some(re=>re.id===O.id))return q;if(O.role==="user"){const re=q.findIndex(we=>we.role==="user"&&we.id.startsWith("temp-")&&we.content.trim()===O.content.trim());if(re>=0){const we=[...q];return we[re]=O,we}}return[...q,O]})}},U=W=>{if(w())return;const{id:V}=JSON.parse(W.data);C(O=>O.filter(q=>q.id!==V))};return Ds(`/api/events${v}`,{events:{"chat:session:created":P,"chat:session:updated":se,"chat:session:deleted":H,"chat:message:added":ae,"chat:message:deleted":U}})},[oe,s,ne]),n.useEffect(()=>()=>{c.current&&(c.current.close(),c.current=null)},[]),{sessions:l,activeSession:u,sessionsLoading:R,messages:D,messagesLoading:Q,isStreaming:L,streamingText:ee,streamingThinking:_,streamingToolCalls:M,pendingMessage:T,selectSession:Oe,createSession:ct,archiveSession:je,deleteSession:Me,sendMessage:ye,stopStreaming:He,clearPendingMessage:wt,loadMoreMessages:Je,hasMoreMessages:z,searchQuery:J,setSearchQuery:Y,filteredSessions:fe,refreshSessions:ie,agentsMap:p}}const Pe="fusion:chat-active-room";function Wt(s){return[...s].sort((r,l)=>new Date(l.updatedAt).getTime()-new Date(r.updatedAt).getTime())}function rt(s,r){const l=s.findIndex(u=>u.id===r.id);if(l===-1)return Wt([r,...s]);const i=[...s];return i[l]=r,Wt(i)}function Le(s){try{return JSON.parse(s.data)}catch{return null}}function Hn(s,r){return{id:`temp-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,roomId:s,role:"user",content:r,thinkingOutput:null,metadata:null,senderAgentId:null,mentions:[],createdAt:new Date().toISOString()}}function Bn(s,r){const[l,i]=n.useState([]),[u,x]=n.useState(!0),[R,E]=n.useState(null),[D,C]=n.useState(null),[Q,S]=n.useState([]),[L,g]=n.useState([]),[ee,N]=n.useState(!1),_=n.useRef(l),b=n.useRef(D),M=n.useRef(0),A=n.useRef(s);_.current=l,b.current=D,A.current!==s&&(A.current=s,M.current+=1);const T=n.useCallback(async(p,o=!0)=>{if(!p){S([]),g([]),N(!1);return}o&&g([]),N(!0);try{const[c,m]=await Promise.all([mn(p.id,s),_t(p.id,{limit:100,order:"desc"},s)]);S(c.members),g(m.messages)}catch{S([]),g([])}finally{N(!1)}},[s]),$=n.useCallback(async()=>{x(!0);try{const p=await hn({},s),o=Wt(p.rooms);i(o),E(null);const c=Es(Pe,s);if(c){const m=o.find(y=>y.id===c)??null;m?(C(m),T(m,!0)):qe(Pe,s)}}catch(p){const o=p instanceof Error?p.message:"Failed to load chat rooms";E(o),r?.(o,"error")}finally{x(!1)}},[r,T,s]),J=n.useCallback(p=>{if(!p){C(null),qe(Pe,s),T(null,!0);return}const o=_.current.find(c=>c.id===p)??null;C(o),o&&(Kt(Pe,o.id,s),T(o,!0))},[T,s]),Y=n.useCallback(async p=>{const c=(await fn({name:p.name,memberAgentIds:p.memberAgentIds},s)).room;return i(m=>rt(m,c)),C(c),Kt(Pe,c.id,s),await T(c,!0),c},[T,s]),z=n.useCallback(async p=>{await gn(p,s),i(o=>o.filter(c=>c.id!==p)),b.current?.id===p&&(C(null),S([]),g([]),qe(Pe,s))},[s]),h=n.useCallback(async(p,o)=>{const c=b.current,m=c?.id;if(!m)throw new Error("Select a room before sending a message");const y=Hn(m,p);b.current?.id===m&&g(k=>[...k,y]);try{const k=await pn(m,{content:p,...o?.attachments?{attachments:o.attachments}:{}},s);k.message?.createdAt&&c&&i(F=>rt(F,{...c,updatedAt:k.message.createdAt})),b.current?.id===m&&g(F=>F.map(G=>G.id===y.id?k.message:G));const Z=await _t(m,{limit:100,order:"desc"},s);if(b.current?.id!==m)return;g(Z.messages)}catch(k){try{const Z=await _t(m,{limit:100,order:"desc"},s);b.current?.id===m&&g(Z.messages)}catch{b.current?.id===m&&g(Z=>Z.filter(F=>F.id!==y.id))}throw k}},[s]);return n.useEffect(()=>{$()},[$]),n.useEffect(()=>{const p=M.current,o=s?`/api/events?projectId=${encodeURIComponent(s)}`:"/api/events";return Ds(o,{onReconnect:()=>{$()},events:{"chat:room:created":c=>{if(M.current!==p)return;const m=Le(c);m&&i(y=>rt(y,m))},"chat:room:updated":c=>{if(M.current!==p)return;const m=Le(c);m&&(i(y=>rt(y,m)),b.current?.id===m.id&&C(m))},"chat:room:deleted":c=>{if(M.current!==p)return;const m=Le(c);m?.id&&(i(y=>y.filter(k=>k.id!==m.id)),b.current?.id===m.id&&(C(null),S([]),g([]),qe(Pe,s)))},"chat:room:member:added":c=>{if(M.current!==p)return;const m=Le(c);!m||b.current?.id!==m.roomId||S(y=>y.some(k=>k.agentId===m.agentId)?y:[...y,m])},"chat:room:member:removed":c=>{if(M.current!==p)return;const m=Le(c);!m||b.current?.id!==m.roomId||S(y=>y.filter(k=>k.agentId!==m.agentId))},"chat:room:message:added":c=>{if(M.current!==p)return;const m=Le(c);m&&(i(y=>{const k=y.find(Z=>Z.id===m.roomId);return k?rt(y,{...k,updatedAt:m.createdAt}):y}),b.current?.id===m.roomId&&g(y=>{if(y.some(k=>k.id===m.id))return y;if(m.role==="user"){const k=y.findIndex(Z=>Z.role==="user"&&Z.id.startsWith("temp-")&&Z.content.trim()===m.content.trim());if(k>=0){const Z=[...y];return Z[k]=m,Z}}return[...y,m]}))},"chat:room:message:updated":c=>{if(M.current!==p)return;const m=Le(c);!m||b.current?.id!==m.roomId||g(y=>y.map(k=>k.id===m.id?m:k))},"chat:room:message:deleted":c=>{if(M.current!==p)return;const m=Le(c);m?.id&&g(y=>y.filter(k=>k.id!==m.id))}}})},[s,$]),n.useEffect(()=>{D&&(l.some(p=>p.id===D.id)||(C(null),S([]),g([]),qe(Pe,s)))},[D,s,l]),{rooms:l,roomsLoading:u,roomsError:R,activeRoom:D,activeRoomMembers:Q,messages:L,messagesLoading:ee,selectRoom:J,createRoom:Y,deleteRoom:z,sendRoomMessage:h,refreshRooms:$}}function Gn(s,r=[]){const l=s.trim().replace(/^#/,"");if(!l)return{ok:!1,error:"Room name is required."};if(/[A-Z]/.test(l))return{ok:!1,error:"Use lowercase letters only."};const i=l.toLowerCase();return i.length>80?{ok:!1,error:"Room names can be at most 80 characters."}:/^[a-z0-9_-]+$/.test(i)?/^[-_]|[-_]$/.test(i)?{ok:!1,error:"Room names cannot start or end with a hyphen or underscore."}:r.some(u=>u.toLowerCase()===i)?{ok:!1,error:"A room with this name already exists."}:{ok:!0,name:i}:{ok:!1,error:"Use lowercase letters, numbers, hyphens, or underscores only."}}function Kn({isOpen:s,onClose:r,onCreate:l,projectId:i,existingRoomNames:u=[]}){const[x,R]=n.useState(""),[E,D]=n.useState([]),[C,Q]=n.useState(""),[S,L]=n.useState([]),[g,ee]=n.useState(!1),[N,_]=n.useState(null),[b,M]=n.useState(!1),A=n.useRef(null),T=n.useRef(null);n.useEffect(()=>{s&&(T.current=document.activeElement instanceof HTMLElement?document.activeElement:null,ee(!0),_(null),yt(void 0,i).then(o=>D(o)).catch(()=>{D([]),_("Failed to load agents.")}).finally(()=>ee(!1)))},[s,i]),n.useEffect(()=>{if(!s){R(""),Q(""),L([]),_(null),M(!1);return}const o=window.requestAnimationFrame(()=>A.current?.focus());return()=>window.cancelAnimationFrame(o)},[s]),n.useEffect(()=>{if(!s)return;const o=c=>{c.key==="Escape"&&r()};return document.addEventListener("keydown",o),()=>document.removeEventListener("keydown",o)},[s,r]),n.useEffect(()=>{s||T.current?.focus()},[s]);const $=n.useMemo(()=>Gn(x,u),[x,u]),J=n.useMemo(()=>{const o=C.trim().toLowerCase();return o?E.filter(c=>c.name.toLowerCase().includes(o)):E},[E,C]),Y=n.useMemo(()=>E.filter(o=>S.includes(o.id)),[E,S]),z=$.ok&&S.length>0&&!b&&!g;if(!s)return null;const h=o=>{b||L(c=>c.includes(o)?c.filter(m=>m!==o):[...c,o])},p=async()=>{if(!$.ok){_($.error);return}if(S.length===0){_("Select at least one member.");return}_(null),M(!0);try{await l({name:$.name,displayName:`#${$.name}`,memberAgentIds:S}),r()}catch(o){_(o instanceof Error?o.message:"Failed to create room.")}finally{M(!1)}};return en.createPortal(t.jsx("div",{className:"modal-overlay open",onClick:o=>o.target===o.currentTarget&&r(),children:t.jsxs("div",{className:"modal modal-lg create-room-modal",role:"dialog","aria-modal":"true","aria-label":"Create room",onClick:o=>o.stopPropagation(),children:[t.jsxs("div",{className:"modal-header",children:[t.jsx("h3",{children:"Create room"}),t.jsx("button",{type:"button",className:"modal-close","aria-label":"Close",onClick:r,children:"×"})]}),t.jsxs("div",{className:"form-group create-room-modal-name-group",children:[t.jsx("label",{htmlFor:"create-room-name",children:"Room name"}),t.jsxs("div",{className:"create-room-modal-name-field",children:[t.jsx("span",{"aria-hidden":"true",className:"create-room-modal-name-hash",children:"#"}),t.jsx("input",{ref:A,id:"create-room-name",className:"input",value:x,disabled:b,onChange:o=>{const c=o.target.value.replace(/^#/,"").replace(/\s+/g,"-").toLowerCase();R(c)}})]}),!$.ok&&t.jsx("div",{className:"form-error",children:$.error})]}),t.jsxs("div",{className:"form-group",children:[t.jsx("label",{htmlFor:"create-room-member-search",children:"Members"}),t.jsx("input",{id:"create-room-member-search",className:"input",placeholder:"Search agents",value:C,disabled:b,onChange:o=>Q(o.target.value)})]}),Y.length>0&&t.jsx("div",{className:"create-room-modal-selected","data-testid":"create-room-selected-chips",children:Y.map(o=>t.jsxs("button",{type:"button",className:"btn btn-sm create-room-modal-chip",onClick:()=>h(o.id),disabled:b,children:[o.name," ×"]},o.id))}),t.jsx("div",{className:"create-room-modal-member-list","data-testid":"create-room-member-list",children:g?t.jsx("div",{className:"create-room-modal-empty",children:"Loading agents..."}):J.length===0?t.jsx("div",{className:"create-room-modal-empty",children:E.length===0?"No agents in this project yet.":"No agents match your search."}):J.map(o=>{const c=S.includes(o.id);return t.jsxs("button",{type:"button",className:`create-room-modal-member-row${c?" create-room-modal-member-row--selected":""}`,onClick:()=>h(o.id),disabled:b,children:[t.jsx($s,{agent:o,size:20}),t.jsx("span",{children:o.name}),t.jsx("span",{className:"create-room-modal-member-role",children:o.role})]},o.id)})}),N&&t.jsx("div",{className:"form-group",children:t.jsx("div",{className:"form-error",children:N})}),t.jsxs("div",{className:"modal-actions",children:[t.jsx("button",{type:"button",className:"btn",onClick:r,disabled:b,children:"Cancel"}),t.jsx("button",{type:"button",className:"btn btn-primary",onClick:()=>void p(),disabled:!z,children:b?"Creating...":"Create room"})]})]})}),document.body)}const Wn=320;function Vn(s){return Math.min(s,Wn)}function Ls(s){const r=new Date(s),i=new Date().getTime()-r.getTime(),u=Math.floor(i/1e3),x=Math.floor(u/60),R=Math.floor(x/60),E=Math.floor(R/24);return u<60?"just now":x<60?`${x}m ago`:R<24?`${R}h ago`:E<7?`${E}d ago`:r.toLocaleDateString()}function js(s,r){if(!s||!r)return null;const l=r.toLowerCase();if(l.includes("claude")){let u=r.replace(/^claude[- ]/i,"Claude ").replace(/sonnet[- ](\d+)[- ](\d+)/i,"Sonnet $1.$2").replace(/sonnet[- ](\d+)/i,"Sonnet $1").replace(/haiku[- ](\d+)/i,"Haiku $1").replace(/opus[- ](\d+)/i,"Opus $1").replace(/sonnet/i,"Sonnet").replace(/haiku/i,"Haiku").replace(/opus/i,"Opus").replace(/-/g," ").trim();return u=u.replace(/\s+/g," "),u.length>30?u.slice(0,30)+"…":u}if(l.includes("gpt")||l.includes("openai")){const u=r.replace(/^gpt-4-turbo$/i,"GPT-4 Turbo").replace(/^gpt-4o-mini$/i,"GPT-4o Mini").replace(/^gpt-4o$/i,"GPT-4o").replace(/^gpt-4$/i,"GPT-4").replace(/^gpt-o1-preview$/i,"GPT-o1 Preview").replace(/^gpt-o1-mini$/i,"GPT-o1 Mini").replace(/^gpt-o1$/i,"GPT-o1").replace(/^gpt/i,"GPT").trim();return u.length>30?u.slice(0,30)+"…":u}if(l.includes("gemini")){const u=r.replace(/^gemini[- ]/i,"Gemini ").replace(/pro[- ](\d+)[- ](\d+)/i,"Pro $1.$2").replace(/pro[- ](\d+)/i,"Pro $1").replace(/-/g," ").replace(/\s+/g," ").trim();return u.length>30?u.slice(0,30)+"…":u}const i=r.replace(/-/g," ").replace(/^\w/,u=>u.toUpperCase()).replace(/\s+/g," ").trim();return i.length>30?i.slice(0,30)+"…":i}function vt(s,r){return s.length<=r?s:`${s.slice(0,r)}…`}function qn(s){if(!s)return null;const r=Object.entries(s);return r.length===0?null:r.map(([l,i])=>{const u=typeof i=="string"?i:(()=>{try{return JSON.stringify(i)}catch{return String(i)}})();return`${l}=${vt(u,50)}`}).join(", ")}function Xn(s){if(s===void 0)return null;if(typeof s=="string")return vt(s,200);try{return vt(JSON.stringify(s),200)}catch{return vt(String(s),200)}}function Jn(s){if(!s)return null;if(s.kind==="mailbox"||s.kind==="mailbox-message"){const r=typeof window>"u"?"/":window.location.pathname||"/",l=new URLSearchParams(typeof window>"u"?"":window.location.search);return l.set("view","mailbox"),l.set("mailbox-message",s.id),`${r}?${l.toString()}#message-${encodeURIComponent(s.id)}`}return null}function Yn(s){if(!s)return null;const r=s.label??`${s.kind} ${s.id}`,l=Jn(s),i=`chat-failure-reference-${s.kind}-${s.id}`.replace(/[^a-zA-Z0-9_-]+/g,"-").toLowerCase();return t.jsxs("div",{className:"chat-message-failure-reference",children:[t.jsx("span",{className:"chat-message-failure-reference-label",children:"Reference"}),t.jsx("span",{className:"chat-message-failure-reference-value",children:r}),l?t.jsx("a",{className:"btn btn-sm chat-message-failure-reference-link",href:l,children:"Open mailbox message"}):t.jsxs("details",{className:"chat-message-failure-reference-details",children:[t.jsx("summary",{className:"btn btn-sm chat-message-failure-reference-link",children:"View failure details"}),t.jsxs("dl",{className:"chat-message-failure-reference-meta",id:i,children:[t.jsxs("div",{children:[t.jsx("dt",{children:"Kind"}),t.jsx("dd",{children:s.kind})]}),t.jsxs("div",{children:[t.jsx("dt",{children:"ID"}),t.jsx("dd",{children:s.id})]}),s.label&&t.jsxs("div",{children:[t.jsx("dt",{children:"Label"}),t.jsx("dd",{children:s.label})]})]})]})]})}function Fs(s){if(!s||s.length===0)return null;const r=(S,L)=>{const g=S.status==="running",ee=S.status==="completed"&&S.isError,N=qn(S.args),_=Xn(S.result),b=g?N:_?`result: ${_}`:N?`args: ${N}`:null,M=g?"running":ee?"error":"completed";return t.jsxs("details",{className:`chat-tool-call${g?" chat-tool-call--running":""}${ee?" chat-tool-call--error":""}`,open:g,children:[t.jsxs("summary",{children:[t.jsx("span",{className:"chat-tool-call-status-dot","aria-hidden":"true"}),t.jsx("span",{className:"chat-tool-call-name",title:S.toolName,children:S.toolName}),b&&t.jsx("span",{className:"chat-tool-call-preview",title:b,children:b}),t.jsx("span",{className:"chat-tool-call-status-text",children:M})]}),t.jsxs("div",{className:"chat-tool-call-content",children:[N&&t.jsxs("div",{className:"chat-tool-call-row",children:[t.jsx("span",{className:"chat-tool-call-label",children:"args"}),t.jsx("span",{className:"chat-tool-call-value",children:N})]}),_&&t.jsxs("div",{className:`chat-tool-call-row${ee?" chat-tool-call-row--error":""}`,children:[t.jsx("span",{className:"chat-tool-call-label",children:"result"}),t.jsx("span",{className:"chat-tool-call-value",children:_})]})]})]},`${S.toolName}-${L}`)},l="chat-tool-calls";if(s.length===1)return t.jsxs("div",{className:l,"data-testid":"chat-tool-calls",children:[t.jsxs("div",{className:"chat-tool-calls-header",children:[t.jsx(Ss,{size:12,"aria-hidden":"true"}),t.jsx("span",{children:"Tool calls"})]}),r(s[0],0)]});const i=s.filter(S=>S.status==="running").length,u=s.filter(S=>S.status==="completed"&&S.isError).length,x=i>0,R=Array.from(new Set(s.map(S=>S.toolName))),E=R.slice(0,5),D=Math.max(0,R.length-E.length),C=D>0?`${E.join(", ")}, +${D} more`:E.join(", "),Q=x?`(${i} running)`:u>0?`(${u} ${u===1?"error":"errors"})`:null;return t.jsx("div",{className:l,"data-testid":"chat-tool-calls",children:t.jsxs("details",{className:"chat-tool-calls-group","data-testid":"chat-tool-calls-group",open:x,children:[t.jsxs("summary",{className:"chat-tool-calls-group-summary",children:[t.jsx(Ss,{size:12,"aria-hidden":"true"}),t.jsxs("span",{className:"chat-tool-calls-count",children:[s.length," tool calls"]}),t.jsx("span",{className:"chat-tool-calls-names",title:C,children:C}),Q&&t.jsx("span",{className:"chat-tool-calls-group-status",children:Q})]}),s.map((S,L)=>r(S,L))]})})}const zs={p:({children:s,...r})=>t.jsx("p",{...r,children:ws(s)}),li:({children:s,...r})=>t.jsx("li",{...r,children:ws(s)}),pre:({children:s,...r})=>t.jsx("pre",{...r,className:"chat-markdown-pre",children:s}),code:({children:s,...r})=>{const l=typeof s=="string"?s:tn.Children.toArray(s).join(""),i=xt(l);return i.length===1&&typeof i[0]=="string"?t.jsx("code",{...r,children:s}):t.jsx("code",{...r,children:i})},table:({children:s,...r})=>t.jsx("table",{...r,className:"chat-markdown-table",children:s})},Xe="__fn_agent__",Qn=280,pt=180,bt=500,Ms="fusion:chat-sidebar-width",Bt="fusion:chat-scope",Zn="fusion:chat-draft:";function Rs(s,r){return r?`${Zn}${s}:${r}`:null}function As(s){if(!s)return"";try{return localStorage.getItem(s)??""}catch{return""}}const ea=["image/png","image/jpeg","image/gif","image/webp","text/plain","application/json","text/yaml","text/markdown","text/csv","application/xml","text/x-log"];function Ts(s){const r=/(^|[\s])\/([^\s]*)$/.exec(s);if(!r)return null;const l=r[1]??"",i=r[2]??"",u=r.index+l.length;return{filter:i,start:u,end:s.length}}function ta(s,r){const l=s.slice(0,r),i=/(^|[\s\n])@([\w-]*)$/.exec(l);if(!i)return null;const u=i[2]??"",x=l.length-u.length-1;return{filter:u,start:x,end:r}}function sa({projectId:s,onClose:r,onCreate:l}){const[i,u]=n.useState("agent"),[x,R]=n.useState([]),[E,D]=n.useState(!0),[C,Q]=n.useState(""),[S,L]=n.useState([]),[g,ee]=n.useState(!0),[N,_]=n.useState(""),[b,M]=n.useState([]),[A,T]=n.useState([]);n.useEffect(()=>{let h=!1;return D(!0),yt(void 0,s).then(p=>{h||R(p)}).catch(()=>{h||R([])}).finally(()=>{h||D(!1)}),()=>{h=!0}},[s]),n.useEffect(()=>{ee(!0),Ln().then(h=>{L(h.models),M(h.favoriteProviders),T(h.favoriteModels)}).catch(()=>{L([]),M([]),T([])}).finally(()=>{ee(!1)})},[]);const $=n.useCallback(async h=>{const p=b,c=p.includes(h)?p.filter(m=>m!==h):[h,...p];M(c);try{await Cs({favoriteProviders:c,favoriteModels:A})}catch{M(p)}},[b,A]),J=n.useCallback(async h=>{const p=A,c=p.includes(h)?p.filter(m=>m!==h):[h,...p];T(c);try{await Cs({favoriteProviders:b,favoriteModels:c})}catch{T(p)}},[A,b]),Y=h=>{if(h.preventDefault(),i==="agent"){if(!C)return;l({agentId:C});return}if(!N)return;const p=N.indexOf("/");if(p<=0)return;const o=N.slice(0,p),c=N.slice(p+1);l({agentId:Xe,modelProvider:o,modelId:c})},z=i==="agent"?!C:!N;return t.jsx("div",{className:"chat-new-dialog-backdrop chat-view-dialog-backdrop",onClick:r,role:"dialog","aria-modal":"true",children:t.jsxs("div",{className:"chat-new-dialog chat-view-dialog",onClick:h=>h.stopPropagation(),children:[t.jsx("h3",{children:"New Chat"}),t.jsxs("div",{className:"chat-new-dialog-mode-toggle","data-testid":"chat-new-dialog-mode-toggle",children:[t.jsx("button",{type:"button",className:`chat-new-dialog-mode-btn${i==="agent"?" chat-new-dialog-mode-btn--active":""}`,"data-testid":"chat-new-dialog-mode-agent",onClick:()=>{u("agent"),_("")},children:"Agent"}),t.jsx("button",{type:"button",className:`chat-new-dialog-mode-btn${i==="model"?" chat-new-dialog-mode-btn--active":""}`,"data-testid":"chat-new-dialog-mode-model",onClick:()=>{u("model"),Q("")},children:"Model"})]}),t.jsxs("form",{onSubmit:Y,children:[i==="agent"&&t.jsxs("label",{className:"chat-new-dialog-model-label",children:["Agent",E?t.jsx("div",{className:"chat-new-dialog-loading",children:"Loading agents..."}):x.length===0?t.jsx("div",{className:"chat-new-dialog-empty",children:"No agents available"}):t.jsx("div",{className:"chat-new-dialog-agent-list",children:x.map(h=>t.jsxs("button",{type:"button",className:`chat-new-dialog-agent-item${C===h.id?" chat-new-dialog-agent-item--selected":""}`,onClick:()=>Q(h.id),"data-testid":`agent-option-${h.id}`,children:[t.jsx(ot,{size:16}),t.jsx("span",{className:"chat-new-dialog-agent-name",children:h.name}),t.jsx("span",{className:"chat-new-dialog-agent-role",children:h.role})]},h.id))})]}),i==="model"&&t.jsx("div",{className:"chat-new-dialog-model-dropdown","data-testid":"chat-new-dialog-model-section",children:g?t.jsx("div",{className:"chat-new-dialog-loading",children:"Loading models..."}):t.jsx(Fn,{models:S,value:N,onChange:_,label:"Model",placeholder:"Select a model",favoriteProviders:b,onToggleFavorite:$,favoriteModels:A,onToggleModelFavorite:J})}),t.jsxs("div",{className:"chat-new-dialog-actions",children:[t.jsx("button",{type:"button",className:"btn btn-sm",onClick:r,children:"Cancel"}),t.jsx("button",{type:"submit",className:"btn btn-sm btn-primary",disabled:z,children:"Create"})]})]})]})})}const Gt=n.memo(function({message:r,forcePlain:l,agentName:i,hideAssistantIdentity:u,showAssistantModelTag:x,activeModelTag:R,activeModelProvider:E,activeSessionId:D,mentionAgentsByName:C,roomContext:Q,copyAction:S}){const L=r.role==="assistant",g=L?r.failureInfo:void 0,ee=L&&(!u||!!g),N=n.useMemo(()=>{if(L)return null;const M=r.content,A=/@([\w-]+)/g,T=[];let $=0,J=A.exec(M);for(;J;){const[Y,z=""]=J,h=J.index;h>$&&T.push(M.slice($,h));const p=z.replace(/_/g," ").toLowerCase(),o=C.get(p);if(o){const c=!!(Q&&!Q.memberIds.has(o.id)),m=c?`Not a member of ${Q?.roomName}`:void 0;T.push(t.jsxs("span",{className:`chat-mention-chip${c?" chat-mention-chip--non-member":""}`,title:m,"aria-label":m,children:["@",o.name.replace(/\s+/g,"_")]},`${o.id}-${h}`))}else T.push(Y);$=h+Y.length,J=A.exec(M)}return $<M.length&&T.push(M.slice($)),T.length===0?M:T},[L,r.content,C,Q]),_=n.useMemo(()=>{const M=r.attachments;if(!M||M.length===0||!D)return null;const A=`/api/chat/sessions/${encodeURIComponent(D)}/attachments/`;return t.jsx("div",{className:"chat-message-attachments",children:M.map(T=>{const $=T.mimeType.startsWith("image/"),J=T.id||T.filename,Y=`${A}${encodeURIComponent(T.filename)}`;return $?t.jsx("a",{className:"chat-message-attachment-link","data-testid":"chat-message-attachment",href:Y,target:"_blank",rel:"noopener noreferrer",children:t.jsx("img",{className:"chat-message-attachment",src:Y,alt:T.originalName})},J):t.jsxs("a",{className:"chat-message-attachment-file","data-testid":"chat-message-attachment",href:Y,target:"_blank",rel:"noopener noreferrer",children:[t.jsx($n,{size:14}),t.jsx("span",{children:T.originalName})]},J)})})},[r.attachments,D]),b=n.useMemo(()=>L?g?t.jsxs("div",{className:"chat-message-content chat-message-content--failure",children:[t.jsxs("div",{className:"chat-message-failure-summary-row",children:[t.jsx("span",{className:"status-dot status-dot--error","aria-hidden":"true"}),t.jsx("span",{className:"chat-message-failure-label",children:"Response failed"})]}),t.jsx("div",{className:"chat-message-failure-summary",children:g.summary}),(g.errorClass||g.code)&&t.jsxs("div",{className:"chat-message-failure-badges",children:[g.errorClass&&t.jsx("span",{className:"chat-message-failure-badge",children:g.errorClass}),g.code&&t.jsx("span",{className:"chat-message-failure-badge",children:g.code})]}),(g.detail||g.reference)&&t.jsxs("details",{className:"chat-message-failure-details",children:[t.jsxs("summary",{children:[t.jsx(In,{size:14,"aria-hidden":"true"}),t.jsx("span",{children:"Failure details"})]}),g.detail&&t.jsx("pre",{className:"chat-message-failure-detail",children:xt(g.detail)}),Yn(g.reference)]})]}):l?t.jsx("div",{className:"chat-message-content chat-message-content--plain",children:r.content}):t.jsx("div",{className:"chat-message-content chat-message-content--markdown",children:t.jsx(Is,{remarkPlugins:[Ps],components:zs,children:r.content})}):null,[g,l,L,r.content]);return t.jsxs("div",{className:`chat-message chat-message--${r.role}${g?" chat-message--failure":""}`,"data-testid":`chat-message-${r.id}`,children:[ee&&t.jsxs("div",{className:"chat-message-avatar",children:[E?t.jsx(it,{provider:E,size:"sm"}):t.jsx(ot,{size:14}),t.jsx("span",{children:i}),x&&R&&t.jsx("span",{className:"chat-model-tag",children:R})]}),L?b:t.jsx("div",{className:"chat-message-content",children:N}),!g&&S,Fs(r.toolCalls),r.thinkingOutput&&t.jsxs("details",{className:"chat-message-thinking",children:[t.jsx("summary",{children:"Thinking"}),t.jsx("pre",{className:"chat-message-thinking-content",children:xt(r.thinkingOutput)})]}),_,t.jsx("div",{className:"chat-message-time",children:Ls(r.createdAt)})]})});function ca({projectId:s,addToast:r,experimentalFeatures:l}){const{activeSession:i,sessionsLoading:u,messages:x,messagesLoading:R,isStreaming:E,streamingText:D,streamingThinking:C,streamingToolCalls:Q,selectSession:S,createSession:L,archiveSession:g,deleteSession:ee,sendMessage:N,stopStreaming:_,pendingMessage:b,clearPendingMessage:M,searchQuery:A,setSearchQuery:T,filteredSessions:$}=On(s,r),[J,Y]=n.useState(!1),z=l?.chatRooms===!0,[h,p]=n.useState(()=>{try{if(localStorage.getItem(Bt)==="rooms"&&z)return"rooms"}catch{}return"direct"}),o=Bn(s,r),[c,m]=n.useState(()=>{const e=Rs(h,h==="rooms"?o.activeRoom?.id:i?.id);return As(e)}),[y,k]=n.useState(null),[Z,F]=n.useState(null),[G,ke]=n.useState(null),[ue,ve]=n.useState(!0),[ie,Ue]=n.useState(Qn),[Fe,te]=n.useState(!1),[me,wt]=n.useState(new Map),[ne,oe]=n.useState([]),[Oe,ct]=n.useState(!0),[je,Me]=n.useState(!1),[Je,He]=n.useState(""),[ze,Re]=n.useState(0),[xe,ye]=n.useState(""),[fe,f]=n.useState(!1),[v,w]=n.useState(0),[P,se]=n.useState(-1),[H,ae]=n.useState(!1),[U,K]=n.useState([]),[W,V]=n.useState(!1),[O,q]=n.useState(!1),[re,we]=n.useState({}),[lt,Be]=n.useState(!1),{pushNav:Vt}=bn(),[,Ye]=n.useState(!1),[_s,Us]=n.useState({top:0,left:0}),B=vn({projectId:s}),St=n.useCallback(e=>{if(!e||!B.mentionActive)return;const a=e.getBoundingClientRect();Us({top:a.top-260,left:a.left+8})},[B.mentionActive]),qt=n.useRef(null),Xt=n.useRef(null),Ae=n.useRef(!1),Ct=n.useRef(null),Jt=n.useRef(null),Te=n.useRef(null),Ee=n.useRef(null),Se=n.useRef(null),ge=n.useRef(null),ce=n.useRef(null),Yt=n.useRef(null),Qt=n.useRef([]),Qe=n.useRef(0),Ze=n.useRef(new Map),I=xn()==="mobile";n.useEffect(()=>{try{const e=localStorage.getItem(Ms);if(!e)return;const a=Number.parseInt(e,10);if(Number.isNaN(a))return;const d=Math.max(pt,Math.min(bt,a));Ue(d)}catch{}},[]),n.useEffect(()=>{try{const e=localStorage.getItem(Bt);if(e==="direct"){p("direct");return}e==="rooms"&&z&&p("rooms")}catch{}},[z]),n.useEffect(()=>{if(!z&&h==="rooms"){p("direct");return}try{localStorage.setItem(Bt,h)}catch{}},[z,h]);const le=Rs(h,h==="rooms"?o.activeRoom?.id:i?.id),Nt=n.useRef(le);n.useEffect(()=>{le!==Nt.current&&(Nt.current=le,m(As(le)))},[le]),n.useEffect(()=>{if(!(!le||Nt.current!==le))try{if(c){localStorage.setItem(le,c);return}localStorage.removeItem(le)}catch{}},[le,c]);const de=z&&h==="rooms"&&!!o.activeRoom,{keyboardOverlap:dt,viewportHeight:Zt,viewportOffsetTop:es,keyboardOpen:et}=yn({enabled:I&&(!!i||de)}),ts=dt>0||es>0,ss=et&&ts?{"--keyboard-overlap":`${dt}px`,"--vv-offset-top":`${es}px`,...Zt!==null?{"--vv-height":`${Zt}px`}:{}}:{},ns=`chat-thread${et&&ts?" chat-thread--keyboard-active":""}`,pe=n.useMemo(()=>{const e=Je.trim().toLowerCase();return(e?ne.filter(d=>d.name.toLowerCase().includes(e)):ne).slice(0,10)},[ne,Je]),Ge=n.useMemo(()=>Array.from(me.values()),[me]),Ce=n.useMemo(()=>!z||h!=="rooms"||!o.activeRoom?null:{roomId:o.activeRoom.id,roomName:o.activeRoom.name,memberIds:new Set(o.activeRoomMembers.map(e=>e.agentId))},[z,h,o.activeRoom,o.activeRoomMembers]),_e=n.useMemo(()=>{const e=Ge.filter(j=>wn(j.name,xe));if(!Ce)return e;const a=e.filter(j=>Ce.memberIds.has(j.id));if(xe.trim().length===0)return a;const d=e.filter(j=>!Ce.memberIds.has(j.id));return[...a,...d]},[Ge,xe,Ce]),kt=n.useMemo(()=>{const e=new Map;for(const a of Ge)e.set(a.name.toLowerCase(),a);return e},[Ge]);n.useEffect(()=>{Re(0)},[pe]),n.useEffect(()=>{w(0)},[xe,fe]),n.useEffect(()=>()=>{Se.current!==null&&window.clearTimeout(Se.current)},[]);const as=n.useCallback(()=>{const e=ge.current;if(!e)return;const d=e.scrollTop+e.clientHeight>=e.scrollHeight-50;q(!d),Ae.current=!d},[]),he=n.useCallback(e=>{if(!e.isConnected)return;let a=0,d=0,j=-1;const X=6,be=()=>{if(e.isConnected){if(e.scrollTop=e.scrollHeight,e.scrollHeight===j?d+=1:(d=0,j=e.scrollHeight),a+=1,a>=X||d>=2){q(!1),Ae.current=!1;return}window.requestAnimationFrame(be)}};be()},[]),tt=n.useCallback(()=>{const e=ge.current;e&&he(e)},[he]);n.useLayoutEffect(()=>{Ee.current!==null&&(window.clearTimeout(Ee.current),Ee.current=null);const e=de?o.activeRoom?.id??null:i?.id??null;if(!e){Ct.current=null;return}const a={threadId:e,loaded:de?!o.messagesLoading:!R,hasMessages:de?o.messages.length>0:x.length>0},d=Ct.current,j=d?.threadId!==e,X=d?.threadId===e&&!d.loaded&&a.loaded,be=d?.threadId===e&&!d.hasMessages&&a.hasMessages;if(!(d===null||j||X||be))return;const Ne=ge.current;if(Ne)return he(Ne),de||(Ee.current=window.setTimeout(()=>{if(Ee.current=null,Ae.current)return;const We=ge.current;We&&he(We)},250)),Ct.current=a,()=>{Ee.current!==null&&(window.clearTimeout(Ee.current),Ee.current=null)}},[de,o.activeRoom?.id,o.messages.length,o.messagesLoading,i?.id,x.length,R,he]);const Os=de?o.messages:x;n.useEffect(()=>{Ae.current||tt()},[Os,D,C,E,tt]),n.useEffect(()=>{dt<=0||!ge.current||tt()},[dt,tt]),Sn(I&&et),n.useEffect(()=>{const e=()=>k(null);if(y)return document.addEventListener("click",e),()=>document.removeEventListener("click",e)},[y]),n.useEffect(()=>{if(!I||!et)return;const e=a=>{a.target?.closest(".chat-messages")||a.preventDefault()};return document.addEventListener("touchmove",e,{passive:!1}),()=>{document.removeEventListener("touchmove",e)}},[I,et]),n.useEffect(()=>{if(!I||!i)return;const e=()=>{const a=ce.current;a&&document.activeElement===a&&(a.blur(),window.setTimeout(()=>{a.focus({preventScroll:!0})},0))};return document.addEventListener("visibilitychange",e),window.addEventListener("pageshow",e),()=>{document.removeEventListener("visibilitychange",e),window.removeEventListener("pageshow",e)}},[I,i]),n.useEffect(()=>{const e=Jt.current;if(Jt.current=h,h!=="direct"||e!==null&&e!=="rooms")return;const a=ge.current;a&&(he(a),Ae.current=!1,q(!1))},[h,he]),n.useEffect(()=>{if(!i&&!de||de&&!I)return;const e=()=>{const d=ge.current;d&&(he(d),Ae.current=!1,q(!1),Te.current!==null&&(window.clearTimeout(Te.current),Te.current=null),Te.current=window.setTimeout(()=>{if(Te.current=null,Ae.current)return;const j=ge.current;j&&he(j)},250))},a=()=>{document.visibilityState==="visible"&&e()};return document.addEventListener("visibilitychange",a),window.addEventListener("pageshow",e),()=>{document.removeEventListener("visibilitychange",a),window.removeEventListener("pageshow",e),Te.current!==null&&(window.clearTimeout(Te.current),Te.current=null)}},[I,i,de,he]),n.useEffect(()=>{if(de||typeof ResizeObserver>"u")return;const e=ge.current;if(!e)return;const a=new ResizeObserver(()=>{Ae.current||he(e)});return a.observe(e),()=>{a.disconnect()}},[de,he,i?.id,h]),n.useEffect(()=>{let e=!1;const a=s;return yt(void 0,s).then(d=>{if(e||a!==s)return;const j=new Map;for(const X of d)j.set(X.id,X);wt(j)}).catch(()=>{}),()=>{e=!0}},[s]),n.useEffect(()=>{let e=!1;return ct(!0),Cn(s).then(a=>{e||oe(a)}).catch(()=>{e||oe([])}).finally(()=>{e||ct(!1)}),()=>{e=!0}},[s]),n.useEffect(()=>{Qt.current=U},[U]),n.useEffect(()=>()=>{for(const e of Qt.current)e.previewUrl&&URL.revokeObjectURL(e.previewUrl);for(const e of Ze.current.values())window.clearTimeout(e);Ze.current.clear()},[]);const ut=n.useCallback(e=>{if(!e||e.length===0)return;const a=[];for(const d of Array.from(e)){if(!ea.includes(d.type))continue;const j=d.type.startsWith("image/");a.push({file:d,previewUrl:j?URL.createObjectURL(d):""})}a.length>0&&K(d=>[...d,...a])},[]),Hs=n.useCallback(e=>{K(a=>{const d=a[e];return d?.previewUrl&&URL.revokeObjectURL(d.previewUrl),a.filter((j,X)=>X!==e)})},[]),Bs=n.useCallback(e=>{const a=e.clipboardData?.files;if(!a||a.length===0)return;const d=Array.from(a).filter(j=>j.type.startsWith("image/"));d.length!==0&&ut(d)},[ut]),Gs=n.useCallback(async e=>{try{await L(e),Y(!1),I&&ve(!1)}catch{r("Failed to create chat session","error")}},[L,r,I]),De=n.useCallback(e=>{const a=e??ce.current;a&&(a.style.height="auto",a.style.height=`${Vn(a.scrollHeight)}px`)},[]);n.useLayoutEffect(()=>{De()},[c,De]);const st=n.useCallback(()=>{if(m(""),le)try{localStorage.removeItem(le)}catch{}Me(!1),He(""),f(!1),ye(""),se(-1),K(e=>{for(const a of e)a.previewUrl&&URL.revokeObjectURL(a.previewUrl);return[]})},[le]),jt=n.useCallback(()=>{const e=c.trim(),a=U.map(d=>d.file);if(!(!e&&a.length===0||!i)){if(e==="/clear"||e==="/new"){st(),_(),M(),L({agentId:i.agentId,modelProvider:i.modelProvider??void 0,modelId:i.modelId??void 0}).catch(()=>{r("Failed to clear conversation","error")});return}st(),N(e,a)}},[c,U,i,st,_,M,L,r,N]),Mt=n.useCallback(async()=>{const e=c.trim();if(e){if(z&&h==="rooms"){if(!o.activeRoom)return;const a=c;st();try{await o.sendRoomMessage(e)}catch(d){m(a);const j=d instanceof Error&&d.message.trim()?d.message:"Failed to send room message";r(j,"error")}return}jt()}},[c,z,h,o,st,r,jt]),Rt=n.useCallback(e=>{m(a=>{const d=Ts(a);if(!d)return a;const j=`/skill:${e.name} `,X=a.slice(0,d.start)+j+a.slice(d.end);return window.requestAnimationFrame(()=>{ce.current&&(De(ce.current),ce.current.focus())}),X}),Me(!1),He(""),Re(0)},[De]),mt=n.useCallback(e=>{const a=ce.current;if(!a||P<0)return;const d=a.selectionStart??Qe.current,j=a.selectionEnd??d,X=Math.max(d,j),be=Math.min(P,X),Ne=`${`@${e.name.replace(/\s+/g,"_")}`} `,We=c.slice(0,be)+Ne+c.slice(X),Ve=be+Ne.length;m(We),f(!1),ye(""),w(0),se(-1),window.requestAnimationFrame(()=>{ce.current&&(De(ce.current),ce.current.focus(),ce.current.setSelectionRange(Ve,Ve))})},[P,c,De]),rs=n.useCallback(e=>{if(Qe.current=e.currentTarget.selectionStart??Qe.current,B.mentionActive&&B.files.length>0){if(B.handleKeyDown(e,c),e.key==="Enter"||e.key==="Tab"){const a=B.files[B.selectedIndex];if(a){const d=B.selectFile(a,c);m(d),B.dismissMention(),Ye(!1)}}return}if(fe&&e.key==="ArrowDown"){e.preventDefault(),_e.length>0&&w(a=>(a+1)%_e.length);return}if(fe&&e.key==="ArrowUp"){e.preventDefault(),_e.length>0&&w(a=>a===0?_e.length-1:a-1);return}if(fe&&e.key==="Enter"){e.preventDefault();const a=_e[v]??_e[0];a&&mt(a);return}if(fe&&e.key==="Escape"){e.preventDefault(),f(!1),ye(""),se(-1);return}if(je&&e.key==="ArrowDown"){e.preventDefault(),pe.length>0&&Re(a=>(a+1)%pe.length);return}if(je&&e.key==="ArrowUp"){e.preventDefault(),pe.length>0&&Re(a=>a===0?pe.length-1:a-1);return}if(je&&(e.key==="Enter"||e.key==="Tab")&&pe.length>0){e.preventDefault();const a=pe[ze]??pe[0];a&&Rt(a);return}if(je&&e.key==="Escape"){e.preventDefault(),Me(!1);return}e.key==="Enter"&&!e.shiftKey&&(e.preventDefault(),Mt())},[fe,_e,v,mt,je,pe,ze,Rt,Mt,B,c]),ht=n.useCallback((e,a)=>{const d=ta(e,a);if(d){f(!0),ye(d.filter),se(d.start);return}f(!1),ye(""),se(-1)},[]),is=n.useCallback(e=>{const a=e.target,d=a.value,j=a.selectionStart??d.length;Qe.current=j,m(d);const X=Ts(d);X?(Me(!0),He(X.filter)):(Me(!1),He("")),ht(d,j),B.detectMention(d,j),Ye(B.mentionActive),B.mentionActive&&St(a),De(a)},[ht,De]),ft=n.useCallback(e=>{const a=e.currentTarget,d=a.selectionStart??a.value.length;Qe.current=d,ht(a.value,d),B.detectMention(a.value,d),Ye(B.mentionActive),B.mentionActive&&St(a)},[ht,B,St]),os=n.useCallback(e=>{e.key!=="Escape"&&ft(e)},[ft]),cs=n.useCallback(()=>{Se.current!==null&&window.clearTimeout(Se.current),Se.current=window.setTimeout(()=>{Me(!1),f(!1),ye(""),se(-1),Ye(!1),B.dismissMention(),Se.current=null},120)},[B]),ls=n.useCallback(()=>{Se.current!==null&&(window.clearTimeout(Se.current),Se.current=null),typeof window<"u"&&window.innerWidth<=768&&window.setTimeout(()=>{(window.scrollY!==0||window.scrollX!==0)&&window.scrollTo(0,0)},0)},[]),Ks=n.useCallback(async e=>{k(null);try{await g(e),r("Conversation archived","success")}catch{r("Failed to archive conversation","error")}},[g,r]),Ws=n.useCallback(async e=>{F(null),k(null);try{await ee(e),r("Conversation deleted","success")}catch{r("Failed to delete conversation","error")}},[ee,r]),nt=n.useCallback(e=>{try{localStorage.setItem(Ms,String(e))}catch{}},[]),Vs=n.useCallback(e=>{if(I)return;e.preventDefault(),e.stopPropagation();const a=e.currentTarget;typeof a.setPointerCapture=="function"&&a.setPointerCapture(e.pointerId);const d=e.clientX,j=ie;let X=j;document.body.style.userSelect="none";const be=Ne=>{const We=Ne.clientX-d,Ve=Math.max(pt,Math.min(bt,j+We));X=Ve,Ue(Ve),nt(Ve)},Ke=Ne=>{typeof a.releasePointerCapture=="function"&&a.releasePointerCapture(Ne.pointerId),document.body.style.userSelect="",document.removeEventListener("pointermove",be),document.removeEventListener("pointerup",Ke),nt(X)};document.addEventListener("pointermove",be),document.addEventListener("pointerup",Ke)},[I,nt,ie]),qs=n.useCallback(e=>{if(I||e.key!=="ArrowLeft"&&e.key!=="ArrowRight")return;e.preventDefault();const a=e.shiftKey?50:10,d=e.key==="ArrowLeft"?-a:a,j=Math.max(pt,Math.min(bt,ie+d));Ue(j),nt(j)},[I,nt,ie]),ds=n.useCallback(e=>{S(e),Be(!1),I&&ve(!1)},[S,I]),At=n.useCallback(()=>{S(""),ve(!0),Be(!1)},[S]),Tt=n.useCallback(()=>{o.selectRoom(null),ve(!0),Be(!1)},[o]),Xs=()=>t.jsxs("div",{className:"chat-empty-state",children:[t.jsx(Pn,{size:48,strokeWidth:1.5}),t.jsx("h2",{children:"Start a new conversation"}),t.jsxs("button",{className:"btn btn-primary",onClick:()=>Y(!0),children:[t.jsx(at,{size:16}),"New Chat"]})]}),$e=js(i?.modelProvider,i?.modelId),Ie=i?.modelProvider??null,Et=!!(i||E||x.length>0),gt=h==="rooms"?de:!!i,us=n.useRef(gt);n.useEffect(()=>{const e=us.current;us.current=gt,I&&(e||!gt||Vt({type:"view",revert:h==="rooms"?Tt:At}))},[h,At,Tt,gt,I,Vt]);const Dt=i?.agentId===Xe?$e??"Fusion":i?.title||me.get(i?.agentId??"")?.name||i?.agentId||"Chat",ms=!!($e&&$e!==Dt),Js=I&&h==="direct"&&!!i,$t=me.get(i?.agentId??"")?.name||(i?.agentId===Xe?$e??"Fusion":i?.agentId?.slice(0,30)??"Fusion"),It=!1,Pt=i?.agentId===Xe,Ys=b.length>50?`${b.slice(0,50)}…`:b,Qs=n.useCallback(()=>{ae(e=>!e)},[]);n.useEffect(()=>{if(!lt)return;const e=a=>{Xt.current?.contains(a.target)||Be(!1)};return document.addEventListener("mousedown",e),()=>{document.removeEventListener("mousedown",e)}},[lt]),n.useEffect(()=>{(!I||h!=="direct"||ue)&&Be(!1)},[I,h,ue]);const Lt=n.useCallback((e,a)=>{const d=Ze.current.get(e);d&&window.clearTimeout(d),we(X=>({...X,[e]:a}));const j=window.setTimeout(()=>{we(X=>{const{[e]:be,...Ke}=X;return Ke}),Ze.current.delete(e)},2e3);Ze.current.set(e,j)},[]),hs=n.useCallback(async(e,a)=>{try{if(!navigator.clipboard?.writeText)throw new Error("Clipboard API unavailable");await navigator.clipboard.writeText(a),Lt(e,"success")}catch{Lt(e,"error")}},[Lt]),Zs=n.useCallback((e,a=!1)=>a?t.jsx("div",{className:"chat-message-content chat-message-content--plain",children:e}):t.jsx("div",{className:"chat-message-content chat-message-content--markdown",children:t.jsx(Is,{remarkPlugins:[Ps],components:zs,children:e})}),[]),Ft=i?.agentId===Xe,zt=n.useCallback((e,a,d)=>t.jsx("button",{type:"button",className:`btn-icon chat-message-copy-action${re[e]==="success"?" chat-message-copy-action--success":""}${re[e]==="error"?" chat-message-copy-action--error":""}`,"data-testid":d??`chat-copy-response-${e}`,"aria-label":re[e]==="success"?"Response copied":re[e]==="error"?"Copy failed":"Copy response",onClick:()=>{hs(e,a)},children:re[e]==="success"?t.jsx(Nn,{size:14}):t.jsx(kn,{size:14})}),[re,hs]);return t.jsxs("div",{className:"chat-view",children:[t.jsxs("div",{className:`chat-sidebar${ue?"":" chat-sidebar--hidden"}`,style:I?void 0:{width:`${ie}px`},children:[z&&t.jsxs("div",{className:"chat-sidebar-scope-toggle",role:"tablist","data-testid":"chat-sidebar-scope-toggle",children:[t.jsx("button",{type:"button",role:"tab",className:`chat-sidebar-scope-btn${h==="direct"?" chat-sidebar-scope-btn--active":""}`,"aria-selected":h==="direct","data-testid":"chat-sidebar-scope-direct",onClick:()=>p("direct"),children:"Direct"}),t.jsx("button",{type:"button",role:"tab",className:`chat-sidebar-scope-btn${h==="rooms"?" chat-sidebar-scope-btn--active":""}`,"aria-selected":h==="rooms","data-testid":"chat-sidebar-scope-rooms",onClick:()=>p("rooms"),children:"Rooms"})]}),!z||h==="direct"?t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"chat-sidebar-search-container",children:t.jsxs("div",{className:"chat-sidebar-search-wrapper",children:[t.jsx(jn,{size:14,className:"chat-sidebar-search-icon"}),t.jsx("input",{type:"text",className:"chat-sidebar-search",placeholder:"Search conversations...",value:A,onChange:e=>T(e.target.value),"data-testid":"chat-search-input"})]})}),t.jsx("div",{className:"chat-session-list chat-sidebar-list",children:u?t.jsx("div",{className:"chat-empty-state chat-empty-state--padded",children:"Loading..."}):$.length===0?t.jsx("div",{className:"chat-empty-state chat-empty-state--padded",children:"No conversations yet"}):$.map(e=>t.jsxs("div",{className:`chat-session-item${i?.id===e.id?" chat-session-item--active":""}`,onClick:()=>ds(e.id),onContextMenu:a=>{a.preventDefault(),k({sessionId:e.id,x:a.clientX,y:a.clientY})},"data-testid":`chat-session-${e.id}`,children:[t.jsx("button",{className:"chat-session-delete-btn",onClick:a=>{a.stopPropagation(),F(e.id)},"data-testid":"chat-session-delete-btn","aria-label":"Delete conversation",children:t.jsx(Ut,{size:14})}),t.jsx("div",{className:"chat-session-title",children:e.title||"Untitled"}),t.jsx("div",{className:"chat-session-preview",children:e.lastMessagePreview||"No messages"}),t.jsxs("div",{className:"chat-session-meta",children:[t.jsxs("span",{className:"chat-session-meta-model",children:[e.modelProvider&&t.jsx(it,{provider:e.modelProvider,size:"sm"}),t.jsx("span",{children:me.get(e.agentId)?.name||(e.agentId===Xe?js(e.modelProvider,e.modelId)??"Fusion":e.agentId.slice(0,30))})]}),t.jsx("span",{children:e.updatedAt?Ls(e.updatedAt):""})]})]},e.id))})]}):t.jsxs("div",{className:"chat-sidebar-rooms","data-testid":"chat-sidebar-rooms",children:[!I&&t.jsx("div",{className:"chat-sidebar-rooms-header","data-testid":"chat-sidebar-rooms-header",children:t.jsxs("button",{type:"button",className:"btn btn-sm btn-primary","data-testid":"chat-create-room-btn",onClick:()=>te(!0),children:[t.jsx(at,{size:14}),"Create room"]})}),o.rooms.length===0?t.jsx("div",{className:"chat-sidebar-rooms-empty","data-testid":"chat-sidebar-rooms-empty",children:"No rooms yet."}):t.jsx("div",{className:"chat-session-list chat-sidebar-list",children:o.rooms.map(e=>{const a=o.activeRoom?.id===e.id;return t.jsxs("div",{role:"button",tabIndex:0,className:`chat-room-item${a?" chat-room-item--active":""}`,"data-testid":`chat-room-item-${e.slug}`,onClick:()=>{o.selectRoom(e.id),I&&ve(!1)},onKeyDown:d=>{(d.key==="Enter"||d.key===" ")&&(d.preventDefault(),o.selectRoom(e.id),I&&ve(!1))},children:[t.jsxs("span",{className:"chat-room-item-details",children:[t.jsxs("span",{className:"chat-room-item-name",children:["#",e.name]}),a?t.jsxs("span",{className:"chat-room-item-meta",children:[o.activeRoomMembers.length," ",o.activeRoomMembers.length===1?"member":"members"]}):null]}),t.jsx("button",{type:"button",className:"btn-icon chat-room-item-delete","data-testid":`chat-room-delete-${e.slug}`,"aria-label":`Delete room ${e.name}`,onClick:d=>{d.stopPropagation(),ke(e.id)},children:t.jsx(Ut,{size:14})})]},e.id)})})]}),h==="rooms"?I?t.jsx("div",{className:"chat-sidebar-footer",children:t.jsxs("button",{type:"button",className:"btn btn-sm btn-primary chat-sidebar-footer-btn","data-testid":"chat-create-room-btn",onClick:()=>te(!0),children:[t.jsx(at,{size:14}),"Create room"]})}):null:t.jsx("div",{className:"chat-sidebar-footer",children:t.jsxs("button",{className:"btn btn-sm btn-primary chat-sidebar-footer-btn",onClick:()=>Y(!0),"data-testid":"chat-new-btn",children:[t.jsx(at,{size:14}),"New Chat"]})})]}),!I&&ue&&t.jsx("div",{className:"chat-sidebar-resize-handle",role:"separator","aria-orientation":"vertical","aria-valuemin":pt,"aria-valuemax":bt,"aria-valuenow":ie,"aria-label":"Resize chat sidebar",tabIndex:0,onPointerDown:Vs,onKeyDown:qs}),y&&t.jsxs("div",{className:"chat-session-context-menu",style:{top:y.y,left:y.x},onClick:e=>e.stopPropagation(),children:[t.jsxs("button",{onClick:()=>Ks(y.sessionId),"data-testid":"chat-context-archive",children:[t.jsx(Mn,{size:14}),"Archive"]}),t.jsxs("button",{onClick:()=>{k(null),F(y.sessionId)},"data-testid":"chat-context-delete",children:[t.jsx(Ut,{size:14}),"Delete"]})]}),Z&&t.jsx("div",{className:"chat-new-dialog-backdrop chat-view-dialog-backdrop",onClick:()=>F(null),children:t.jsxs("div",{className:"chat-new-dialog chat-view-dialog",onClick:e=>e.stopPropagation(),children:[t.jsx("h3",{children:"Delete Conversation?"}),t.jsx("p",{className:"chat-view-delete-dialog-copy",children:"This action cannot be undone. All messages in this conversation will be permanently deleted."}),t.jsxs("div",{className:"chat-new-dialog-actions",children:[t.jsx("button",{className:"btn btn-sm",onClick:()=>F(null),children:"Cancel"}),t.jsx("button",{className:"btn btn-sm btn-danger",onClick:()=>void Ws(Z),children:"Delete"})]})]})}),z&&G&&t.jsx("div",{className:"chat-new-dialog-backdrop chat-view-dialog-backdrop",onClick:()=>ke(null),children:t.jsxs("div",{className:"chat-new-dialog chat-view-dialog",onClick:e=>e.stopPropagation(),children:[t.jsx("h3",{children:"Delete Room?"}),t.jsx("p",{className:"chat-view-delete-dialog-copy",children:"This action cannot be undone. This room and all its messages will be permanently deleted."}),t.jsxs("div",{className:"chat-new-dialog-actions",children:[t.jsx("button",{className:"btn btn-sm",onClick:()=>ke(null),children:"Cancel"}),t.jsx("button",{className:"btn btn-sm btn-danger",onClick:()=>{(async()=>{try{await o.deleteRoom(G),ke(null)}catch{r("Failed to delete room","error")}})()},children:"Delete"})]})]})}),z&&h==="rooms"?t.jsxs("div",{className:ns,style:ss,children:[o.activeRoom?t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"chat-room-thread-header",children:[I&&t.jsx("button",{className:"btn-icon",onClick:Tt,"data-testid":"chat-back-btn",children:t.jsx(bs,{size:16})}),t.jsxs("div",{className:"chat-thread-header-title",children:["#",o.activeRoom.name]}),t.jsx("div",{className:"chat-room-thread-members",children:o.activeRoomMembers.map(e=>t.jsx($s,{agent:me.get(e.agentId)??{id:e.agentId,name:e.agentId.slice(0,30)}},e.agentId))})]}),t.jsxs("div",{className:"chat-messages",ref:ge,onScroll:as,children:[o.messagesLoading?t.jsx("div",{className:"chat-empty-state",children:"Loading messages..."}):o.messages.length===0?t.jsx("div",{className:"chat-empty-state",children:"No messages yet. Start the conversation!"}):o.messages.map(e=>{const a=e.senderAgentId?me.get(e.senderAgentId)?.name??e.senderAgentId.slice(0,30):"You",d={id:e.id,sessionId:e.roomId,role:e.role,content:e.content,thinkingOutput:e.thinkingOutput??void 0,toolCalls:void 0,fallbackInfo:void 0,attachments:e.attachments,createdAt:e.createdAt};return t.jsx(Gt,{message:d,forcePlain:H,agentName:a,hideAssistantIdentity:!1,showAssistantModelTag:!1,activeModelTag:null,activeModelProvider:null,activeSessionId:o.activeRoom?.id??null,mentionAgentsByName:kt,roomContext:Ce},e.id)}),t.jsx("div",{ref:qt})]})]}):t.jsx("div",{className:"chat-room-empty-pane","data-testid":"chat-rooms-empty-pane",children:"Select a room or create one"}),o.activeRoom&&t.jsx("div",{className:"chat-input-area",children:t.jsxs("div",{className:"chat-input-row",children:[t.jsxs("div",{className:"chat-input-wrapper",children:[t.jsx("textarea",{ref:ce,className:"chat-input-textarea",placeholder:"Type a message...",value:c,onChange:is,onKeyDown:rs,onKeyUp:os,onClick:ft,onBlur:cs,onFocus:ls,onTouchStart:e=>{typeof window>"u"||window.innerWidth>768||document.activeElement!==e.currentTarget&&(e.preventDefault(),e.currentTarget.focus({preventScroll:!0}))},rows:1,"data-testid":"chat-input"}),t.jsx(vs,{agents:Ge,filter:xe,highlightedIndex:v,visible:fe,onSelect:mt,position:"below",roomMemberIds:Ce?.memberIds,roomName:Ce?.roomName})]}),t.jsx("button",{type:"button",className:"chat-input-send",onPointerDown:e=>{e.pointerType&&e.pointerType!=="mouse"&&e.preventDefault()},onMouseDown:e=>{e.preventDefault()},onClick:()=>{Mt()},disabled:!c.trim(),"data-testid":"chat-send-btn",style:{touchAction:"manipulation"},children:t.jsx(xs,{size:16})})]})})]}):t.jsxs("div",{className:ns,style:ss,children:[(Et||!I)&&t.jsxs("div",{className:"chat-thread-header",children:[I&&Et&&t.jsx("button",{className:"btn-icon",onClick:At,"data-testid":"chat-back-btn",children:t.jsx(bs,{size:16})}),t.jsx("div",{className:"chat-thread-header-identity","data-testid":"chat-thread-header-identity",children:Js?t.jsxs("div",{className:"chat-mobile-session-menu",ref:Xt,children:[t.jsxs("button",{type:"button",className:"btn chat-mobile-session-trigger","data-testid":"chat-mobile-session-trigger","aria-haspopup":"menu","aria-expanded":lt,onClick:()=>Be(e=>!e),children:[Ie?t.jsx(it,{provider:Ie,size:"md"}):t.jsx(ot,{size:16}),t.jsx("span",{className:"chat-thread-header-title",children:Dt}),ms&&t.jsx("span",{className:"chat-model-tag",children:$e}),t.jsx(ys,{size:16,"aria-hidden":"true"})]}),lt&&t.jsx("div",{className:"chat-mobile-session-dropdown",role:"menu","data-testid":"chat-mobile-session-dropdown",children:$.map(e=>t.jsx("button",{type:"button",role:"menuitem",className:`chat-mobile-session-option${i?.id===e.id?" chat-mobile-session-option--active":""}`,"data-testid":`chat-mobile-session-option-${e.id}`,onClick:()=>ds(e.id),children:t.jsx("span",{className:"chat-mobile-session-option-title",children:e.title||"Untitled"})},e.id))})]}):t.jsxs(t.Fragment,{children:[Ie?t.jsx(it,{provider:Ie,size:"md"}):t.jsx(ot,{size:16}),t.jsx("span",{className:"chat-thread-header-title",children:Dt}),ms&&t.jsx("span",{className:"chat-model-tag",children:$e})]})}),Et&&t.jsx("button",{type:"button",className:`chat-thread-header-render-toggle${H?" chat-thread-header-render-toggle--plain":""}`,"data-testid":"chat-thread-render-toggle","aria-label":H?"Show all messages as rendered Markdown":"Show all messages as plain text",onClick:Qs,children:H?t.jsx(Rn,{size:14}):t.jsx(An,{size:14})}),!I&&t.jsxs("button",{className:"btn btn-sm btn-primary chat-thread-header-new-chat",onClick:()=>Y(!0),"data-testid":"chat-thread-new-chat-btn",children:[t.jsx(at,{size:14}),"New Chat"]})]}),t.jsxs("div",{className:"chat-messages",ref:ge,onScroll:as,children:[E?t.jsxs(t.Fragment,{children:[x.map(e=>t.jsx(Gt,{message:e,forcePlain:H,agentName:$t,hideAssistantIdentity:Pt,showAssistantModelTag:It,activeModelTag:$e,activeModelProvider:Ie,activeSessionId:i?.id??null,mentionAgentsByName:kt,roomContext:null,copyAction:Ft&&e.role==="assistant"?zt(e.id,e.content):void 0},e.id)),t.jsxs("div",{className:"chat-message chat-message--assistant chat-message--streaming",children:[!Pt&&t.jsxs("div",{className:"chat-message-avatar",children:[Ie?t.jsx(it,{provider:Ie,size:"sm"}):t.jsx(ot,{size:14}),t.jsx("span",{children:$t}),It]}),D?Zs(D,H):t.jsx("div",{className:"chat-message-content chat-message-content--waiting",children:C?"Thinking…":"Connecting…"}),Ft&&D&&zt("__streaming__",D,"chat-copy-response-streaming"),Fs(Q),C&&t.jsxs("details",{className:"chat-message-thinking",children:[t.jsx("summary",{children:"Thinking"}),t.jsx("pre",{className:"chat-message-thinking-content",children:xt(C)})]}),t.jsxs("div",{className:"chat-typing-indicator",children:[t.jsx("span",{}),t.jsx("span",{}),t.jsx("span",{})]})]})]}):R?t.jsx("div",{className:"chat-empty-state",children:"Loading messages..."}):x.length===0&&!i?Xs():x.length===0&&i?t.jsx("div",{className:"chat-empty-state",children:"No messages yet. Start the conversation!"}):t.jsx(t.Fragment,{children:x.map(e=>t.jsx(Gt,{message:e,forcePlain:H,agentName:$t,hideAssistantIdentity:Pt,showAssistantModelTag:It,activeModelTag:$e,activeModelProvider:Ie,activeSessionId:i?.id??null,mentionAgentsByName:kt,roomContext:null,copyAction:Ft&&e.role==="assistant"?zt(e.id,e.content):void 0},e.id))}),t.jsx("div",{ref:qt})]}),O&&t.jsxs("button",{type:"button",className:"btn btn-sm chat-jump-to-latest","data-testid":"chat-jump-to-latest",onClick:tt,children:[t.jsx(ys,{size:14}),"Latest"]}),i&&t.jsxs("div",{className:"chat-input-area",children:[t.jsx("input",{ref:Yt,type:"file",accept:"image/*,.txt,.json,.yaml,.yml,.log,.csv,.xml,.md",multiple:!0,style:{display:"none"},onChange:e=>{ut(e.target.files),e.target.value=""}}),je&&t.jsx("div",{className:"chat-skill-menu","data-testid":"chat-skill-menu",role:"listbox","aria-label":"Skill suggestions",children:Oe?t.jsx("div",{className:"chat-skill-menu-empty",children:"Loading skills…"}):pe.length===0?t.jsx("div",{className:"chat-skill-menu-empty",children:Je?"No skills found":"No skills available"}):pe.map((e,a)=>t.jsxs("button",{type:"button",role:"option","aria-selected":a===ze,className:`chat-skill-menu-item${a===ze?" chat-skill-menu-item--highlighted":""}`,onMouseDown:d=>d.preventDefault(),onMouseEnter:()=>Re(a),onClick:()=>Rt(e),children:[t.jsx("span",{className:"chat-skill-menu-item-name",children:e.name}),t.jsx("span",{className:"chat-skill-menu-item-description",title:e.relativePath,children:e.relativePath})]},e.id))}),U.length>0&&t.jsx("div",{className:"chat-attachment-previews","data-testid":"chat-attachment-previews",children:U.map((e,a)=>t.jsxs("div",{className:"chat-attachment-preview","data-testid":`chat-attachment-preview-${a}`,children:[e.previewUrl?t.jsx("img",{src:e.previewUrl,alt:e.file.name}):t.jsx("span",{className:"chat-attachment-preview-name",children:e.file.name}),t.jsx("button",{type:"button",className:"chat-attachment-remove",onClick:()=>Hs(a),"data-testid":`chat-attachment-remove-${a}`,"aria-label":`Remove ${e.file.name}`,children:"×"})]},e.previewUrl||`${e.file.name}-${a}`))}),t.jsxs("div",{className:"chat-input-row",children:[t.jsx("button",{type:"button",className:"btn-icon chat-attach-btn","data-testid":"chat-attach-btn","aria-label":"Attach files",onClick:()=>Yt.current?.click(),children:t.jsx(Tn,{size:16})}),t.jsxs("div",{className:`chat-input-wrapper${W?" chat-input-wrapper--dragover":""}`,onDragOver:e=>{e.preventDefault(),V(!0)},onDragLeave:()=>V(!1),onDrop:e=>{e.preventDefault(),V(!1),ut(e.dataTransfer.files)},children:[t.jsx("textarea",{ref:ce,className:"chat-input-textarea",placeholder:"Type a message...",value:c,onChange:is,onKeyDown:rs,onKeyUp:os,onClick:ft,onBlur:cs,onFocus:ls,onPaste:Bs,onTouchStart:e=>{typeof window>"u"||window.innerWidth>768||document.activeElement!==e.currentTarget&&(e.preventDefault(),e.currentTarget.focus({preventScroll:!0}))},rows:1,"data-testid":"chat-input"}),t.jsx(vs,{agents:Ge,filter:xe,highlightedIndex:v,visible:fe,onSelect:mt,position:"below",roomMemberIds:Ce?.memberIds,roomName:Ce?.roomName}),t.jsx(En,{visible:B.mentionActive&&!fe,position:_s,files:B.files,selectedIndex:B.selectedIndex,onSelect:e=>{const a=B.selectFile(e,c);m(a),B.dismissMention(),Ye(!1),ce.current?.focus()},loading:B.loading}),b&&t.jsxs("div",{className:"chat-pending-message","data-testid":"chat-pending-indicator",children:[t.jsx("span",{children:`Queued: ${Ys}`}),t.jsx("button",{type:"button",className:"chat-pending-message-dismiss","aria-label":"Dismiss queued message","data-testid":"chat-pending-dismiss",onClick:M,children:"×"})]})]}),E?t.jsx("button",{className:"chat-input-stop",onClick:_,"aria-label":"Stop generation","data-testid":"chat-stop-btn",children:t.jsx(Dn,{size:14})}):t.jsx("button",{type:"button",className:"chat-input-send",onPointerDown:e=>{e.pointerType&&e.pointerType!=="mouse"&&e.preventDefault()},onMouseDown:e=>{e.preventDefault()},onClick:()=>{jt()},disabled:!c.trim()&&U.length===0,"data-testid":"chat-send-btn",style:{touchAction:"manipulation"},children:t.jsx(xs,{size:16})})]})]})]}),z&&t.jsx(Kn,{isOpen:Fe,onClose:()=>te(!1),projectId:s,existingRoomNames:o.rooms.map(e=>e.name),onCreate:async e=>{await o.createRoom({name:e.name,memberAgentIds:e.memberAgentIds}),h!=="rooms"&&p("rooms"),te(!1),I&&ve(!1)}}),J&&t.jsx(sa,{projectId:s,onClose:()=>Y(!1),onCreate:Gs})]})}export{ca as ChatView,Vn as clampChatInputHeight};
@@ -1 +0,0 @@
1
- import{r as s,j as e}from"./vendor-react-K0fH_qHe.js";import{a6 as oe,a7 as K,f as le,a8 as ie,F as z,a9 as de,aa as ue,S as me,X as he,R as pe,ab as fe,ac as W,ad as V,a as X,b as je,ae as xe}from"./index-DTFPgu6_.js";import"./vendor-xterm-DzcZoU0P.js";import"./vendor-codemirror-jBKmHyH0.js";function we(n){const{projectId:c,searchQuery:u,includeProjectFiles:a=!0}=n??{},[x,l]=s.useState([]),[h,i]=s.useState([]),[o,p]=s.useState(!0),[k,b]=s.useState(null),f=s.useRef(null),g=s.useRef(!1),m=s.useRef(null),j=s.useCallback(async()=>{f.current&&f.current.abort();const C=new AbortController;f.current=C;const E=!g.current;E&&p(!0),b(null);const L=oe(u?{q:u}:void 0,c),y=a?K(c):Promise.resolve({files:[]}),[v,F]=await Promise.allSettled([L,y]);if(C.signal.aborted)return;let R=null;if(v.status==="fulfilled"?(l(v.value),g.current=!0):R=v.reason instanceof Error?v.reason.message:String(v.reason),F.status==="fulfilled"){const M=F.value.files,P=u?.trim().toLowerCase(),T=P?M.filter(N=>N.name.toLowerCase().includes(P)||N.path.toLowerCase().includes(P)):M;i(T)}b(R),E&&p(!1)},[a,c,u]);return s.useEffect(()=>(m.current&&clearTimeout(m.current),m.current=setTimeout(()=>{j()},300),()=>{m.current&&clearTimeout(m.current)}),[j]),s.useEffect(()=>(j(),()=>{f.current&&f.current.abort()}),[]),{documents:x,projectFiles:h,loading:o,error:k,refresh:j}}function ke(n,c){const[u,a]=s.useState([]),[x,l]=s.useState(!0),[h,i]=s.useState(null),o=s.useRef(null),p=s.useRef(!1),k=c?.showHidden??!1,b=s.useCallback(async f=>{o.current&&o.current.abort();const g=new AbortController;o.current=g;const m=!p.current;m&&l(!0),i(null);try{const j=await K(n,{showHidden:f?.showHidden??k});if(g.signal.aborted)return;a(j.files),p.current=!0}catch(j){if(g.signal.aborted)return;i(j instanceof Error?j.message:String(j))}finally{!g.signal.aborted&&m&&l(!1)}},[n,k]);return s.useEffect(()=>(p.current=!1,b({showHidden:k}),()=>{o.current&&o.current.abort()}),[b,k]),{files:u,loading:x,error:h,refresh:b}}const be=768;function _(n){return n?new Date(n).toLocaleString():""}function ge(n){return n<1024?`${n} B`:n<1024*1024?`${(n/1024).toFixed(n>=10*1024?0:1)} KB`:`${(n/(1024*1024)).toFixed(1)} MB`}function ve(n,c=200){return n.length<=c?n:`${n.substring(0,c)}…`}function Ne({document:n,renderMarkdown:c,onToggleMarkdown:u}){const[a,x]=s.useState(!1),l=ve(n.content),h=n.content.length>200;return e.jsxs("div",{className:"document-card",children:[e.jsxs("div",{className:"document-card-header",children:[e.jsxs("div",{className:"document-card-key",children:[e.jsx(z,{size:14}),e.jsx("span",{className:"document-card-key-text",children:n.key}),e.jsxs("span",{className:"document-card-revision-badge",children:["v",n.revision]})]}),e.jsx("div",{className:"document-card-actions",children:e.jsx("button",{className:"btn btn-sm document-card-expand-btn",onClick:()=>x(i=>!i),title:a?"Collapse":"Expand","aria-label":a?"Collapse content":"Expand content",children:a?e.jsx(xe,{size:14}):e.jsx(X,{size:14})})})]}),e.jsxs("div",{className:"document-card-meta",children:[e.jsx("span",{className:"document-card-author",children:n.author}),e.jsx("span",{className:"document-card-separator",children:"·"}),e.jsx("span",{className:"document-card-date",children:_(n.updatedAt)})]}),e.jsxs("div",{className:`document-card-content${a?" document-card-content--expanded":""}`,children:[a?e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"document-card-content-header",children:e.jsx("button",{className:"btn btn-sm document-mode-toggle",onClick:u,"aria-label":c?"Switch to plain text":"Switch to markdown","aria-pressed":c,title:c?"Switch to plain text":"Switch to markdown",children:c?"Markdown":"Plain"})}),c?e.jsx("div",{className:"document-card-content-markdown",children:e.jsx("div",{className:"markdown-body",children:e.jsx(W,{remarkPlugins:[V],children:n.content})})}):e.jsx("pre",{className:"document-card-content-text",children:n.content})]}):e.jsx("p",{className:"document-card-preview",children:l}),h&&!a&&e.jsx("p",{className:"document-card-preview-truncated",children:"…"})]})]})}function Se({taskId:n,taskTitle:c,documents:u,onOpenTask:a,renderMarkdownStates:x,onToggleMarkdown:l}){const[h,i]=s.useState(!1);return e.jsxs("div",{className:"documents-group",children:[e.jsxs("div",{className:"documents-group-header",children:[e.jsxs("button",{className:"documents-group-toggle-btn",onClick:()=>i(o=>!o),"aria-expanded":h,"aria-label":`${h?"Collapse":"Expand"} documents for task ${n}`,children:[e.jsx("span",{className:"documents-group-toggle","aria-hidden":"true",children:h?e.jsx(X,{size:16}):e.jsx(je,{size:16})}),e.jsx("span",{className:"documents-group-task-id",children:n}),e.jsx("span",{className:"documents-group-task-title",children:c||"Untitled"})]}),e.jsxs("span",{className:"documents-group-count",children:[u.length," doc",u.length!==1?"s":""]}),e.jsx("button",{className:"documents-group-task-link",onClick:()=>a(n),"aria-label":`Open task ${n}: ${c||"Untitled"}`,children:"Open task"})]}),h&&e.jsx("div",{className:"documents-group-content",children:u.map(o=>e.jsx(Ne,{document:o,renderMarkdown:x.get(o.id)??!1,onToggleMarkdown:()=>l(o.id)},o.id))})]})}function Pe({projectId:n,addToast:c,onOpenDetail:u}){const[a,x]=s.useState("project"),[l,h]=s.useState(""),[i,o]=s.useState(null),[p,k]=s.useState(!1),[b,f]=s.useState(null),[g,m]=s.useState(!1),[j,C]=s.useState(null),[E,L]=s.useState(!1),y=s.useRef(0),v=s.useRef(!1),[F,R]=s.useState(!1),[M,P]=s.useState(new Map),T=a==="tasks"?l.trim():"",{documents:N,loading:D,error:J,refresh:B}=we({projectId:n,searchQuery:T||void 0,includeProjectFiles:!1}),{files:S,loading:$,error:Y,refresh:O}=ke(n,{showHidden:p});s.useEffect(()=>{const t=()=>{L(window.innerWidth<=be)};return t(),window.addEventListener("resize",t),()=>{window.removeEventListener("resize",t)}},[]),s.useEffect(()=>{v.current=!1,x("project"),o(null),k(!1),f(null),C(null),m(!1),R(!1),P(new Map)},[n]),s.useEffect(()=>{v.current||D||$||(S.length>0?x("project"):N.length>0&&x("tasks"),v.current=!0)},[N.length,D,S.length,$]);const H=s.useMemo(()=>{const t=new Map;for(const r of N){const d=t.get(r.taskId)||[];t.set(r.taskId,[...d,r])}return Array.from(t.entries()).map(([r,d])=>{const w=[...d].sort((re,ce)=>ce.updatedAt.localeCompare(re.updatedAt));return{taskId:r,taskTitle:w[0]?.taskTitle,documents:w,latestUpdated:w[0]?.updatedAt??""}}).sort((r,d)=>d.latestUpdated.localeCompare(r.latestUpdated))},[N]),A=s.useMemo(()=>{const t=l.trim().toLowerCase();return t?S.filter(r=>{const d=r.path.toLowerCase(),w=r.name.toLowerCase();return d.includes(t)||w.includes(t)}):S},[S,l]);s.useEffect(()=>{if(!i)return;S.some(r=>r.path===i.path)||(o(null),f(null),C(null),m(!1))},[S,i]);const Z=s.useCallback(t=>{h(t.target.value)},[]),I=s.useCallback(()=>{h("")},[]),Q=s.useCallback(t=>{x(t)},[]),ee=s.useCallback(async t=>{try{const r=await le(t,n);u(r)}catch{c(`Failed to open task ${t}`,"error")}},[n,u,c]),se=s.useCallback(async t=>{o(t),m(!0),C(null),f(null);const r=y.current+1;y.current=r;try{const d=await ie("project",t.path,n);if(y.current!==r)return;f(d.content)}catch(d){if(y.current!==r)return;const w=d instanceof Error?d.message:`Failed to open ${t.path}`;C(w),c(w,"error")}finally{y.current===r&&m(!1)}},[n,c]),te=s.useCallback(()=>{o(null),f(null),C(null),m(!1)},[]),ne=s.useCallback(t=>{P(r=>{const d=new Map(r),w=d.get(t)??!1;return d.set(t,!w),d})},[]),U=a==="project"?Y:J,ae=s.useCallback(async()=>{if(a==="project"){await O();return}await B()},[a,O,B]),q=a==="project"?A.length:N.length,G=a==="project"?"Search project markdown files…":"Search task documents…";return e.jsxs("div",{className:"documents-view",children:[e.jsxs("div",{className:"documents-view-header",children:[e.jsxs("div",{className:"documents-view-title-row",children:[e.jsxs("h2",{className:"documents-view-title",children:[e.jsx(z,{size:20}),"Documents"]}),e.jsxs("span",{className:"documents-view-count",children:[q," result",q!==1?"s":""]})]}),e.jsxs("div",{className:"documents-controls-row",children:[e.jsxs("div",{className:"documents-tab-bar",role:"tablist","aria-label":"Documents sections",children:[e.jsxs("button",{className:`btn documents-tab${a==="project"?" active":""}`,role:"tab","aria-selected":a==="project","aria-label":"Show project markdown files",onClick:()=>Q("project"),children:["Project Files",e.jsx("span",{className:"documents-tab-count",children:S.length})]}),e.jsxs("button",{className:`btn documents-tab${a==="tasks"?" active":""}`,role:"tab","aria-selected":a==="tasks","aria-label":"Show task documents",onClick:()=>Q("tasks"),children:["Task Documents",e.jsx("span",{className:"documents-tab-count",children:H.length})]})]}),a==="project"&&e.jsxs("button",{className:"btn btn-sm documents-hidden-toggle",onClick:()=>k(t=>!t),"aria-pressed":p,"aria-label":p?"Hide hidden project files":"Show hidden project files",title:p?"Hide hidden files":"Show hidden files",children:[p?e.jsx(de,{size:14}):e.jsx(ue,{size:14}),p?"Hide Hidden":"Show Hidden"]}),e.jsxs("div",{className:"documents-search",children:[e.jsx(me,{size:16,className:"documents-search-icon"}),e.jsx("input",{type:"text",className:"documents-search-input",placeholder:G,value:l,onChange:Z,"aria-label":G}),l&&e.jsx("button",{className:"documents-search-clear",onClick:I,"aria-label":"Clear search",children:e.jsx(he,{size:16})})]})]})]}),e.jsx("div",{className:"documents-view-content",children:U?e.jsxs("div",{className:"documents-view-error",children:[e.jsxs("p",{children:["Failed to load ",a==="project"?"project files":"task documents",": ",U]}),e.jsxs("button",{className:"btn btn-primary",onClick:()=>void ae(),"aria-label":"Retry loading documents",children:[e.jsx(pe,{size:16}),"Retry"]})]}):a==="project"?$&&S.length===0?e.jsx("div",{className:"documents-view-loading",children:e.jsx("p",{children:"Loading project markdown files…"})}):A.length===0?e.jsx("div",{className:"documents-view-empty",children:l.trim()?e.jsxs("p",{children:['No project markdown files match "',l.trim(),'".']}):e.jsxs(e.Fragment,{children:[e.jsx(z,{size:48,className:"documents-view-empty-icon"}),e.jsx("p",{children:"No Markdown files found in this project."})]})}):e.jsxs("div",{className:`documents-project-layout${E?" documents-project-layout--mobile":""}`,children:[(!E||!i)&&e.jsx("aside",{className:"documents-view-sidebar","aria-label":"Project markdown files",children:e.jsx("ul",{className:"markdown-file-list",children:A.map(t=>{const r=i?.path===t.path;return e.jsx("li",{className:"markdown-file-list-item",children:e.jsxs("button",{className:`markdown-file-item${r?" markdown-file-item--selected":""}`,onClick:()=>void se(t),"aria-label":`Open ${t.path}`,"aria-current":r?"true":void 0,children:[e.jsx("span",{className:"markdown-file-item-name",children:t.name}),e.jsx("span",{className:"markdown-file-item-path",children:t.path}),e.jsxs("span",{className:"markdown-file-item-meta",children:[ge(t.size)," · ",_(t.mtime)]})]})},t.path)})})}),(!E||i)&&e.jsxs("section",{className:"documents-view-main","aria-label":"Project file content preview",children:[E&&i&&e.jsxs("button",{className:"btn btn-sm documents-mobile-back",onClick:te,"aria-label":"Back to project files list",children:[e.jsx(fe,{size:14}),"Back to files"]}),i?e.jsxs("div",{className:"documents-content-viewer",children:[e.jsxs("div",{className:"documents-content-header",children:[e.jsx("p",{className:"documents-file-path-header",children:i.path}),e.jsx("button",{className:"btn btn-sm document-mode-toggle",onClick:()=>R(t=>!t),"aria-label":F?"Switch to plain text":"Switch to markdown","aria-pressed":F,title:F?"Switch to plain text":"Switch to markdown",children:F?"Markdown":"Plain"})]}),g?e.jsx("p",{className:"documents-content-state",children:"Loading file content…"}):j?e.jsx("p",{className:"documents-content-state documents-content-state--error",children:j}):F?e.jsx("div",{className:"documents-content-markdown",children:e.jsx("div",{className:"markdown-body",children:e.jsx(W,{remarkPlugins:[V],children:b??""})})}):e.jsx("pre",{className:"document-card-content-text documents-content-viewer-text",children:b??""})]}):e.jsx("div",{className:"documents-view-empty",children:e.jsx("p",{children:"Select a Markdown file to view its content."})})]})]}):D&&N.length===0?e.jsx("div",{className:"documents-view-loading",children:e.jsx("p",{children:"Loading task documents…"})}):H.length===0?e.jsx("div",{className:"documents-view-empty",children:l.trim()?e.jsxs("p",{children:['No task documents match "',l.trim(),'".']}):e.jsxs(e.Fragment,{children:[e.jsx(z,{size:48,className:"documents-view-empty-icon"}),e.jsx("p",{children:"No task documents yet."}),e.jsx("p",{className:"documents-view-empty-hint",children:"Documents are created in task detail tabs."})]})}):e.jsx("div",{className:"documents-task-list-wrap",children:e.jsx("div",{className:"documents-view-list",children:H.map(({taskId:t,taskTitle:r,documents:d})=>e.jsx(Se,{taskId:t,taskTitle:r,documents:d,onOpenTask:ee,renderMarkdownStates:M,onToggleMarkdown:ne},t))})})})]})}export{Pe as DocumentsView};
@@ -1 +0,0 @@
1
- import{r as l,j as e}from"./vendor-react-K0fH_qHe.js";import{aH as z,aI as F,aJ as O,x as U,aq as _,R as D,au as V}from"./index-DTFPgu6_.js";import"./vendor-xterm-DzcZoU0P.js";import"./vendor-codemirror-jBKmHyH0.js";const $=300,P=15e3;function T(a){if(!a.trim())return;const t=Number(a);return Number.isFinite(t)?t:void 0}function j(...a){for(const t of a)if(Array.isArray(t))return t;return[]}function v(a){return typeof a=="object"&&a!==null?a:{}}function q(a){const t=v(a),r=v(t.taskSnapshot);return{id:String(t.id??t.evalId??""),runId:String(t.runId??t.batchId??""),taskId:String(t.taskId??r.taskId??""),taskTitle:String(r.title??t.taskTitle??t.title??"Untitled task"),createdAt:String(t.createdAt??t.timestamp??t.updatedAt??new Date(0).toISOString()),overallScore:typeof t.overallScore=="number"?t.overallScore:null,maxScore:typeof t.maxScore=="number"?t.maxScore:null,categoryScores:j(t.categoryScores,v(t.scores).categories)}}function B(a){const t=v(a);return{...q(t),rationale:String(t.rationale??t.summary??""),evidence:j(t.evidence,v(t.details).evidence),followUps:j(t.followUps,v(t.recommendations).followUps)}}function H(a){const t=a?.projectId,[r,g]=l.useState({q:"",runId:"",scoreMin:"",scoreMax:""}),[S,h]=l.useState([]),[I,p]=l.useState([]),[i,f]=l.useState(null),[k,c]=l.useState(null),[E,w]=l.useState(0),[N,b]=l.useState(!0),[R,s]=l.useState(null),n=l.useRef(0),d=l.useCallback(async()=>{const u=++n.current;b(!0),s(null);try{const[o,y]=await Promise.all([z({q:r.q||void 0,runId:r.runId||void 0,scoreMin:T(r.scoreMin),scoreMax:T(r.scoreMax),limit:100,offset:0},t),F(t)]);if(u!==n.current)return;const M=j(o.results,o.evals,o.items).map(q);p(M),w(typeof o.count=="number"?o.count:M.length);const L=j(y.runs,y.items);h(L.map(C=>{const x=v(C),A=v(x.counts);return{id:String(x.id??""),createdAt:String(x.createdAt??""),completedAt:typeof x.completedAt=="string"?x.completedAt:void 0,status:String(x.status??"pending"),evaluatedTaskCount:typeof A.totalTasks=="number"?A.totalTasks:0}})),i&&!M.some(C=>C.id===i)&&(f(null),c(null))}catch(o){if(u!==n.current)return;s(o instanceof Error?o.message:"Failed to load evals")}finally{u===n.current&&b(!1)}},[r.q,r.runId,r.scoreMax,r.scoreMin,t,i]),m=l.useCallback(async u=>{const o=await O(u,t),y=o.result??o;c(B(y))},[t]);return l.useEffect(()=>{const u=window.setTimeout(()=>{d()},$);return()=>window.clearTimeout(u)},[d]),l.useEffect(()=>{if(!i){c(null);return}m(i)},[m,i]),l.useEffect(()=>{const u=window.setInterval(()=>{d(),i&&m(i)},P);return()=>window.clearInterval(u)},[m,d,i]),{loading:N,error:R,results:I,count:E,runs:S,filters:r,setFilters:g,refresh:d,selectedEvalId:i,setSelectedEvalId:f,selectedEval:k}}function X({projectId:a,onOpenSettings:t,onOpenTaskDetail:r}){const{loading:g,error:S,results:h,runs:I,filters:p,setFilters:i,selectedEvalId:f,setSelectedEvalId:k,selectedEval:c,refresh:E}=H({projectId:a}),[w,N]=l.useState(!0);l.useEffect(()=>{let s=!1;return U(a).then(n=>{if(s)return;const d=n.evalSettings?.enabled;N(d??!1)}).catch(()=>{s||N(!1)}),()=>{s=!0}},[a]);const b=h.length>0,R=l.useMemo(()=>h.find(s=>s.id===f)??null,[h,f]);return w?e.jsxs("section",{className:"evals-view","data-testid":"evals-view",children:[e.jsxs("div",{className:"evals-list card",children:[e.jsxs("div",{className:"evals-toolbar",children:[e.jsx("input",{className:"input",placeholder:"Search task or rationale",value:p.q,onChange:s=>i(n=>({...n,q:s.target.value}))}),e.jsxs("select",{className:"select",value:p.runId,onChange:s=>i(n=>({...n,runId:s.target.value})),children:[e.jsx("option",{value:"",children:"All runs"}),I.map(s=>e.jsx("option",{value:s.id,children:s.id},s.id))]}),e.jsx("input",{className:"input",placeholder:"Min score",value:p.scoreMin,onChange:s=>i(n=>({...n,scoreMin:s.target.value}))}),e.jsx("input",{className:"input",placeholder:"Max score",value:p.scoreMax,onChange:s=>i(n=>({...n,scoreMax:s.target.value}))}),e.jsx("button",{className:"btn btn-icon",type:"button",onClick:()=>void E(),"aria-label":"Refresh evals",children:e.jsx(D,{size:16})})]}),g&&e.jsx("p",{className:"evals-state","data-testid":"evals-loading",children:"Loading evals…"}),S&&e.jsx("p",{className:"evals-state evals-state--error",children:S}),!g&&!S&&!b&&e.jsx("p",{className:"evals-state",children:"No evals yet. Scheduled evals review tasks completed since the last run."}),e.jsx("ul",{className:"evals-results","data-testid":"evals-results",children:h.map(s=>e.jsx("li",{children:e.jsxs("button",{className:`evals-result ${s.id===f?"evals-result--active":""}`,type:"button",onClick:()=>k(s.id),children:[e.jsx("span",{className:"evals-result-title",children:s.taskTitle}),e.jsxs("span",{className:"evals-result-meta",children:[s.taskId," · ",s.runId," · ",s.overallScore??"n/a"]})]})},s.id))})]}),e.jsxs("div",{className:"evals-detail card","data-testid":"evals-detail",children:[!c&&e.jsx("p",{className:"evals-state",children:"Select an evaluation to inspect scores, rationale, and evidence."}),c&&e.jsxs(e.Fragment,{children:[e.jsx("h3",{className:"evals-detail-title",children:R?.taskTitle??c.taskTitle}),e.jsxs("p",{className:"evals-result-meta",children:[c.taskId," · ",c.runId]}),e.jsxs("p",{className:"evals-score",children:["Overall score: ",c.overallScore??"n/a"]}),e.jsx("ul",{className:"evals-categories",children:c.categoryScores.map(s=>e.jsxs("li",{children:[s.category,": ",s.finalScore]},s.category))}),e.jsx("p",{className:"evals-rationale",children:c.rationale||"No rationale recorded."}),e.jsxs("div",{children:[e.jsx("h4",{children:"Evidence"}),e.jsx("ul",{className:"evals-links",children:c.evidence.map((s,n)=>{const d=typeof s.metadata?.taskId=="string"?s.metadata.taskId:void 0,m=typeof s.metadata?.url=="string"?s.metadata.url:void 0;return e.jsx("li",{children:d?e.jsx("button",{type:"button",className:"btn",onClick:()=>r?.(d),children:s.ref}):m?e.jsxs("a",{href:m,target:"_blank",rel:"noreferrer",className:"evals-external-link",children:[s.ref,e.jsx(V,{size:14})]}):e.jsx("span",{children:s.ref})},`${s.ref}-${n}`)})})]}),e.jsxs("div",{children:[e.jsx("h4",{children:"Suggested follow-up tasks"}),e.jsxs("ul",{className:"evals-follow-ups",children:[c.followUps.length===0&&e.jsx("li",{children:"None"}),c.followUps.map(s=>e.jsxs("li",{children:[e.jsx("strong",{children:s.title}),e.jsx("p",{children:s.rationale})]},s.suggestionId))]})]})]})]})]}):e.jsxs("section",{className:"evals-view card","data-testid":"evals-disabled",children:[e.jsx("h2",{className:"evals-title",children:"Scheduled evals are disabled"}),e.jsx("p",{className:"evals-empty-copy",children:"Enable Scheduled Evals to review scored tasks, evidence, and follow-up recommendations."}),e.jsxs("button",{className:"btn btn-primary",type:"button",onClick:()=>t?.("scheduled-evals"),children:[e.jsx(_,{size:16}),"Open Scheduled Evals Settings"]})]})}export{X as EvalsView};
@@ -1,11 +0,0 @@
1
- import{r,j as e}from"./vendor-react-K0fH_qHe.js";import{c as ye,af as $e,ag as De,ah as Le,ai as Pe,aj as Ue,ak as Te,al as _e,am as de,an as Ge,h as Oe,j as ue,ao as w,X as ge,ap as ne,R as j,aq as qe,m as Be,C as pe,ar as W,as as me,at as He,J as be,au as Ve,av as we,aw as Ye}from"./index-DTFPgu6_.js";import{U as ve}from"./users-CbALDtDk.js";import"./vendor-xterm-DzcZoU0P.js";import"./vendor-codemirror-jBKmHyH0.js";/**
2
- * @license lucide-react v1.7.0 - ISC
3
- *
4
- * This source code is licensed under the ISC license.
5
- * See the LICENSE file in the root directory of this source tree.
6
- */const Je=[["path",{d:"M12 10h.01",key:"1nrarc"}],["path",{d:"M12 14h.01",key:"1etili"}],["path",{d:"M12 6h.01",key:"1vi96p"}],["path",{d:"M16 10h.01",key:"1m94wz"}],["path",{d:"M16 14h.01",key:"1gbofw"}],["path",{d:"M16 6h.01",key:"1x0f13"}],["path",{d:"M8 10h.01",key:"19clt8"}],["path",{d:"M8 14h.01",key:"6423bh"}],["path",{d:"M8 6h.01",key:"1dz90k"}],["path",{d:"M9 22v-3a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v3",key:"cabbwy"}],["rect",{x:"4",y:"2",width:"16",height:"20",rx:"2",key:"1uxh74"}]],Qe=ye("building",Je);/**
7
- * @license lucide-react v1.7.0 - ISC
8
- *
9
- * This source code is licensed under the ISC license.
10
- * See the LICENSE file in the root directory of this source tree.
11
- */const We=[["path",{d:"M3 3v16a2 2 0 0 0 2 2h16",key:"c24i48"}],["path",{d:"m19 9-5 5-4-4-3 3",key:"2osh9i"}]],Xe=ye("chart-line",We),ie=["architecture","quality","workflow","performance","reliability","security","ux","testability","documentation","dependency","features","competitive_analysis","research","trends","other"],fe={quality:"Quality",performance:"Performance",architecture:"Architecture",security:"Security",reliability:"Reliability",ux:"User Experience",testability:"Testability",documentation:"Documentation",dependency:"Dependencies",workflow:"Workflow",other:"Other",features:"Features",competitive_analysis:"Competitive Analysis",research:"Research",trends:"Trends"};function Ke(m){const[l,y]=r.useState([]),[S,$]=r.useState(()=>ie.map(i=>({category:i,label:fe[i]??i,items:[],isLoading:!1,error:null}))),[P,N]=r.useState(!0),[U,v]=r.useState(null),[D,M]=r.useState(null),[T,L]=r.useState(!1),[_,k]=r.useState(null),[G,I]=r.useState(new Map),[X,F]=r.useState(new Map),[O,A]=r.useState(new Map),[q,E]=r.useState(new Map),[R,B]=r.useState(!1),x=r.useCallback(async()=>{N(!0),v(null);try{const i=await $e({status:void 0,limit:1e3},m);y(i.insights.filter(s=>s.status!=="dismissed"));const t=await De(m);t.runs.length>0&&M(t.runs[0])}catch(i){const t=i instanceof Error?i.message:"Failed to fetch insights";v(t)}finally{N(!1)}},[m]),d=r.useCallback(()=>{B(i=>!i)},[]),C=r.useCallback(async(i,t)=>{L(!0),k(null);try{const s=await Le("manual",void 0,m,i,t);M(s),s.status==="completed"?await x():s.status==="failed"&&s.error&&k(s.error)}catch(s){if(s instanceof Pe&&s.status===409&&s.details?.code==="ACTIVE_RUN_CONFLICT"){const g=typeof s.details.activeRunId=="string"?s.details.activeRunId:null;if(g)try{const se=await Ue(g,m);M(se)}catch{}throw k("Insight generation is already running"),s}const h=s instanceof Error?s.message:"Failed to generate insights";throw k(h),s}finally{L(!1)}},[m,x]),u=r.useCallback(async i=>{I(t=>{const s=new Map(t);return s.set(i,{running:!0,error:null}),s});try{await Te(i,m),y(t=>t.filter(s=>s.id!==i)),I(t=>{const s=new Map(t);return s.set(i,{running:!1,error:null}),s})}catch(t){const s=t instanceof Error?t.message:"Failed to dismiss insight";throw I(h=>{const g=new Map(h);return g.set(i,{running:!1,error:s}),g}),t}},[m]),H=r.useCallback(async i=>{F(t=>{const s=new Map(t);return s.set(i,{running:!0,error:null}),s});try{const t=await _e(i,m);return await de(i,m),y(s=>s.map(h=>h.id===i?{...h,status:"archived",updatedAt:new Date().toISOString()}:h)),F(s=>{const h=new Map(s);return h.set(i,{running:!1,error:null}),h}),{title:t.suggestedTitle,description:t.suggestedDescription}}catch(t){const s=t instanceof Error?t.message:"Failed to create task";throw F(h=>{const g=new Map(h);return g.set(i,{running:!1,error:s}),g}),t}},[m]);r.useEffect(()=>{const i=new Map;for(const t of ie)i.set(t,[]);for(const t of l){if(!R&&t.status==="archived")continue;const s=i.get(t.category)??[];i.set(t.category,[...s,t])}$(ie.map(t=>({category:t,label:fe[t]??t,items:i.get(t)??[],isLoading:!1,error:null})))},[l,R]);const K=r.useCallback(async i=>{A(t=>{const s=new Map(t);return s.set(i,{running:!0,error:null}),s});try{await de(i,m),y(t=>t.map(s=>s.id===i?{...s,status:"archived",updatedAt:new Date().toISOString()}:s)),A(t=>{const s=new Map(t);return s.set(i,{running:!1,error:null}),s})}catch(t){const s=t instanceof Error?t.message:"Failed to archive insight";throw A(h=>{const g=new Map(h);return g.set(i,{running:!1,error:s}),g}),t}},[m]),f=r.useCallback(async i=>{E(t=>{const s=new Map(t);return s.set(i,{running:!0,error:null}),s});try{await Ge(i,m),y(t=>t.map(s=>s.id===i?{...s,status:"confirmed",updatedAt:new Date().toISOString()}:s)),E(t=>{const s=new Map(t);return s.set(i,{running:!1,error:null}),s})}catch(t){const s=t instanceof Error?t.message:"Failed to unarchive insight";throw E(h=>{const g=new Map(h);return g.set(i,{running:!1,error:s}),g}),t}},[m]),V=r.useMemo(()=>S.reduce((i,t)=>i+t.items.length,0),[S]),Z=r.useMemo(()=>0,[]),ee=r.useMemo(()=>l.filter(i=>i.status==="archived").length,[l]);return r.useEffect(()=>{x()},[x]),{sections:S,loading:P,error:U,latestRun:D,isRunInFlight:T,runError:_,refresh:x,runInsights:C,dismiss:u,createTask:H,archive:K,unarchive:f,toggleShowArchived:d,dismissStates:G,createTaskStates:X,archiveStates:O,unarchiveStates:q,totalCount:V,dismissedCount:Z,archivedCount:ee,showArchived:R}}const xe={architecture:Qe,quality:pe,workflow:we,performance:me,reliability:j,security:W,ux:ve,testability:ne,documentation:Ve,dependency:be,features:He,competitive_analysis:ve,research:Xe,trends:me,other:w};function ns({projectId:m,addToast:l,onClose:y,onCreateTask:S,models:$}){const{sections:P,loading:N,error:U,latestRun:v,isRunInFlight:D,runError:M,refresh:T,runInsights:L,dismiss:_,createTask:k,archive:G=async()=>{},unarchive:I=async()=>{},toggleShowArchived:X=()=>{},dismissStates:F,createTaskStates:O,archiveStates:A=new Map,unarchiveStates:q=new Map,totalCount:E,archivedCount:R=0,showArchived:B=!1}=Ke(m),[x,d]=r.useState(null),[C,u]=r.useState("info"),[H,K]=r.useState(!1),[f,V]=r.useState(()=>localStorage.getItem("fusion-insight-model")??""),[Z,ee]=r.useState([]),[i,t]=r.useState([]),[s,h]=r.useState([]),[g,se]=r.useState();r.useEffect(()=>{$||Oe().then(a=>{ee(a.models),t(a.favoriteProviders),h(a.favoriteModels),se(a.resolvedPlanningProvider);const n=localStorage.getItem("fusion-insight-model");n&&(a.models.some(o=>`${o.provider}/${o.id}`===n)||(localStorage.removeItem("fusion-insight-model"),V("")))}).catch(()=>{})},[$]);const je=$??Z,Se=r.useMemo(()=>i.length>0?i:g?[g]:[],[i,g]),ke=r.useCallback(async a=>{const c=i.includes(a)?i.filter(o=>o!==a):[a,...i];t(c);try{await ue({favoriteProviders:c,favoriteModels:s})}catch{t(i)}},[i,s]),Ce=r.useCallback(async a=>{const c=s.includes(a)?s.filter(o=>o!==a):[a,...s];h(c);try{await ue({favoriteProviders:i,favoriteModels:c})}catch{h(s)}},[s,i]),Ne=r.useCallback(a=>{V(a),a?localStorage.setItem("fusion-insight-model",a):localStorage.removeItem("fusion-insight-model")},[]),p=r.useMemo(()=>P.filter(a=>a.items.length>0),[P]),[z,te]=r.useState(null);r.useEffect(()=>{if(p.length===0){z!==null&&te(null);return}z&&p.some(n=>n.category===z)||te(p[0].category)},[p,z]);const b=r.useMemo(()=>p.find(a=>a.category===z)??p[0],[p,z]);r.useEffect(()=>{if(x){const a=setTimeout(()=>d(null),5e3);return()=>clearTimeout(a)}},[x]);const ae=r.useCallback(async()=>{try{d("Generating insights..."),u("info");let a,n;if(f){const c=f.indexOf("/");if(c!==-1){const o=f.slice(0,c),Y=f.slice(c+1);o&&Y&&(a=o,n=Y)}}await L(a,n),d("Insight generation started"),u("success"),l("Insight generation started","success")}catch(a){const n=a instanceof Error?a.message:"Failed to start generation";if(n==="Insight generation is already running"){d("Insight generation is already running. Showing the active run."),u("info"),l("Insight generation is already running","info");return}d(n),u("error"),l(n,"error")}},[L,l,f]),Me=r.useCallback(async(a,n)=>{try{d(`Dismissing "${n}"...`),u("info"),await _(a),d(`Dismissed "${n}"`),u("success"),l(`Insight dismissed: ${n}`,"success")}catch(c){const o=c instanceof Error?c.message:"Failed to dismiss insight";d(o),u("error"),l(o,"error")}},[_,l]),Ie=r.useCallback(async(a,n)=>{try{d(`Archiving "${n}"...`),u("info"),await G(a),d(`Archived "${n}"`),u("success"),l(`Insight archived: ${n}`,"success")}catch(c){const o=c instanceof Error?c.message:"Failed to archive insight";d(o),u("error"),l(o,"error")}},[G,l]),Fe=r.useCallback(async(a,n)=>{try{d(`Unarchiving "${n}"...`),u("info"),await I(a),d(`Unarchived "${n}"`),u("success"),l(`Insight unarchived: ${n}`,"success")}catch(c){const o=c instanceof Error?c.message:"Failed to unarchive insight";d(o),u("error"),l(o,"error")}},[I,l]),Ae=r.useCallback(async(a,n)=>{try{if(d(`Creating task from "${n}"...`),u("info"),!S)throw new Error("Task creation is unavailable in this view");const c=await k(a);if(!c)throw new Error("Failed to prepare task payload from insight");await S({insightId:a,title:c.title,description:c.description}),d(`Task created from "${n}"`),u("success"),l(`Task created: ${c.title}`,"success")}catch(c){const o=c instanceof Error?c.message:"Failed to create task";d(o),u("error"),l(o,"error")}},[k,S,l]),Ee=a=>{const n=xe[a.category]??w,c=b?.category===a.category;return e.jsx("li",{children:e.jsxs("button",{type:"button",className:`insights-category-item${c?" insights-category-item--active":""}`,onClick:()=>te(a.category),"aria-current":c?"true":void 0,"data-testid":`insights-category-${a.category}`,children:[e.jsx(n,{size:16,className:"insights-category-icon"}),e.jsx("span",{className:"insights-category-label",children:a.label}),e.jsx("span",{className:"insights-category-count",children:a.items.length})]})},a.category)},Re=()=>{if(!b)return null;const a=xe[b.category]??w;return e.jsxs("section",{className:"insights-section","data-testid":`insights-section-${b.category}`,children:[e.jsx("div",{className:"insights-section-header",children:e.jsxs("div",{className:"insights-section-title",children:[e.jsx(a,{size:20,className:"insights-section-icon"}),e.jsx("h3",{children:b.label}),e.jsx("span",{className:"insights-section-count",children:b.items.length})]})}),e.jsx("div",{className:"insights-section-content",children:e.jsx("ul",{className:"insights-list",children:b.items.map(n=>{const c=F.get(n.id),o=O.get(n.id),Y=A.get(n.id),ze=q.get(n.id),re=c?.running??!1,ce=o?.running??!1,oe=Y?.running??!1,le=ze?.running??!1,he=n.status==="archived",J=b.items.some(Q=>F.get(Q.id)?.running||O.get(Q.id)?.running||A.get(Q.id)?.running||q.get(Q.id)?.running);return e.jsxs("li",{className:`insight-item${he?" insight-item--archived":""}`,"data-insight-id":n.id,children:[e.jsxs("div",{className:"insight-item-header",children:[e.jsx("h4",{className:"insight-item-title",children:n.title}),e.jsxs("div",{className:"insight-item-actions",children:[he?e.jsx("button",{className:"insight-item-action-btn",onClick:()=>void Fe(n.id,n.title),disabled:le||J,title:"Unarchive this insight","aria-label":"Unarchive this insight","data-testid":`unarchive-${n.id}`,children:le?e.jsx(j,{size:20,className:"spin"}):e.jsx(Ye,{size:20})}):e.jsxs(e.Fragment,{children:[e.jsx("button",{className:"insight-item-action-btn",onClick:()=>void Ae(n.id,n.title),disabled:ce||J,title:"Create task from this insight","aria-label":"Create task from this insight","data-testid":`create-task-${n.id}`,children:ce?e.jsx(j,{size:20,className:"spin"}):e.jsx(be,{size:20})}),e.jsx("button",{className:"insight-item-action-btn",onClick:()=>void Ie(n.id,n.title),disabled:oe||J,title:"Archive this insight","aria-label":"Archive this insight","data-testid":`archive-${n.id}`,children:oe?e.jsx(j,{size:20,className:"spin"}):e.jsx(ne,{size:20})})]}),e.jsx("button",{className:"insight-item-action-btn",onClick:()=>void Me(n.id,n.title),disabled:re||J,title:"Dismiss this insight","aria-label":"Dismiss this insight","data-testid":`dismiss-${n.id}`,children:re?e.jsx(j,{size:20,className:"spin"}):e.jsx(ge,{size:20})})]})]}),n.content&&e.jsx("p",{className:"insight-item-content",children:n.content}),e.jsxs("div",{className:"insight-item-meta",children:[e.jsx("span",{className:`insight-item-status insight-item-status--${n.status}`,children:n.status}),n.createdAt&&e.jsxs("span",{className:"insight-item-date",children:[e.jsx(we,{size:12}),new Date(n.createdAt).toLocaleDateString()]})]})]},n.id)})})})]})};return e.jsxs("div",{className:"insights-view","data-testid":"insights-view",children:[e.jsxs("div",{className:"insights-view-header",children:[e.jsxs("div",{className:"insights-view-title",children:[e.jsxs("h2",{children:[e.jsx(w,{size:20}),"Insights"]}),e.jsxs("span",{className:"insights-view-count",children:[E," total"]})]}),e.jsxs("div",{className:"insights-view-actions",children:[y&&e.jsx("button",{className:"btn btn-sm insights-view-close",onClick:y,"aria-label":"Close insights view",title:"Close",children:e.jsx(ge,{size:16})}),R>0&&e.jsxs("button",{className:"btn btn-sm insights-show-archived-toggle",onClick:X,"aria-label":B?"Hide archived insights":"Show archived insights","data-testid":"toggle-archived-insights",children:[e.jsx(ne,{size:14}),B?"Hide Archived":`Show Archived (${R})`]}),e.jsxs("button",{className:"btn btn-sm",onClick:()=>void T(),disabled:N,"aria-label":"Refresh insights","data-testid":"refresh-insights",children:[e.jsx(j,{size:14,className:N?"spin":""}),"Refresh"]}),e.jsxs("button",{className:"btn btn-sm insights-model-toggle",onClick:()=>K(a=>!a),"aria-label":"Configure insight generation model","aria-expanded":H,"data-testid":"toggle-model-config",title:f?`Model: ${f}`:"Configure model",children:[e.jsx(qe,{size:14}),f&&e.jsx("span",{className:"insights-model-indicator"})]}),e.jsx("button",{className:"btn btn-primary btn-sm",onClick:()=>void ae(),disabled:D,"aria-label":"Generate new insights","data-testid":"run-insights",children:D?e.jsxs(e.Fragment,{children:[e.jsx(j,{size:14,className:"spin"}),"Generating..."]}):e.jsxs(e.Fragment,{children:[e.jsx(w,{size:14}),"Generate Insights"]})})]})]}),H&&e.jsxs("div",{className:"insights-model-config","data-testid":"model-config",children:[e.jsx("label",{htmlFor:"insight-model-select",className:"insights-model-label",children:"Model"}),e.jsx(Be,{models:je,value:f,onChange:Ne,placeholder:"Use planning default",label:"Insight generation model",disabled:D,id:"insight-model-select",favoriteProviders:Se,favoriteModels:s,onToggleFavorite:ke,onToggleModelFavorite:Ce})]}),e.jsx("div",{className:"insights-status-region","aria-live":"polite","data-testid":"insights-status",children:x&&e.jsxs("div",{className:`insights-status-message insights-status-message--${C}`,role:C==="error"?"alert":void 0,children:[C==="success"&&e.jsx(pe,{size:16}),C==="error"&&e.jsx(W,{size:16}),C==="info"&&e.jsx(w,{size:16}),e.jsx("span",{children:x})]})}),M&&e.jsxs("div",{className:"insights-error-callout",role:"alert","data-testid":"run-error",children:[e.jsx(W,{size:16}),e.jsx("span",{children:M})]}),v&&e.jsx("div",{className:"insights-run-info","data-testid":"latest-run",children:e.jsxs("span",{className:"insights-run-status",children:["Latest run: ",v.status,v.status==="completed"&&e.jsxs(e.Fragment,{children:[" — ",v.insightsCreated," created, ",v.insightsUpdated," updated"]}),v.status==="failed"&&v.error&&e.jsxs(e.Fragment,{children:[" — ",v.error]})]})}),N?e.jsxs("div",{className:"insights-loading","data-testid":"insights-loading",children:[e.jsx(j,{size:24,className:"spin"}),e.jsx("p",{children:"Loading insights..."})]}):U?e.jsxs("div",{className:"insights-error","data-testid":"insights-error",children:[e.jsx(W,{size:24}),e.jsx("p",{children:U}),e.jsx("button",{className:"btn btn-sm",onClick:()=>void T(),children:"Retry"})]}):E===0?e.jsxs("div",{className:"insights-empty","data-testid":"insights-empty",children:[e.jsx(w,{size:48}),e.jsx("h3",{children:"No insights yet"}),e.jsx("p",{children:"Generate insights to get AI-powered recommendations for your project."}),e.jsxs("button",{className:"btn btn-primary",onClick:()=>void ae(),children:[e.jsx(w,{size:14}),"Generate First Insights"]})]}):e.jsxs("div",{className:"insights-body",children:[e.jsx("aside",{className:"insights-sidebar","aria-label":"Insight categories",children:e.jsx("ul",{className:"insights-category-list",children:p.map(Ee)})}),e.jsx("div",{className:"insights-detail",children:Re()})]})]})}export{ns as InsightsView};
@@ -1 +0,0 @@
1
- .reliability-view{display:flex;flex-direction:column;gap:var(--space-lg);height:100%;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch}.reliability-card{padding:var(--space-lg);border:var(--border-width-thin, .0625rem) solid var(--border);border-radius:var(--radius-md);background:var(--card)}.reliability-headline-card{display:flex;flex-direction:column;gap:var(--space-sm)}.reliability-headline{font-size:var(--font-size-2xl, 1.75rem);font-weight:700}.reliability-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--space-lg)}.reliability-table{width:100%;border-collapse:collapse;margin-top:var(--space-sm)}.reliability-table th,.reliability-table td{text-align:left;padding:var(--space-xs) var(--space-sm);border-bottom:var(--border-width-thin, .0625rem) solid var(--border)}.reliability-stat-row{display:flex;justify-content:space-between;align-items:center;padding:var(--space-xs) 0}.reliability-muted{color:var(--text-muted)}.reliability-histogram{list-style:none;margin:var(--space-sm) 0 0;padding:0;display:flex;flex-direction:column;gap:var(--space-sm)}.reliability-histogram li{display:grid;grid-template-columns:minmax(0,2fr) minmax(0,6fr) minmax(0,1fr);align-items:center;gap:var(--space-sm)}.reliability-histogram-bar-wrap{width:100%;border-radius:var(--radius-pill);background:color-mix(in srgb,var(--color-info) 15%,transparent);overflow:hidden}.reliability-histogram-bar{height:var(--space-md);background:var(--color-info)}@media(max-width:768px){.reliability-view{padding-bottom:calc(var(--space-lg) + var(--mobile-nav-height) + env(safe-area-inset-bottom,0px) + var(--standalone-bottom-gap))}.reliability-grid{grid-template-columns:minmax(0,1fr)}}
@@ -1 +0,0 @@
1
- import{r as a,j as e}from"./vendor-react-K0fH_qHe.js";function c(i){return`${(i*100).toFixed(1)}%`}function n(i){return i===null?"—":`${(i/6e4).toFixed(1)}m`}function h(){const[i,t]=a.useState(null),l=a.useCallback(async()=>{const r=await fetch("/api/health/reliability");if(!r.ok)throw new Error(`Failed to load reliability metrics (${r.status})`);const s=await r.json();t(s)},[]);a.useEffect(()=>{l();const r=setInterval(()=>{l()},6e4);return()=>clearInterval(r)},[l]);const d=a.useMemo(()=>{const r=i?.headline.inReviewFailureRate7d;return r==null?"var(--text-muted)":r<.05?"var(--color-success)":r<.1?"var(--color-warning)":"var(--color-error)"},[i]);return e.jsxs("section",{className:"reliability-view",children:[e.jsxs("div",{className:"card reliability-card reliability-headline-card",children:[e.jsx("h2",{children:"Reliability"}),e.jsx("div",{className:"reliability-headline",style:{color:d},children:i?.headline.inReviewFailureRate7d===null||i?.headline.inReviewFailureRate7d===void 0?`Insufficient data — ${i?.headline.reason??"unknown"}`:c(i.headline.inReviewFailureRate7d)})]}),e.jsxs("div",{className:"reliability-grid",children:[e.jsxs("div",{className:"card reliability-card",children:[e.jsx("h3",{children:"In-review flow"}),e.jsxs("table",{className:"reliability-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Date"}),e.jsx("th",{children:"Entered"}),e.jsx("th",{children:"Bounced"})]})}),e.jsx("tbody",{children:i?.perDay.map(r=>e.jsxs("tr",{children:[e.jsx("td",{children:r.date}),e.jsx("td",{children:r.tasksEnteredInReview}),e.jsx("td",{children:r.tasksBouncedToInProgress})]},r.date))})]})]}),e.jsxs("div",{className:"card reliability-card",children:[e.jsx("h3",{children:"Duration"}),e.jsxs("div",{className:"reliability-stat-row",children:[e.jsx("span",{children:"P50"}),e.jsx("strong",{children:n(i?.duration.p50Ms??null)})]}),e.jsxs("div",{className:"reliability-stat-row",children:[e.jsx("span",{children:"P95"}),e.jsx("strong",{children:n(i?.duration.p95Ms??null)})]}),e.jsxs("div",{className:"reliability-muted",children:["Samples: ",i?.duration.sampleCount??0]})]}),e.jsxs("div",{className:"card reliability-card",children:[e.jsx("h3",{children:"Merge attempts"}),e.jsxs("div",{className:"reliability-stat-row",children:[e.jsx("span",{children:"Mean"}),e.jsx("strong",{children:i?.mergeAttempts.mean?.toFixed(2)??"—"})]}),e.jsxs("div",{className:"reliability-stat-row",children:[e.jsx("span",{children:"Max"}),e.jsx("strong",{children:i?.mergeAttempts.max??"—"})]}),e.jsx("ul",{className:"reliability-histogram",children:Object.entries(i?.mergeAttempts.histogram??{}).map(([r,s])=>e.jsxs("li",{children:[e.jsx("span",{children:r}),e.jsx("div",{className:"reliability-histogram-bar-wrap",children:e.jsx("div",{className:"reliability-histogram-bar",style:{width:`${Math.min(s*20,100)}%`}})}),e.jsx("strong",{children:s})]},r))})]})]})]})}export{h as ReliabilityView};