@runfusion/fusion 0.38.1 → 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.
- package/dist/bin.js +3325 -858
- package/dist/client/.vite/manifest.json +58 -58
- package/dist/client/assets/{AgentDetailView-DuRYmHK3.js → AgentDetailView-nS4sABBv.js} +1 -1
- package/dist/client/assets/{AgentPermissionPolicyEditor-ClY32kYN.js → AgentPermissionPolicyEditor-DiYAo51R.js} +1 -1
- package/dist/client/assets/{AgentsView-UbCAHs_i.js → AgentsView-VbUsJLma.js} +3 -3
- package/dist/client/assets/ChatView-B1AMky9x.js +6 -0
- package/dist/client/assets/{DevServerView-DY5GlJcD.js → DevServerView-CyFdAcCd.js} +1 -1
- package/dist/client/assets/{DirectoryPicker-B4VRL2BH.js → DirectoryPicker-C7v2Esic.js} +1 -1
- package/dist/client/assets/{DocumentsView-tqpIZ9t9.js → DocumentsView-P_YIsnO0.js} +1 -1
- package/dist/client/assets/{EvalsView-C_Br3ry8.js → EvalsView-2zyH0dWG.js} +1 -1
- package/dist/client/assets/{ExperimentalAgentOnboardingModal-lXM--LV-.js → ExperimentalAgentOnboardingModal-DoRPGkfN.js} +1 -1
- package/dist/client/assets/{GoalsView-B65urz9k.css → GoalsView-Dky8vDoG.css} +1 -1
- package/dist/client/assets/GoalsView-l0PVSxK4.js +2 -0
- package/dist/client/assets/{InsightsView-BYfsVobi.js → InsightsView-BZKu5-C3.js} +1 -1
- package/dist/client/assets/{MemoryView-DT4vIhaW.js → MemoryView-CYBNC_h8.js} +1 -1
- package/dist/client/assets/{NodesView-Dx6HFqjI.js → NodesView-CQ63uWC8.js} +1 -1
- package/dist/client/assets/{PiExtensionsManager-BcGBnNiC.js → PiExtensionsManager-BNXxlpb6.js} +1 -1
- package/dist/client/assets/{PluginManager-T_XZ7iNI.js → PluginManager-DejpEyl7.js} +1 -1
- package/dist/client/assets/{ResearchView-Bv4igpnv.js → ResearchView-B4u2YieX.js} +1 -1
- package/dist/client/assets/{SecretsView-C4VX2ZTa.js → SecretsView-DvMMG_rf.js} +1 -1
- package/dist/client/assets/SettingsModal-986SEzVN.css +1 -0
- package/dist/client/assets/SettingsModal-C2mfeKp1.js +31 -0
- package/dist/client/assets/{SettingsModal-Cy42vswI.js → SettingsModal-Dmz2aH3c.js} +1 -1
- package/dist/client/assets/{SetupWizardModal-LqloAL4J.js → SetupWizardModal-BiIFP3De.js} +1 -1
- package/dist/client/assets/{SkillsView-I1SDKaRz.js → SkillsView-CRARYL_G.js} +1 -1
- package/dist/client/assets/{StashRecoveryView-DMUUR3cy.js → StashRecoveryView-DHj0O6sE.js} +1 -1
- package/dist/client/assets/{TodoView-PKvJKjtV.js → TodoView-CjyU1h-B.js} +1 -1
- package/dist/client/assets/{dashboard-view-D4XVI1XP.js → dashboard-view-BVckVLAO.js} +1 -1
- package/dist/client/assets/{folder-open-Doam5g-y.js → folder-open-CJgBSqdA.js} +1 -1
- package/dist/client/assets/index-BonLYFW-.js +742 -0
- package/dist/client/assets/{index-ktpD_W3I.css → index-nzIVQsA_.css} +1 -1
- package/dist/client/assets/{upload-BUfrZl69.js → upload-hsiV4Ixv.js} +1 -1
- package/dist/client/assets/{users-XNGnYBJb.js → users-D63HpHlZ.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/client/version.json +1 -1
- package/dist/droid-cli/package.json +1 -1
- package/dist/extension.js +3073 -785
- package/dist/pi-claude-cli/package.json +1 -1
- package/dist/plugins/fusion-plugin-cli-printing-press/package.json +1 -1
- package/dist/plugins/fusion-plugin-cursor-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-dependency-graph/package.json +1 -1
- package/dist/plugins/fusion-plugin-droid-runtime/bundled.js +38 -4
- package/dist/plugins/fusion-plugin-droid-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-hermes-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-openclaw-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-paperclip-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-reports/package.json +1 -1
- package/dist/plugins/fusion-plugin-roadmap/package.json +1 -1
- package/dist/plugins/fusion-plugin-whatsapp-chat/package.json +1 -1
- package/package.json +1 -1
- package/skill/fusion/SKILL.md +1 -1
- package/skill/fusion/references/extension-tools.md +47 -1
- package/skill/fusion/references/fusion-capabilities.md +6 -1
- package/dist/client/assets/ChatView-DDDjYRKc.js +0 -6
- package/dist/client/assets/GoalsView-CI3Bzs1b.js +0 -1
- package/dist/client/assets/SettingsModal-CLEkhLK_.js +0 -31
- package/dist/client/assets/SettingsModal-D_uIvf6n.css +0 -1
- package/dist/client/assets/index-BS-jSWPW.js +0 -742
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fusion/pi-claude-cli",
|
|
3
|
-
"version": "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,
|
|
@@ -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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
137265
|
+
delta,
|
|
137232
137266
|
partial: output
|
|
137233
137267
|
});
|
|
137234
137268
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@runfusion/fusion",
|
|
3
|
-
"version": "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",
|
package/skill/fusion/SKILL.md
CHANGED
|
@@ -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-BS-jSWPW.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-BS-jSWPW.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};
|