@wrongstack/webui 0.77.0 → 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.html +3 -3
- package/dist/index.js +166 -50
- package/dist/index.js.map +1 -1
- package/dist/server/entry.js +33 -13
- package/dist/server/entry.js.map +1 -1
- package/dist/server/index.d.ts +14 -14
- package/dist/server/index.js +33 -13
- package/dist/server/index.js.map +1 -1
- package/package.json +5 -5
- package/dist/assets/index-Df1jRLwk.css +0 -1
- package/dist/assets/index-H4ofeiKr.js +0 -94
- package/dist/assets/vendor-DBuK7aZd.js +0 -546
package/dist/index.html
CHANGED
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
<link rel="icon" type="image/svg+xml" href="/wrongstack.svg" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<title>WrongStack WebUI</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
9
|
-
<link rel="modulepreload" crossorigin href="/assets/vendor-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-D1cZ__pQ.js"></script>
|
|
9
|
+
<link rel="modulepreload" crossorigin href="/assets/vendor-CumDpIdV.js">
|
|
10
10
|
<link rel="stylesheet" crossorigin href="/assets/vendor-DW1jimNH.css">
|
|
11
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
11
|
+
<link rel="stylesheet" crossorigin href="/assets/index-DB5NTtW7.css">
|
|
12
12
|
</head>
|
|
13
13
|
<body>
|
|
14
14
|
<div id="root"></div>
|
package/dist/index.js
CHANGED
|
@@ -473,19 +473,25 @@ function getWSClient(url) {
|
|
|
473
473
|
// src/stores/chat-store.ts
|
|
474
474
|
import { create } from "zustand";
|
|
475
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
|
+
}
|
|
476
482
|
function dedupeRepeatedBlocks(text) {
|
|
477
483
|
if (!text) return text;
|
|
478
484
|
const paraSplit = text.split(/\n{2,}/);
|
|
479
485
|
const paras = [];
|
|
480
486
|
for (const p of paraSplit) {
|
|
481
|
-
if (paras.length > 0 && paras[paras.length - 1]
|
|
487
|
+
if (paras.length > 0 && paras[paras.length - 1]?.trim() === p.trim()) continue;
|
|
482
488
|
paras.push(p);
|
|
483
489
|
}
|
|
484
490
|
const cleaned = paras.map((p) => {
|
|
485
491
|
const lines = p.split("\n");
|
|
486
492
|
const out = [];
|
|
487
493
|
for (const line of lines) {
|
|
488
|
-
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()) {
|
|
489
495
|
continue;
|
|
490
496
|
}
|
|
491
497
|
out.push(line);
|
|
@@ -595,7 +601,7 @@ var useChatStore = create()(
|
|
|
595
601
|
if (queue.length === 0) return null;
|
|
596
602
|
const [next, ...rest] = queue;
|
|
597
603
|
set({ queue: rest });
|
|
598
|
-
return next;
|
|
604
|
+
return expectDefined(next);
|
|
599
605
|
},
|
|
600
606
|
removeQueued: (idx) => set((state) => ({ queue: state.queue.filter((_, i) => i !== idx) })),
|
|
601
607
|
clearQueue: () => set({ queue: [] }),
|
|
@@ -1052,6 +1058,12 @@ function notifyIfHidden(title, body, tag) {
|
|
|
1052
1058
|
}
|
|
1053
1059
|
|
|
1054
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
|
+
}
|
|
1055
1067
|
function handleSessionStart(msg) {
|
|
1056
1068
|
const payload = msg.payload;
|
|
1057
1069
|
const prev = useSessionStore.getState().session?.id;
|
|
@@ -1101,8 +1113,8 @@ function handleSessionStart(msg) {
|
|
|
1101
1113
|
const all = useChatStore.getState().messages;
|
|
1102
1114
|
let last;
|
|
1103
1115
|
for (let i = all.length - 1; i >= 0; i--) {
|
|
1104
|
-
if (all[i]
|
|
1105
|
-
last = all[i];
|
|
1116
|
+
if (all[i]?.toolUseId === String(b.tool_use_id ?? "")) {
|
|
1117
|
+
last = expectDefined2(all[i]);
|
|
1106
1118
|
break;
|
|
1107
1119
|
}
|
|
1108
1120
|
}
|
|
@@ -1147,7 +1159,7 @@ function handleKeyOperationResult(msg) {
|
|
|
1147
1159
|
function handleContextCompacted(msg) {
|
|
1148
1160
|
const payload = msg.payload;
|
|
1149
1161
|
let summary = payload.reductions.length ? payload.reductions.map((r) => `${r.phase}: ${r.saved}`).join(", ") : "no-op";
|
|
1150
|
-
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`;
|
|
1151
1163
|
useChatStore.getState().addMessage({ role: "assistant", content: `\u{1F5DC}\uFE0F Context compacted: ${payload.before} \u2192 ${payload.after} tokens (saved ~${payload.saved}). ${summary}` });
|
|
1152
1164
|
useSessionStore.setState({ lastInputTokens: payload.after });
|
|
1153
1165
|
}
|
|
@@ -1261,14 +1273,14 @@ function handleRunResult(msg) {
|
|
|
1261
1273
|
let lastAssistantIdx = -1;
|
|
1262
1274
|
let toolCount = 0;
|
|
1263
1275
|
for (let i = all.length - 1; i >= 0; i--) {
|
|
1264
|
-
const m = all[i];
|
|
1276
|
+
const m = expectDefined2(all[i]);
|
|
1265
1277
|
if (m.role === "assistant" && lastAssistantIdx === -1 && m.content) lastAssistantIdx = i;
|
|
1266
1278
|
if (m.role === "tool" && m.timestamp >= runStart.at) toolCount += 1;
|
|
1267
1279
|
if (m.role === "user" && m.timestamp <= runStart.at) break;
|
|
1268
1280
|
}
|
|
1269
1281
|
if (lastAssistantIdx !== -1) {
|
|
1270
1282
|
const sessionCost = useSessionStore.getState().cost;
|
|
1271
|
-
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) } });
|
|
1272
1284
|
}
|
|
1273
1285
|
}
|
|
1274
1286
|
useChatStore.getState().setRunStart(null);
|
|
@@ -2060,7 +2072,7 @@ function renderGroupedList(filtered, index, dispatch, setIndex) {
|
|
|
2060
2072
|
const groups = {};
|
|
2061
2073
|
filtered.forEach((it, i) => {
|
|
2062
2074
|
if (!groups[it.category]) groups[it.category] = [];
|
|
2063
|
-
groups[it.category]
|
|
2075
|
+
groups[it.category]?.push({ item: it, globalIdx: i });
|
|
2064
2076
|
});
|
|
2065
2077
|
return /* @__PURE__ */ jsx2("div", { className: "p-1", children: Object.entries(groups).map(([cat, rows]) => /* @__PURE__ */ jsxs2("div", { children: [
|
|
2066
2078
|
/* @__PURE__ */ jsx2("div", { className: "px-3 pt-2 pb-1 text-[10px] uppercase tracking-wider text-muted-foreground", children: cat }),
|
|
@@ -2096,6 +2108,12 @@ function renderGroupedList(filtered, index, dispatch, setIndex) {
|
|
|
2096
2108
|
import { FileText, Folder } from "lucide-react";
|
|
2097
2109
|
import { useEffect as useEffect4, useRef as useRef3, useState as useState2 } from "react";
|
|
2098
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
|
+
}
|
|
2099
2117
|
function FilePicker({ query, onPick, onClose }) {
|
|
2100
2118
|
const ws = useWebSocket();
|
|
2101
2119
|
const wsUrl = useConfigStore((s) => s.wsUrl);
|
|
@@ -2134,7 +2152,7 @@ function FilePicker({ query, onPick, onClose }) {
|
|
|
2134
2152
|
} else if (e.key === "Enter" || e.key === "Tab") {
|
|
2135
2153
|
if (files.length === 0) return;
|
|
2136
2154
|
e.preventDefault();
|
|
2137
|
-
onPick(files[index]);
|
|
2155
|
+
onPick(expectDefined3(files[index]));
|
|
2138
2156
|
} else if (e.key === "Escape") {
|
|
2139
2157
|
e.preventDefault();
|
|
2140
2158
|
onClose();
|
|
@@ -2210,25 +2228,64 @@ var Button = React.forwardRef(
|
|
|
2210
2228
|
Button.displayName = "Button";
|
|
2211
2229
|
|
|
2212
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
|
+
}
|
|
2213
2237
|
var SLASH_COMMANDS = [
|
|
2214
|
-
|
|
2215
|
-
{ name: "/
|
|
2216
|
-
|
|
2217
|
-
{ 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
|
|
2218
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)" },
|
|
2219
2243
|
{ name: "/compact", category: "Session", description: "Shrink context \u2014 elide ancient tool output" },
|
|
2220
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
|
|
2221
2250
|
{ name: "/debug", category: "Inspect", aliases: ["/context"], description: "Per-section context size breakdown" },
|
|
2222
2251
|
{ name: "/tools", category: "Inspect", description: "List every registered tool the model can call" },
|
|
2223
2252
|
{ name: "/memory", category: "Inspect", description: "Show all remembered notes (project + user scope)" },
|
|
2224
2253
|
{ name: "/skill", category: "Inspect", aliases: ["/skills"], description: "List active skills" },
|
|
2225
2254
|
{ name: "/diag", category: "Inspect", description: "Runtime diagnostics (provider, tools, features, mode, usage)" },
|
|
2226
2255
|
{ name: "/stats", category: "Inspect", description: "Session stats: tokens, cache hit ratio, cost, elapsed" },
|
|
2227
|
-
{ name: "/
|
|
2228
|
-
{ name: "/
|
|
2229
|
-
|
|
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" }
|
|
2230
2287
|
];
|
|
2231
|
-
var SLASH_CATEGORY_ORDER = ["Run", "Session", "Inspect", "App"];
|
|
2288
|
+
var SLASH_CATEGORY_ORDER = ["Run", "Session", "Inspect", "Agent", "Config", "App"];
|
|
2232
2289
|
function matchSlash(query) {
|
|
2233
2290
|
const q = query.toLowerCase();
|
|
2234
2291
|
if (q === "/" || q === "") return SLASH_COMMANDS;
|
|
@@ -2239,7 +2296,7 @@ function matchSlash(query) {
|
|
|
2239
2296
|
function detectAtMention(value, cursor) {
|
|
2240
2297
|
let i = cursor - 1;
|
|
2241
2298
|
while (i >= 0) {
|
|
2242
|
-
const c = value[i];
|
|
2299
|
+
const c = expectDefined4(value[i]);
|
|
2243
2300
|
if (c === "@") {
|
|
2244
2301
|
const prev = i > 0 ? value[i - 1] : "";
|
|
2245
2302
|
if (i === 0 || /\s/.test(prev ?? "")) {
|
|
@@ -2255,6 +2312,12 @@ function detectAtMention(value, cursor) {
|
|
|
2255
2312
|
|
|
2256
2313
|
// src/components/ChatInput.tsx
|
|
2257
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
|
+
}
|
|
2258
2321
|
function ChatInput() {
|
|
2259
2322
|
const { isLoading, setLoading, addMessage, clearMessages } = useChatStore();
|
|
2260
2323
|
const queue = useChatStore((s) => s.queue);
|
|
@@ -2448,7 +2511,7 @@ function ChatInput() {
|
|
|
2448
2511
|
setLoading(false);
|
|
2449
2512
|
const all = useChatStore.getState().messages;
|
|
2450
2513
|
for (let i = all.length - 1; i >= 0; i--) {
|
|
2451
|
-
const m = all[i];
|
|
2514
|
+
const m = expectDefined5(all[i]);
|
|
2452
2515
|
if (m.role === "user" && m.content) {
|
|
2453
2516
|
setInput(m.content);
|
|
2454
2517
|
requestAnimationFrame(() => {
|
|
@@ -2660,7 +2723,7 @@ function ChatInput() {
|
|
|
2660
2723
|
const next = before + insertion + after;
|
|
2661
2724
|
setInput(next);
|
|
2662
2725
|
const lastTokenStart = before.length + lead.length + tokens.slice(0, -1).join(" ").length + (tokens.length > 1 ? 1 : 0);
|
|
2663
|
-
const lastBasename = files[files.length - 1]
|
|
2726
|
+
const lastBasename = files[files.length - 1]?.name;
|
|
2664
2727
|
requestAnimationFrame(() => {
|
|
2665
2728
|
if (ta) {
|
|
2666
2729
|
const cur = before.length + insertion.length - trail.length;
|
|
@@ -2712,14 +2775,14 @@ function ChatInput() {
|
|
|
2712
2775
|
const byCategory = {};
|
|
2713
2776
|
slashSuggestions.forEach((cmd, idx) => {
|
|
2714
2777
|
if (!byCategory[cmd.category]) byCategory[cmd.category] = [];
|
|
2715
|
-
byCategory[cmd.category]
|
|
2778
|
+
byCategory[cmd.category]?.push({ cmd, idx });
|
|
2716
2779
|
});
|
|
2717
2780
|
const orderedCategories = SLASH_CATEGORY_ORDER.filter((c) => byCategory[c]?.length);
|
|
2718
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: [
|
|
2719
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" }),
|
|
2720
2783
|
orderedCategories.map((cat) => /* @__PURE__ */ jsxs4("div", { className: "mb-1", children: [
|
|
2721
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 }),
|
|
2722
|
-
byCategory[cat]
|
|
2785
|
+
byCategory[cat]?.map(({ cmd, idx }) => /* @__PURE__ */ jsxs4(
|
|
2723
2786
|
"button",
|
|
2724
2787
|
{
|
|
2725
2788
|
type: "button",
|
|
@@ -2950,6 +3013,12 @@ function ConnectionChip({ wsStatus, wsConnected }) {
|
|
|
2950
3013
|
import { Check, ChevronDown, Gauge } from "lucide-react";
|
|
2951
3014
|
import { useEffect as useEffect7, useRef as useRef5, useState as useState5 } from "react";
|
|
2952
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
|
+
}
|
|
2953
3022
|
var FALLBACK_MODES = [
|
|
2954
3023
|
{
|
|
2955
3024
|
id: "balanced",
|
|
@@ -2985,7 +3054,7 @@ function ContextModePicker() {
|
|
|
2985
3054
|
};
|
|
2986
3055
|
}, [open]);
|
|
2987
3056
|
const items = contextModes.length > 0 ? contextModes : FALLBACK_MODES;
|
|
2988
|
-
const active = items.find((m) => m.id === contextMode) ?? items[0];
|
|
3057
|
+
const active = items.find((m) => m.id === contextMode) ?? expectDefined6(items[0]);
|
|
2989
3058
|
return /* @__PURE__ */ jsxs6("div", { ref: rootRef, className: "relative shrink-0", children: [
|
|
2990
3059
|
/* @__PURE__ */ jsxs6(
|
|
2991
3060
|
"button",
|
|
@@ -3032,7 +3101,7 @@ function ContextModePicker() {
|
|
|
3032
3101
|
/* @__PURE__ */ jsxs6("div", { className: "min-w-0 flex-1", children: [
|
|
3033
3102
|
/* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between gap-2", children: [
|
|
3034
3103
|
/* @__PURE__ */ jsx7("span", { className: "text-xs font-mono", children: m.id }),
|
|
3035
|
-
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: [
|
|
3036
3105
|
Math.round(m.thresholds.warn * 100),
|
|
3037
3106
|
"/",
|
|
3038
3107
|
Math.round(m.thresholds.soft * 100),
|
|
@@ -3322,6 +3391,12 @@ import remarkGfm from "remark-gfm";
|
|
|
3322
3391
|
// src/components/DiffView.tsx
|
|
3323
3392
|
import { memo, useMemo as useMemo2 } from "react";
|
|
3324
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
|
+
}
|
|
3325
3400
|
var DiffView = memo(function DiffView2({ oldText, newText, caption }) {
|
|
3326
3401
|
const rows = useMemo2(() => computeDiff(oldText, newText), [oldText, newText]);
|
|
3327
3402
|
if (rows === null) {
|
|
@@ -3391,8 +3466,8 @@ function computeDiff(oldText, newText) {
|
|
|
3391
3466
|
const dp = Array.from({ length: n + 1 }, () => new Array(m + 1).fill(0));
|
|
3392
3467
|
for (let i2 = n - 1; i2 >= 0; i2--) {
|
|
3393
3468
|
for (let j2 = m - 1; j2 >= 0; j2--) {
|
|
3394
|
-
if (a[i2] === b[j2]) dp[i2][j2] = dp[i2 + 1][j2 + 1] + 1;
|
|
3395
|
-
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]));
|
|
3396
3471
|
}
|
|
3397
3472
|
}
|
|
3398
3473
|
const rows = [];
|
|
@@ -3400,19 +3475,19 @@ function computeDiff(oldText, newText) {
|
|
|
3400
3475
|
let j = 0;
|
|
3401
3476
|
while (i < n && j < m) {
|
|
3402
3477
|
if (a[i] === b[j]) {
|
|
3403
|
-
rows.push({ kind: "ctx", text: a[i] });
|
|
3478
|
+
rows.push({ kind: "ctx", text: expectDefined7(a[i]) });
|
|
3404
3479
|
i++;
|
|
3405
3480
|
j++;
|
|
3406
|
-
} else if (dp[i + 1][j] >= dp[i][j + 1]) {
|
|
3407
|
-
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]) });
|
|
3408
3483
|
i++;
|
|
3409
3484
|
} else {
|
|
3410
|
-
rows.push({ kind: "add", text: b[j] });
|
|
3485
|
+
rows.push({ kind: "add", text: expectDefined7(b[j]) });
|
|
3411
3486
|
j++;
|
|
3412
3487
|
}
|
|
3413
3488
|
}
|
|
3414
|
-
while (i < n) rows.push({ kind: "del", text: a[i++] });
|
|
3415
|
-
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++]) });
|
|
3416
3491
|
return rows;
|
|
3417
3492
|
}
|
|
3418
3493
|
function diffFromToolInput(toolName, input) {
|
|
@@ -3779,10 +3854,16 @@ function CopyButton({
|
|
|
3779
3854
|
// src/components/MessageBubble/ErrorBody.tsx
|
|
3780
3855
|
import { useState as useState9 } from "react";
|
|
3781
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
|
+
}
|
|
3782
3863
|
function detectStackBoundary(text) {
|
|
3783
3864
|
const lines = text.split("\n");
|
|
3784
3865
|
for (let i = 0; i < lines.length; i++) {
|
|
3785
|
-
const ln = lines[i];
|
|
3866
|
+
const ln = expectDefined8(lines[i]);
|
|
3786
3867
|
if (/^\s*at\s+\S+.*\(.*:\d+:\d+\)\s*$/.test(ln)) return i;
|
|
3787
3868
|
if (/^\s*at\s+\S+\.\S+\(\S+\.java:\d+\)\s*$/.test(ln)) return i;
|
|
3788
3869
|
if (/^\s+File "[^"]+", line \d+/.test(ln)) return i;
|
|
@@ -3885,6 +3966,12 @@ function ToolInputView({ input }) {
|
|
|
3885
3966
|
|
|
3886
3967
|
// src/components/MessageBubble/index.tsx
|
|
3887
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
|
+
}
|
|
3888
3975
|
var MessageBubble = memo3(function MessageBubble2({
|
|
3889
3976
|
message,
|
|
3890
3977
|
isFirst = false,
|
|
@@ -3913,7 +4000,7 @@ var MessageBubble = memo3(function MessageBubble2({
|
|
|
3913
4000
|
if (message.role !== "assistant" || isLoading) return false;
|
|
3914
4001
|
const all = useChatStore.getState().messages;
|
|
3915
4002
|
for (let i = all.length - 1; i >= 0; i--) {
|
|
3916
|
-
const m = all[i];
|
|
4003
|
+
const m = expectDefined9(all[i]);
|
|
3917
4004
|
if (m.role === "assistant") return m.id === message.id;
|
|
3918
4005
|
}
|
|
3919
4006
|
return false;
|
|
@@ -3924,13 +4011,13 @@ var MessageBubble = memo3(function MessageBubble2({
|
|
|
3924
4011
|
if (idx === -1) return;
|
|
3925
4012
|
let userIdx = -1;
|
|
3926
4013
|
for (let i = idx - 1; i >= 0; i--) {
|
|
3927
|
-
if (all[i]
|
|
4014
|
+
if (all[i]?.role === "user") {
|
|
3928
4015
|
userIdx = i;
|
|
3929
4016
|
break;
|
|
3930
4017
|
}
|
|
3931
4018
|
}
|
|
3932
4019
|
if (userIdx === -1) return;
|
|
3933
|
-
const userMsg = all[userIdx];
|
|
4020
|
+
const userMsg = expectDefined9(all[userIdx]);
|
|
3934
4021
|
truncateAfter(userMsg.id);
|
|
3935
4022
|
addMessage({ role: "user", content: userMsg.content });
|
|
3936
4023
|
setLoading(true);
|
|
@@ -4007,7 +4094,14 @@ var MessageBubble = memo3(function MessageBubble2({
|
|
|
4007
4094
|
const lines = message.toolResult ? message.toolResult.split("\n").length : 0;
|
|
4008
4095
|
return /* @__PURE__ */ jsxs14("div", { className: "space-y-1", children: [
|
|
4009
4096
|
inputSummary && !expanded && /* @__PURE__ */ jsx15("div", { className: "text-xs text-muted-foreground font-mono truncate", children: inputSummary }),
|
|
4010
|
-
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
|
+
})() }),
|
|
4011
4105
|
expanded && message.toolInput !== void 0 && (() => {
|
|
4012
4106
|
const diffArgs = diffFromToolInput(message.toolName, message.toolInput);
|
|
4013
4107
|
if (diffArgs) return /* @__PURE__ */ jsx15(DiffView, { oldText: diffArgs.oldText, newText: diffArgs.newText, caption: diffArgs.caption });
|
|
@@ -4451,7 +4545,6 @@ function ThemeToggle({ className }) {
|
|
|
4451
4545
|
"inline-flex items-center gap-0.5 rounded-lg border border-border bg-card/70 p-0.5 shadow-sm",
|
|
4452
4546
|
className
|
|
4453
4547
|
),
|
|
4454
|
-
role: "radiogroup",
|
|
4455
4548
|
"aria-label": "Theme",
|
|
4456
4549
|
children: OPTIONS.map(({ value, icon: Icon2, label }) => {
|
|
4457
4550
|
const active = theme === value;
|
|
@@ -4459,8 +4552,7 @@ function ThemeToggle({ className }) {
|
|
|
4459
4552
|
"button",
|
|
4460
4553
|
{
|
|
4461
4554
|
type: "button",
|
|
4462
|
-
|
|
4463
|
-
"aria-checked": active,
|
|
4555
|
+
"aria-pressed": active,
|
|
4464
4556
|
title: `${label} theme`,
|
|
4465
4557
|
"aria-label": `${label} theme`,
|
|
4466
4558
|
onClick: () => setTheme(value),
|
|
@@ -4481,6 +4573,12 @@ function ThemeToggle({ className }) {
|
|
|
4481
4573
|
import { CheckCircle2 as CheckCircle23, ChevronDown as ChevronDown5, ChevronRight as ChevronRight3, Loader2 as Loader22, Terminal as Terminal2, XCircle as XCircle3 } from "lucide-react";
|
|
4482
4574
|
import { memo as memo4, useState as useState15 } from "react";
|
|
4483
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
|
+
}
|
|
4484
4582
|
function formatDuration(ms) {
|
|
4485
4583
|
if (ms < 1e3) return `${ms}ms`;
|
|
4486
4584
|
if (ms < 6e4) return `${(ms / 1e3).toFixed(ms < 1e4 ? 2 : 1)}s`;
|
|
@@ -4495,7 +4593,7 @@ var ToolGroup = memo4(function ToolGroup2({
|
|
|
4495
4593
|
}) {
|
|
4496
4594
|
const [open, setOpen] = useState15(defaultOpen);
|
|
4497
4595
|
if (tools.length === 1) {
|
|
4498
|
-
return /* @__PURE__ */ jsx20(MessageBubble, { message: tools[0], isFirst: true, isContinuation });
|
|
4596
|
+
return /* @__PURE__ */ jsx20(MessageBubble, { message: expectDefined10(tools[0]), isFirst: true, isContinuation });
|
|
4499
4597
|
}
|
|
4500
4598
|
const running = tools.filter((t) => t.toolResult === void 0).length;
|
|
4501
4599
|
const errored = tools.filter((t) => t.isError).length;
|
|
@@ -4868,6 +4966,12 @@ function ThinkingBubble() {
|
|
|
4868
4966
|
|
|
4869
4967
|
// src/components/ChatView/index.tsx
|
|
4870
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
|
+
}
|
|
4871
4975
|
function ChatView() {
|
|
4872
4976
|
const { messages, isLoading } = useChatStore();
|
|
4873
4977
|
const setPaletteOpen = useUIStore((s) => s.setPaletteOpen);
|
|
@@ -5172,7 +5276,7 @@ function ChatView() {
|
|
|
5172
5276
|
(() => {
|
|
5173
5277
|
const groups = [];
|
|
5174
5278
|
for (let i = 0; i < messages.length; i++) {
|
|
5175
|
-
const m = messages[i];
|
|
5279
|
+
const m = expectDefined11(messages[i]);
|
|
5176
5280
|
if (m.role === "tool") {
|
|
5177
5281
|
const last = groups[groups.length - 1];
|
|
5178
5282
|
if (last && last.kind === "tools") {
|
|
@@ -5223,12 +5327,12 @@ function ChatView() {
|
|
|
5223
5327
|
};
|
|
5224
5328
|
const turnTs = (t) => {
|
|
5225
5329
|
if (t.kind === "user") return t.message.timestamp;
|
|
5226
|
-
const first = t.items[0];
|
|
5227
|
-
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;
|
|
5228
5332
|
};
|
|
5229
5333
|
const out = [];
|
|
5230
5334
|
for (let idx = 0; idx < turns.length; idx++) {
|
|
5231
|
-
const t = turns[idx];
|
|
5335
|
+
const t = expectDefined11(turns[idx]);
|
|
5232
5336
|
const ts = turnTs(t);
|
|
5233
5337
|
const day = dayKey(ts);
|
|
5234
5338
|
if (day !== prevDay) {
|
|
@@ -6565,7 +6669,7 @@ function ProviderSection({
|
|
|
6565
6669
|
const catalogByFamily = filteredCatalog.reduce(
|
|
6566
6670
|
(acc, p) => {
|
|
6567
6671
|
if (!acc[p.family]) acc[p.family] = [];
|
|
6568
|
-
acc[p.family]
|
|
6672
|
+
acc[p.family]?.push(p);
|
|
6569
6673
|
return acc;
|
|
6570
6674
|
},
|
|
6571
6675
|
{}
|
|
@@ -7908,6 +8012,12 @@ function TodosPanel() {
|
|
|
7908
8012
|
|
|
7909
8013
|
// src/App.tsx
|
|
7910
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
|
+
}
|
|
7911
8021
|
function AppInner() {
|
|
7912
8022
|
const { theme } = useTheme();
|
|
7913
8023
|
const { currentView, sidebarOpen, toggleSidebar, setSearchOpen, setSidebarOpen } = useUIStore();
|
|
@@ -8016,12 +8126,12 @@ function AppInner() {
|
|
|
8016
8126
|
}
|
|
8017
8127
|
if (e.key === "g" && !e.shiftKey) {
|
|
8018
8128
|
e.preventDefault();
|
|
8019
|
-
focusBubble(bubbles[0]);
|
|
8129
|
+
focusBubble(expectDefined12(bubbles[0]));
|
|
8020
8130
|
return;
|
|
8021
8131
|
}
|
|
8022
8132
|
if (e.key === "G" || e.key === "g" && e.shiftKey) {
|
|
8023
8133
|
e.preventDefault();
|
|
8024
|
-
focusBubble(bubbles[bubbles.length - 1]);
|
|
8134
|
+
focusBubble(expectDefined12(bubbles[bubbles.length - 1]));
|
|
8025
8135
|
return;
|
|
8026
8136
|
}
|
|
8027
8137
|
if (e.key === "Escape" && current) {
|
|
@@ -8070,7 +8180,13 @@ function App() {
|
|
|
8070
8180
|
|
|
8071
8181
|
// src/main.tsx
|
|
8072
8182
|
import { jsx as jsx45 } from "react/jsx-runtime";
|
|
8073
|
-
|
|
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(
|
|
8074
8190
|
/* @__PURE__ */ jsx45(React6.StrictMode, { children: /* @__PURE__ */ jsx45(App, {}) })
|
|
8075
8191
|
);
|
|
8076
8192
|
//# sourceMappingURL=index.js.map
|