@runfusion/fusion 0.38.0 → 0.39.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 (59) hide show
  1. package/dist/bin.js +3325 -858
  2. package/dist/client/.vite/manifest.json +58 -58
  3. package/dist/client/assets/{AgentDetailView-CquLtIia.js → AgentDetailView-nS4sABBv.js} +1 -1
  4. package/dist/client/assets/{AgentPermissionPolicyEditor-Dk-oEs1X.js → AgentPermissionPolicyEditor-DiYAo51R.js} +1 -1
  5. package/dist/client/assets/{AgentsView-BZVOpQ05.js → AgentsView-VbUsJLma.js} +3 -3
  6. package/dist/client/assets/ChatView-B1AMky9x.js +6 -0
  7. package/dist/client/assets/{DevServerView-BRA00XoT.js → DevServerView-CyFdAcCd.js} +1 -1
  8. package/dist/client/assets/{DirectoryPicker-D496NTjZ.js → DirectoryPicker-C7v2Esic.js} +1 -1
  9. package/dist/client/assets/{DocumentsView-DIRlgdeB.js → DocumentsView-P_YIsnO0.js} +1 -1
  10. package/dist/client/assets/{EvalsView-By5mtr80.js → EvalsView-2zyH0dWG.js} +1 -1
  11. package/dist/client/assets/{ExperimentalAgentOnboardingModal-Br57oNdX.js → ExperimentalAgentOnboardingModal-DoRPGkfN.js} +1 -1
  12. package/dist/client/assets/{GoalsView-B65urz9k.css → GoalsView-Dky8vDoG.css} +1 -1
  13. package/dist/client/assets/GoalsView-l0PVSxK4.js +2 -0
  14. package/dist/client/assets/{InsightsView-Hm7vX2lr.js → InsightsView-BZKu5-C3.js} +1 -1
  15. package/dist/client/assets/{MemoryView-BLozyYur.js → MemoryView-CYBNC_h8.js} +1 -1
  16. package/dist/client/assets/{NodesView-bXC6WoE2.js → NodesView-CQ63uWC8.js} +1 -1
  17. package/dist/client/assets/{PiExtensionsManager-DEiqcMkx.js → PiExtensionsManager-BNXxlpb6.js} +1 -1
  18. package/dist/client/assets/{PluginManager-l4224zxk.js → PluginManager-DejpEyl7.js} +1 -1
  19. package/dist/client/assets/{ResearchView-CpsR1Q56.js → ResearchView-B4u2YieX.js} +1 -1
  20. package/dist/client/assets/{SecretsView-Bwme1zZI.js → SecretsView-DvMMG_rf.js} +1 -1
  21. package/dist/client/assets/SettingsModal-986SEzVN.css +1 -0
  22. package/dist/client/assets/SettingsModal-C2mfeKp1.js +31 -0
  23. package/dist/client/assets/{SettingsModal-32vUNWRe.js → SettingsModal-Dmz2aH3c.js} +1 -1
  24. package/dist/client/assets/{SetupWizardModal-BFD9E0H_.js → SetupWizardModal-BiIFP3De.js} +1 -1
  25. package/dist/client/assets/{SkillsView-CZMLY7F_.js → SkillsView-CRARYL_G.js} +1 -1
  26. package/dist/client/assets/{StashRecoveryView-jgZeWbZo.js → StashRecoveryView-DHj0O6sE.js} +1 -1
  27. package/dist/client/assets/{TodoView-DXdnOymj.js → TodoView-CjyU1h-B.js} +1 -1
  28. package/dist/client/assets/{dashboard-view-H8SnaCPP.js → dashboard-view-BVckVLAO.js} +1 -1
  29. package/dist/client/assets/{folder-open-Dh5_gv6L.js → folder-open-CJgBSqdA.js} +1 -1
  30. package/dist/client/assets/index-BonLYFW-.js +742 -0
  31. package/dist/client/assets/index-nzIVQsA_.css +1 -0
  32. package/dist/client/assets/{upload-ntU2YHPl.js → upload-hsiV4Ixv.js} +1 -1
  33. package/dist/client/assets/{users-BWK61s9U.js → users-D63HpHlZ.js} +1 -1
  34. package/dist/client/index.html +2 -2
  35. package/dist/client/version.json +1 -1
  36. package/dist/droid-cli/package.json +1 -1
  37. package/dist/extension.js +3073 -785
  38. package/dist/pi-claude-cli/package.json +1 -1
  39. package/dist/plugins/fusion-plugin-cli-printing-press/package.json +1 -1
  40. package/dist/plugins/fusion-plugin-cursor-runtime/package.json +1 -1
  41. package/dist/plugins/fusion-plugin-dependency-graph/package.json +1 -1
  42. package/dist/plugins/fusion-plugin-droid-runtime/bundled.js +38 -4
  43. package/dist/plugins/fusion-plugin-droid-runtime/package.json +1 -1
  44. package/dist/plugins/fusion-plugin-hermes-runtime/package.json +1 -1
  45. package/dist/plugins/fusion-plugin-openclaw-runtime/package.json +1 -1
  46. package/dist/plugins/fusion-plugin-paperclip-runtime/package.json +1 -1
  47. package/dist/plugins/fusion-plugin-reports/package.json +1 -1
  48. package/dist/plugins/fusion-plugin-roadmap/package.json +1 -1
  49. package/dist/plugins/fusion-plugin-whatsapp-chat/package.json +1 -1
  50. package/package.json +1 -1
  51. package/skill/fusion/SKILL.md +1 -1
  52. package/skill/fusion/references/extension-tools.md +47 -1
  53. package/skill/fusion/references/fusion-capabilities.md +6 -1
  54. package/dist/client/assets/ChatView-CErtz86Y.js +0 -6
  55. package/dist/client/assets/GoalsView-COI14CWJ.js +0 -1
  56. package/dist/client/assets/SettingsModal-D_uIvf6n.css +0 -1
  57. package/dist/client/assets/SettingsModal-DdrXxMPW.js +0 -31
  58. package/dist/client/assets/index-B9hAW3eU.css +0 -1
  59. package/dist/client/assets/index-w1dPHtmq.js +0 -742
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion/pi-claude-cli",
3
- "version": "0.38.0",
3
+ "version": "0.39.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.15",
3
+ "version": "0.1.17",
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.17",
3
+ "version": "0.1.19",
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.29",
3
+ "version": "0.1.31",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -137081,6 +137081,20 @@ function mapStopReason5(reason) {
137081
137081
  return "stop";
137082
137082
  }
137083
137083
  }
