@wrongstack/webui 0.73.1 → 0.82.6
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/assets/index-D1cZ__pQ.js +94 -0
- package/dist/assets/index-DB5NTtW7.css +1 -0
- package/dist/assets/vendor-CumDpIdV.js +81 -0
- package/dist/index.css +23 -0
- package/dist/index.css.map +1 -1
- package/dist/index.html +3 -3
- package/dist/index.js +284 -73
- package/dist/index.js.map +1 -1
- package/dist/server/entry.js +59 -12
- package/dist/server/entry.js.map +1 -1
- package/dist/server/index.d.ts +14 -14
- package/dist/server/index.js +59 -12
- package/dist/server/index.js.map +1 -1
- package/package.json +5 -5
- package/dist/assets/index-BH3RI9-8.js +0 -94
- package/dist/assets/index-C_0-qbQ-.css +0 -1
- package/dist/assets/vendor-DBuK7aZd.js +0 -546
package/dist/index.js
CHANGED
|
@@ -408,6 +408,10 @@ var WrongStackWebSocketClient = class {
|
|
|
408
408
|
clearTodos() {
|
|
409
409
|
this.send({ type: "todos.clear" });
|
|
410
410
|
}
|
|
411
|
+
removeTodo(idOrIndex) {
|
|
412
|
+
const payload = typeof idOrIndex === "number" ? { index: idOrIndex } : { id: idOrIndex };
|
|
413
|
+
this.send({ type: "todos.remove", payload });
|
|
414
|
+
}
|
|
411
415
|
listSessions(limit = 50) {
|
|
412
416
|
this.send({ type: "sessions.list", payload: { limit } });
|
|
413
417
|
}
|
|
@@ -469,19 +473,25 @@ function getWSClient(url) {
|
|
|
469
473
|
// src/stores/chat-store.ts
|
|
470
474
|
import { create } from "zustand";
|
|
471
475
|
import { persist } from "zustand/middleware";
|
|
476
|
+
function expectDefined(value) {
|
|
477
|
+
if (value === null || value === void 0) {
|
|
478
|
+
throw new Error("Expected value to be defined");
|
|
479
|
+
}
|
|
480
|
+
return value;
|
|
481
|
+
}
|
|
472
482
|
function dedupeRepeatedBlocks(text) {
|
|
473
483
|
if (!text) return text;
|
|
474
484
|
const paraSplit = text.split(/\n{2,}/);
|
|
475
485
|
const paras = [];
|
|
476
486
|
for (const p of paraSplit) {
|
|
477
|
-
if (paras.length > 0 && paras[paras.length - 1]
|
|
487
|
+
if (paras.length > 0 && paras[paras.length - 1]?.trim() === p.trim()) continue;
|
|
478
488
|
paras.push(p);
|
|
479
489
|
}
|
|
480
490
|
const cleaned = paras.map((p) => {
|
|
481
491
|
const lines = p.split("\n");
|
|
482
492
|
const out = [];
|
|
483
493
|
for (const line of lines) {
|
|
484
|
-
if (out.length > 0 && line.trim().length > 0 && out[out.length - 1]
|
|
494
|
+
if (out.length > 0 && line.trim().length > 0 && out[out.length - 1]?.trim() === line.trim()) {
|
|
485
495
|
continue;
|
|
486
496
|
}
|
|
487
497
|
out.push(line);
|
|
@@ -591,7 +601,7 @@ var useChatStore = create()(
|
|
|
591
601
|
if (queue.length === 0) return null;
|
|
592
602
|
const [next, ...rest] = queue;
|
|
593
603
|
set({ queue: rest });
|
|
594
|
-
return next;
|
|
604
|
+
return expectDefined(next);
|
|
595
605
|
},
|
|
596
606
|
removeQueued: (idx) => set((state) => ({ queue: state.queue.filter((_, i) => i !== idx) })),
|
|
597
607
|
clearQueue: () => set({ queue: [] }),
|
|
@@ -1048,6 +1058,12 @@ function notifyIfHidden(title, body, tag) {
|
|
|
1048
1058
|
}
|
|
1049
1059
|
|
|
1050
1060
|
// src/hooks/ws-handlers.ts
|
|
1061
|
+
function expectDefined2(value) {
|
|
1062
|
+
if (value === null || value === void 0) {
|
|
1063
|
+
throw new Error("Expected value to be defined");
|
|
1064
|
+
}
|
|
1065
|
+
return value;
|
|
1066
|
+
}
|
|
1051
1067
|
function handleSessionStart(msg) {
|
|
1052
1068
|
const payload = msg.payload;
|
|
1053
1069
|
const prev = useSessionStore.getState().session?.id;
|
|
@@ -1097,8 +1113,8 @@ function handleSessionStart(msg) {
|
|
|
1097
1113
|
const all = useChatStore.getState().messages;
|
|
1098
1114
|
let last;
|
|
1099
1115
|
for (let i = all.length - 1; i >= 0; i--) {
|
|
1100
|
-
if (all[i]
|
|
1101
|
-
last = all[i];
|
|
1116
|
+
if (all[i]?.toolUseId === String(b.tool_use_id ?? "")) {
|
|
1117
|
+
last = expectDefined2(all[i]);
|
|
1102
1118
|
break;
|
|
1103
1119
|
}
|
|
1104
1120
|
}
|
|
@@ -1143,7 +1159,7 @@ function handleKeyOperationResult(msg) {
|
|
|
1143
1159
|
function handleContextCompacted(msg) {
|
|
1144
1160
|
const payload = msg.payload;
|
|
1145
1161
|
let summary = payload.reductions.length ? payload.reductions.map((r) => `${r.phase}: ${r.saved}`).join(", ") : "no-op";
|
|
1146
|
-
if (payload.repaired) summary += `; repaired ${payload.repaired.removedToolUses
|
|
1162
|
+
if (payload.repaired) summary += `; repaired ${payload.repaired.removedToolUses?.length ?? 0} tool_use, ${payload.repaired.removedToolResults?.length ?? 0} tool_result, ${payload.repaired.removedMessages} empty messages`;
|
|
1147
1163
|
useChatStore.getState().addMessage({ role: "assistant", content: `\u{1F5DC}\uFE0F Context compacted: ${payload.before} \u2192 ${payload.after} tokens (saved ~${payload.saved}). ${summary}` });
|
|
1148
1164
|
useSessionStore.setState({ lastInputTokens: payload.after });
|
|
1149
1165
|
}
|
|
@@ -1257,14 +1273,14 @@ function handleRunResult(msg) {
|
|
|
1257
1273
|
let lastAssistantIdx = -1;
|
|
1258
1274
|
let toolCount = 0;
|
|
1259
1275
|
for (let i = all.length - 1; i >= 0; i--) {
|
|
1260
|
-
const m = all[i];
|
|
1276
|
+
const m = expectDefined2(all[i]);
|
|
1261
1277
|
if (m.role === "assistant" && lastAssistantIdx === -1 && m.content) lastAssistantIdx = i;
|
|
1262
1278
|
if (m.role === "tool" && m.timestamp >= runStart.at) toolCount += 1;
|
|
1263
1279
|
if (m.role === "user" && m.timestamp <= runStart.at) break;
|
|
1264
1280
|
}
|
|
1265
1281
|
if (lastAssistantIdx !== -1) {
|
|
1266
1282
|
const sessionCost = useSessionStore.getState().cost;
|
|
1267
|
-
useChatStore.getState().updateMessage(all[lastAssistantIdx]
|
|
1283
|
+
useChatStore.getState().updateMessage(all[lastAssistantIdx]?.id, { runSummary: { iterations: payload.iterations, tools: toolCount, durationMs: Date.now() - runStart.at, costDelta: Math.max(0, sessionCost - runStart.cost) } });
|
|
1268
1284
|
}
|
|
1269
1285
|
}
|
|
1270
1286
|
useChatStore.getState().setRunStart(null);
|
|
@@ -1605,7 +1621,7 @@ function useWebSocket() {
|
|
|
1605
1621
|
}
|
|
1606
1622
|
|
|
1607
1623
|
// src/App.tsx
|
|
1608
|
-
import { useEffect as
|
|
1624
|
+
import { useEffect as useEffect22 } from "react";
|
|
1609
1625
|
|
|
1610
1626
|
// src/components/ChatView/index.tsx
|
|
1611
1627
|
import {
|
|
@@ -2056,7 +2072,7 @@ function renderGroupedList(filtered, index, dispatch, setIndex) {
|
|
|
2056
2072
|
const groups = {};
|
|
2057
2073
|
filtered.forEach((it, i) => {
|
|
2058
2074
|
if (!groups[it.category]) groups[it.category] = [];
|
|
2059
|
-
groups[it.category]
|
|
2075
|
+
groups[it.category]?.push({ item: it, globalIdx: i });
|
|
2060
2076
|
});
|
|
2061
2077
|
return /* @__PURE__ */ jsx2("div", { className: "p-1", children: Object.entries(groups).map(([cat, rows]) => /* @__PURE__ */ jsxs2("div", { children: [
|
|
2062
2078
|
/* @__PURE__ */ jsx2("div", { className: "px-3 pt-2 pb-1 text-[10px] uppercase tracking-wider text-muted-foreground", children: cat }),
|
|
@@ -2092,6 +2108,12 @@ function renderGroupedList(filtered, index, dispatch, setIndex) {
|
|
|
2092
2108
|
import { FileText, Folder } from "lucide-react";
|
|
2093
2109
|
import { useEffect as useEffect4, useRef as useRef3, useState as useState2 } from "react";
|
|
2094
2110
|
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
2111
|
+
function expectDefined3(value) {
|
|
2112
|
+
if (value === null || value === void 0) {
|
|
2113
|
+
throw new Error("Expected value to be defined");
|
|
2114
|
+
}
|
|
2115
|
+
return value;
|
|
2116
|
+
}
|
|
2095
2117
|
function FilePicker({ query, onPick, onClose }) {
|
|
2096
2118
|
const ws = useWebSocket();
|
|
2097
2119
|
const wsUrl = useConfigStore((s) => s.wsUrl);
|
|
@@ -2130,7 +2152,7 @@ function FilePicker({ query, onPick, onClose }) {
|
|
|
2130
2152
|
} else if (e.key === "Enter" || e.key === "Tab") {
|
|
2131
2153
|
if (files.length === 0) return;
|
|
2132
2154
|
e.preventDefault();
|
|
2133
|
-
onPick(files[index]);
|
|
2155
|
+
onPick(expectDefined3(files[index]));
|
|
2134
2156
|
} else if (e.key === "Escape") {
|
|
2135
2157
|
e.preventDefault();
|
|
2136
2158
|
onClose();
|
|
@@ -2206,25 +2228,64 @@ var Button = React.forwardRef(
|
|
|
2206
2228
|
Button.displayName = "Button";
|
|
2207
2229
|
|
|
2208
2230
|
// src/components/ChatInput/slash-commands.ts
|
|
2231
|
+
function expectDefined4(value) {
|
|
2232
|
+
if (value === null || value === void 0) {
|
|
2233
|
+
throw new Error("Expected value to be defined");
|
|
2234
|
+
}
|
|
2235
|
+
return value;
|
|
2236
|
+
}
|
|
2209
2237
|
var SLASH_COMMANDS = [
|
|
2210
|
-
|
|
2211
|
-
{ name: "/
|
|
2212
|
-
|
|
2213
|
-
{ name: "/clear", category: "Session", description: "Wipe current context (keeps session id, disk record stays)" },
|
|
2238
|
+
// Run
|
|
2239
|
+
{ name: "/abort", category: "Run", aliases: ["/stop"], description: "Abort the current run" },
|
|
2240
|
+
// Session
|
|
2214
2241
|
{ name: "/new", category: "Session", description: "Start a brand-new session (fresh on disk and in memory)" },
|
|
2242
|
+
{ name: "/clear", category: "Session", description: "Wipe current context (keeps session id, disk record stays)" },
|
|
2215
2243
|
{ name: "/compact", category: "Session", description: "Shrink context \u2014 elide ancient tool output" },
|
|
2216
2244
|
{ name: "/repair", category: "Session", description: "Repair orphan tool_use/tool_result blocks in context" },
|
|
2245
|
+
{ name: "/save", category: "Session", description: "Force-flush the session (auto-saved already)" },
|
|
2246
|
+
{ name: "/load", category: "Session", aliases: ["/resume"], description: "Resume a previous session from disk" },
|
|
2247
|
+
{ name: "/prune", category: "Session", description: "Delete old sessions (default older than 30 days)" },
|
|
2248
|
+
{ name: "/export", category: "Session", description: "Download the current chat as markdown" },
|
|
2249
|
+
// Inspect
|
|
2217
2250
|
{ name: "/debug", category: "Inspect", aliases: ["/context"], description: "Per-section context size breakdown" },
|
|
2218
2251
|
{ name: "/tools", category: "Inspect", description: "List every registered tool the model can call" },
|
|
2219
2252
|
{ name: "/memory", category: "Inspect", description: "Show all remembered notes (project + user scope)" },
|
|
2220
2253
|
{ name: "/skill", category: "Inspect", aliases: ["/skills"], description: "List active skills" },
|
|
2221
2254
|
{ name: "/diag", category: "Inspect", description: "Runtime diagnostics (provider, tools, features, mode, usage)" },
|
|
2222
2255
|
{ name: "/stats", category: "Inspect", description: "Session stats: tokens, cache hit ratio, cost, elapsed" },
|
|
2223
|
-
{ name: "/
|
|
2224
|
-
{ name: "/
|
|
2225
|
-
|
|
2256
|
+
{ name: "/todos", category: "Inspect", description: "List current todos (try `/todos clear` to reset)" },
|
|
2257
|
+
{ name: "/codebase-reindex", category: "Inspect", aliases: ["/reindex"], description: "Rebuild the codebase symbol index" },
|
|
2258
|
+
// Agent
|
|
2259
|
+
{ name: "/spawn", category: "Agent", description: "Spawn an isolated subagent to handle a task" },
|
|
2260
|
+
{ name: "/agents", category: "Agent", description: "Show status of spawned subagents" },
|
|
2261
|
+
{ name: "/fleet", category: "Agent", description: "Inspect and control the agent fleet" },
|
|
2262
|
+
{ name: "/director", category: "Agent", description: "Promote to director mode at runtime" },
|
|
2263
|
+
{ name: "/autonomy", category: "Agent", description: "Toggle or query autonomy mode (self-driving agent)" },
|
|
2264
|
+
{ name: "/goal", category: "Agent", description: "Set, inspect, or clear the autonomous mission" },
|
|
2265
|
+
{ name: "/autophase", category: "Agent", description: "Autonomous phase-based workflow with subagents" },
|
|
2266
|
+
{ name: "/fix", category: "Agent", description: "Diagnose and fix a reported error or bug" },
|
|
2267
|
+
{ name: "/sdd", category: "Agent", description: "AI-driven Specification-Driven Development workflow" },
|
|
2268
|
+
{ name: "/btw", category: "Agent", description: "Drop a mid-run note without interrupting the agent" },
|
|
2269
|
+
{ name: "/collab", category: "Agent", description: "Live collaboration helpers (status / invite / history)" },
|
|
2270
|
+
// Config
|
|
2271
|
+
{ name: "/settings", category: "Config", aliases: ["/model"], description: "Open settings (provider/model/keys)" },
|
|
2272
|
+
{ name: "/setmodel", category: "Config", description: "Quick-switch the active provider/model" },
|
|
2273
|
+
{ name: "/models", category: "Config", description: "List available providers and models" },
|
|
2274
|
+
{ name: "/mode", category: "Config", description: "Switch the active mode (persona/skill set)" },
|
|
2275
|
+
{ name: "/yolo", category: "Config", description: "Toggle or query YOLO (auto-approve) mode" },
|
|
2276
|
+
{ name: "/next", category: "Config", description: "Toggle next-task prediction after each turn" },
|
|
2277
|
+
{ name: "/enhance", category: "Config", description: "Toggle prompt refinement before sending" },
|
|
2278
|
+
{ name: "/mcp", category: "Config", aliases: ["/mcp-servers"], description: "Manage MCP servers" },
|
|
2279
|
+
{ name: "/plugin", category: "Config", aliases: ["/plugins"], description: "Manage plugins" },
|
|
2280
|
+
{ name: "/statusline", category: "Config", aliases: ["/sl"], description: "Customize status bar chips" },
|
|
2281
|
+
{ name: "/telegram-setup", category: "Config", aliases: ["/tg-setup"], description: "Configure Telegram bot token and chat" },
|
|
2282
|
+
{ name: "/init", category: "Config", description: "Create or update .wrongstack/AGENTS.md project context" },
|
|
2283
|
+
{ name: "/worktree", category: "Config", aliases: ["/wt"], description: "Inspect/manage git worktrees for AutoPhase" },
|
|
2284
|
+
// App
|
|
2285
|
+
{ name: "/help", category: "App", description: "Show every slash command and what it does" },
|
|
2286
|
+
{ name: "/exit", category: "App", description: "Exit the current session" }
|
|
2226
2287
|
];
|
|
2227
|
-
var SLASH_CATEGORY_ORDER = ["Run", "Session", "Inspect", "App"];
|
|
2288
|
+
var SLASH_CATEGORY_ORDER = ["Run", "Session", "Inspect", "Agent", "Config", "App"];
|
|
2228
2289
|
function matchSlash(query) {
|
|
2229
2290
|
const q = query.toLowerCase();
|
|
2230
2291
|
if (q === "/" || q === "") return SLASH_COMMANDS;
|
|
@@ -2235,7 +2296,7 @@ function matchSlash(query) {
|
|
|
2235
2296
|
function detectAtMention(value, cursor) {
|
|
2236
2297
|
let i = cursor - 1;
|
|
2237
2298
|
while (i >= 0) {
|
|
2238
|
-
const c = value[i];
|
|
2299
|
+
const c = expectDefined4(value[i]);
|
|
2239
2300
|
if (c === "@") {
|
|
2240
2301
|
const prev = i > 0 ? value[i - 1] : "";
|
|
2241
2302
|
if (i === 0 || /\s/.test(prev ?? "")) {
|
|
@@ -2251,6 +2312,12 @@ function detectAtMention(value, cursor) {
|
|
|
2251
2312
|
|
|
2252
2313
|
// src/components/ChatInput.tsx
|
|
2253
2314
|
import { Fragment, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
2315
|
+
function expectDefined5(value) {
|
|
2316
|
+
if (value === null || value === void 0) {
|
|
2317
|
+
throw new Error("Expected value to be defined");
|
|
2318
|
+
}
|
|
2319
|
+
return value;
|
|
2320
|
+
}
|
|
2254
2321
|
function ChatInput() {
|
|
2255
2322
|
const { isLoading, setLoading, addMessage, clearMessages } = useChatStore();
|
|
2256
2323
|
const queue = useChatStore((s) => s.queue);
|
|
@@ -2444,7 +2511,7 @@ function ChatInput() {
|
|
|
2444
2511
|
setLoading(false);
|
|
2445
2512
|
const all = useChatStore.getState().messages;
|
|
2446
2513
|
for (let i = all.length - 1; i >= 0; i--) {
|
|
2447
|
-
const m = all[i];
|
|
2514
|
+
const m = expectDefined5(all[i]);
|
|
2448
2515
|
if (m.role === "user" && m.content) {
|
|
2449
2516
|
setInput(m.content);
|
|
2450
2517
|
requestAnimationFrame(() => {
|
|
@@ -2656,7 +2723,7 @@ function ChatInput() {
|
|
|
2656
2723
|
const next = before + insertion + after;
|
|
2657
2724
|
setInput(next);
|
|
2658
2725
|
const lastTokenStart = before.length + lead.length + tokens.slice(0, -1).join(" ").length + (tokens.length > 1 ? 1 : 0);
|
|
2659
|
-
const lastBasename = files[files.length - 1]
|
|
2726
|
+
const lastBasename = files[files.length - 1]?.name;
|
|
2660
2727
|
requestAnimationFrame(() => {
|
|
2661
2728
|
if (ta) {
|
|
2662
2729
|
const cur = before.length + insertion.length - trail.length;
|
|
@@ -2708,14 +2775,14 @@ function ChatInput() {
|
|
|
2708
2775
|
const byCategory = {};
|
|
2709
2776
|
slashSuggestions.forEach((cmd, idx) => {
|
|
2710
2777
|
if (!byCategory[cmd.category]) byCategory[cmd.category] = [];
|
|
2711
|
-
byCategory[cmd.category]
|
|
2778
|
+
byCategory[cmd.category]?.push({ cmd, idx });
|
|
2712
2779
|
});
|
|
2713
2780
|
const orderedCategories = SLASH_CATEGORY_ORDER.filter((c) => byCategory[c]?.length);
|
|
2714
2781
|
return /* @__PURE__ */ jsxs4("div", { className: "absolute bottom-full left-0 right-0 mb-2 rounded-lg border bg-popover shadow-md p-1 text-sm max-h-72 overflow-auto", children: [
|
|
2715
2782
|
/* @__PURE__ */ jsx5("div", { className: "px-3 py-1 text-[10px] uppercase tracking-wider text-muted-foreground border-b mb-1", children: "\u2191/\u2193 select \xB7 Tab complete \xB7 Enter dispatch \xB7 Esc dismiss" }),
|
|
2716
2783
|
orderedCategories.map((cat) => /* @__PURE__ */ jsxs4("div", { className: "mb-1", children: [
|
|
2717
2784
|
/* @__PURE__ */ jsx5("div", { className: "px-3 pt-1 pb-0.5 text-[10px] uppercase tracking-wider text-muted-foreground/70 font-semibold", children: cat }),
|
|
2718
|
-
byCategory[cat]
|
|
2785
|
+
byCategory[cat]?.map(({ cmd, idx }) => /* @__PURE__ */ jsxs4(
|
|
2719
2786
|
"button",
|
|
2720
2787
|
{
|
|
2721
2788
|
type: "button",
|
|
@@ -2946,6 +3013,12 @@ function ConnectionChip({ wsStatus, wsConnected }) {
|
|
|
2946
3013
|
import { Check, ChevronDown, Gauge } from "lucide-react";
|
|
2947
3014
|
import { useEffect as useEffect7, useRef as useRef5, useState as useState5 } from "react";
|
|
2948
3015
|
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
3016
|
+
function expectDefined6(value) {
|
|
3017
|
+
if (value === null || value === void 0) {
|
|
3018
|
+
throw new Error("Expected value to be defined");
|
|
3019
|
+
}
|
|
3020
|
+
return value;
|
|
3021
|
+
}
|
|
2949
3022
|
var FALLBACK_MODES = [
|
|
2950
3023
|
{
|
|
2951
3024
|
id: "balanced",
|
|
@@ -2981,7 +3054,7 @@ function ContextModePicker() {
|
|
|
2981
3054
|
};
|
|
2982
3055
|
}, [open]);
|
|
2983
3056
|
const items = contextModes.length > 0 ? contextModes : FALLBACK_MODES;
|
|
2984
|
-
const active = items.find((m) => m.id === contextMode) ?? items[0];
|
|
3057
|
+
const active = items.find((m) => m.id === contextMode) ?? expectDefined6(items[0]);
|
|
2985
3058
|
return /* @__PURE__ */ jsxs6("div", { ref: rootRef, className: "relative shrink-0", children: [
|
|
2986
3059
|
/* @__PURE__ */ jsxs6(
|
|
2987
3060
|
"button",
|
|
@@ -3028,7 +3101,7 @@ function ContextModePicker() {
|
|
|
3028
3101
|
/* @__PURE__ */ jsxs6("div", { className: "min-w-0 flex-1", children: [
|
|
3029
3102
|
/* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between gap-2", children: [
|
|
3030
3103
|
/* @__PURE__ */ jsx7("span", { className: "text-xs font-mono", children: m.id }),
|
|
3031
|
-
m.thresholds && /* @__PURE__ */ jsxs6("span", { className: "text-[10px] text-muted-foreground tabular-nums", children: [
|
|
3104
|
+
m.thresholds?.warn !== void 0 && /* @__PURE__ */ jsxs6("span", { className: "text-[10px] text-muted-foreground tabular-nums", children: [
|
|
3032
3105
|
Math.round(m.thresholds.warn * 100),
|
|
3033
3106
|
"/",
|
|
3034
3107
|
Math.round(m.thresholds.soft * 100),
|
|
@@ -3318,6 +3391,12 @@ import remarkGfm from "remark-gfm";
|
|
|
3318
3391
|
// src/components/DiffView.tsx
|
|
3319
3392
|
import { memo, useMemo as useMemo2 } from "react";
|
|
3320
3393
|
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
3394
|
+
function expectDefined7(value) {
|
|
3395
|
+
if (value === null || value === void 0) {
|
|
3396
|
+
throw new Error("Expected value to be defined");
|
|
3397
|
+
}
|
|
3398
|
+
return value;
|
|
3399
|
+
}
|
|
3321
3400
|
var DiffView = memo(function DiffView2({ oldText, newText, caption }) {
|
|
3322
3401
|
const rows = useMemo2(() => computeDiff(oldText, newText), [oldText, newText]);
|
|
3323
3402
|
if (rows === null) {
|
|
@@ -3387,8 +3466,8 @@ function computeDiff(oldText, newText) {
|
|
|
3387
3466
|
const dp = Array.from({ length: n + 1 }, () => new Array(m + 1).fill(0));
|
|
3388
3467
|
for (let i2 = n - 1; i2 >= 0; i2--) {
|
|
3389
3468
|
for (let j2 = m - 1; j2 >= 0; j2--) {
|
|
3390
|
-
if (a[i2] === b[j2]) dp[i2][j2] = dp[i2 + 1][j2 + 1] + 1;
|
|
3391
|
-
else dp[i2][j2] = Math.max(dp[i2 + 1][j2], dp[i2][j2 + 1]);
|
|
3469
|
+
if (a[i2] === b[j2]) expectDefined7(dp[i2])[j2] = expectDefined7(dp[i2 + 1]?.[j2 + 1]) + 1;
|
|
3470
|
+
else expectDefined7(dp[i2])[j2] = Math.max(expectDefined7(dp[i2 + 1]?.[j2]), expectDefined7(dp[i2]?.[j2 + 1]));
|
|
3392
3471
|
}
|
|
3393
3472
|
}
|
|
3394
3473
|
const rows = [];
|
|
@@ -3396,19 +3475,19 @@ function computeDiff(oldText, newText) {
|
|
|
3396
3475
|
let j = 0;
|
|
3397
3476
|
while (i < n && j < m) {
|
|
3398
3477
|
if (a[i] === b[j]) {
|
|
3399
|
-
rows.push({ kind: "ctx", text: a[i] });
|
|
3478
|
+
rows.push({ kind: "ctx", text: expectDefined7(a[i]) });
|
|
3400
3479
|
i++;
|
|
3401
3480
|
j++;
|
|
3402
|
-
} else if (dp[i + 1][j] >= dp[i][j + 1]) {
|
|
3403
|
-
rows.push({ kind: "del", text: a[i] });
|
|
3481
|
+
} else if (expectDefined7(dp[i + 1]?.[j]) >= expectDefined7(dp[i]?.[j + 1])) {
|
|
3482
|
+
rows.push({ kind: "del", text: expectDefined7(a[i]) });
|
|
3404
3483
|
i++;
|
|
3405
3484
|
} else {
|
|
3406
|
-
rows.push({ kind: "add", text: b[j] });
|
|
3485
|
+
rows.push({ kind: "add", text: expectDefined7(b[j]) });
|
|
3407
3486
|
j++;
|
|
3408
3487
|
}
|
|
3409
3488
|
}
|
|
3410
|
-
while (i < n) rows.push({ kind: "del", text: a[i++] });
|
|
3411
|
-
while (j < m) rows.push({ kind: "add", text: b[j++] });
|
|
3489
|
+
while (i < n) rows.push({ kind: "del", text: expectDefined7(a[i++]) });
|
|
3490
|
+
while (j < m) rows.push({ kind: "add", text: expectDefined7(b[j++]) });
|
|
3412
3491
|
return rows;
|
|
3413
3492
|
}
|
|
3414
3493
|
function diffFromToolInput(toolName, input) {
|
|
@@ -3775,10 +3854,16 @@ function CopyButton({
|
|
|
3775
3854
|
// src/components/MessageBubble/ErrorBody.tsx
|
|
3776
3855
|
import { useState as useState9 } from "react";
|
|
3777
3856
|
import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
3857
|
+
function expectDefined8(value) {
|
|
3858
|
+
if (value === null || value === void 0) {
|
|
3859
|
+
throw new Error("Expected value to be defined");
|
|
3860
|
+
}
|
|
3861
|
+
return value;
|
|
3862
|
+
}
|
|
3778
3863
|
function detectStackBoundary(text) {
|
|
3779
3864
|
const lines = text.split("\n");
|
|
3780
3865
|
for (let i = 0; i < lines.length; i++) {
|
|
3781
|
-
const ln = lines[i];
|
|
3866
|
+
const ln = expectDefined8(lines[i]);
|
|
3782
3867
|
if (/^\s*at\s+\S+.*\(.*:\d+:\d+\)\s*$/.test(ln)) return i;
|
|
3783
3868
|
if (/^\s*at\s+\S+\.\S+\(\S+\.java:\d+\)\s*$/.test(ln)) return i;
|
|
3784
3869
|
if (/^\s+File "[^"]+", line \d+/.test(ln)) return i;
|
|
@@ -3881,6 +3966,12 @@ function ToolInputView({ input }) {
|
|
|
3881
3966
|
|
|
3882
3967
|
// src/components/MessageBubble/index.tsx
|
|
3883
3968
|
import { jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
3969
|
+
function expectDefined9(value) {
|
|
3970
|
+
if (value === null || value === void 0) {
|
|
3971
|
+
throw new Error("Expected value to be defined");
|
|
3972
|
+
}
|
|
3973
|
+
return value;
|
|
3974
|
+
}
|
|
3884
3975
|
var MessageBubble = memo3(function MessageBubble2({
|
|
3885
3976
|
message,
|
|
3886
3977
|
isFirst = false,
|
|
@@ -3909,7 +4000,7 @@ var MessageBubble = memo3(function MessageBubble2({
|
|
|
3909
4000
|
if (message.role !== "assistant" || isLoading) return false;
|
|
3910
4001
|
const all = useChatStore.getState().messages;
|
|
3911
4002
|
for (let i = all.length - 1; i >= 0; i--) {
|
|
3912
|
-
const m = all[i];
|
|
4003
|
+
const m = expectDefined9(all[i]);
|
|
3913
4004
|
if (m.role === "assistant") return m.id === message.id;
|
|
3914
4005
|
}
|
|
3915
4006
|
return false;
|
|
@@ -3920,13 +4011,13 @@ var MessageBubble = memo3(function MessageBubble2({
|
|
|
3920
4011
|
if (idx === -1) return;
|
|
3921
4012
|
let userIdx = -1;
|
|
3922
4013
|
for (let i = idx - 1; i >= 0; i--) {
|
|
3923
|
-
if (all[i]
|
|
4014
|
+
if (all[i]?.role === "user") {
|
|
3924
4015
|
userIdx = i;
|
|
3925
4016
|
break;
|
|
3926
4017
|
}
|
|
3927
4018
|
}
|
|
3928
4019
|
if (userIdx === -1) return;
|
|
3929
|
-
const userMsg = all[userIdx];
|
|
4020
|
+
const userMsg = expectDefined9(all[userIdx]);
|
|
3930
4021
|
truncateAfter(userMsg.id);
|
|
3931
4022
|
addMessage({ role: "user", content: userMsg.content });
|
|
3932
4023
|
setLoading(true);
|
|
@@ -4003,7 +4094,14 @@ var MessageBubble = memo3(function MessageBubble2({
|
|
|
4003
4094
|
const lines = message.toolResult ? message.toolResult.split("\n").length : 0;
|
|
4004
4095
|
return /* @__PURE__ */ jsxs14("div", { className: "space-y-1", children: [
|
|
4005
4096
|
inputSummary && !expanded && /* @__PURE__ */ jsx15("div", { className: "text-xs text-muted-foreground font-mono truncate", children: inputSummary }),
|
|
4006
|
-
message.toolResult === void 0 && message.progressLines && message.progressLines.length > 0 && /* @__PURE__ */ jsx15("div", { className: "mt-1 rounded-md border border-amber-500/20 bg-amber-500/5 p-1.5 text-[11px] font-mono leading-snug max-h-32 overflow-auto", children:
|
|
4097
|
+
message.toolResult === void 0 && message.progressLines && message.progressLines.length > 0 && /* @__PURE__ */ jsx15("div", { className: "mt-1 rounded-md border border-amber-500/20 bg-amber-500/5 p-1.5 text-[11px] font-mono leading-snug max-h-32 overflow-auto", children: (() => {
|
|
4098
|
+
const seen = /* @__PURE__ */ new Map();
|
|
4099
|
+
return message.progressLines.slice(-6).map((line) => {
|
|
4100
|
+
const occurrence = seen.get(line) ?? 0;
|
|
4101
|
+
seen.set(line, occurrence + 1);
|
|
4102
|
+
return /* @__PURE__ */ jsx15("div", { className: "truncate text-muted-foreground", children: line }, `${line}-${occurrence}`);
|
|
4103
|
+
});
|
|
4104
|
+
})() }),
|
|
4007
4105
|
expanded && message.toolInput !== void 0 && (() => {
|
|
4008
4106
|
const diffArgs = diffFromToolInput(message.toolName, message.toolInput);
|
|
4009
4107
|
if (diffArgs) return /* @__PURE__ */ jsx15(DiffView, { oldText: diffArgs.oldText, newText: diffArgs.newText, caption: diffArgs.caption });
|
|
@@ -4447,7 +4545,6 @@ function ThemeToggle({ className }) {
|
|
|
4447
4545
|
"inline-flex items-center gap-0.5 rounded-lg border border-border bg-card/70 p-0.5 shadow-sm",
|
|
4448
4546
|
className
|
|
4449
4547
|
),
|
|
4450
|
-
role: "radiogroup",
|
|
4451
4548
|
"aria-label": "Theme",
|
|
4452
4549
|
children: OPTIONS.map(({ value, icon: Icon2, label }) => {
|
|
4453
4550
|
const active = theme === value;
|
|
@@ -4455,8 +4552,7 @@ function ThemeToggle({ className }) {
|
|
|
4455
4552
|
"button",
|
|
4456
4553
|
{
|
|
4457
4554
|
type: "button",
|
|
4458
|
-
|
|
4459
|
-
"aria-checked": active,
|
|
4555
|
+
"aria-pressed": active,
|
|
4460
4556
|
title: `${label} theme`,
|
|
4461
4557
|
"aria-label": `${label} theme`,
|
|
4462
4558
|
onClick: () => setTheme(value),
|
|
@@ -4477,6 +4573,12 @@ function ThemeToggle({ className }) {
|
|
|
4477
4573
|
import { CheckCircle2 as CheckCircle23, ChevronDown as ChevronDown5, ChevronRight as ChevronRight3, Loader2 as Loader22, Terminal as Terminal2, XCircle as XCircle3 } from "lucide-react";
|
|
4478
4574
|
import { memo as memo4, useState as useState15 } from "react";
|
|
4479
4575
|
import { jsx as jsx20, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
4576
|
+
function expectDefined10(value) {
|
|
4577
|
+
if (value === null || value === void 0) {
|
|
4578
|
+
throw new Error("Expected value to be defined");
|
|
4579
|
+
}
|
|
4580
|
+
return value;
|
|
4581
|
+
}
|
|
4480
4582
|
function formatDuration(ms) {
|
|
4481
4583
|
if (ms < 1e3) return `${ms}ms`;
|
|
4482
4584
|
if (ms < 6e4) return `${(ms / 1e3).toFixed(ms < 1e4 ? 2 : 1)}s`;
|
|
@@ -4491,7 +4593,7 @@ var ToolGroup = memo4(function ToolGroup2({
|
|
|
4491
4593
|
}) {
|
|
4492
4594
|
const [open, setOpen] = useState15(defaultOpen);
|
|
4493
4595
|
if (tools.length === 1) {
|
|
4494
|
-
return /* @__PURE__ */ jsx20(MessageBubble, { message: tools[0], isFirst: true, isContinuation });
|
|
4596
|
+
return /* @__PURE__ */ jsx20(MessageBubble, { message: expectDefined10(tools[0]), isFirst: true, isContinuation });
|
|
4495
4597
|
}
|
|
4496
4598
|
const running = tools.filter((t) => t.toolResult === void 0).length;
|
|
4497
4599
|
const errored = tools.filter((t) => t.isError).length;
|
|
@@ -4864,6 +4966,12 @@ function ThinkingBubble() {
|
|
|
4864
4966
|
|
|
4865
4967
|
// src/components/ChatView/index.tsx
|
|
4866
4968
|
import { Fragment as Fragment6, jsx as jsx24, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
4969
|
+
function expectDefined11(value) {
|
|
4970
|
+
if (value === null || value === void 0) {
|
|
4971
|
+
throw new Error("Expected value to be defined");
|
|
4972
|
+
}
|
|
4973
|
+
return value;
|
|
4974
|
+
}
|
|
4867
4975
|
function ChatView() {
|
|
4868
4976
|
const { messages, isLoading } = useChatStore();
|
|
4869
4977
|
const setPaletteOpen = useUIStore((s) => s.setPaletteOpen);
|
|
@@ -5168,7 +5276,7 @@ function ChatView() {
|
|
|
5168
5276
|
(() => {
|
|
5169
5277
|
const groups = [];
|
|
5170
5278
|
for (let i = 0; i < messages.length; i++) {
|
|
5171
|
-
const m = messages[i];
|
|
5279
|
+
const m = expectDefined11(messages[i]);
|
|
5172
5280
|
if (m.role === "tool") {
|
|
5173
5281
|
const last = groups[groups.length - 1];
|
|
5174
5282
|
if (last && last.kind === "tools") {
|
|
@@ -5219,12 +5327,12 @@ function ChatView() {
|
|
|
5219
5327
|
};
|
|
5220
5328
|
const turnTs = (t) => {
|
|
5221
5329
|
if (t.kind === "user") return t.message.timestamp;
|
|
5222
|
-
const first = t.items[0];
|
|
5223
|
-
return first.kind === "msg" ? first.message.timestamp : first.tools[0]
|
|
5330
|
+
const first = expectDefined11(t.items[0]);
|
|
5331
|
+
return first.kind === "msg" ? first.message.timestamp : first.tools[0]?.timestamp;
|
|
5224
5332
|
};
|
|
5225
5333
|
const out = [];
|
|
5226
5334
|
for (let idx = 0; idx < turns.length; idx++) {
|
|
5227
|
-
const t = turns[idx];
|
|
5335
|
+
const t = expectDefined11(turns[idx]);
|
|
5228
5336
|
const ts = turnTs(t);
|
|
5229
5337
|
const day = dayKey(ts);
|
|
5230
5338
|
if (day !== prevDay) {
|
|
@@ -6561,7 +6669,7 @@ function ProviderSection({
|
|
|
6561
6669
|
const catalogByFamily = filteredCatalog.reduce(
|
|
6562
6670
|
(acc, p) => {
|
|
6563
6671
|
if (!acc[p.family]) acc[p.family] = [];
|
|
6564
|
-
acc[p.family]
|
|
6672
|
+
acc[p.family]?.push(p);
|
|
6565
6673
|
return acc;
|
|
6566
6674
|
},
|
|
6567
6675
|
{}
|
|
@@ -7812,8 +7920,104 @@ function Sidebar() {
|
|
|
7812
7920
|
] });
|
|
7813
7921
|
}
|
|
7814
7922
|
|
|
7923
|
+
// src/components/TodosPanel.tsx
|
|
7924
|
+
import { CheckCircle2 as CheckCircle27, Circle as Circle2, Clock as Clock3, X as X8 } from "lucide-react";
|
|
7925
|
+
import { useCallback as useCallback6, useEffect as useEffect21, useRef as useRef12, useState as useState26 } from "react";
|
|
7926
|
+
import { jsx as jsx43, jsxs as jsxs38 } from "react/jsx-runtime";
|
|
7927
|
+
function TodosPanel() {
|
|
7928
|
+
const [todos, setTodos] = useState26([]);
|
|
7929
|
+
const ws = getWSClient();
|
|
7930
|
+
const offRef = useRef12(null);
|
|
7931
|
+
useEffect21(() => {
|
|
7932
|
+
ws.send({ type: "todos.get" });
|
|
7933
|
+
offRef.current = ws.on("todos.updated", (msg) => {
|
|
7934
|
+
const payload = msg?.payload;
|
|
7935
|
+
if (payload?.todos) setTodos(payload.todos);
|
|
7936
|
+
});
|
|
7937
|
+
return () => {
|
|
7938
|
+
offRef.current?.();
|
|
7939
|
+
};
|
|
7940
|
+
}, [ws]);
|
|
7941
|
+
const handleRemove = useCallback6(
|
|
7942
|
+
(id) => {
|
|
7943
|
+
ws.removeTodo(id);
|
|
7944
|
+
},
|
|
7945
|
+
[ws]
|
|
7946
|
+
);
|
|
7947
|
+
const pending = todos.filter((t) => t.status === "pending");
|
|
7948
|
+
const inProgress = todos.filter((t) => t.status === "in_progress");
|
|
7949
|
+
const completed = todos.filter((t) => t.status === "completed");
|
|
7950
|
+
return /* @__PURE__ */ jsxs38("div", { className: "flex flex-col h-full bg-background", children: [
|
|
7951
|
+
/* @__PURE__ */ jsxs38("div", { className: "px-4 py-3 border-b border-border flex items-center justify-between shrink-0", children: [
|
|
7952
|
+
/* @__PURE__ */ jsxs38("div", { className: "flex items-center gap-2", children: [
|
|
7953
|
+
/* @__PURE__ */ jsx43("h2", { className: "text-sm font-semibold text-foreground", children: "TODOS" }),
|
|
7954
|
+
/* @__PURE__ */ jsxs38("span", { className: "text-xs text-muted-foreground tabular-nums", children: [
|
|
7955
|
+
completed.length,
|
|
7956
|
+
"/",
|
|
7957
|
+
todos.length
|
|
7958
|
+
] })
|
|
7959
|
+
] }),
|
|
7960
|
+
/* @__PURE__ */ jsxs38("div", { className: "flex items-center gap-2 text-xs", children: [
|
|
7961
|
+
inProgress.length > 0 && /* @__PURE__ */ jsxs38("span", { className: "flex items-center gap-1 text-yellow-600 dark:text-yellow-400", children: [
|
|
7962
|
+
/* @__PURE__ */ jsx43(Clock3, { className: "w-3 h-3" }),
|
|
7963
|
+
inProgress.length
|
|
7964
|
+
] }),
|
|
7965
|
+
pending.length > 0 && /* @__PURE__ */ jsxs38("span", { className: "flex items-center gap-1 text-muted-foreground", children: [
|
|
7966
|
+
/* @__PURE__ */ jsx43(Circle2, { className: "w-3 h-3" }),
|
|
7967
|
+
pending.length
|
|
7968
|
+
] }),
|
|
7969
|
+
completed.length > 0 && /* @__PURE__ */ jsxs38("span", { className: "flex items-center gap-1 text-emerald-600 dark:text-emerald-400", children: [
|
|
7970
|
+
/* @__PURE__ */ jsx43(CheckCircle27, { className: "w-3 h-3" }),
|
|
7971
|
+
completed.length
|
|
7972
|
+
] })
|
|
7973
|
+
] })
|
|
7974
|
+
] }),
|
|
7975
|
+
/* @__PURE__ */ jsx43("div", { className: "flex-1 overflow-y-auto", children: todos.length === 0 ? /* @__PURE__ */ jsx43("p", { className: "px-4 py-8 text-xs text-muted-foreground text-center", children: "No todos yet. The agent will create them as it plans work." }) : /* @__PURE__ */ jsx43("div", { className: "py-1", children: todos.map((t) => {
|
|
7976
|
+
const label = t.status === "in_progress" && t.activeForm ? t.activeForm : t.content;
|
|
7977
|
+
const isInProgress = t.status === "in_progress";
|
|
7978
|
+
const isCompleted = t.status === "completed";
|
|
7979
|
+
return /* @__PURE__ */ jsxs38(
|
|
7980
|
+
"div",
|
|
7981
|
+
{
|
|
7982
|
+
className: `px-4 py-2 flex items-start gap-2.5 text-sm border-l-2 group ${isInProgress ? "border-l-yellow-500 bg-yellow-50/40 dark:bg-yellow-950/20" : isCompleted ? "border-l-emerald-500 bg-emerald-50/30 dark:bg-emerald-950/15" : "border-l-transparent"}`,
|
|
7983
|
+
children: [
|
|
7984
|
+
/* @__PURE__ */ jsx43("span", { className: "mt-0.5 shrink-0", children: isCompleted ? /* @__PURE__ */ jsx43(CheckCircle27, { className: "w-3.5 h-3.5 text-emerald-500" }) : isInProgress ? /* @__PURE__ */ jsx43(Clock3, { className: "w-3.5 h-3.5 text-yellow-500 animate-spin" }) : /* @__PURE__ */ jsx43(Circle2, { className: "w-3.5 h-3.5 text-muted-foreground/50" }) }),
|
|
7985
|
+
/* @__PURE__ */ jsx43(
|
|
7986
|
+
"span",
|
|
7987
|
+
{
|
|
7988
|
+
className: `leading-snug flex-1 ${isInProgress ? "text-yellow-800 dark:text-yellow-200 font-medium" : isCompleted ? "text-muted-foreground line-through" : "text-foreground"}`,
|
|
7989
|
+
children: label
|
|
7990
|
+
}
|
|
7991
|
+
),
|
|
7992
|
+
/* @__PURE__ */ jsx43(
|
|
7993
|
+
"button",
|
|
7994
|
+
{
|
|
7995
|
+
type: "button",
|
|
7996
|
+
onClick: (e) => {
|
|
7997
|
+
e.stopPropagation();
|
|
7998
|
+
handleRemove(t.id);
|
|
7999
|
+
},
|
|
8000
|
+
className: "shrink-0 p-0.5 rounded opacity-0 group-hover:opacity-60 hover:opacity-100 hover:bg-muted transition-all",
|
|
8001
|
+
title: "Remove",
|
|
8002
|
+
children: /* @__PURE__ */ jsx43(X8, { className: "w-3 h-3 text-muted-foreground" })
|
|
8003
|
+
}
|
|
8004
|
+
)
|
|
8005
|
+
]
|
|
8006
|
+
},
|
|
8007
|
+
t.id
|
|
8008
|
+
);
|
|
8009
|
+
}) }) })
|
|
8010
|
+
] });
|
|
8011
|
+
}
|
|
8012
|
+
|
|
7815
8013
|
// src/App.tsx
|
|
7816
|
-
import { Fragment as Fragment11, jsx as
|
|
8014
|
+
import { Fragment as Fragment11, jsx as jsx44, jsxs as jsxs39 } from "react/jsx-runtime";
|
|
8015
|
+
function expectDefined12(value) {
|
|
8016
|
+
if (value === null || value === void 0) {
|
|
8017
|
+
throw new Error("Expected value to be defined");
|
|
8018
|
+
}
|
|
8019
|
+
return value;
|
|
8020
|
+
}
|
|
7817
8021
|
function AppInner() {
|
|
7818
8022
|
const { theme } = useTheme();
|
|
7819
8023
|
const { currentView, sidebarOpen, toggleSidebar, setSearchOpen, setSidebarOpen } = useUIStore();
|
|
@@ -7823,7 +8027,7 @@ function AppInner() {
|
|
|
7823
8027
|
const sessionTitle = useSessionStore((s) => s.session?.title);
|
|
7824
8028
|
const sessionId = useSessionStore((s) => s.session?.id);
|
|
7825
8029
|
const nickname = useUIStore((s) => sessionId ? s.sessionNicknames[sessionId] : void 0);
|
|
7826
|
-
|
|
8030
|
+
useEffect22(() => {
|
|
7827
8031
|
if (typeof window === "undefined") return;
|
|
7828
8032
|
const mq = window.matchMedia("(max-width: 768px)");
|
|
7829
8033
|
const apply = () => {
|
|
@@ -7836,7 +8040,7 @@ function AppInner() {
|
|
|
7836
8040
|
return () => mq.removeEventListener("change", apply);
|
|
7837
8041
|
}, [setSidebarOpen]);
|
|
7838
8042
|
useWebSocketBootstrap();
|
|
7839
|
-
|
|
8043
|
+
useEffect22(() => {
|
|
7840
8044
|
const parts = [];
|
|
7841
8045
|
if (isLoading) {
|
|
7842
8046
|
const it = iteration ? ` iter ${iteration.index}${iteration.max ? `/${iteration.max}` : ""}` : "";
|
|
@@ -7853,7 +8057,7 @@ function AppInner() {
|
|
|
7853
8057
|
document.title = "WrongStack";
|
|
7854
8058
|
};
|
|
7855
8059
|
}, [isLoading, iteration, projectName, sessionTitle, nickname]);
|
|
7856
|
-
|
|
8060
|
+
useEffect22(() => {
|
|
7857
8061
|
const onKey = (e) => {
|
|
7858
8062
|
const t = e.target;
|
|
7859
8063
|
const tag = t?.tagName?.toLowerCase();
|
|
@@ -7922,12 +8126,12 @@ function AppInner() {
|
|
|
7922
8126
|
}
|
|
7923
8127
|
if (e.key === "g" && !e.shiftKey) {
|
|
7924
8128
|
e.preventDefault();
|
|
7925
|
-
focusBubble(bubbles[0]);
|
|
8129
|
+
focusBubble(expectDefined12(bubbles[0]));
|
|
7926
8130
|
return;
|
|
7927
8131
|
}
|
|
7928
8132
|
if (e.key === "G" || e.key === "g" && e.shiftKey) {
|
|
7929
8133
|
e.preventDefault();
|
|
7930
|
-
focusBubble(bubbles[bubbles.length - 1]);
|
|
8134
|
+
focusBubble(expectDefined12(bubbles[bubbles.length - 1]));
|
|
7931
8135
|
return;
|
|
7932
8136
|
}
|
|
7933
8137
|
if (e.key === "Escape" && current) {
|
|
@@ -7949,33 +8153,40 @@ function AppInner() {
|
|
|
7949
8153
|
window.addEventListener("keydown", onKey);
|
|
7950
8154
|
return () => window.removeEventListener("keydown", onKey);
|
|
7951
8155
|
}, [toggleSidebar, setSearchOpen]);
|
|
7952
|
-
return /* @__PURE__ */
|
|
7953
|
-
sidebarOpen && /* @__PURE__ */
|
|
7954
|
-
/* @__PURE__ */
|
|
7955
|
-
/* @__PURE__ */
|
|
7956
|
-
currentView === "chat" && /* @__PURE__ */
|
|
7957
|
-
sessionId && /* @__PURE__ */
|
|
7958
|
-
/* @__PURE__ */
|
|
7959
|
-
/* @__PURE__ */
|
|
8156
|
+
return /* @__PURE__ */ jsxs39("div", { className: cn("flex h-screen", theme), children: [
|
|
8157
|
+
sidebarOpen && /* @__PURE__ */ jsx44(Sidebar, {}),
|
|
8158
|
+
/* @__PURE__ */ jsxs39("main", { className: "flex-1 flex flex-col overflow-hidden", children: [
|
|
8159
|
+
/* @__PURE__ */ jsx44(ConnectionBanner, {}),
|
|
8160
|
+
currentView === "chat" && /* @__PURE__ */ jsxs39(Fragment11, { children: [
|
|
8161
|
+
sessionId && /* @__PURE__ */ jsxs39("div", { className: "px-4 pt-2 space-y-2", children: [
|
|
8162
|
+
/* @__PURE__ */ jsx44(CollabPanel, { sessionId }),
|
|
8163
|
+
/* @__PURE__ */ jsx44(FleetPanel, {}),
|
|
8164
|
+
/* @__PURE__ */ jsx44(TodosPanel, {})
|
|
7960
8165
|
] }),
|
|
7961
|
-
/* @__PURE__ */
|
|
8166
|
+
/* @__PURE__ */ jsx44(ChatView, {})
|
|
7962
8167
|
] }),
|
|
7963
|
-
currentView === "settings" && /* @__PURE__ */
|
|
8168
|
+
currentView === "settings" && /* @__PURE__ */ jsx44(SettingsPanel, {})
|
|
7964
8169
|
] }),
|
|
7965
|
-
/* @__PURE__ */
|
|
7966
|
-
/* @__PURE__ */
|
|
7967
|
-
/* @__PURE__ */
|
|
7968
|
-
/* @__PURE__ */
|
|
7969
|
-
/* @__PURE__ */
|
|
8170
|
+
/* @__PURE__ */ jsx44(ConfirmDialog, {}),
|
|
8171
|
+
/* @__PURE__ */ jsx44(CommandPalette, {}),
|
|
8172
|
+
/* @__PURE__ */ jsx44(ShortcutsOverlay, {}),
|
|
8173
|
+
/* @__PURE__ */ jsx44(QuickModelSwitcher, {}),
|
|
8174
|
+
/* @__PURE__ */ jsx44(Toaster, {})
|
|
7970
8175
|
] });
|
|
7971
8176
|
}
|
|
7972
8177
|
function App() {
|
|
7973
|
-
return /* @__PURE__ */
|
|
8178
|
+
return /* @__PURE__ */ jsx44(ErrorBoundary, { children: /* @__PURE__ */ jsx44(ThemeProvider, { defaultTheme: "system", children: /* @__PURE__ */ jsx44(AppInner, {}) }) });
|
|
7974
8179
|
}
|
|
7975
8180
|
|
|
7976
8181
|
// src/main.tsx
|
|
7977
|
-
import { jsx as
|
|
7978
|
-
|
|
7979
|
-
|
|
8182
|
+
import { jsx as jsx45 } from "react/jsx-runtime";
|
|
8183
|
+
function expectDefined13(value) {
|
|
8184
|
+
if (value === null || value === void 0) {
|
|
8185
|
+
throw new Error("Expected value to be defined");
|
|
8186
|
+
}
|
|
8187
|
+
return value;
|
|
8188
|
+
}
|
|
8189
|
+
ReactDOM.createRoot(expectDefined13(document.getElementById("root"))).render(
|
|
8190
|
+
/* @__PURE__ */ jsx45(React6.StrictMode, { children: /* @__PURE__ */ jsx45(App, {}) })
|
|
7980
8191
|
);
|
|
7981
8192
|
//# sourceMappingURL=index.js.map
|