137084
+ function normalizeStreamingDelta(previousText, nextDelta) {
137085
+ if (!previousText || !nextDelta) {
137086
+ return nextDelta;
137087
+ }
137088
+ const previousChar = previousText.slice(-1);
137089
+ const nextChar = nextDelta[0] ?? "";
137090
+ if (/\s/.test(previousChar) || /\s/.test(nextChar)) {
137091
+ return nextDelta;
137092
+ }
137093
+ if (/[.!?]/.test(previousChar) && /[A-Z0-9"'([]/.test(nextChar)) {
137094
+ return ` ${nextDelta}`;
137095
+ }
137096
+ return nextDelta;
137097
+ }
137084
137098
  function createEventBridge(stream2, model) {
137085
137099
  const blocks = [];
137086
137100
  const output = {
@@ -137101,6 +137115,18 @@ function createEventBridge(stream2, model) {
137101
137115
  timestamp: Date.now()
137102
137116
  };
137103
137117
  let started = false;
137118
+ function getPreviousContentText(contentIndex, type) {
137119
+ for (let i2 = contentIndex - 1; i2 >= 0; i2--) {
137120
+ const contentBlock = output.content[i2];
137121
+ if (type === "text" && contentBlock?.type === "text") {
137122
+ return contentBlock.text;
137123
+ }
137124
+ if (type === "thinking" && contentBlock?.type === "thinking") {
137125
+ return contentBlock.thinking;
137126
+ }
137127
+ }
137128
+ return "";
137129
+ }
137104
137130
  function handleEvent(event) {
137105
137131
  if (!started) {
137106
137132
  stream2.push({ type: "start", partial: output });
@@ -137207,13 +137233,17 @@ function createEventBridge(stream2, model) {
137207
137233
  if (idx === -1) return;
137208
137234
  const block = blocks[idx];
137209
137235
  if (block.type === "text") {
137210
- block.text += event.delta.text;
137236
+ const delta = normalizeStreamingDelta(
137237
+ block.text || getPreviousContentText(idx, "text"),
137238
+ event.delta.text
137239
+ );
137240
+ block.text += delta;
137211
137241
  const contentBlock = output.content[idx];
137212
137242
  contentBlock.text = block.text;
137213
137243
  stream2.push({
137214
137244
  type: "text_delta",
137215
137245
  contentIndex: idx,
137216
- delta: event.delta.text,
137246
+ delta,
137217
137247
  partial: output
137218
137248
  });
137219
137249
  }
@@ -137222,13 +137252,17 @@ function createEventBridge(stream2, model) {
137222
137252
  if (idx === -1) return;
137223
137253
  const block = blocks[idx];
137224
137254
  if (block.type === "thinking") {
137225
- block.text += event.delta.thinking;
137255
+ const delta = normalizeStreamingDelta(
137256
+ block.text || getPreviousContentText(idx, "thinking"),
137257
+ event.delta.thinking
137258
+ );
137259
+ block.text += delta;
137226
137260
  const contentBlock = output.content[idx];
137227
137261
  contentBlock.thinking = block.text;
137228
137262
  stream2.push({
137229
137263
  type: "thinking_delta",
137230
137264
  contentIndex: idx,
137231
- delta: event.delta.thinking,
137265
+ delta,
137232
137266
  partial: output
137233
137267
  });
137234
137268
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fusion-plugin-examples/droid-runtime",
3
- "version": "0.1.24",
3
+ "version": "0.1.26",
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.48",
3
+ "version": "0.2.50",
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.48",
3
+ "version": "0.2.50",
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.48",
3
+ "version": "0.2.50",
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.17",
3
+ "version": "0.1.19",
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.17",
3
+ "version": "0.1.19",
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.17",
3
+ "version": "0.1.19",
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.38.0",
3
+ "version": "0.39.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",
@@ -29,7 +29,7 @@ Mission → Milestone → Slice → Feature → Task
29
29
  <!-- BEGIN: tool-categories (auto-generated by scripts/sync-fusion-skill-tools.mjs — do not edit by hand) -->
30
30
  - **Task tools** — `fn_task_create`, `fn_task_update`, `fn_task_list`, `fn_task_show`, `fn_task_attach`, `fn_task_pause`, `fn_task_unpause`, `fn_task_retry`, `fn_task_duplicate`, `fn_task_refine`, `fn_task_archive`, `fn_task_unarchive`, `fn_task_delete`, `fn_task_plan`
31
31
  - **GitHub tools** — `fn_task_import_github`, `fn_task_import_github_issue`, `fn_task_browse_github_issues`
32
- - **Mission tools** — `fn_mission_create`, `fn_mission_list`, `fn_mission_show`, `fn_mission_delete`, `fn_milestone_add`, `fn_slice_add`, `fn_feature_add`, `fn_slice_activate`, `fn_feature_link_task`, `fn_feature_update`, `fn_milestone_update`
32
+ - **Mission tools** — `fn_mission_create`, `fn_mission_list`, `fn_mission_show`, `fn_mission_backfill_assertions`, `fn_mission_delete`, `fn_mission_update`, `fn_milestone_add`, `fn_slice_add`, `fn_feature_add`, `fn_feature_delete`, `fn_slice_delete`, `fn_milestone_delete`, `fn_slice_activate`, `fn_feature_link_task`, `fn_feature_update`, `fn_milestone_update`
33
33
  - **Goal tools** — `fn_goal_list`, `fn_goal_create`, `fn_goal_archive`, `fn_goal_show`
34
34
  - **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`
35
35
  - **Skills tools** — `fn_skills_search`, `fn_skills_install`
@@ -196,6 +196,15 @@ Show mission details with full hierarchy: milestones → slices → features.
196
196
  |-----------|------|----------|-------------|
197
197
  | `id` | string | ✓ | Mission ID (e.g., M-001) |
198
198
 
199
+ ### fn_mission_backfill_assertions
200
+
201
+ Backfill mission assertions by deriving and linking one store-managed assertion for each feature without linked assertions. Supports dry-run mode.
202
+
203
+ | Parameter | Type | Required | Description |
204
+ |-----------|------|----------|-------------|
205
+ | `missionId` | string | — | Mission ID to scope backfill to (e.g., M-001) |
206
+ | `dryRun` | boolean | — | When true, preview repairs without writing changes (default: true) |
207
+
199
208
  ### fn_mission_delete
200
209
 
201
210
  Delete a mission and all its milestones, slices, and features. Cannot be undone.
@@ -204,6 +213,16 @@ Delete a mission and all its milestones, slices, and features. Cannot be undone.
204
213
  |-----------|------|----------|-------------|
205
214
  | `id` | string | ✓ | Mission ID to delete (e.g., M-001) |
206
215
 
216
+ ### fn_mission_update
217
+
218
+ Update an existing mission's title or description. Partial patches leave untouched fields intact.
219
+
220
+ | Parameter | Type | Required | Description |
221
+ |-----------|------|----------|-------------|
222
+ | `id` | string | ✓ | Mission ID to update (e.g., M-001) |
223
+ | `title` | string | — | Updated mission title |
224
+ | `description` | string | — | Updated mission description |
225
+
207
226
  ### fn_milestone_add
208
227
 
209
228
  Add a milestone to a mission. Milestones represent phases of work.
@@ -235,6 +254,33 @@ Add a feature to a slice. Features are deliverables that can be linked to tasks.
235
254
  | `description` | string | — | Feature description |
236
255
  | `acceptanceCriteria` | string | — | Acceptance criteria for completing the feature |
237
256
 
257
+ ### fn_feature_delete
258
+
259
+ Delete a feature. Rejects deletion when linked to a live task unless force=true.
260
+
261
+ | Parameter | Type | Required | Description |
262
+ |-----------|------|----------|-------------|
263
+ | `featureId` | string | ✓ | Feature ID to delete (e.g., F-001) |
264
+ | `force` | boolean | — | Override linked-task guard |
265
+
266
+ ### fn_slice_delete
267
+
268
+ Delete a slice and its features. Rejects deletion when child features link to live tasks unless force=true.
269
+
270
+ | Parameter | Type | Required | Description |
271
+ |-----------|------|----------|-------------|
272
+ | `sliceId` | string | ✓ | Slice ID to delete (e.g., SL-001) |
273
+ | `force` | boolean | — | Override linked-task guard |
274
+
275
+ ### fn_milestone_delete
276
+
277
+ Delete a milestone and all descendant slices/features. Rejects deletion when child features link to live tasks unless force=true.
278
+
279
+ | Parameter | Type | Required | Description |
280
+ |-----------|------|----------|-------------|
281
+ | `milestoneId` | string | ✓ | Milestone ID to delete (e.g., MS-001) |
282
+ | `force` | boolean | — | Override linked-task guard |
283
+
238
284
  ### fn_slice_activate
239
285
 
240
286
  Activate a pending slice for implementation. Sets status to 'active' and enables task linking for its features.
@@ -245,7 +291,7 @@ Activate a pending slice for implementation. Sets status to 'active' and enables
245
291
 
246
292
  ### fn_feature_link_task
247
293
 
248
- Link a feature to a fn task for implementation. Updates the feature status to 'triaged' and associates it with the task.
294
+ Link a feature to a fn task for implementation. Updates the feature status to 'triaged' and associates it with the task. If the target task is not on the active board (for example archived, deleted, or never created), the tool returns a clear validation error indicating that only active tasks can be linked.
249
295
 
250
296
  | Parameter | Type | Required | Description |
251
297
  |-----------|------|----------|-------------|
@@ -48,12 +48,17 @@ All skill/extension tool invocations in this catalog use the public `fn_*` names
48
48
  | `fn_goal_archive` | Archive a goal by ID. |
49
49
  | `fn_goal_show` | Show full details for a single goal by ID. |
50
50
  | `fn_mission_show` | Show mission details with full hierarchy: milestones → slices → features. |
51
+ | `fn_mission_backfill_assertions` | Backfill mission assertions by deriving and linking one store-managed assertion for each feature without linked assertions. Supports dry-run mode. |
51
52
  | `fn_mission_delete` | Delete a mission and all its milestones, slices, and features. Cannot be undone. |
53
+ | `fn_mission_update` | Update an existing mission's title or description. Partial patches leave untouched fields intact. |
52
54
  | `fn_milestone_add` | Add a milestone to a mission. Milestones represent phases of work. |
53
55
  | `fn_slice_add` | Add a slice to a milestone. Slices are work units that can be activated for implementation. |
54
56
  | `fn_feature_add` | Add a feature to a slice. Features are deliverables that can be linked to tasks. |
57
+ | `fn_feature_delete` | Delete a feature. Rejects deletion when linked to a live task unless force=true. |
58
+ | `fn_slice_delete` | Delete a slice and its features. Rejects deletion when child features link to live tasks unless force=true. |
59
+ | `fn_milestone_delete` | Delete a milestone and all descendant slices/features. Rejects deletion when child features link to live tasks unless force=true. |
55
60
  | `fn_slice_activate` | Activate a pending slice for implementation. Sets status to 'active' and enables task linking for its features. |
56
- | `fn_feature_link_task` | Link a feature to a fn task for implementation. Updates the feature status to 'triaged' and associates it with the task. |
61
+ | `fn_feature_link_task` | Link a feature to a fn task for implementation. Updates the feature status to 'triaged' and associates it with the task. If the target task is not on the active board (for example archived, deleted, or never created), the tool returns a clear validation error indicating that only active tasks can be linked. |
57
62
  | `fn_feature_update` | Update an existing feature's title, description, or acceptance criteria. Partial patches leave untouched fields intact. |
58
63
  | `fn_milestone_update` | Update an existing milestone's title, description, or acceptance criteria (the structured pass/fail bar, distinct from verification's free-form how-to-confirm notes). Partial patches leave untouched fields intact. |
59
64
  | `fn_agent_stop` | Stop a running agent — pauses its execution. Transitions the agent from running/active to paused state. |
@@ -1,6 +0,0 @@
1
- import{r as s,a as wn,j as t,R as Sn}from"./vendor-react-K0fH_qHe.js";import{c as Cn,a9 as Ts,a7 as Is,bd as $s,be as ls,aG as At,bf as Ds,ac as Ps,bg as ts,t as kn,bh as Nn,bi as Ls,bj as jn,bk as ss,w as Mn,bl as Rn,bm as An,bn as En,bo as Tn,bp as In,bq as $n,br as Dn,s as Pn,bs as Ln,j as Fn,k as Qs,bt as _n,bu as zn,bv as Zs,bw as Hn,bx as Un,by as On,p as Bn,bz as Kn,bA as Gn,u as Wn,bB as Vn,ah as en,ai as tn,bC as qn,bD as Xn,S as Yn,_ as ns,P as dt,J as lt,aw as Jn,bE as Fs,a as Nt,bF as _s,bG as zs,bH as Hs,B as ut,ae as Qn,af as Zn,b2 as Et,bI as ea,bJ as ta,a$ as sa,bK as Us,bL as na,T as aa,bM as Os,bN as ra,au as Bs,m as ia}from"./index-w1dPHtmq.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 oa=[["path",{d:"M5 3h14",key:"7usisc"}],["path",{d:"m18 13-6-6-6 6",key:"1kf1n9"}],["path",{d:"M12 7v14",key:"1akyts"}]],ca=Cn("arrow-up-to-line",oa),as="kb-chat-active-session";function Ks(n){const r=typeof n=="string"?n.trim():"",d=r.indexOf("/");return!r||d<=0||d>=r.length-1?{}:{modelProvider:r.slice(0,d),modelId:r.slice(d+1)}}function la(n){const r=n?.toolCalls;if(!Array.isArray(r))return;const d=r.map(i=>{if(!i||typeof i!="object")return null;const g=i,b=typeof g.toolName=="string"?g.toolName:"";if(!b)return null;const y=g.args;return{toolName:b,...y&&typeof y=="object"?{args:y}:{},isError:!!g.isError,result:g.result,status:"completed"}}).filter(i=>i!==null);return d.length>0?d:void 0}function da(n){const r=n?.fallback;if(!r||typeof r!="object")return;const d=r,i=typeof d.primaryModel=="string"?d.primaryModel:"",g=typeof d.fallbackModel=="string"?d.fallbackModel:"",b=d.triggerPoint;if(!(!i||!g||b!=="session-creation"&&b!=="prompt-time"))return{primaryModel:i,fallbackModel:g,triggerPoint:b}}function ua(n){const r=n?.failureInfo;if(!r||typeof r!="object")return;const d=r,i=typeof d.summary=="string"?d.summary.trim():"";if(!i)return;const g=(()=>{const b=d.reference;if(!b||typeof b!="object")return;const y=b,f=typeof y.kind=="string"?y.kind.trim():"",I=typeof y.id=="string"?y.id.trim():"";if(!(!f||!I))return{kind:f,id:I,...typeof y.label=="string"&&y.label.trim()?{label:y.label.trim()}:{}}})();return{summary:i,...typeof d.errorClass=="string"&&d.errorClass.trim()?{errorClass:d.errorClass.trim()}:{},...typeof d.code=="string"&&d.code.trim()?{code:d.code.trim()}:{},...typeof d.detail=="string"&&d.detail.trim()?{detail:d.detail.trim()}:{},...g?{reference:g}:{}}}function Gs(n){return typeof n=="string"?{summary:n.trim()||"Failed to get response"}:{summary:typeof n.summary=="string"&&n.summary.trim()?n.summary.trim():"Failed to get response",...typeof n.errorClass=="string"&&n.errorClass.trim()?{errorClass:n.errorClass.trim()}:{},...typeof n.code=="string"&&n.code.trim()?{code:n.code.trim()}:{},...typeof n.detail=="string"&&n.detail.trim()?{detail:n.detail.trim()}:{},...n.reference?{reference:n.reference}:{}}}function rs(n){return{id:n.id,sessionId:n.sessionId,role:n.role,content:n.content,thinkingOutput:n.thinkingOutput,toolCalls:la(n.metadata),fallbackInfo:da(n.metadata),failureInfo:ua(n.metadata),attachments:n.attachments,createdAt:n.createdAt}}function ma(n,r){const d=s.useCallback(l=>l?`${Ts.CHAT_SESSIONS_PREFIX}${l}`:null,[]),i=s.useCallback((l,u)=>l&&u?`${Ts.CHAT_MESSAGES_PREFIX}${l}:${u}`:null,[]),g=s.useCallback(l=>{const u=d(l);return u?Is(u,{maxAgeMs:$s})??[]:[]},[d]),[b,y]=s.useState(()=>g(n)),[f,I]=s.useState(null),[J,Q]=s.useState(()=>g(n).length===0),[w,j]=s.useState([]),[z,S]=s.useState(!1),[Z,C]=s.useState(!1),[O,N]=s.useState(""),[X,E]=s.useState(""),[_,T]=s.useState([]),[Y,k]=s.useState(""),[B,te]=s.useState(""),[h,p]=s.useState(!1),{agentsMap:he}=ls(n),c=s.useRef(null),re=s.useRef(null),se=s.useRef(!1),$=s.useRef(""),ue=s.useRef(null),be=s.useRef(b),G=s.useRef(f),Ge=s.useRef(w),K=s.useRef(Z);be.current=b,G.current=f,Ge.current=w,K.current=Z,s.useEffect(()=>{$.current=Y},[Y]);const We=s.useRef(new Set),ye=s.useRef(0),Ie=s.useRef(n);Ie.current!==n&&(At({view:"useChat",trigger:"project-context-change",projectId:n,replayAttempted:!1,detail:{previousProjectId:Ie.current??null}}),Ie.current=n,ye.current++);const oe=s.useCallback(async()=>{be.current.length===0&&Q(!0);try{const u=[...(await Ds(n)).sessions].sort((D,H)=>new Date(H.updatedAt).getTime()-new Date(D.updatedAt).getTime());y(u);const v=d(n);v&&Ps(v,u,{maxBytes:5e5})}catch{const l=g(n);if(be.current.length===0&&l.length===0){const u=d(n);u&&ts(u)}}finally{Q(!1)}},[d,n]);s.useEffect(()=>{const l=g(n);y(l),Q(l.length===0)},[n,g]),s.useEffect(()=>{oe()},[oe,n]);const Se=s.useRef(()=>{}),Ce=s.useRef(!1);s.useEffect(()=>{Ce.current=!1,re.current=null},[n]),s.useEffect(()=>{if(J||Ce.current||G.current)return;const l=kn(as,n);if(!l){Ce.current=!0;return}const u=b.find(v=>v.id===l);if(u){Ce.current=!0,Se.current(l,u);return}Ce.current=!0},[J,b,n]);const Ve=s.useCallback((l,u)=>{const v=i(l,u);return v?Is(v,{maxAgeMs:$s})??[]:[]},[i]),Oe=s.useCallback(l=>{const u=Ve(n,l);return u.length>0?(j(u),S(!1),!0):(j([]),!1)},[n,Ve]),ce=s.useCallback(async(l,u)=>{const v=typeof u?.offset=="number"&&u.offset>0||typeof u?.before=="string",D=i(n,l),H=v?[]:Ve(n,l),A=H.length>0;!v&&A?(j(H),S(!1)):S(!0);try{const ee=await Nn(l,{limit:50,order:"desc",...u},n),M=ee.messages.slice().reverse().map(rs);v?G.current?.id===l&&(j(U=>[...M,...U]),p(ee.messages.length>=50)):G.current?.id===l&&(j(M),p(ee.messages.length>=50),D&&Ps(D,M,{maxBytes:5e5}))}catch{!v&&Ge.current.length===0&&A&&(j(H),S(!1))}finally{S(!1)}},[i,n,Ve]),me=s.useCallback(()=>{ue.current?.(),ue.current=null,$.current="",k(""),N(""),E(""),T([]),C(!1)},[]),mt=s.useCallback(()=>{$.current="",k("")},[]),ie=s.useCallback(()=>{const l=$.current.trim();l&&($.current="",k(""),Be.current(l))},[]),le=s.useCallback((l,u,v)=>{if(c.current||!l)return!0;se.current=!1,u&&(N(u.streamingText),E(u.streamingThinking),T(u.toolCalls)),C(!0);const{handlers:D}=Ls({sessionId:l,tempUserMessageId:"",setStreamingText:N,setStreamingThinking:E,setStreamingToolCalls:T,cancelStreamingFlushesRef:ue,addToast:v?.silent?void 0:r,onFallbackSession:(A,ee)=>{const M=Ks(A.fallbackModel);y(U=>U.map(W=>W.id===ee?{...W,...M}:W)),I(U=>U&&U.id===ee?{...U,...M}:U)},onDone:()=>{N(""),E(""),T([]),C(!1),K.current=!1,c.current=null,re.current=null,ce(l),ie()},onError:A=>{N(""),E(""),T([]),C(!1),K.current=!1,c.current=null,re.current=null;const ee=Gs(A);v?.silent||r?.(ee.summary,"error"),ce(l),ie()}});At({view:"useChat",trigger:"sse-open",projectId:n,replayAttempted:typeof u?.replayFromEventId=="number",replayFromEventId:u?.replayFromEventId??null,lastEventId:u?.replayFromEventId??null});const H=jn(l,D,n,{...typeof u?.replayFromEventId=="number"?{lastEventId:u.replayFromEventId}:{}});return c.current=H,re.current={sessionId:l,replayFromEventId:typeof u?.replayFromEventId=="number"?u.replayFromEventId:null},!0},[r,ce,n,ie]),$e=s.useCallback((l,u)=>{const v=G.current?.id??null;if(l&&v===l&&!u)return;c.current&&(c.current.close(),c.current=null),re.current=null;const D=u??b.find(H=>H.id===l);I(D||null),l&&ss(l,n).then(({session:H})=>{!H.isGenerating||!H.inFlightGeneration||I(A=>!A||A.id!==l?A:{...A,...H})}).catch(()=>{}),me(),p(!1),l?(Oe(l),ce(l)):j([]),D?.isGenerating&&le(D.id,D.inFlightGeneration),l?Mn(as,l,n):Rn(as,n)},[le,Oe,b,ce,n,me]);Se.current=$e;const Tt=s.useCallback(async l=>{const u=await An(l,n);c.current&&(c.current.close(),c.current=null),re.current=null;const v={id:u.session.id,title:u.session.title,agentId:u.session.agentId,status:u.session.status,modelProvider:u.session.modelProvider,modelId:u.session.modelId,createdAt:u.session.createdAt,updatedAt:u.session.updatedAt};return y(D=>D.some(H=>H.id===v.id)?D:[v,...D]),me(),$e(v.id,v),v},[n,me,$e]),De=s.useCallback(async l=>{await En(l,{status:"archived"},n),y(u=>u.filter(v=>v.id!==l)),f?.id===l&&(re.current=null,I(null),j([]))},[f,n]),Pe=s.useCallback(async l=>{f?.id===l&&c.current&&(c.current.close(),c.current=null),f?.id===l&&(re.current=null),await Tn(l,n);const u=i(n,l);u&&ts(u),y(v=>v.filter(D=>D.id!==l)),f?.id===l&&(I(null),j([]))},[f,i,n]),nt=s.useCallback(async()=>{if(!f||!h)return;const l=Ge.current[0]?.createdAt;l&&await ce(f.id,{before:l})},[f,h,ce]),qe=s.useCallback(()=>{f&&(se.current=!0,ue.current?.(),ue.current=null,c.current?.close(),c.current=null,re.current=null,In(f.id,n).catch(()=>{}),C(!1),K.current=!1,N(""),E(""),T([]),ie())},[f,n,ie]),Be=s.useRef(()=>{}),Le=$n(),ke=s.useCallback(async l=>{try{await oe();const u=await ss(l,n);G.current?.id===l&&I(v=>!v||v.id!==l?v:{...v,...u.session}),u.session.isGenerating?(N(""),E(""),T([]),C(!0),K.current=!0,le(l,u.session.inFlightGeneration,{silent:!0})):(N(""),E(""),T([]),C(!1),K.current=!1,await ce(l))}catch{}},[le,ce,n,oe]),Ne=s.useCallback((l,u)=>{if(!f)return;if(K.current){$.current=l,k(l);return}se.current=!1,c.current&&(c.current.close(),c.current=null),re.current=null;const v=`temp-${Date.now()}`,D={id:v,sessionId:f.id,role:"user",content:l,createdAt:new Date().toISOString()};j(A=>[...A,D]),N(""),E(""),T([]),C(!0);const{handlers:H}=Ls({sessionId:f.id,tempUserMessageId:v,setStreamingText:N,setStreamingThinking:E,setStreamingToolCalls:T,cancelStreamingFlushesRef:ue,addToast:r,onFallbackSession:(A,ee)=>{const M=Ks(A.fallbackModel);y(U=>U.map(W=>W.id===ee?{...W,...M}:W)),I(U=>U&&U.id===ee?{...U,...M}:U)},onDone:({messageId:A,message:ee,accumulated:M})=>{const U=ee?{...rs(ee),...M.text.length>0?{content:M.text}:{}}:{id:A||`msg-${Date.now()}`,sessionId:f.id,role:"assistant",content:M.text,thinkingOutput:M.thinking,toolCalls:M.toolCalls.length>0?M.toolCalls:void 0,fallbackInfo:M.fallbackInfo,createdAt:new Date().toISOString()};We.current.add(U.id),j(W=>[...W,U]),N(""),E(""),T([]),C(!1),K.current=!1,c.current=null,re.current=null,setTimeout(()=>{We.current.delete(U.id)},1e3),oe(),ie()},onError:(A,ee)=>{const M=Gs(A),U=typeof A=="string"?A:M.summary,W=Ln(U);j(V=>{const P=V.filter(q=>q.id!==ee);return W?P:[...P,{id:`error-${Date.now()}`,sessionId:f.id,role:"assistant",content:M.summary,failureInfo:M,createdAt:new Date().toISOString()}]}),N(""),E(""),T([]),C(!1),K.current=!1,c.current=null,re.current=null,console.error("[useChat] Stream error:",A),W?(console.info("[useChat] Suppressed tab-suspension stream error:",A),f?.id&&(N(""),E(""),T([]),C(!0),K.current=!0,ke(f.id))):(r?.(M.summary,"error"),oe()),se.current||ie()}});c.current=Dn(f.id,l,H,u,n)},[f,n,oe,r,le,ke,ie]);Be.current=Ne;const ve=B?b.filter(l=>l.title?.toLowerCase().includes(B.toLowerCase())||l.agentId.toLowerCase().includes(B.toLowerCase())):b;return s.useEffect(()=>{if(!f?.id||f.isGenerating!==!0||c.current)return;const l=typeof f.inFlightGeneration?.replayFromEventId=="number"?f.inFlightGeneration.replayFromEventId:null,u=re.current;u?.sessionId===f.id&&u.replayFromEventId===l||le(f.id,f.inFlightGeneration,{silent:!0})},[f?.id,f?.isGenerating,f?.inFlightGeneration,le]),s.useEffect(()=>{if(!G.current?.isGenerating||(c.current||le(G.current.id,G.current.inFlightGeneration),!K.current||c.current||!G.current))return;const l=setInterval(async()=>{if(!K.current||c.current||!G.current){clearInterval(l);return}try{(await Ds(n)).sessions.find(D=>D.id===G.current?.id)?.isGenerating||(clearInterval(l),await ce(G.current.id),N(""),E(""),T([]),C(!1),K.current=!1,ie())}catch{}},3e3);return()=>clearInterval(l)},[le,ce,n,f,ie]),s.useEffect(()=>Le.onBecameVisible(()=>{const u=G.current;if(!u||c.current)return;const v=ye.current;ss(u.id,n).then(D=>{if(!(ye.current!==v||c.current)){if(D.session.isGenerating){N(""),E(""),T([]),C(!0),K.current=!0,le(u.id,D.session.inFlightGeneration,{silent:!0});return}K.current&&(N(""),E(""),T([]),C(!1),K.current=!1,ie(),ce(u.id))}}).catch(()=>{})}),[le,ce,n,Le,ie]),s.useEffect(()=>{const l=ye.current,u=n?`?projectId=${encodeURIComponent(n)}`:"",v=()=>ye.current!==l,D=W=>{if(v())return;const V=JSON.parse(W.data);y(P=>P.some(q=>q.id===V.id)?P:[V,...P])},H=W=>{if(v())return;const V=JSON.parse(W.data);y(P=>[...P.map(ne=>ne.id===V.id?V:ne)]),G.current?.id===V.id&&(I(V),V.isGenerating&&!c.current&&le(V.id,V.inFlightGeneration))},A=W=>{if(v())return;const{id:V}=JSON.parse(W.data);y(q=>q.filter(ne=>ne.id!==V));const P=i(n,V);P&&ts(P),G.current?.id===V&&(I(null),j([]))},ee=W=>{if(v())return;const V=JSON.parse(W.data),P=rs(V);if(!We.current.has(P.id)){if(G.current?.id===P.sessionId&&K.current&&!c.current&&P.role==="assistant"){j(q=>q.some(ne=>ne.id===P.id)?q:[...q,P]),N(""),E(""),T([]),C(!1),K.current=!1,ie();return}G.current?.id===P.sessionId&&!K.current&&j(q=>{if(q.some(ne=>ne.id===P.id))return q;if(P.role==="user"){const ne=q.findIndex(je=>je.role==="user"&&je.id.startsWith("temp-")&&je.content.trim()===P.content.trim());if(ne>=0){const je=[...q];return je[ne]=P,je}}return[...q,P]})}},M=W=>{if(v())return;const{id:V}=JSON.parse(W.data);j(P=>P.filter(q=>q.id!==V))};return Pn(`/api/events${u}`,{events:{"chat:session:created":D,"chat:session:updated":H,"chat:session:deleted":A,"chat:message:added":ee,"chat:message:deleted":M}})},[le,i,n,ie]),s.useEffect(()=>()=>{c.current&&(c.current.close(),c.current=null),re.current=null},[]),{sessions:b,activeSession:f,sessionsLoading:J,messages:w,messagesLoading:z,isStreaming:Z,streamingText:O,streamingThinking:X,streamingToolCalls:_,pendingMessage:Y,selectSession:$e,createSession:Tt,archiveSession:De,deleteSession:Pe,sendMessage:Ne,stopStreaming:qe,clearPendingMessage:mt,loadMoreMessages:nt,hasMoreMessages:h,searchQuery:B,setSearchQuery:te,filteredSessions:ve,refreshSessions:oe,agentsMap:he}}function ha(n,r=[]){const d=n.trim().replace(/^#/,"");if(!d)return{ok:!1,error:"Room name is required."};if(/[A-Z]/.test(d))return{ok:!1,error:"Use lowercase letters only."};const i=d.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(g=>g.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 fa({isOpen:n,onClose:r,onCreate:d,projectId:i,existingRoomNames:g=[]}){const[b,y]=s.useState(""),[f,I]=s.useState([]),[J,Q]=s.useState(""),[w,j]=s.useState([]),[z,S]=s.useState(!1),[Z,C]=s.useState(null),[O,N]=s.useState(!1),X=s.useRef(null),E=s.useRef(null);s.useEffect(()=>{n&&(E.current=document.activeElement instanceof HTMLElement?document.activeElement:null,S(!0),C(null),Fn(void 0,i).then(h=>I(h)).catch(()=>{I([]),C("Failed to load agents.")}).finally(()=>S(!1)))},[n,i]),s.useEffect(()=>{if(!n){y(""),Q(""),j([]),C(null),N(!1);return}const h=window.requestAnimationFrame(()=>X.current?.focus());return()=>window.cancelAnimationFrame(h)},[n]),s.useEffect(()=>{if(!n)return;const h=p=>{p.key==="Escape"&&r()};return document.addEventListener("keydown",h),()=>document.removeEventListener("keydown",h)},[n,r]),s.useEffect(()=>{n||E.current?.focus()},[n]);const _=s.useMemo(()=>ha(b,g),[b,g]),T=s.useMemo(()=>{const h=J.trim().toLowerCase();return h?f.filter(p=>p.name.toLowerCase().includes(h)):f},[f,J]),Y=s.useMemo(()=>f.filter(h=>w.includes(h.id)),[f,w]),k=_.ok&&w.length>0&&!O&&!z;if(!n)return null;const B=h=>{O||j(p=>p.includes(h)?p.filter(he=>he!==h):[...p,h])},te=async()=>{if(!_.ok){C(_.error);return}if(w.length===0){C("Select at least one member.");return}C(null),N(!0);try{await d({name:_.name,displayName:`#${_.name}`,memberAgentIds:w}),r()}catch(h){C(h instanceof Error?h.message:"Failed to create room.")}finally{N(!1)}};return wn.createPortal(t.jsx("div",{className:"modal-overlay open",onClick:h=>h.target===h.currentTarget&&r(),children:t.jsxs("div",{className:"modal modal-lg create-room-modal",role:"dialog","aria-modal":"true","aria-label":"Create room",onClick:h=>h.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:X,id:"create-room-name",className:"input",value:b,disabled:O,onChange:h=>{const p=h.target.value.replace(/^#/,"").replace(/\s+/g,"-").toLowerCase();y(p)}})]}),!_.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:J,disabled:O,onChange:h=>Q(h.target.value)})]}),Y.length>0&&t.jsx("div",{className:"create-room-modal-selected","data-testid":"create-room-selected-chips",children:Y.map(h=>t.jsxs("button",{type:"button",className:"btn btn-sm create-room-modal-chip",onClick:()=>B(h.id),disabled:O,children:[h.name," ×"]},h.id))}),t.jsx("div",{className:"create-room-modal-member-list","data-testid":"create-room-member-list",children:z?t.jsx("div",{className:"create-room-modal-empty",children:"Loading agents..."}):T.length===0?t.jsx("div",{className:"create-room-modal-empty",children:f.length===0?"No agents in this project yet.":"No agents match your search."}):T.map(h=>{const p=w.includes(h.id);return t.jsxs("button",{type:"button",className:`create-room-modal-member-row${p?" create-room-modal-member-row--selected":""}`,onClick:()=>B(h.id),disabled:O,children:[t.jsx(Qs,{agent:h,size:20}),t.jsx("span",{children:h.name}),t.jsx("span",{className:"create-room-modal-member-role",children:h.role})]},h.id)})}),Z&&t.jsx("div",{className:"form-group",children:t.jsx("div",{className:"form-error",children:Z})}),t.jsxs("div",{className:"modal-actions",children:[t.jsx("button",{type:"button",className:"btn",onClick:r,disabled:O,children:"Cancel"}),t.jsx("button",{type:"button",className:"btn btn-primary",onClick:()=>void te(),disabled:!k,children:O?"Creating...":"Create room"})]})]})}),document.body)}const sn=640;let is=!1;function ga(n){return n>sn?"auto":"hidden"}function pa(n){return Math.max(40,Math.min(n,sn))}function nn(n){const r=new Date(n),i=new Date().getTime()-r.getTime(),g=Math.floor(i/1e3),b=Math.floor(g/60),y=Math.floor(b/60),f=Math.floor(y/24);return g<60?"just now":b<60?`${b}m ago`:y<24?`${y}h ago`:f<7?`${f}d ago`:r.toLocaleDateString()}function Ws(n,r){if(!n||!r)return null;const d=r.toLowerCase();if(d.includes("claude")){let g=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 g=g.replace(/\s+/g," "),g.length>30?g.slice(0,30)+"…":g}if(d.includes("gpt")||d.includes("openai")){const g=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 g.length>30?g.slice(0,30)+"…":g}if(d.includes("gemini")){const g=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 g.length>30?g.slice(0,30)+"…":g}const i=r.replace(/-/g," ").replace(/^\w/,g=>g.toUpperCase()).replace(/\s+/g," ").trim();return i.length>30?i.slice(0,30)+"…":i}function Rt(n,r){return n.length<=r?n:`${n.slice(0,r)}…`}function ba(n){if(!n)return null;const r=Object.entries(n);return r.length===0?null:r.map(([d,i])=>{const g=typeof i=="string"?i:(()=>{try{return JSON.stringify(i)}catch{return String(i)}})();return`${d}=${Rt(g,50)}`}).join(", ")}function va(n){if(n===void 0)return null;if(typeof n=="string")return Rt(n,200);try{return Rt(JSON.stringify(n),200)}catch{return Rt(String(n),200)}}function xa(n){if(!n)return null;if(n.kind==="mailbox"||n.kind==="mailbox-message"){const r=typeof window>"u"?"/":window.location.pathname||"/",d=new URLSearchParams(typeof window>"u"?"":window.location.search);return d.set("view","mailbox"),d.set("mailbox-message",n.id),`${r}?${d.toString()}#message-${encodeURIComponent(n.id)}`}return null}function ya(n){if(!n)return null;const r=n.label??`${n.kind} ${n.id}`,d=xa(n),i=`chat-failure-reference-${n.kind}-${n.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}),d?t.jsx("a",{className:"btn btn-sm chat-message-failure-reference-link",href:d,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:n.kind})]}),t.jsxs("div",{children:[t.jsx("dt",{children:"ID"}),t.jsx("dd",{children:n.id})]}),n.label&&t.jsxs("div",{children:[t.jsx("dt",{children:"Label"}),t.jsx("dd",{children:n.label})]})]})]})]})}function an(n){if(!n||n.length===0)return null;const r=(w,j)=>{const z=w.status==="running",S=w.status==="completed"&&w.isError,Z=ba(w.args),C=va(w.result),O=z?Z:C?`result: ${C}`:Z?`args: ${Z}`:null,N=z?"running":S?"error":"completed";return t.jsxs("details",{className:`chat-tool-call${z?" chat-tool-call--running":""}${S?" chat-tool-call--error":""}`,open:z,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:w.toolName,children:w.toolName}),O&&t.jsx("span",{className:"chat-tool-call-preview",title:O,children:O}),t.jsx("span",{className:"chat-tool-call-status-text",children:N})]}),t.jsxs("div",{className:"chat-tool-call-content",children:[Z&&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:Z})]}),C&&t.jsxs("div",{className:`chat-tool-call-row${S?" 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:C})]})]})]},`${w.toolName}-${j}`)},d="chat-tool-calls";if(n.length===1)return t.jsxs("div",{className:d,"data-testid":"chat-tool-calls",children:[t.jsxs("div",{className:"chat-tool-calls-header",children:[t.jsx(Os,{size:12,"aria-hidden":"true"}),t.jsx("span",{children:"Tool calls"})]}),r(n[0],0)]});const i=n.filter(w=>w.status==="running").length,g=n.filter(w=>w.status==="completed"&&w.isError).length,b=i>0,y=Array.from(new Set(n.map(w=>w.toolName))),f=y.slice(0,5),I=Math.max(0,y.length-f.length),J=I>0?`${f.join(", ")}, +${I} more`:f.join(", "),Q=b?`(${i} running)`:g>0?`(${g} ${g===1?"error":"errors"})`:null;return t.jsx("div",{className:d,"data-testid":"chat-tool-calls",children:t.jsxs("details",{className:"chat-tool-calls-group","data-testid":"chat-tool-calls-group",open:b,children:[t.jsxs("summary",{className:"chat-tool-calls-group-summary",children:[t.jsx(Os,{size:12,"aria-hidden":"true"}),t.jsxs("span",{className:"chat-tool-calls-count",children:[n.length," tool calls"]}),t.jsx("span",{className:"chat-tool-calls-names",title:J,children:J}),Q&&t.jsx("span",{className:"chat-tool-calls-group-status",children:Q})]}),n.map((w,j)=>r(w,j))]})})}const rn={p:({children:n,...r})=>t.jsx("p",{...r,children:Us(n)}),li:({children:n,...r})=>t.jsx("li",{...r,children:Us(n)}),pre:({children:n,...r})=>t.jsx("pre",{...r,className:"chat-markdown-pre",children:n}),code:({children:n,...r})=>{const d=typeof n=="string"?n:Sn.Children.toArray(n).join(""),i=Et(d);return i.length===1&&typeof i[0]=="string"?t.jsx("code",{...r,children:n}):t.jsx("code",{...r,children:i})},table:({children:n,...r})=>t.jsx("table",{...r,className:"chat-markdown-table",children:n})},st="__fn_agent__",wa=280,jt=180,Mt=500,Vs="fusion:chat-sidebar-width",os="fusion:chat-scope",Sa="fusion:chat-draft:";function qs(n,r){return r?`${Sa}${n}:${r}`:null}function Xs(n){if(!n)return"";try{return localStorage.getItem(n)??""}catch{return""}}const Ca=["image/png","image/jpeg","image/gif","image/webp","text/plain","application/json","text/yaml","text/markdown","text/csv","application/xml","text/x-log"];function Ys(n){const r=/(^|[\s])\/([^\s]*)$/.exec(n);if(!r)return null;const d=r[1]??"",i=r[2]??"",g=r.index+d.length;return{filter:i,start:g,end:n.length}}function ka(n,r){const d=n.slice(0,r),i=/(^|[\s\n])@([\w-]*)$/.exec(d);if(!i)return null;const g=i[2]??"",b=d.length-g.length-1;return{filter:g,start:b,end:r}}function Na(n){const r=n?.runtimeConfig;if(!r||typeof r!="object")return null;const d=Reflect.get(r,"modelProvider"),i=Reflect.get(r,"modelId");return typeof d!="string"||d.trim().length===0||typeof i!="string"||i.trim().length===0?null:{provider:d,modelId:i}}function Js(n,r,d){if(n?.modelProvider&&n?.modelId)return{provider:n.modelProvider,modelId:n.modelId};const i=Na(r??void 0);return i||(d.provider&&d.modelId?{provider:d.provider,modelId:d.modelId}:null)}function ja({projectId:n,onClose:r,onCreate:d}){const[i,g]=s.useState("agent"),{agents:b,loading:y}=ls(n),[f,I]=s.useState(""),{models:J,favoriteProviders:Q,favoriteModels:w,loading:j,refresh:z}=Zs(),[S,Z]=s.useState(""),[C,O]=s.useState(Q),[N,X]=s.useState(w);s.useEffect(()=>{O(Q)},[Q]),s.useEffect(()=>{X(w)},[w]);const E=s.useCallback(async k=>{const B=C,h=B.includes(k)?B.filter(p=>p!==k):[k,...B];O(h);try{await Bs({favoriteProviders:h,favoriteModels:N}),await z()}catch{O(B)}},[C,N,z]),_=s.useCallback(async k=>{const B=N,h=B.includes(k)?B.filter(p=>p!==k):[k,...B];X(h);try{await Bs({favoriteProviders:C,favoriteModels:h}),await z()}catch{X(B)}},[N,C,z]),T=k=>{if(k.preventDefault(),i==="agent"){if(!f)return;d({agentId:f});return}if(!S)return;const B=S.indexOf("/");if(B<=0)return;const te=S.slice(0,B),h=S.slice(B+1);d({agentId:st,modelProvider:te,modelId:h})},Y=i==="agent"?!f:!S;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:k=>k.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:()=>{g("agent"),Z("")},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:()=>{g("model"),I("")},children:"Model"})]}),t.jsxs("form",{onSubmit:T,children:[i==="agent"&&t.jsxs("label",{className:"chat-new-dialog-model-label",children:["Agent",y?t.jsx("div",{className:"chat-new-dialog-loading",children:"Loading agents..."}):b.length===0?t.jsx("div",{className:"chat-new-dialog-empty",children:"No agents available"}):t.jsx("div",{className:"chat-new-dialog-agent-list",children:b.map(k=>t.jsxs("button",{type:"button",className:`chat-new-dialog-agent-item${f===k.id?" chat-new-dialog-agent-item--selected":""}`,onClick:()=>I(k.id),"data-testid":`agent-option-${k.id}`,children:[t.jsx(ut,{size:16}),t.jsx("span",{className:"chat-new-dialog-agent-name",children:k.name}),t.jsx("span",{className:"chat-new-dialog-agent-role",children:k.role})]},k.id))})]}),i==="model"&&t.jsx("div",{className:"chat-new-dialog-model-dropdown","data-testid":"chat-new-dialog-model-section",children:j?t.jsx("div",{className:"chat-new-dialog-loading",children:"Loading models..."}):t.jsx(ia,{models:J,value:S,onChange:Z,label:"Model",placeholder:"Select a model",favoriteProviders:C,onToggleFavorite:E,favoriteModels:N,onToggleModelFavorite:_})}),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:Y,children:"Create"})]})]})]})})}const cs=s.memo(function({message:r,forcePlain:d,agentName:i,hideAssistantIdentity:g,showAssistantModelTag:b,activeModelTag:y,activeModelProvider:f,activeSessionId:I,mentionAgentsByName:J,roomContext:Q,copyAction:w,onScrollToTop:j}){const z=r.role==="assistant",S=z?r.failureInfo:void 0,Z=z&&(!g||!!S),C=s.useMemo(()=>{if(z)return null;const X=r.content,E=/@([\w-]+)/g,_=[];let T=0,Y=E.exec(X);for(;Y;){const[k,B=""]=Y,te=Y.index;te>T&&_.push(X.slice(T,te));const h=B.replace(/_/g," ").toLowerCase(),p=J.get(h);if(p){const he=!!(Q&&!Q.memberIds.has(p.id)),c=he?`Not a member of ${Q?.roomName}`:void 0;_.push(t.jsxs("span",{className:`chat-mention-chip${he?" chat-mention-chip--non-member":""}`,title:c,"aria-label":c,children:["@",p.name.replace(/\s+/g,"_")]},`${p.id}-${te}`))}else _.push(k);T=te+k.length,Y=E.exec(X)}return T<X.length&&_.push(X.slice(T)),_.length===0?X:_},[z,r.content,J,Q]),O=s.useMemo(()=>{const X=r.attachments;if(!X||X.length===0)return null;const E=r.roomId?`/api/chat/rooms/${encodeURIComponent(r.roomId)}/attachments/`:I?`/api/chat/sessions/${encodeURIComponent(I)}/attachments/`:null;return E?t.jsx("div",{className:"chat-message-attachments",children:X.map(_=>{const T=_.mimeType.startsWith("image/"),Y=_.id||_.filename,k=`${E}${encodeURIComponent(_.filename)}`;return T?t.jsx("a",{className:"chat-message-attachment-link","data-testid":"chat-message-attachment",href:k,target:"_blank",rel:"noopener noreferrer",children:t.jsx("img",{className:"chat-message-attachment",src:k,alt:_.originalName})},Y):t.jsxs("a",{className:"chat-message-attachment-file","data-testid":"chat-message-attachment",href:k,target:"_blank",rel:"noopener noreferrer",children:[t.jsx(na,{size:14}),t.jsx("span",{children:_.originalName})]},Y)})}):null},[r.attachments,r.roomId,I]),N=s.useMemo(()=>z?S?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:S.summary}),(S.errorClass||S.code)&&t.jsxs("div",{className:"chat-message-failure-badges",children:[S.errorClass&&t.jsx("span",{className:"chat-message-failure-badge",children:S.errorClass}),S.code&&t.jsx("span",{className:"chat-message-failure-badge",children:S.code})]}),(S.detail||S.reference)&&t.jsxs("details",{className:"chat-message-failure-details",children:[t.jsxs("summary",{children:[t.jsx(aa,{size:14,"aria-hidden":"true"}),t.jsx("span",{children:"Failure details"})]}),S.detail&&t.jsx("pre",{className:"chat-message-failure-detail",children:Et(S.detail)}),ya(S.reference)]})]}):d?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(en,{remarkPlugins:[tn],components:rn,children:r.content})}):null,[S,d,z,r.content]);return t.jsxs("div",{className:`chat-message chat-message--${r.role}${S?" chat-message--failure":""}`,"data-testid":`chat-message-${r.id}`,"data-message-id":r.id,children:[Z&&t.jsxs("div",{className:"chat-message-avatar",children:[f?t.jsx(dt,{provider:f,size:"sm"}):t.jsx(ut,{size:14}),t.jsx("span",{children:i}),b&&y&&t.jsx("span",{className:"chat-model-tag",children:y})]}),z?N:t.jsx("div",{className:"chat-message-content",children:C}),z&&!S&&(w||j)&&t.jsxs("div",{className:"chat-message-actions",children:[w,j&&t.jsx("button",{type:"button",className:"btn-icon chat-message-scroll-to-top-action","aria-label":"Scroll message to top","data-testid":`chat-message-scroll-to-top-${r.id}`,onClick:()=>j(r.id),children:t.jsx(ca,{size:14})})]}),an(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:Et(r.thinkingOutput)})]}),O,t.jsx("div",{className:"chat-message-time",children:nn(r.createdAt)})]})});function Ia({projectId:n,addToast:r,experimentalFeatures:d}){s.useEffect(()=>(At({view:"ChatView",trigger:is?"route-active":"remount",projectId:n,replayAttempted:!1}),is=!1,()=>{is=!0,At({view:"ChatView",trigger:"route-inactive",projectId:n,replayAttempted:!1})}),[n]);const{activeSession:i,sessionsLoading:g,messages:b,messagesLoading:y,isStreaming:f,streamingText:I,streamingThinking:J,streamingToolCalls:Q,selectSession:w,createSession:j,archiveSession:z,deleteSession:S,sendMessage:Z,stopStreaming:C,pendingMessage:O,clearPendingMessage:N,loadMoreMessages:X,hasMoreMessages:E,searchQuery:_,setSearchQuery:T,filteredSessions:Y,agentsMap:k}=ma(n,r),[B,te]=s.useState(!1),h=d?.chatRooms===!0,[p,he]=s.useState(()=>{try{if(localStorage.getItem(os)==="rooms"&&h)return"rooms"}catch{}return"direct"}),c=_n(n,r),{isUnread:re,markRead:se}=zn(n),[$,ue]=s.useState(()=>{const e=qs(p,p==="rooms"?c.activeRoom?.id:i?.id);return Xs(e)}),[be,G]=s.useState(null),[Ge,K]=s.useState(null),[We,ye]=s.useState(null),[Ie,oe]=s.useState(!0),[Se,Ce]=s.useState(wa),[Ve,Oe]=s.useState(!1),{agentsMap:ce}=ls(n),me=s.useMemo(()=>k.size>0?k:ce,[ce,k]),{defaultProvider:mt,defaultModelId:ie}=Zs(),le=s.useMemo(()=>({provider:mt,modelId:ie}),[ie,mt]),{skills:$e,loading:Tt}=Hn(n),[De,Pe]=s.useState(!1),[nt,qe]=s.useState(""),[Be,Le]=s.useState(0),[ke,Ne]=s.useState(""),[ve,l]=s.useState(!1),[u,v]=s.useState(0),[D,H]=s.useState(-1),[A,ee]=s.useState(!1),[M,U]=s.useState([]),[W,V]=s.useState(!1),[P,q]=s.useState(!1),[ne,je]=s.useState({}),[ht,Xe]=s.useState(!1),[ft,at]=s.useState(!1),{pushNav:ds}=Un(),[,gt]=s.useState(!1),[on,cn]=s.useState({top:0,left:0}),L=On({projectId:n}),It=s.useCallback(e=>{if(!e||!L.mentionActive)return;const a=e.getBoundingClientRect();cn({top:a.top-260,left:a.left+8})},[L.mentionActive]),us=s.useRef(null),ms=s.useRef(null),hs=s.useRef(null),fs=s.useRef(null),we=s.useRef(!1),$t=s.useRef(null),gs=s.useRef(null),Fe=s.useRef(null),pt=s.useRef(0),Dt=s.useRef(null),bt=s.useRef(null),Me=s.useRef(null),ge=s.useRef(null),Pt=s.useRef(null),vt=s.useRef(!1),Re=s.useRef(null),de=s.useRef(null),ps=s.useRef(null),bs=s.useRef([]),Ye=s.useRef(0),rt=s.useRef(new Map),R=Bn()==="mobile";s.useEffect(()=>{i?.id&&se("direct",i.id,i.lastMessageAt??i.updatedAt)},[i?.id,i?.lastMessageAt,i?.updatedAt,se]),s.useEffect(()=>{c.activeRoom?.id&&se("room",c.activeRoom.id,c.activeRoom.updatedAt)},[c.activeRoom?.id,c.activeRoom?.updatedAt,se]),s.useEffect(()=>{if(!i?.id||b.length===0)return;const e=b[b.length-1];se("direct",i.id,e?.createdAt??i.lastMessageAt??i.updatedAt)},[i?.id,i?.lastMessageAt,i?.updatedAt,se,b]),s.useEffect(()=>{if(!c.activeRoom?.id||c.messages.length===0)return;const e=c.messages[c.messages.length-1];se("room",c.activeRoom.id,e?.createdAt??c.activeRoom.updatedAt)},[se,c.activeRoom?.id,c.activeRoom?.updatedAt,c.messages]),s.useEffect(()=>{try{const e=localStorage.getItem(Vs);if(!e)return;const a=Number.parseInt(e,10);if(Number.isNaN(a))return;const o=Math.max(jt,Math.min(Mt,a));Ce(o)}catch{}},[]),s.useEffect(()=>{try{const e=localStorage.getItem(os);if(e==="direct"){he("direct");return}e==="rooms"&&h&&he("rooms")}catch{}},[h]),s.useEffect(()=>{if(!h&&p==="rooms"){he("direct");return}try{localStorage.setItem(os,p)}catch{}},[h,p]);const fe=qs(p,p==="rooms"?c.activeRoom?.id:i?.id),Lt=s.useRef(fe);s.useEffect(()=>{fe!==Lt.current&&(Lt.current=fe,ue(Xs(fe)))},[fe]),s.useEffect(()=>{if(!(!fe||Lt.current!==fe))try{if($){localStorage.setItem(fe,$);return}localStorage.removeItem(fe)}catch{}},[fe,$]);const ae=h&&p==="rooms"&&!!c.activeRoom,{keyboardOverlap:vs,keyboardOpen:Ft}=Kn({enabled:R&&(!!i||ae)}),xe=s.useMemo(()=>{const e=nt.trim().toLowerCase();return(e?$e.filter(o=>o.name.toLowerCase().includes(e)):$e).slice(0,10)},[$e,nt]),Je=s.useMemo(()=>Array.from(me.values()),[me]),Ae=s.useMemo(()=>!h||p!=="rooms"||!c.activeRoom?null:{roomId:c.activeRoom.id,roomName:c.activeRoom.name,memberIds:new Set(c.activeRoomMembers.map(e=>e.agentId))},[h,p,c.activeRoom,c.activeRoomMembers]),Ke=s.useMemo(()=>{const e=Je.filter(m=>Gn(m.name,ke));if(!Ae)return e;const a=e.filter(m=>Ae.memberIds.has(m.id));if(ke.trim().length===0)return a;const o=e.filter(m=>!Ae.memberIds.has(m.id));return[...a,...o]},[Je,ke,Ae]),_t=s.useMemo(()=>{const e=new Map;for(const a of Je)e.set(a.name.toLowerCase(),a);return e},[Je]);s.useEffect(()=>{Le(0)},[xe]),s.useEffect(()=>{v(0)},[ke,ve]),s.useEffect(()=>()=>{Me.current!==null&&window.clearTimeout(Me.current)},[]),s.useEffect(()=>{const e=ms.current;if(!e||!E||y)return;const a=new IntersectionObserver(o=>{o[0].isIntersecting&&X()},{threshold:.1});return a.observe(e),()=>a.disconnect()},[E,y,X]);const Qe=s.useCallback(()=>ae?c.activeRoom?.id??null:i?.id??null,[ae,c.activeRoom?.id,i?.id]),xs=s.useCallback((e,a)=>typeof CSS<"u"&&typeof CSS.escape=="function"?e.querySelector(`.chat-message[data-message-id="${CSS.escape(a)}"]`):e.querySelector(`.chat-message[data-message-id="${a.replace(/"/g,'\\"')}"]`),[]),xt=s.useCallback(()=>{const e=ge.current,a=Qe();if(!e||!a)return;const o=e.querySelector(".chat-message[data-message-id]"),m=o?.getAttribute("data-message-id")??null,x=o?o.offsetTop-e.scrollTop:0;bt.current={threadId:a,scrollTop:e.scrollTop,scrollHeight:e.scrollHeight,clientHeight:e.clientHeight,anchorMessageId:m,anchorOffset:x,wasPinnedBefore:!we.current}},[Qe]),ys=s.useCallback(()=>{const e=ge.current;if(!e)return;const o=e.scrollTop+e.clientHeight>=e.scrollHeight-50;q(!o),we.current=!o,xt()},[xt]),Ee=s.useCallback(e=>{if(!e.isConnected)return;let a=0,o=0,m=-1;const x=6,F=()=>{if(e.isConnected){if(e.scrollTop=e.scrollHeight,e.scrollHeight===m?o+=1:(o=0,m=e.scrollHeight),a+=1,a>=x||o>=2){q(!1),we.current=!1;return}window.requestAnimationFrame(F)}};F()},[]),it=ae?c.messages:b;s.useLayoutEffect(()=>{const e=ge.current,a=Qe(),o=bt.current;if(!e||!a||!o||o.threadId!==a||o.wasPinnedBefore)return;let m=o.scrollTop;if(o.anchorMessageId){const x=xs(e,o.anchorMessageId);x?m=x.offsetTop-o.anchorOffset:m=o.scrollTop+(e.scrollHeight-o.scrollHeight)}else m=o.scrollTop+(e.scrollHeight-o.scrollHeight);e.scrollTop=Math.max(0,m),we.current=!0,q(!0),bt.current=null},[it,Qe,xs]);const zt=s.useCallback(e=>{},[it.length,ae]),_e=s.useCallback(e=>{zt(e);const a=ge.current;a&&(bt.current=null,we.current=!1,Ee(a))},[Ee,zt]);s.useLayoutEffect(()=>{Fe.current!==null&&(window.clearTimeout(Fe.current),Fe.current=null);const e=ae?c.activeRoom?.id??null:i?.id??null;if(!e){$t.current=null;return}const a={threadId:e,loaded:ae?!c.messagesLoading:!y,hasMessages:ae?c.messages.length>0:b.length>0},o=$t.current,m=o?.threadId!==e,x=o?.threadId===e&&!o.loaded&&a.loaded,F=o?.threadId===e&&!o.hasMessages&&a.hasMessages;if(!(o===null||m||x||F))return;const Te=ge.current;if(Te)return zt(m?"thread-change":x?"finished-loading":F?"first-messages":"mount"),Ee(Te),ae||(Fe.current=window.setTimeout(()=>{if(Fe.current=null,we.current)return;const et=ge.current;et&&Ee(et)},250)),$t.current=a,()=>{Fe.current!==null&&(window.clearTimeout(Fe.current),Fe.current=null)}},[ae,c.activeRoom?.id,c.messages.length,c.messagesLoading,i?.id,b.length,y,Ee]),s.useEffect(()=>{!f||we.current||_e("streaming")},[f,I,J,_e]),s.useEffect(()=>{const e=Qe();if(!e){pt.current=0,Dt.current=null;return}if(Dt.current!==e){Dt.current=e,pt.current=it.length;return}const a=pt.current,o=it.length,m=o>a,x=!we.current;pt.current=o,m&&x&&_e("new-message")},[it,Qe,_e]),s.useEffect(()=>{vs<=0||!ge.current||_e("keyboard")},[vs,_e]),Wn(R&&Ft),s.useLayoutEffect(()=>{if(!R||!i&&!ae||typeof window>"u")return;const e=Pt.current,a=window.visualViewport;if(!e||!a)return;const o=x=>{if(!(x instanceof HTMLElement))return!1;if(x.tagName==="TEXTAREA")return!0;if(x.tagName!=="INPUT")return!1;const F=x.type.toLowerCase();return["","text","search","email","url","tel","password","number"].includes(F)},m=()=>{if(vt.current){e.classList.remove("chat-thread--keyboard-active");return}const x=Math.max(0,window.innerHeight-a.offsetTop-a.height),F=a.offsetTop||0;e.style.setProperty("--vv-height",`${a.height}px`),e.style.setProperty("--vv-offset-top",`${F}px`),e.style.setProperty("--keyboard-overlap",`${x}px`);const Ue=(x>0||F>0)&&o(document.activeElement);e.classList.toggle("chat-thread--keyboard-active",Ue)};return m(),a.addEventListener("resize",m),a.addEventListener("scroll",m),document.addEventListener("focusin",m),document.addEventListener("focusout",m),window.addEventListener("pageshow",m),document.addEventListener("visibilitychange",m),()=>{a.removeEventListener("resize",m),a.removeEventListener("scroll",m),document.removeEventListener("focusin",m),document.removeEventListener("focusout",m),window.removeEventListener("pageshow",m),document.removeEventListener("visibilitychange",m),e.classList.remove("chat-thread--keyboard-active")}},[i,R,ae]),s.useEffect(()=>{const e=()=>G(null);if(be)return document.addEventListener("click",e),()=>document.removeEventListener("click",e)},[be]),s.useEffect(()=>{if(!R||!Ft)return;const e=a=>{a.target?.closest(".chat-messages")||a.preventDefault()};return document.addEventListener("touchmove",e,{passive:!1}),()=>{document.removeEventListener("touchmove",e)}},[R,Ft]),s.useEffect(()=>{if(!R||!i)return;const e=()=>{const a=de.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)}},[R,i]),s.useEffect(()=>{const e=gs.current;if(gs.current=p,p!=="direct"||e!==null&&e!=="rooms")return;const a=ge.current;a&&(Ee(a),we.current=!1,q(!1))},[p,Ee]),s.useEffect(()=>{if(!i&&!ae||ae&&!R)return;const e=()=>{xt()},a=()=>{document.visibilityState==="visible"&&e()};return document.addEventListener("visibilitychange",a),window.addEventListener("pageshow",e),()=>{document.removeEventListener("visibilitychange",a),window.removeEventListener("pageshow",e)}},[R,i,ae,xt]),s.useEffect(()=>{if(ae||typeof ResizeObserver>"u")return;const e=ge.current;if(!e)return;const a=new ResizeObserver(()=>{we.current||Ee(e)});return a.observe(e),()=>{a.disconnect()}},[ae,Ee,i?.id,p]),s.useEffect(()=>{bs.current=M},[M]),s.useEffect(()=>()=>{for(const e of bs.current)e.previewUrl&&URL.revokeObjectURL(e.previewUrl);for(const e of rt.current.values())window.clearTimeout(e);rt.current.clear()},[]);const yt=s.useCallback(e=>{if(!e||e.length===0)return;const a=[];for(const o of Array.from(e)){if(!Ca.includes(o.type))continue;const m=o.type.startsWith("image/");a.push({file:o,previewUrl:m?URL.createObjectURL(o):""})}a.length>0&&U(o=>[...o,...a])},[]),ln=s.useCallback(e=>{U(a=>{const o=a[e];return o?.previewUrl&&URL.revokeObjectURL(o.previewUrl),a.filter((m,x)=>x!==e)})},[]),dn=s.useCallback(e=>{const a=e.clipboardData?.files;if(!a||a.length===0)return;const o=Array.from(a).filter(m=>m.type.startsWith("image/"));o.length!==0&&yt(o)},[yt]),un=s.useCallback(async e=>{try{await j(e),te(!1),R&&oe(!1)}catch{r("Failed to create chat session","error")}},[j,r,R]),pe=s.useCallback(e=>{const a=e??de.current;a&&(a.style.height="auto",a.style.height=`${pa(a.scrollHeight)}px`,a.style.overflowY=ga(a.scrollHeight))},[]),ws=s.useCallback(e=>{de.current=e,e&&pe(e)},[pe]);s.useLayoutEffect(()=>{pe()},[p,$,i?.id,c.activeRoom?.id,pe]);const Ze=s.useCallback(()=>{if(ue(""),fe)try{localStorage.removeItem(fe)}catch{}Pe(!1),qe(""),l(!1),Ne(""),H(-1),U(e=>{for(const a of e)a.previewUrl&&URL.revokeObjectURL(a.previewUrl);return[]})},[fe]),Ht=s.useCallback(()=>{const e=$.trim(),a=M.map(o=>o.file);if(!(!e&&a.length===0||!i)){if(e==="/clear"||e==="/new"){Ze(),N(),C(),j({agentId:i.agentId,modelProvider:i.modelProvider??void 0,modelId:i.modelId??void 0}).catch(()=>{r("Failed to clear conversation","error")});return}Ze(),Z(e,a)}},[$,M,i,Ze,C,N,j,r,Z]),Ut=s.useCallback(async()=>{const e=$.trim();if(e){if(h&&p==="rooms"){if(!c.activeRoom)return;if(e==="/clear"||e==="/new"){Ze();try{await c.clearRoom(c.activeRoom.id)}catch{r("Failed to clear room conversation","error")}return}const a=$;Ze();try{await c.sendRoomMessage(e,{files:M.map(o=>o.file)})}catch(o){if(o instanceof Vn){const x=o.message.trim()?o.message:"Message sent, but assistant reply failed";r(`Message sent, but assistant reply failed: ${x}`,"error");return}ue(a);const m=o instanceof Error&&o.message.trim()?o.message:"Failed to send room message";r(m,"error")}return}Ht()}},[$,M,h,p,c,c.clearRoom,Ze,r,Ht]),Ot=s.useCallback(e=>{ue(a=>{const o=Ys(a);if(!o)return a;const m=`/skill:${e.name} `,x=a.slice(0,o.start)+m+a.slice(o.end);return window.requestAnimationFrame(()=>{de.current&&(pe(de.current),de.current.focus())}),x}),Pe(!1),qe(""),Le(0)},[pe]),wt=s.useCallback(e=>{const a=de.current;if(!a||D<0)return;const o=a.selectionStart??Ye.current,m=a.selectionEnd??o,x=Math.max(o,m),F=Math.min(D,x),Te=`${`@${e.name.replace(/\s+/g,"_")}`} `,et=$.slice(0,F)+Te+$.slice(x),tt=F+Te.length;ue(et),l(!1),Ne(""),v(0),H(-1),window.requestAnimationFrame(()=>{de.current&&(pe(de.current),de.current.focus(),de.current.setSelectionRange(tt,tt))})},[D,$,pe]),ot=s.useCallback((e,a)=>{const m=de.current?.selectionStart??Ye.current,x=$.lastIndexOf("#",m),F=x>=0?x+a.length:e.length;ue(e),L.dismissMention(),gt(!1),window.requestAnimationFrame(()=>{de.current&&(pe(de.current),de.current.focus(),de.current.setSelectionRange(F,F))})},[L,$,pe]),Ss=s.useCallback(e=>{if(Ye.current=e.currentTarget.selectionStart??Ye.current,L.mentionActive&&L.combinedItems.length>0){if(L.handleKeyDown(e,$),e.key==="Enter"||e.key==="Tab"){const a=L.combinedItems[L.selectedIndex];a?.kind==="task"?ot(L.selectTask(a.task,$),`#${a.task.id}`):a?.kind==="file"&&ot(L.selectFile(a.file,$),`#${a.file.path}`)}return}if(ve&&e.key==="ArrowDown"){e.preventDefault(),Ke.length>0&&v(a=>(a+1)%Ke.length);return}if(ve&&e.key==="ArrowUp"){e.preventDefault(),Ke.length>0&&v(a=>a===0?Ke.length-1:a-1);return}if(ve&&e.key==="Enter"){e.preventDefault();const a=Ke[u]??Ke[0];a&&wt(a);return}if(ve&&e.key==="Escape"){e.preventDefault(),l(!1),Ne(""),H(-1);return}if(De&&e.key==="ArrowDown"){e.preventDefault(),xe.length>0&&Le(a=>(a+1)%xe.length);return}if(De&&e.key==="ArrowUp"){e.preventDefault(),xe.length>0&&Le(a=>a===0?xe.length-1:a-1);return}if(De&&(e.key==="Enter"||e.key==="Tab")&&xe.length>0){e.preventDefault();const a=xe[Be]??xe[0];a&&Ot(a);return}if(De&&e.key==="Escape"){e.preventDefault(),Pe(!1);return}e.key==="Enter"&&!e.shiftKey&&(e.preventDefault(),Ut())},[ve,Ke,u,wt,De,xe,Be,Ot,Ut,L,ot,$]),St=s.useCallback((e,a)=>{const o=ka(e,a);if(o){l(!0),Ne(o.filter),H(o.start);return}l(!1),Ne(""),H(-1)},[]),Cs=s.useCallback(e=>{const a=e.target,o=a.value,m=a.selectionStart??o.length;pe(a),Ye.current=m,ue(o);const x=Ys(o);x?(Pe(!0),qe(x.filter)):(Pe(!1),qe("")),St(o,m),L.detectMention(o,m),gt(L.mentionActive),L.mentionActive&&It(a)},[St,pe]),Ct=s.useCallback(e=>{const a=e.currentTarget,o=a.selectionStart??a.value.length;Ye.current=o,St(a.value,o),L.detectMention(a.value,o),gt(L.mentionActive),L.mentionActive&&It(a)},[St,L,It]),ks=s.useCallback(e=>{e.key!=="Escape"&&Ct(e)},[Ct]),Ns=s.useCallback(()=>{typeof window<"u"&&window.innerWidth<=768&&(vt.current=!0,Re.current!==null&&window.clearTimeout(Re.current),Re.current=window.setTimeout(()=>{vt.current=!1,Re.current=null},450)),Me.current!==null&&window.clearTimeout(Me.current),Me.current=window.setTimeout(()=>{Pe(!1),l(!1),Ne(""),H(-1),gt(!1),L.dismissMention(),Me.current=null},120)},[L]),js=s.useCallback(()=>{vt.current=!1,Re.current!==null&&(window.clearTimeout(Re.current),Re.current=null),Me.current!==null&&(window.clearTimeout(Me.current),Me.current=null),typeof window<"u"&&window.innerWidth<=768&&queueMicrotask(()=>{(window.scrollY!==0||window.scrollX!==0)&&window.scrollTo(0,0)})},[]);s.useEffect(()=>()=>{Re.current!==null&&window.clearTimeout(Re.current)},[]);const mn=s.useCallback(async e=>{G(null);try{await z(e),r("Conversation archived","success")}catch{r("Failed to archive conversation","error")}},[z,r]),hn=s.useCallback(async e=>{K(null),G(null);try{await S(e),r("Conversation deleted","success")}catch{r("Failed to delete conversation","error")}},[S,r]),ct=s.useCallback(e=>{try{localStorage.setItem(Vs,String(e))}catch{}},[]),fn=s.useCallback(e=>{if(R)return;e.preventDefault(),e.stopPropagation();const a=e.currentTarget;typeof a.setPointerCapture=="function"&&a.setPointerCapture(e.pointerId);const o=e.clientX,m=Se;let x=m;document.body.style.userSelect="none";const F=Te=>{const et=Te.clientX-o,tt=Math.max(jt,Math.min(Mt,m+et));x=tt,Ce(tt),ct(tt)},Ue=Te=>{typeof a.releasePointerCapture=="function"&&a.releasePointerCapture(Te.pointerId),document.body.style.userSelect="",document.removeEventListener("pointermove",F),document.removeEventListener("pointerup",Ue),ct(x)};document.addEventListener("pointermove",F),document.addEventListener("pointerup",Ue)},[R,ct,Se]),gn=s.useCallback(e=>{if(R||e.key!=="ArrowLeft"&&e.key!=="ArrowRight")return;e.preventDefault();const a=e.shiftKey?50:10,o=e.key==="ArrowLeft"?-a:a,m=Math.max(jt,Math.min(Mt,Se+o));Ce(m),ct(m)},[R,ct,Se]),Ms=s.useCallback(e=>{const a=Y.find(o=>o.id===e);se("direct",e,a?.lastMessageAt??a?.updatedAt),w(e),Xe(!1),R&&oe(!1)},[Y,R,se,w]),Bt=s.useCallback(()=>{w(""),oe(!0),Xe(!1)},[w]),Kt=s.useCallback(()=>{c.selectRoom(null),oe(!0),Xe(!1)},[c]),pn=()=>t.jsxs("div",{className:"chat-empty-state",children:[t.jsx(ra,{size:48,strokeWidth:1.5}),t.jsx("h2",{children:"Start a new conversation"}),t.jsxs("button",{className:"btn btn-primary",onClick:()=>te(!0),children:[t.jsx(lt,{size:16}),"New Chat"]})]}),Gt=Js(i,i?.agentId?me.get(i.agentId)??null:null,le),ze=Ws(Gt?.provider,Gt?.modelId),He=Gt?.provider??null,Wt=!!(i||f||b.length>0),kt=p==="rooms"?ae:!!i,Rs=s.useRef(kt);s.useEffect(()=>{const e=Rs.current;Rs.current=kt,R&&(e||!kt||ds({type:"view",revert:p==="rooms"?Kt:Bt}))},[p,Bt,Kt,kt,R,ds]);const Vt=i?.agentId===st?ze??"Fusion":i?.title||me.get(i?.agentId??"")?.name||i?.agentId||"Chat",As=!!(ze&&ze!==Vt),bn=R&&p==="direct"&&!!i,qt=me.get(i?.agentId??"")?.name||(i?.agentId===st?ze??"Fusion":i?.agentId?.slice(0,30)??"Fusion"),Xt=!1,Yt=i?.agentId===st,vn=O.length>50?`${O.slice(0,50)}…`:O,xn=s.useCallback(()=>{ee(e=>!e)},[]);s.useEffect(()=>{if(!ht)return;const e=a=>{hs.current?.contains(a.target)||Xe(!1)};return document.addEventListener("mousedown",e),()=>{document.removeEventListener("mousedown",e)}},[ht]),s.useEffect(()=>{if(!ft)return;const e=o=>{fs.current?.contains(o.target)||at(!1)},a=o=>{o.key==="Escape"&&at(!1)};return document.addEventListener("mousedown",e),document.addEventListener("keydown",a),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("keydown",a)}},[ft]),s.useEffect(()=>{(!R||p!=="direct"||Ie)&&Xe(!1)},[R,p,Ie]),s.useEffect(()=>{at(!1)},[c.activeRoom?.id]);const Jt=s.useCallback((e,a)=>{const o=rt.current.get(e);o&&window.clearTimeout(o),je(x=>({...x,[e]:a}));const m=window.setTimeout(()=>{je(x=>{const{[e]:F,...Ue}=x;return Ue}),rt.current.delete(e)},2e3);rt.current.set(e,m)},[]),Es=s.useCallback(async(e,a)=>{try{if(!navigator.clipboard?.writeText)throw new Error("Clipboard API unavailable");await navigator.clipboard.writeText(a),Jt(e,"success")}catch{Jt(e,"error")}},[Jt]),yn=s.useCallback((e,a=!1)=>a?t.jsx("div",{className:"chat-message-content chat-message-content--plain",children:e}):t.jsx("div",{className:"chat-message-content chat-message-content--markdown",children:t.jsx(en,{remarkPlugins:[tn],components:rn,children:e})}),[]),Qt=i?.agentId===st,Zt=s.useCallback((e,a,o)=>t.jsx("button",{type:"button",className:`btn-icon chat-message-copy-action${ne[e]==="success"?" chat-message-copy-action--success":""}${ne[e]==="error"?" chat-message-copy-action--error":""}`,"data-testid":o??`chat-copy-response-${e}`,"aria-label":ne[e]==="success"?"Response copied":ne[e]==="error"?"Copy failed":"Copy response",onClick:()=>{Es(e,a)},children:ne[e]==="success"?t.jsx(qn,{size:14}):t.jsx(Xn,{size:14})}),[ne,Es]),es=s.useCallback(e=>{const a=ge.current;if(!a)return;const o=`[data-testid="chat-message-${e}"]`,m=a.querySelector(o);if(!m)return;const x=m.getBoundingClientRect().top-a.getBoundingClientRect().top+a.scrollTop,F=typeof window<"u"&&window.matchMedia?.("(prefers-reduced-motion: reduce)").matches;a.scrollTo({top:x,behavior:F?"auto":"smooth"})},[]);return t.jsxs("div",{className:"chat-view",children:[t.jsxs("div",{className:`chat-sidebar${Ie?"":" chat-sidebar--hidden"}`,style:R?void 0:{width:`${Se}px`},children:[h&&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${p==="direct"?" chat-sidebar-scope-btn--active":""}`,"aria-selected":p==="direct","data-testid":"chat-sidebar-scope-direct",onClick:()=>he("direct"),children:"Direct"}),t.jsx("button",{type:"button",role:"tab",className:`chat-sidebar-scope-btn${p==="rooms"?" chat-sidebar-scope-btn--active":""}`,"aria-selected":p==="rooms","data-testid":"chat-sidebar-scope-rooms",onClick:()=>he("rooms"),children:"Rooms"})]}),!h||p==="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(Yn,{size:14,className:"chat-sidebar-search-icon"}),t.jsx("input",{type:"text",className:"chat-sidebar-search",placeholder:"Search conversations...",value:_,onChange:e=>T(e.target.value),"data-testid":"chat-search-input"})]})}),t.jsx("div",{className:"chat-session-list chat-sidebar-list",children:g?t.jsx("div",{className:"chat-empty-state chat-empty-state--padded",children:"Loading..."}):Y.length===0?t.jsx("div",{className:"chat-empty-state chat-empty-state--padded",children:"No conversations yet"}):Y.map(e=>{const a=i?.id===e.id,o=!a&&re("direct",e.id,e.lastMessageAt??e.updatedAt),m=Js(e,me.get(e.agentId)??null,le),x=Ws(m?.provider,m?.modelId)??"Fusion";return t.jsxs("div",{className:`chat-session-item${a?" chat-session-item--active":""}`,onClick:()=>Ms(e.id),onContextMenu:F=>{F.preventDefault(),G({sessionId:e.id,x:F.clientX,y:F.clientY})},"data-testid":`chat-session-${e.id}`,children:[t.jsx("button",{className:"chat-session-delete-btn",onClick:F=>{F.stopPropagation(),K(e.id)},"data-testid":"chat-session-delete-btn","aria-label":"Delete conversation",children:t.jsx(ns,{size:14})}),t.jsxs("div",{className:"chat-session-title",children:[e.title||"Untitled",o?t.jsx("span",{className:"chat-unread-dot","data-testid":`chat-unread-dot-${e.id}`,"aria-label":"Unread messages"}):null]}),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:[m?.provider?t.jsx(dt,{provider:m.provider,size:"sm"}):null,t.jsx("span",{children:me.get(e.agentId)?.name||(e.agentId===st?x:e.agentId.slice(0,30))})]}),t.jsx("span",{children:e.updatedAt?nn(e.updatedAt):""})]})]},e.id)})})]}):t.jsxs("div",{className:"chat-sidebar-rooms","data-testid":"chat-sidebar-rooms",children:[!R&&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:()=>Oe(!0),children:[t.jsx(lt,{size:14}),"Create room"]})}),c.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:c.rooms.map(e=>{const a=c.activeRoom?.id===e.id,o=!a&&re("room",e.id,e.updatedAt);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:()=>{se("room",e.id,e.updatedAt),c.selectRoom(e.id),R&&oe(!1)},onKeyDown:m=>{(m.key==="Enter"||m.key===" ")&&(m.preventDefault(),se("room",e.id,e.updatedAt),c.selectRoom(e.id),R&&oe(!1))},children:[t.jsxs("span",{className:"chat-room-item-details",children:[t.jsxs("span",{className:"chat-room-item-name-row",children:[t.jsxs("span",{className:"chat-room-item-name",children:["#",e.name]}),o?t.jsx("span",{className:"chat-unread-dot","data-testid":`chat-unread-dot-${e.id}`,"aria-label":"Unread messages"}):null]}),a?t.jsxs("span",{className:"chat-room-item-meta",children:[c.activeRoomMembers.length," ",c.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:m=>{m.stopPropagation(),ye(e.id)},children:t.jsx(ns,{size:14})})]},e.id)})})]}),p==="rooms"?R?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:()=>Oe(!0),children:[t.jsx(lt,{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:()=>te(!0),"data-testid":"chat-new-btn",children:[t.jsx(lt,{size:14}),"New Chat"]})})]}),!R&&Ie&&t.jsx("div",{className:"chat-sidebar-resize-handle",role:"separator","aria-orientation":"vertical","aria-valuemin":jt,"aria-valuemax":Mt,"aria-valuenow":Se,"aria-label":"Resize chat sidebar",tabIndex:0,onPointerDown:fn,onKeyDown:gn}),be&&t.jsxs("div",{className:"chat-session-context-menu",style:{top:be.y,left:be.x},onClick:e=>e.stopPropagation(),children:[t.jsxs("button",{onClick:()=>mn(be.sessionId),"data-testid":"chat-context-archive",children:[t.jsx(Jn,{size:14}),"Archive"]}),t.jsxs("button",{onClick:()=>{G(null),K(be.sessionId)},"data-testid":"chat-context-delete",children:[t.jsx(ns,{size:14}),"Delete"]})]}),Ge&&t.jsx("div",{className:"chat-new-dialog-backdrop chat-view-dialog-backdrop",onClick:()=>K(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:()=>K(null),children:"Cancel"}),t.jsx("button",{className:"btn btn-sm btn-danger",onClick:()=>void hn(Ge),children:"Delete"})]})]})}),h&&We&&t.jsx("div",{className:"chat-new-dialog-backdrop chat-view-dialog-backdrop",onClick:()=>ye(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:()=>ye(null),children:"Cancel"}),t.jsx("button",{className:"btn btn-sm btn-danger",onClick:()=>{(async()=>{try{await c.deleteRoom(We),ye(null)}catch{r("Failed to delete room","error")}})()},children:"Delete"})]})]})}),h&&p==="rooms"?t.jsxs("div",{ref:Pt,className:"chat-thread",children:[c.activeRoom?t.jsxs(t.Fragment,{children:[t.jsxs("div",{className:"chat-room-thread-header",children:[R&&t.jsx("button",{className:"btn-icon",onClick:Kt,"data-testid":"chat-back-btn",children:t.jsx(Fs,{size:16})}),t.jsxs("div",{className:"chat-room-switcher-menu",ref:fs,children:[t.jsxs("button",{type:"button",className:"chat-room-switcher-trigger","data-testid":"chat-room-switcher-trigger","aria-haspopup":"menu","aria-expanded":ft,onClick:()=>at(e=>!e),children:[t.jsxs("span",{className:"chat-thread-header-title",children:["#",c.activeRoom.name]}),t.jsx(Nt,{size:16,"aria-hidden":"true"})]}),ft&&t.jsx("div",{role:"menu",className:"chat-room-switcher-dropdown","data-testid":"chat-room-switcher-dropdown",children:c.rooms.map(e=>t.jsxs("button",{type:"button",role:"menuitem",className:`chat-room-switcher-option${e.id===c.activeRoom?.id?" chat-room-switcher-option--active":""}`,"data-testid":`chat-room-switcher-option-${e.id}`,onClick:()=>{se("room",e.id,e.updatedAt),c.selectRoom(e.id),at(!1)},children:["#",e.name]},e.id))})]}),t.jsx("div",{className:"chat-room-thread-members",children:c.activeRoomMembers.map(e=>t.jsx(Qs,{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:ys,children:[c.messagesLoading?t.jsx("div",{className:"chat-empty-state",children:"Loading messages..."}):c.messages.length===0?t.jsx("div",{className:"chat-empty-state",children:"No messages yet. Start the conversation!"}):c.messages.map(e=>{const a=e.senderAgentId?me.get(e.senderAgentId)?.name??e.senderAgentId.slice(0,30):"You",o={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(cs,{message:o,forcePlain:A,agentName:a,hideAssistantIdentity:!1,showAssistantModelTag:!1,activeModelTag:null,activeModelProvider:null,activeSessionId:c.activeRoom?.id??null,mentionAgentsByName:_t,roomContext:Ae,onScrollToTop:es},e.id)}),t.jsx("div",{ref:us})]}),c.activeRoom&&P&&t.jsxs("button",{type:"button",className:"btn btn-sm chat-jump-to-latest","data-testid":"chat-jump-to-latest",onClick:()=>_e("fab-click"),children:[t.jsx(Nt,{size:14}),"Latest"]})]}):t.jsx("div",{className:"chat-room-empty-pane","data-testid":"chat-rooms-empty-pane",children:"Select a room or create one"}),c.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:ws,className:"chat-input-textarea",placeholder:"Type a message...",value:$,onChange:Cs,onKeyDown:Ss,onKeyUp:ks,onClick:Ct,onBlur:Ns,onFocus:js,onTouchStart:e=>{typeof window>"u"||window.innerWidth>768||_s()&&document.activeElement!==e.currentTarget&&(e.preventDefault(),e.currentTarget.focus({preventScroll:!0}))},rows:1,"data-testid":"chat-input"}),t.jsx(zs,{agents:Je,filter:ke,highlightedIndex:u,visible:ve,onSelect:wt,position:"below",roomMemberIds:Ae?.memberIds,roomName:Ae?.roomName})]}),t.jsx("button",{type:"button",className:"chat-input-send",onPointerDown:e=>{e.pointerType&&e.pointerType!=="mouse"&&e.preventDefault()},onMouseDown:e=>{e.preventDefault()},onClick:()=>{Ut()},disabled:!$.trim(),"data-testid":"chat-send-btn",style:{touchAction:"manipulation"},children:t.jsx(Hs,{size:16})})]})})]}):t.jsxs("div",{ref:Pt,className:"chat-thread",children:[(Wt||!R)&&t.jsxs("div",{className:"chat-thread-header",children:[R&&Wt&&t.jsx("button",{className:"btn-icon",onClick:Bt,"data-testid":"chat-back-btn",children:t.jsx(Fs,{size:16})}),t.jsx("div",{className:"chat-thread-header-identity","data-testid":"chat-thread-header-identity",children:bn?t.jsxs("div",{className:"chat-mobile-session-menu",ref:hs,children:[t.jsxs("button",{type:"button",className:"btn chat-mobile-session-trigger","data-testid":"chat-mobile-session-trigger","aria-haspopup":"menu","aria-expanded":ht,onClick:()=>Xe(e=>!e),children:[He?t.jsx(dt,{provider:He,size:"md"}):t.jsx(ut,{size:16}),t.jsx("span",{className:"chat-thread-header-title",children:Vt}),As&&t.jsx("span",{className:"chat-model-tag",children:ze}),t.jsx(Nt,{size:16,"aria-hidden":"true"})]}),ht&&t.jsx("div",{className:"chat-mobile-session-dropdown",role:"menu","data-testid":"chat-mobile-session-dropdown",children:Y.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:()=>Ms(e.id),children:t.jsx("span",{className:"chat-mobile-session-option-title",children:e.title||"Untitled"})},e.id))})]}):t.jsxs(t.Fragment,{children:[He?t.jsx(dt,{provider:He,size:"md"}):t.jsx(ut,{size:16}),t.jsx("span",{className:"chat-thread-header-title",children:Vt}),As&&t.jsx("span",{className:"chat-model-tag",children:ze})]})}),Wt&&t.jsx("button",{type:"button",className:`chat-thread-header-render-toggle${A?" chat-thread-header-render-toggle--plain":""}`,"data-testid":"chat-thread-render-toggle","aria-label":A?"Show all messages as rendered Markdown":"Show all messages as plain text",onClick:xn,children:A?t.jsx(Qn,{size:14}):t.jsx(Zn,{size:14})}),!R&&t.jsxs("button",{className:"btn btn-sm btn-primary chat-thread-header-new-chat",onClick:()=>te(!0),"data-testid":"chat-thread-new-chat-btn",children:[t.jsx(lt,{size:14}),"New Chat"]})]}),t.jsxs("div",{className:"chat-messages",ref:ge,onScroll:ys,children:[t.jsx("div",{ref:ms,className:"chat-load-more-sentinel",children:E&&y&&t.jsx("div",{className:"chat-loading-older",children:"Loading older messages…"})}),f?t.jsxs(t.Fragment,{children:[b.map(e=>t.jsx(cs,{message:e,forcePlain:A,agentName:qt,hideAssistantIdentity:Yt,showAssistantModelTag:Xt,activeModelTag:ze,activeModelProvider:He,activeSessionId:i?.id??null,mentionAgentsByName:_t,roomContext:null,copyAction:Qt&&e.role==="assistant"?Zt(e.id,e.content):void 0,onScrollToTop:es},e.id)),t.jsxs("div",{className:"chat-message chat-message--assistant chat-message--streaming",children:[!Yt&&t.jsxs("div",{className:"chat-message-avatar",children:[He?t.jsx(dt,{provider:He,size:"sm"}):t.jsx(ut,{size:14}),t.jsx("span",{children:qt}),Xt]}),I?yn(I,A):t.jsx("div",{className:"chat-message-content chat-message-content--waiting",children:J?"Thinking…":"Connecting…"}),Qt&&I&&Zt("__streaming__",I,"chat-copy-response-streaming"),an(Q),J&&t.jsxs("details",{className:"chat-message-thinking",children:[t.jsx("summary",{children:"Thinking"}),t.jsx("pre",{className:"chat-message-thinking-content",children:Et(J)})]}),t.jsxs("div",{className:"chat-typing-indicator",children:[t.jsx("span",{}),t.jsx("span",{}),t.jsx("span",{})]})]})]}):y?t.jsx("div",{className:"chat-empty-state",children:"Loading messages..."}):b.length===0&&!i?pn():b.length===0&&i?t.jsx("div",{className:"chat-empty-state",children:"No messages yet. Start the conversation!"}):t.jsx(t.Fragment,{children:b.map(e=>t.jsx(cs,{message:e,forcePlain:A,agentName:qt,hideAssistantIdentity:Yt,showAssistantModelTag:Xt,activeModelTag:ze,activeModelProvider:He,activeSessionId:i?.id??null,mentionAgentsByName:_t,roomContext:null,copyAction:Qt&&e.role==="assistant"?Zt(e.id,e.content):void 0,onScrollToTop:es},e.id))}),t.jsx("div",{ref:us})]}),P&&t.jsxs("button",{type:"button",className:"btn btn-sm chat-jump-to-latest","data-testid":"chat-jump-to-latest",onClick:()=>_e("fab-click"),children:[t.jsx(Nt,{size:14}),"Latest"]}),i&&t.jsxs("div",{className:"chat-input-area",children:[t.jsx("input",{ref:ps,type:"file",accept:"image/*,.txt,.json,.yaml,.yml,.log,.csv,.xml,.md",multiple:!0,style:{display:"none"},onChange:e=>{yt(e.target.files),e.target.value=""}}),De&&t.jsx("div",{className:"chat-skill-menu","data-testid":"chat-skill-menu",role:"listbox","aria-label":"Skill suggestions",children:Tt?t.jsx("div",{className:"chat-skill-menu-empty",children:"Loading skills…"}):xe.length===0?t.jsx("div",{className:"chat-skill-menu-empty",children:nt?"No skills found":"No skills available"}):xe.map((e,a)=>t.jsxs("button",{type:"button",role:"option","aria-selected":a===Be,className:`chat-skill-menu-item${a===Be?" chat-skill-menu-item--highlighted":""}`,onMouseDown:o=>o.preventDefault(),onMouseEnter:()=>Le(a),onClick:()=>Ot(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))}),M.length>0&&t.jsx("div",{className:"chat-attachment-previews","data-testid":"chat-attachment-previews",children:M.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:()=>ln(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:()=>ps.current?.click(),children:t.jsx(ea,{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),yt(e.dataTransfer.files)},children:[t.jsx("textarea",{ref:ws,className:"chat-input-textarea",placeholder:"Type a message...",value:$,onChange:Cs,onKeyDown:Ss,onKeyUp:ks,onClick:Ct,onBlur:Ns,onFocus:js,onPaste:dn,onTouchStart:e=>{typeof window>"u"||window.innerWidth>768||_s()&&document.activeElement!==e.currentTarget&&(e.preventDefault(),e.currentTarget.focus({preventScroll:!0}))},rows:1,"data-testid":"chat-input"}),t.jsx(zs,{agents:Je,filter:ke,highlightedIndex:u,visible:ve,onSelect:wt,position:"below",roomMemberIds:Ae?.memberIds,roomName:Ae?.roomName}),t.jsx(ta,{visible:L.mentionActive&&!ve,position:on,tasks:L.tasks,files:L.files,selectedIndex:L.selectedIndex,onSelectTask:e=>{ot(L.selectTask(e,$),`#${e.id}`)},onSelectFile:e=>{ot(L.selectFile(e,$),`#${e.path}`)},loading:L.loading}),O&&t.jsxs("div",{className:"chat-pending-message","data-testid":"chat-pending-indicator",children:[t.jsx("span",{children:`Queued: ${vn}`}),t.jsx("button",{type:"button",className:"chat-pending-message-dismiss","aria-label":"Dismiss queued message","data-testid":"chat-pending-dismiss",onClick:N,children:"×"})]})]}),f?t.jsx("button",{className:"chat-input-stop",onClick:C,"aria-label":"Stop generation","data-testid":"chat-stop-btn",children:t.jsx(sa,{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:()=>{Ht()},disabled:!$.trim()&&M.length===0,"data-testid":"chat-send-btn",style:{touchAction:"manipulation"},children:t.jsx(Hs,{size:16})})]})]})]}),h&&t.jsx(fa,{isOpen:Ve,onClose:()=>Oe(!1),projectId:n,existingRoomNames:c.rooms.map(e=>e.name),onCreate:async e=>{await c.createRoom({name:e.name,memberAgentIds:e.memberAgentIds}),p!=="rooms"&&he("rooms"),Oe(!1),R&&oe(!1)}}),B&&t.jsx(ja,{projectId:n,onClose:()=>te(!1),onCreate:un})]})}export{Ia as ChatView,pa as clampChatInputHeight,ga as resolveChatInputOverflowY,Js as resolveSessionProvider};
@@ -1 +0,0 @@
1
- import{r as i,j as a}from"./vendor-react-K0fH_qHe.js";import{J as X}from"./index-w1dPHtmq.js";import"./vendor-xterm-DzcZoU0P.js";import"./vendor-codemirror-jBKmHyH0.js";const B=5,K=3,_="Cannot activate more than 5 goals. Resolve an active goal before activating another.";function R(o){return!!(o&&typeof o=="object"&&"code"in o&&o.code==="ACTIVE_GOAL_LIMIT_EXCEEDED")}function tt({initialGoals:o}){const[c,g]=i.useState(()=>o??[]),[m,b]=i.useState(o===void 0),[x,n]=i.useState(null),[U,j]=i.useState(!1),[y,N]=i.useState(""),[E,S]=i.useState(""),[w,d]=i.useState(null),[A,C]=i.useState(!1),[h,$]=i.useState(null),[G,p]=i.useState(""),[T,f]=i.useState(""),[k,u]=i.useState(null),[F,P]=i.useState(!1);i.useEffect(()=>{if(o!==void 0)return;let t=!0;return(async()=>{try{b(!0),n(null);const s=await fetch("/api/goals");if(!s.ok)throw new Error(`Failed to load goals (${s.status})`);const l=await s.json();if(!t)return;g(Array.isArray(l.goals)?l.goals:[])}catch{if(!t)return;n("Unable to load goals right now. Please try again.")}finally{t&&b(!1)}})(),()=>{t=!1}},[o]);const v=i.useMemo(()=>c.filter(t=>t.status==="active").length,[c]),M=v>=K&&v<=B;function H(){n(null),d(null),j(!0)}function J(t){$(t.id),p(t.title),f(t.description??""),u(null)}function I(){$(null),p(""),f(""),u(null)}function L(){j(!1),N(""),S(""),d(null)}async function V(){const t=y.trim();if(!t){d("Title is required.");return}try{C(!0),d(null),n(null);const e=await fetch("/api/goals",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({title:t,description:E})});if(e.ok){const l=await e.json();g(r=>[...r,l]),L();return}let s=null;try{s=await e.json()}catch{s=null}if(e.status===409&&R(s)){n(_);return}d("Unable to create goal right now. Please try again.")}catch{d("Unable to create goal right now. Please try again.")}finally{C(!1)}}async function q(){if(!h)return;const t=G.trim();if(!t){u("Title is required.");return}try{P(!0),u(null);const e=await fetch(`/api/goals/${h}`,{method:"PATCH",headers:{"content-type":"application/json"},body:JSON.stringify({title:t,description:T})});if(!e.ok)throw new Error(`Failed to update goal (${e.status})`);const s=await e.json();g(l=>l.map(r=>r.id===s.id?s:r)),I()}catch{u("Unable to save goal right now. Please try again.")}finally{P(!1)}}async function O(t){const e=t.status==="active"?`/api/goals/${t.id}/archive`:`/api/goals/${t.id}/unarchive`;try{n(null);const s=await fetch(e,{method:"POST"});if(s.ok){const r=await s.json();g(W=>W.map(D=>D.id===r.id?r:D));return}let l=null;try{l=await s.json()}catch{l=null}if(s.status===409&&R(l)){n(_);return}n("Unable to update goal status right now. Please try again.")}catch{n("Unable to update goal status right now. Please try again.")}}return a.jsxs("section",{className:"goals-view","data-testid":"goals-view",children:[a.jsxs("header",{className:"goals-header",children:[a.jsxs("div",{children:[a.jsx("h2",{className:"goals-title",children:"Goals"}),a.jsxs("p",{className:"goals-count","data-testid":"goals-active-count",children:[v," active goals"]})]}),a.jsxs("button",{type:"button",className:"btn btn-primary goals-add-button",onClick:H,"data-testid":"goals-add-button",children:[a.jsx(X,{"aria-hidden":"true"}),"Add Goal"]})]}),U?a.jsxs("div",{className:"card goals-form","data-testid":"goals-form",children:[a.jsx("label",{className:"goals-form-label",htmlFor:"goals-form-title",children:"Title"}),a.jsx("input",{id:"goals-form-title",className:"input",type:"text",value:y,maxLength:200,onChange:t=>N(t.target.value),"data-testid":"goals-form-title"}),a.jsx("label",{className:"goals-form-label",htmlFor:"goals-form-description",children:"Description"}),a.jsx("textarea",{id:"goals-form-description",className:"input",value:E,maxLength:5e3,onChange:t=>S(t.target.value),"data-testid":"goals-form-description"}),w?a.jsx("p",{className:"form-error goals-error",role:"alert",children:w}):null,a.jsxs("div",{className:"goals-form-actions",children:[a.jsx("button",{type:"button",className:"btn btn-primary",onClick:()=>void V(),disabled:A,"data-testid":"goals-form-submit",children:"Save"}),a.jsx("button",{type:"button",className:"btn",onClick:L,disabled:A,"data-testid":"goals-form-cancel",children:"Cancel"})]})]}):null,M?a.jsx("p",{className:"goals-warning",role:"status",children:"Approaching the 5-active goal cap. Keep active goals focused."}):null,x?a.jsx("p",{className:"form-error goals-error",role:"alert","data-testid":"goals-error",children:x}):null,m?a.jsx("p",{className:"goals-loading",role:"status","data-testid":"goals-loading",children:"Loading goals…"}):null,!m&&c.length===0?a.jsx("div",{className:"goals-empty card","data-testid":"goals-empty-state",children:"No goals yet. Add one to begin tracking strategic outcomes."}):null,!m&&c.length>0?a.jsx("div",{className:"goals-list","data-testid":"goals-list",children:c.map(t=>a.jsx("article",{className:`card goals-card ${t.status==="archived"?"goals-card-archived":""}`.trim(),"data-testid":`goal-card-${t.id}`,children:h===t.id?a.jsxs("div",{className:"goals-card-main goals-card-edit",children:[a.jsx("label",{className:"goals-form-label",htmlFor:`goal-edit-title-${t.id}`,children:"Title"}),a.jsx("input",{id:`goal-edit-title-${t.id}`,className:"input",type:"text",value:G,maxLength:200,onChange:e=>p(e.target.value),"data-testid":`goal-edit-title-${t.id}`}),a.jsx("label",{className:"goals-form-label",htmlFor:`goal-edit-description-${t.id}`,children:"Description"}),a.jsx("textarea",{id:`goal-edit-description-${t.id}`,className:"input",value:T,maxLength:5e3,onChange:e=>f(e.target.value),"data-testid":`goal-edit-description-${t.id}`}),k?a.jsx("p",{className:"form-error goals-error",role:"alert",children:k}):null,a.jsxs("div",{className:"goals-card-actions",children:[a.jsx("button",{type:"button",className:"btn btn-primary",onClick:()=>void q(),disabled:F,"data-testid":`goal-edit-save-${t.id}`,children:"Save"}),a.jsx("button",{type:"button",className:"btn",onClick:I,disabled:F,"data-testid":`goal-edit-cancel-${t.id}`,children:"Cancel"})]})]}):a.jsxs(a.Fragment,{children:[a.jsxs("div",{className:"goals-card-main",children:[a.jsx("h3",{className:"goals-card-title",children:t.title}),t.description?a.jsx("p",{className:"goals-card-description",children:t.description}):null,a.jsxs("p",{className:"goals-card-status",children:["Status: ",t.status]})]}),a.jsxs("div",{className:"goals-card-actions",children:[a.jsx("button",{type:"button",className:"btn",onClick:()=>J(t),"data-testid":`goal-edit-${t.id}`,children:"Edit"}),t.status==="active"?a.jsx("button",{type:"button",className:"btn goals-activate-button",onClick:()=>void O(t),"data-testid":`goal-archive-${t.id}`,children:"Archive"}):a.jsx("button",{type:"button",className:"btn goals-activate-button",onClick:()=>void O(t),"data-testid":`goal-unarchive-${t.id}`,children:"Unarchive"})]})]})},t.id))}):null]})}export{tt as GoalsView};
@@ -1 +0,0 @@
1
- .settings-header-actions{--settings-header-action-height: calc(var(--space-md) * 2 + var(--space-xs) / 2);display:flex;align-items:stretch;gap:var(--space-xs);margin-left:auto;margin-right:var(--space-sm)}.settings-header-actions>.settings-github-star-btn,.settings-header-actions>.settings-header-help-btn{height:var(--settings-header-action-height);box-sizing:border-box}.settings-header-help-btn{display:inline-flex;align-items:center}@media(max-width:768px){.settings-modal .modal-header{flex-wrap:nowrap;align-items:center;column-gap:var(--space-sm)}.settings-modal-heading{flex:1 1 0;min-width:0}.settings-update-check{flex-wrap:wrap;row-gap:var(--space-xs)}.settings-header-actions{margin-left:auto;margin-right:var(--space-sm)}}.settings-github-star-btn{display:inline-flex;align-items:stretch;border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-pill);background:var(--card);color:var(--text);font-size:12px;font-weight:500;text-decoration:none;overflow:hidden;transition:border-color var(--transition-fast),background var(--transition-fast)}.settings-github-star-btn:hover{border-color:var(--text-muted);background:var(--card-hover)}.settings-github-star-btn:focus-visible{outline:none;box-shadow:var(--focus-ring-strong);border-color:var(--todo)}.settings-github-star-btn__action{display:inline-flex;align-items:center;gap:var(--space-xs);padding:var(--space-xs) calc(var(--space-sm) + var(--space-xs) / 2)}.settings-github-star-btn__count{display:inline-flex;align-items:center;padding:var(--space-xs) calc(var(--space-sm) + var(--space-xs) / 4);border-left:var(--btn-border-width) solid var(--border);background:color-mix(in srgb,var(--surface) 60%,var(--card));color:var(--text-muted);font-variant-numeric:tabular-nums}.settings-modal{width:min(95vw,1100px);max-width:95vw;min-width:520px;height:80vh;min-height:480px;max-height:calc(100dvh - var(--overlay-padding-top, 10vh) - 16px);overflow:hidden;resize:both}@media(max-width:768px){.modal-overlay.settings-modal-overlay,.modal-overlay:has(.settings-modal){padding:0;inset:0;align-items:stretch;justify-content:stretch}.modal.settings-modal{width:100vw;min-width:0;max-width:100vw;height:100dvh;min-height:100dvh;max-height:100dvh;margin:0;border:none;border-radius:0;resize:none;flex:1 1 auto}.modal.settings-modal[style*=--keyboard-overlap]{height:var(--vv-height, 100dvh);min-height:var(--vv-height, 100dvh);max-height:var(--vv-height, 100dvh);transform:translateY(var(--vv-offset-top, 0px));will-change:transform}}.settings-modal-heading{display:flex;flex-direction:column;gap:var(--space-xs)}.settings-modal-heading h3{margin:0}.settings-modal-version{margin:0;font-size:.85rem;color:var(--text-muted);font-weight:500}.settings-update-check{display:flex;align-items:center;gap:var(--space-sm)}.settings-version-check-btn{--settings-inline-touch-target: calc(var(--space-lg) + var(--space-lg) + var(--space-xs));display:inline-flex;align-items:center;gap:var(--space-xs);margin:0;min-height:var(--settings-inline-touch-target);padding:var(--space-xs) var(--space-sm);border:none;background:transparent;color:var(--text-muted);cursor:pointer;transition:opacity var(--transition-fast),box-shadow var(--transition-fast)}.settings-version-check-btn:hover:not(:disabled){opacity:.85}.settings-version-check-btn:focus-visible{outline:none;box-shadow:var(--focus-ring-strong);border-radius:var(--radius-sm)}.settings-version-check-btn:disabled{cursor:default;opacity:.7}.settings-version-check-btn svg{color:var(--text-muted)}.settings-version-check-btn svg.spinning{animation:settings-update-spin 1s linear infinite}.settings-update-result{font-size:.85rem;font-weight:500}.settings-update-result--up-to-date{color:var(--color-success)}.settings-update-result--available{color:var(--color-info)}.settings-update-result--error{color:var(--text-muted)}.settings-update-result-link{color:var(--color-info);text-decoration:underline;transition:color var(--transition-fast),box-shadow var(--transition-fast)}.settings-update-result-link:hover{color:color-mix(in srgb,var(--color-info) 80%,var(--text))}.settings-update-result-link:focus-visible{outline:none;box-shadow:var(--focus-ring-strong);border-radius:var(--radius-sm)}@keyframes settings-update-spin{to{transform:rotate(360deg)}}.backup-stats{display:flex;align-items:center;gap:var(--space-lg);padding:var(--space-sm) var(--space-md);border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-md);background:color-mix(in srgb,var(--surface) 85%,transparent)}.backup-stat{display:flex;flex:1 1 0;flex-direction:column;align-items:center;gap:var(--space-xs);min-width:0}.backup-stat-value{color:var(--text);font-size:1rem;font-weight:600;font-variant-numeric:tabular-nums}.backup-stat-label{color:var(--text-muted);font-size:.75rem;font-weight:600;letter-spacing:.04em;text-transform:uppercase}.backup-list{margin-top:var(--space-sm)}.backup-list summary{padding:var(--space-sm) 0;color:var(--text-muted);cursor:pointer;transition:color var(--transition-fast)}.backup-list summary:hover{color:var(--text)}.backup-list summary:focus-visible{outline:none;border-radius:var(--radius-sm);box-shadow:var(--focus-ring-strong)}.backup-list ul{display:flex;flex-direction:column;gap:var(--space-xs);margin:0;margin-top:var(--space-sm);padding:0;list-style:none}.backup-list li{display:flex;align-items:center;justify-content:space-between;gap:var(--space-sm);padding:var(--space-sm) 0;border-top:var(--btn-border-width) solid color-mix(in srgb,var(--border) 80%,transparent)}.backup-list li code{min-width:0;color:var(--text);font-family:var(--font-mono);font-size:.75rem;white-space:nowrap;overflow-x:auto}.backup-size{color:var(--text-muted);font-family:var(--font-mono);font-size:.75rem;text-align:right;white-space:nowrap}@media(max-width:768px){.backup-stats{flex-direction:column;align-items:stretch;gap:var(--space-sm)}.backup-stat{align-items:flex-start}.backup-list ul{max-height:calc(var(--space-xl) * 9 + var(--space-md));overflow-y:auto;-webkit-overflow-scrolling:touch}.backup-list li code{white-space:normal;overflow-wrap:anywhere;word-break:normal}}.settings-layout{display:flex;flex:1;flex-direction:row;min-height:0;overflow:hidden}.settings-mobile-section-picker{display:none}.settings-sidebar{width:170px;min-width:170px;border-right:1px solid var(--border);display:flex;flex-direction:column;overflow-y:auto;padding:var(--space-sm) var(--space-sm);gap:calc(var(--space-xs) / 2);background:color-mix(in srgb,var(--text) 10%,transparent);scrollbar-color:var(--border) transparent;scrollbar-width:thin}.settings-sidebar::-webkit-scrollbar{width:6px}.settings-sidebar::-webkit-scrollbar-track{background:transparent}.settings-sidebar::-webkit-scrollbar-thumb{background:var(--border);border-radius:var(--radius-sm)}.settings-sidebar::-webkit-scrollbar-thumb:hover{background:var(--text-muted)}.settings-research-source-locked{cursor:default;color:var(--text-muted)!important}.settings-research-source-locked input[type=checkbox]{cursor:not-allowed}.settings-research-source-grid,.settings-research-limits-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--space-sm)}.settings-research-limit-field{display:flex;flex-direction:column;gap:var(--space-xs)}.settings-research-limits-error{grid-column:1 / -1}@media(max-width:768px){.settings-research-source-grid,.settings-research-limits-grid{grid-template-columns:1fr}}.settings-nav-item{display:block;width:100%;padding:var(--space-sm) var(--space-md);font-size:13px;font-weight:500;color:var(--text-muted);background:none;border:none;border-left:3px solid transparent;border-radius:0 var(--radius-md) var(--radius-md) 0;cursor:pointer;text-align:left;transition:background var(--transition-fast),color var(--transition-fast),border-color var(--transition-fast)}.settings-nav-item:hover{background:var(--bg);color:var(--text);border-left-color:var(--border)}.settings-nav-item:focus-visible{box-shadow:var(--focus-ring-strong);outline:none}.settings-nav-item.active{background:var(--bg);color:var(--todo);font-weight:600;border-left-color:var(--todo)}.settings-group-header{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:var(--text-muted);padding:var(--space-md) var(--space-md) var(--space-xs);margin-top:var(--space-sm);user-select:none}.settings-group-header:first-child{margin-top:0}.settings-content{flex:1;overflow-x:hidden;overflow-y:auto;padding:4px 0 12px;scrollbar-color:var(--border) transparent;scrollbar-width:thin}.settings-content::-webkit-scrollbar{width:6px}.settings-content::-webkit-scrollbar-track{background:transparent}.settings-content::-webkit-scrollbar-thumb{background:var(--border);border-radius:var(--radius-sm)}.settings-content::-webkit-scrollbar-thumb:hover{background:var(--text-muted)}.settings-content>*{animation:settingsFadeIn var(--transition-normal)}@keyframes settingsFadeIn{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.settings-section-heading{font-size:14px;font-weight:600;padding:var(--space-lg) var(--space-xl) var(--space-md);margin:0 0 var(--space-md);color:var(--text);border-bottom:1px solid var(--border)}.settings-content>.settings-section-heading:first-child,.settings-modal-section>.settings-section-heading:first-child{padding-top:var(--space-md)}.settings-section-heading--spaced{margin-top:var(--space-lg)}.settings-section-description{margin:0;padding:0 var(--space-xl);margin-bottom:var(--space-sm);color:var(--text-muted);font-size:13px;line-height:1.5}.settings-plugins-subsection-toggle{display:inline-flex;gap:var(--space-xs);padding:0 var(--space-xl);margin:var(--space-md) 0}.settings-plugins-subsection-btn{display:inline-flex;align-items:center;justify-content:center;border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-pill);background:var(--surface);color:var(--text-muted);font-size:.85rem;font-weight:600;padding:var(--space-xs) var(--space-md);cursor:pointer;transition:background var(--transition-fast),color var(--transition-fast),border-color var(--transition-fast),box-shadow var(--transition-fast)}.settings-plugins-subsection-btn:hover{background:var(--surface-hover, color-mix(in srgb, var(--text) 6%, transparent));color:var(--text)}.settings-plugins-subsection-btn:focus-visible{outline:none;box-shadow:var(--focus-ring-strong)}.settings-plugins-subsection-btn.active{background:color-mix(in srgb,var(--todo) 14%,transparent);border-color:color-mix(in srgb,var(--todo) 45%,var(--border));color:var(--todo)}.settings-plugins-subsection-panel{padding-bottom:var(--space-md)}.settings-scope-icon{margin-right:6px;display:inline-flex;vertical-align:middle;color:var(--text-muted)}.settings-scope-banner{display:flex;align-items:center;gap:var(--space-sm);padding:var(--space-sm) var(--space-xl);margin:0 var(--space-xl) var(--space-xs);font-size:12px;border-radius:var(--radius-md);color:var(--text-muted)}.settings-scope-global{background:color-mix(in srgb,var(--color-info) 8%,transparent);border-left:3px solid color-mix(in srgb,var(--color-info) 40%,transparent)}.settings-scope-project{background:color-mix(in srgb,var(--color-success) 8%,transparent);border-left:3px solid color-mix(in srgb,var(--color-success) 40%,transparent)}.settings-scope-mixed{background:color-mix(in srgb,var(--triage) 8%,transparent);border-left:3px solid color-mix(in srgb,var(--triage) 40%,transparent)}.settings-note{display:block;padding:0 var(--space-xl);margin-top:var(--space-xs);font-size:12px;color:var(--text-muted)}.form-inline-group{display:flex;align-items:center;gap:var(--space-sm)}.form-inline-group .input{flex:1;min-width:0}.btn-link{background:none;border:none;padding:0;font-size:12px;color:var(--accent, #4a90e2);cursor:pointer;text-decoration:underline;white-space:nowrap}.btn-link:hover{text-decoration:none}.settings-overlap-ignore-group code{font-family:var(--font-mono);font-size:.9em}.settings-button-row{display:flex;flex-wrap:wrap;gap:var(--space-sm);margin-top:var(--space-sm)}.settings-raw-output{margin:var(--space-sm) 0 0;padding:var(--space-sm);border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--surface);color:var(--text-muted);max-height:calc(var(--space-2xl) * 7);overflow:auto;font-family:var(--font-mono);font-size:calc(var(--space-sm) + var(--space-xs))}.settings-url-output{display:block;margin-top:var(--space-xs);padding:var(--space-sm);border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--surface);color:var(--text-muted);font-family:var(--font-mono);font-size:calc(var(--space-sm) + var(--space-xs));overflow-wrap:anywhere;word-break:break-word;overflow-x:auto;max-width:100%}.settings-qr-preview{margin-top:var(--space-sm);display:flex;flex-direction:column;gap:var(--space-sm)}.settings-qr-preview-label{margin:0;font-size:calc(var(--space-sm) + var(--space-xs));color:var(--text-muted)}.settings-qr-preview-image-wrap{width:fit-content;max-width:100%;padding:var(--space-sm);border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--card)}.settings-qr-preview-image{display:block;width:min(calc(var(--space-2xl) * 6),100%);height:auto;aspect-ratio:1 / 1}.remote-provider-selector{display:flex;gap:var(--space-xs);border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-md);padding:var(--space-xs);background:var(--surface)}.remote-provider-option{position:relative;flex:1;cursor:pointer}.remote-provider-option input{position:absolute;opacity:0;width:0;height:0}.remote-provider-option span{display:block;padding:var(--space-sm) var(--space-md);text-align:center;border-radius:var(--radius-sm);border:var(--btn-border-width) solid transparent;color:var(--text-muted);transition:background var(--transition-fast),color var(--transition-fast),border-color var(--transition-fast)}.remote-provider-option-content{display:inline-flex;align-items:center;gap:var(--space-xs)}.remote-provider-option input:checked+span{background:var(--card);color:var(--text);border-color:var(--border)}.remote-provider-option input:focus-visible+span{box-shadow:var(--focus-ring-strong)}.remote-status-bar{--status-color: var(--text-muted);display:flex;align-items:center;gap:var(--space-sm);padding:var(--space-sm) var(--space-md);border-radius:var(--radius-md);margin:0 var(--space-xl) var(--space-md);background:color-mix(in srgb,var(--status-color) 10%,transparent)}.remote-status-bar--running{--status-color: var(--color-success)}.remote-status-bar--starting{--status-color: var(--color-warning)}.remote-status-bar--error{--status-color: var(--color-error)}.remote-status-bar--stopped{--status-color: var(--text-muted)}.remote-share-block{display:flex;flex-direction:column;gap:var(--space-sm);margin:0 var(--space-xl) var(--space-md);padding:var(--space-sm) var(--space-md);border:1px solid var(--border);border-radius:var(--radius-md);background:color-mix(in srgb,var(--text-muted) 5%,transparent)}.remote-share-row{display:flex;flex-direction:column;gap:var(--space-xs)}.remote-share-row .settings-qr-preview-image{margin-top:var(--space-xs)}.remote-status-dot{width:var(--space-sm);height:var(--space-sm);border-radius:50%;display:inline-block;flex-shrink:0}.remote-status-dot--running{background:var(--color-success)}.remote-status-dot--starting{background:var(--color-warning)}.remote-status-dot--error{background:var(--color-error)}.remote-status-dot--stopped{background:var(--text-muted)}.remote-status-url{margin-left:auto;font-family:var(--font-mono);overflow-wrap:anywhere;word-break:break-word;user-select:all}.remote-provider-settings{display:flex;flex-direction:column;gap:var(--space-sm)}.remote-cli-detection{display:flex;align-items:flex-start;gap:var(--space-sm);margin:0 var(--space-xl) var(--space-md);padding:var(--space-sm) var(--space-md);border-radius:var(--radius-sm)}.remote-cli-detection--available{background:color-mix(in srgb,var(--color-success) 10%,transparent);color:var(--color-success)}.remote-cli-detection--missing{background:color-mix(in srgb,var(--color-warning) 10%,transparent);color:var(--color-warning)}.remote-cli-detection-content{display:flex;flex-direction:column;gap:var(--space-xs);color:var(--text)}.remote-cli-detection .btn{align-self:flex-start}.remote-cli-install-error{color:var(--color-error)}.remote-cli-manual{color:var(--text-dim)}.remote-external-tunnel-panel{display:flex;flex-direction:column;gap:var(--space-sm);margin:0 var(--space-xl) var(--space-md);padding:var(--space-sm) var(--space-md);border:1px solid var(--border);border-radius:var(--radius-md);background:color-mix(in srgb,var(--color-info) 10%,transparent)}.remote-external-tunnel-header{display:flex;align-items:center;gap:var(--space-sm);color:var(--color-info)}.remote-external-tunnel-qr{display:flex;flex-direction:column;gap:var(--space-xs)}.remote-external-tunnel-actions{display:flex;flex-direction:column;gap:var(--space-sm)}.remote-advanced-details{margin:var(--space-lg) var(--space-xl) 0;border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-md);padding:var(--space-md);background:var(--surface)}.remote-advanced-details>summary{cursor:pointer;color:var(--text-muted);font-size:calc(var(--space-sm) + var(--space-xs));list-style:none}.remote-advanced-details>summary::-webkit-details-marker{display:none}.remote-advanced-details>summary:before{content:"▸";margin-right:var(--space-xs)}.remote-advanced-details[open]>summary:before{content:"▾"}.settings-option-details{margin-top:var(--space-xs)}.settings-research-provider-group{display:flex;flex-direction:column;gap:var(--space-sm)}.settings-research-provider-advanced-details{margin-left:var(--space-md)}.settings-research-empty-state{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-sm)}@media(max-width:768px){.settings-research-provider-advanced-details{margin-left:0}}.settings-option-details>summary{cursor:pointer;color:var(--text-muted);font-size:calc(var(--space-sm) + var(--space-xs));list-style:none}.settings-option-details>summary::-webkit-details-marker{display:none}.settings-option-details>summary:before{content:"▸";margin-right:var(--space-xs)}.settings-option-details[open]>summary:before{content:"▾"}.remote-cf-advanced-details{margin-top:var(--space-xs)}.remote-cf-advanced-details>summary{cursor:pointer;color:var(--text-muted);font-size:calc(var(--space-sm) + var(--space-xs));list-style:none}.remote-cf-advanced-details>summary::-webkit-details-marker{display:none}.remote-cf-advanced-details>summary:before{content:"▸";margin-right:var(--space-xs)}.remote-cf-advanced-details[open]>summary:before{content:"▾"}.remote-cf-advanced-fields{display:flex;flex-direction:column;gap:var(--space-sm);margin-top:var(--space-sm)}.remote-tunnel-actions{margin-top:var(--space-md)}.remote-tunnel-actions .btn{width:100%}.settings-overlap-ignore-list{display:flex;flex-direction:column;gap:var(--space-sm);margin:var(--space-sm) 0}.settings-overlap-ignore-row,.settings-overlap-ignore-path-controls{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:var(--space-sm);align-items:center}.settings-overlap-path-picker-modal{max-width:min(960px,calc(100vw - var(--space-2xl)))}.settings-overlap-path-picker-body{display:flex;flex-direction:column;gap:var(--space-sm);max-height:min(70vh,720px)}.settings-overlap-path-picker-note{margin:0;font-size:12px;color:var(--text-muted)}.settings-section-divider{border-top:1px solid var(--border);margin:var(--space-lg) var(--space-xl)}@media(max-width:768px){.settings-note{padding:0 var(--space-lg)}.settings-overlap-ignore-row,.settings-overlap-ignore-path-controls{grid-template-columns:minmax(0,1fr)}.settings-overlap-ignore-row>.btn{justify-self:start}.settings-overlap-path-picker-modal{max-width:calc(100vw - var(--space-md))}.remote-provider-selector{flex-direction:column}.remote-status-bar{flex-wrap:wrap;margin:0 var(--space-lg) var(--space-md)}.remote-share-block{margin:0 var(--space-lg) var(--space-md)}.remote-status-url{width:100%;margin-left:0;font-size:.8em}.remote-provider-option,.remote-tunnel-actions .btn{min-height:36px}.remote-cli-detection,.remote-external-tunnel-panel{margin:0 var(--space-lg) var(--space-md)}}.ntfy-advanced-disclosure{margin-top:var(--space-md);border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-md);background:var(--surface)}.ntfy-advanced-disclosure>summary{cursor:pointer;list-style:none;padding:var(--space-sm) var(--space-md);font-size:12px;font-weight:600;color:var(--text)}.ntfy-advanced-disclosure>summary::-webkit-details-marker{display:none}.ntfy-advanced-content{padding:0 var(--space-md) var(--space-md);display:flex;flex-direction:column;gap:var(--space-sm)}.settings-inline-link{color:var(--todo);text-decoration:none;transition:text-decoration var(--transition-fast)}.settings-inline-link:hover{text-decoration:underline}.settings-inline-link:focus-visible{outline:none;box-shadow:var(--focus-ring-strong);border-radius:var(--radius-sm)}.notification-provider-card{border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-lg);background:var(--surface);margin:0 var(--space-xl) var(--space-lg);overflow:hidden}.notification-provider-header{display:flex;align-items:center;justify-content:space-between;padding:var(--space-md) var(--space-lg);border-bottom:var(--btn-border-width) solid var(--border)}.notification-provider-body{padding:var(--space-lg);display:flex;flex-direction:column;gap:var(--space-lg)}.notification-provider-actions{display:flex;flex-wrap:wrap;gap:var(--space-sm);padding-top:var(--space-md);border-top:var(--btn-border-width) solid var(--border);margin-top:var(--space-md)}.notification-test-feedback{display:flex;flex-direction:column;gap:var(--space-xs);margin-top:var(--space-sm)}.notification-test-feedback-item{border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-sm);padding:var(--space-xs) var(--space-sm)}.notification-test-feedback-item--success{border-color:color-mix(in srgb,var(--color-success) 45%,var(--border));background:color-mix(in srgb,var(--color-success) 8%,transparent);color:var(--color-success)}.notification-test-feedback-item--error{border-color:color-mix(in srgb,var(--color-error) 45%,var(--border));background:color-mix(in srgb,var(--color-error) 8%,transparent);color:var(--color-error)}@media(max-width:768px){.notification-provider-actions{flex-direction:column}.notification-provider-actions .btn{width:100%}}.memory-status-message{display:flex;gap:var(--space-md);align-items:center;justify-content:space-between;margin-bottom:var(--space-md)}.memory-status-message span{min-width:0}.memory-retrieval-test{margin-top:var(--space-lg)}.memory-test-result{margin:0 var(--space-xl) var(--space-lg);padding:var(--space-md);border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-md);background:var(--card)}.memory-test-result strong,.memory-test-result span{color:var(--text);font-size:12px}.memory-test-result small{display:block;margin-top:var(--space-xs);color:var(--text-muted);font-size:12px}.memory-test-result ul{margin:var(--space-md) 0 0;padding:0;list-style:none}.memory-test-result li{padding-top:var(--space-sm);border-top:var(--btn-border-width) solid var(--border)}.memory-test-result li+li{margin-top:var(--space-sm)}.memory-test-result p{margin:var(--space-xs) 0 0;color:var(--text-muted);font-size:12px;line-height:1.5;overflow-wrap:anywhere}.memory-editor-section{margin-top:var(--space-lg);display:flex;flex:1 1 auto;flex-direction:column;min-height:0}.memory-editor-form-group{display:flex;flex:1 1 auto;flex-direction:column;min-height:0}.memory-file-summary{display:grid;grid-template-columns:auto minmax(0,1fr);gap:var(--space-xs) var(--space-md);align-items:center;margin:0 var(--space-xl) var(--space-md);padding:var(--space-md);border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-md);background:var(--card)}.memory-file-summary span{display:inline-flex;align-items:center;justify-content:center;padding:var(--space-xs) var(--space-sm);border-radius:var(--radius-pill);color:var(--color-info);background:color-mix(in srgb,var(--color-info) 12%,transparent);font-size:11px;font-weight:600}.memory-file-summary strong{min-width:0;overflow-wrap:anywhere;color:var(--text);font-family:var(--font-mono);font-size:12px}.memory-file-summary small{grid-column:2;color:var(--text-muted);font-size:12px}.memory-editor-frame{min-height:50vh;border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-md);overflow:hidden;display:flex;flex:1 1 auto;flex-direction:column;min-width:0}.auth-panel-body{padding-inline:var(--space-md)}.auth-section-hint{padding:var(--space-md) var(--space-lg);margin-bottom:var(--space-md);background:var(--bg-tertiary);border-radius:var(--radius-md);font-size:13px;color:var(--text-muted);border-left:3px solid var(--text-muted)}.auth-provider-group{margin-bottom:calc(var(--space-sm) + var(--space-xs) / 2)}.auth-group-label{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.5px;color:var(--text-muted);margin-bottom:var(--space-xs);padding:0 4px}.auth-provider-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-md);margin-bottom:var(--space-xs);overflow:hidden;transition:border-color var(--transition-fast),box-shadow var(--transition-fast)}.auth-provider-card:hover{border-color:var(--text-dim)}.auth-provider-card--authenticated{border-color:color-mix(in srgb,var(--color-success) 40%,var(--border));background:color-mix(in srgb,var(--color-success) 5%,var(--surface))}.auth-provider-card--authenticated:hover{border-color:color-mix(in srgb,var(--color-success) 60%,var(--border))}.auth-provider-header{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding:var(--space-sm) var(--space-md);gap:12px}.auth-provider-info{display:flex;align-items:center;gap:10px;flex-wrap:wrap;flex:1;min-width:0}.auth-provider-info strong{font-weight:500;color:var(--text)}.auth-provider-icon-slot{display:inline-flex;align-items:center;justify-content:center;inline-size:calc(var(--space-md) + var(--space-xs) * 2);block-size:calc(var(--space-md) + var(--space-xs) * 2);flex-shrink:0}.auth-provider-icon-slot .provider-icon{display:inline-flex}.auth-hint{display:block;padding:12px 4px 0;font-size:12px;color:var(--text-muted);border-top:1px solid var(--border);margin-top:8px}.auth-apikey-section{display:flex;flex-direction:column;gap:var(--space-xs);align-items:flex-end;flex-shrink:0}.auth-apikey-input-row{display:flex;gap:6px;align-items:center}.auth-apikey-input{background:var(--bg-input);border:1px solid var(--border);border-radius:6px;color:var(--text);padding:6px 10px;font-size:13px;width:180px;font-family:monospace}.auth-apikey-input:focus{outline:none;border-color:var(--todo);box-shadow:var(--focus-ring)}.auth-apikey-input:disabled{opacity:.6}.auth-apikey-progress{font-size:calc(var(--space-sm) + var(--space-xs) * .75);color:var(--text-muted);padding-right:4px}.auth-apikey-error{font-size:11px;color:var(--color-error);padding-right:4px}.auth-provider-actions-row{display:flex;width:100%;align-items:center;gap:var(--space-sm)}.auth-device-code-panel{width:100%;margin-top:var(--space-sm);padding:var(--space-sm);border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-md);background:color-mix(in srgb,var(--surface) 85%,transparent);display:flex;flex-direction:column;gap:var(--space-sm)}.auth-device-code-pill{font-family:var(--font-mono);font-size:calc(var(--space-md) + var(--space-xs) * .5);letter-spacing:var(--space-xs);padding:var(--space-sm) var(--space-md);border-radius:var(--radius-pill);border:var(--btn-border-width) solid var(--border);background:var(--card);color:var(--text);display:flex;align-self:stretch}.auth-key-hint{font-family:var(--font-mono);font-size:12px;color:var(--text-muted);display:inline-block;margin-top:var(--space-xs);user-select:none}.settings-lane-badge{display:inline-flex;align-items:center;padding:2px 8px;border-radius:10px;font-size:11px;font-weight:500;white-space:nowrap}.settings-lane-badge--override{background-color:color-mix(in srgb,var(--todo) 20%,transparent);color:var(--todo)}.settings-lane-badge--inherited{background-color:color-mix(in srgb,var(--text-muted) 15%,transparent);color:var(--text-muted)}.settings-description{font-size:13px;color:var(--text-dim);padding-inline:var(--space-xl);margin-block:0 var(--space-md);line-height:1.5}.settings-token-cap-row{display:flex;align-items:center;gap:var(--space-sm)}.settings-model-lane-label-row{display:flex;align-items:center;gap:var(--space-sm);margin-bottom:var(--space-xs)}.settings-model-lane-control-row{display:flex;align-items:center;gap:var(--space-sm)}.settings-model-lane-control-main{flex:1}.settings-summarization-actions{justify-content:flex-start}.settings-model-presets{display:flex;flex-direction:column;gap:var(--space-md)}.settings-preset-list{display:flex;flex-direction:column;gap:var(--space-sm)}.settings-preset-item{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--space-md);padding:var(--space-md);border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-md);background:var(--card)}.settings-preset-item-meta{display:flex;flex-direction:column;gap:var(--space-xs);min-width:0}.settings-preset-item-meta strong{color:var(--text);overflow-wrap:anywhere}.settings-preset-summary{font-size:12px;overflow-wrap:anywhere}.settings-preset-item-actions{display:flex;gap:var(--space-xs);flex-wrap:wrap;justify-content:flex-end}.settings-preset-actions{display:flex;justify-content:flex-start}.settings-preset-editor{display:flex;flex-direction:column;gap:var(--space-md);padding:var(--space-md);border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-md);background:color-mix(in srgb,var(--surface) 85%,var(--card))}.settings-preset-editor-fields{display:flex;flex-direction:column;gap:var(--space-sm)}.settings-preset-editor .form-group{padding:0}.settings-preset-editor-actions{justify-content:flex-start;margin-top:0;padding:0}.settings-preset-auto-select{margin-top:var(--space-sm)}.settings-preset-size-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--space-sm)}.settings-preset-size-row{padding:0}@media(max-width:768px){.settings-layout{flex-direction:column;min-height:0}.settings-mobile-section-picker{display:flex;flex-direction:column;gap:var(--space-xs);padding:var(--space-md) var(--space-lg);border-bottom:var(--btn-border-width) solid var(--border);background:var(--surface)}.settings-mobile-section-picker label{color:var(--text-muted);font-weight:600;text-transform:uppercase}.settings-mobile-section-picker select{width:100%}.settings-mobile-section-picker select:focus-visible{outline:none;border-color:var(--todo);box-shadow:var(--focus-ring-strong)}.settings-sidebar{display:none}.settings-nav-item{display:flex;align-items:center;justify-content:center;gap:var(--space-xs);border-left:none;border-bottom:2px solid transparent;border-radius:var(--radius-md) var(--radius-md) 0 0;padding:calc(var(--space-xs) + var(--space-xs) / 2) var(--space-md);white-space:nowrap}.settings-nav-item:hover{border-left-color:transparent;border-bottom-color:var(--border)}.settings-nav-item.active{border-left-color:transparent;border-bottom-color:var(--todo)}.settings-group-header{display:none}.notification-provider-card{margin:0 var(--space-lg) var(--space-md)}.notification-provider-header{padding:var(--space-sm) var(--space-md)}.notification-provider-body{padding:var(--space-md)}.settings-scope-icon{margin-right:0}.settings-content{flex:1;min-height:0;overflow-x:hidden;overflow-y:auto}.settings-content .form-group small{overflow-wrap:break-word;word-break:normal}.settings-content input,.settings-content select,.settings-content textarea{font-size:16px}.settings-section-heading{padding:var(--space-lg) var(--space-lg) var(--space-md);margin:0 0 var(--space-md)}.settings-plugins-subsection-toggle{display:flex;width:100%;padding:0 var(--space-lg)}.settings-plugins-subsection-btn{flex:1;min-height:36px}.settings-plugins-subsection-panel{padding-left:var(--space-lg);padding-right:var(--space-lg)}.form-group{padding:0 calc(var(--space-md) + var(--space-xs) / 2)}.settings-scope-banner{padding:var(--space-sm) var(--space-lg)}.memory-editor-frame{min-height:65vh}.memory-file-summary{grid-template-columns:1fr;margin:0 var(--space-lg) var(--space-md)}.memory-status-message{align-items:stretch;flex-direction:column}.memory-file-summary span{justify-content:flex-start}.memory-file-summary small{grid-column:auto}.settings-description{padding:0 var(--space-lg)}.settings-content .btn,.settings-preset-item-actions .btn{min-height:36px}.auth-provider-row{flex-wrap:wrap;padding:var(--space-md) calc(var(--space-md) + var(--space-xs) / 2);gap:var(--space-sm)}.auth-section-hint{margin:0 calc(var(--space-md) + var(--space-xs) / 2) var(--space-md);padding:calc(var(--space-sm) + var(--space-xs) / 2) calc(var(--space-md) + var(--space-xs) / 2)}.auth-provider-group{margin-bottom:var(--space-md)}.auth-group-label{padding:0 calc(var(--space-md) + var(--space-xs) / 2)}.auth-provider-card{margin:0 calc(var(--space-md) + var(--space-xs) / 2) var(--space-sm)}.auth-provider-header{flex-wrap:wrap;padding:calc(var(--space-sm) + var(--space-xs) / 2) calc(var(--space-md) + var(--space-xs) / 2);gap:10px}.auth-provider-header>div:not(.auth-provider-info):not(.auth-apikey-section){margin-left:auto}.auth-provider-actions-row{width:100%;justify-content:flex-end}.auth-device-code-panel{width:100%}.auth-device-code-pill{max-width:100%;overflow-wrap:anywhere}.auth-provider-info{width:100%;flex-basis:100%}.auth-apikey-section{width:100%;flex-basis:100%;align-items:flex-end}.auth-apikey-input-row{width:100%;flex-wrap:wrap;justify-content:flex-end}.auth-apikey-input{flex:1;min-width:120px;width:auto}.auth-apikey-input-row .btn{flex-shrink:0;margin-left:auto}.auth-hint{padding:var(--space-md) calc(var(--space-md) + var(--space-xs) / 2) 0}.settings-model-presets{gap:var(--space-sm)}.settings-preset-item{flex-direction:column;align-items:stretch;padding:var(--space-sm) var(--space-md)}.settings-preset-item-actions{justify-content:flex-start}.settings-preset-editor{padding:var(--space-sm) var(--space-md)}.settings-preset-editor-actions{flex-wrap:wrap}.settings-preset-size-grid{grid-template-columns:1fr;gap:var(--space-xs)}.settings-node-routing-note{padding:var(--space-sm) var(--space-md);font-size:12px}}.settings-node-routing-note{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-md);padding:var(--space-md) var(--space-lg);margin-top:var(--space-sm);color:var(--text-muted);font-size:13px;line-height:1.5}.settings-node-status{display:inline-flex;align-items:center;gap:var(--space-xs);margin-top:var(--space-sm);font-size:12px;color:var(--text-muted)}.auth-advanced-disclosure{margin-top:var(--space-md);border:1px solid var(--border);border-radius:var(--radius-md);background:var(--surface)}.auth-advanced-disclosure>summary{cursor:pointer;padding:var(--space-sm) var(--space-md)}.auth-advanced-content{display:flex;flex-direction:column;gap:var(--space-sm);padding:0 var(--space-md) var(--space-md)}.auth-custom-provider-item{display:flex;justify-content:space-between;align-items:center;gap:var(--space-sm)}.auth-custom-provider-actions{display:flex;gap:var(--space-sm)}.settings-warning-banner{margin-top:var(--space-sm);padding:var(--space-sm) var(--space-md);border:1px solid var(--color-warning);border-radius:var(--radius-md);background:color-mix(in srgb,var(--color-warning) 12%,transparent);color:var(--text);font-size:var(--font-sm, .875rem);line-height:1.4}.settings-warning-banner strong{color:var(--color-warning);margin-right:var(--space-xs)}@media(max-width:768px){.auth-custom-provider-item{flex-direction:column;align-items:flex-start}.settings-warning-banner{padding:var(--space-sm)}}