mirror of
https://github.com/Sea-Haven-Industries/open-swe.git
synced 2026-09-30 09:13:14 +00:00
fix(ui): resolve eslint errors in dashboard components (#1538)
Clears ~83 pre-existing eslint errors in the UI: auto-fixable rules (array-type, import/order, sort-imports, type-only imports, redundant assertions/conditions) plus manual fixes for unnecessary conditions and banned @ts-nocheck directives. The 8 ported components excluded from tsconfig are now also ignored by eslint so type-aware linting no longer fails to parse them. Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
This commit is contained in:
parent
3297e799de
commit
0108d764d9
29 changed files with 91 additions and 83 deletions
|
|
@ -11,6 +11,17 @@ export default [
|
|||
"dist/**",
|
||||
"src/routeTree.gen.ts",
|
||||
"src/components/ui/**",
|
||||
// Ported from a desktop host app and excluded from tsconfig (not yet
|
||||
// integrated), so type-aware linting cannot resolve them. Keep this list
|
||||
// in sync with the `exclude` entries in tsconfig.json.
|
||||
"src/components/agents/ported/ChatView.tsx",
|
||||
"src/components/agents/ported/PromptBar.tsx",
|
||||
"src/components/agents/ported/BranchSelector.tsx",
|
||||
"src/components/agents/ported/ContextIndicator.tsx",
|
||||
"src/components/agents/ported/SourceControlPanel.tsx",
|
||||
"src/components/agents/ported/SourceControlTile.tsx",
|
||||
"src/components/agents/ported/Footer.tsx",
|
||||
"src/components/agents/ported/ThreadPicker.tsx",
|
||||
],
|
||||
},
|
||||
...tanstackConfig,
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ export function AgentInstructionsPanel() {
|
|||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (detail.data) setDraft(detail.data.instructions ?? "");
|
||||
if (detail.data) setDraft(detail.data.instructions);
|
||||
}, [detail.data?.instructions, detail.data?.full_name]);
|
||||
|
||||
const create = useMutation({
|
||||
|
|
@ -104,7 +104,7 @@ export function AgentInstructionsPanel() {
|
|||
const canAdd = normalizedAddRepo !== null && !configured.has(normalizedAddRepo);
|
||||
const active =
|
||||
detail.data ?? instructions.data?.find((s) => s.full_name === selected) ?? null;
|
||||
const dirty = active != null && draft !== (active.instructions ?? "");
|
||||
const dirty = active != null && draft !== active.instructions;
|
||||
|
||||
const handleAdd = () => {
|
||||
if (!normalizedAddRepo || !canAdd) return;
|
||||
|
|
|
|||
|
|
@ -9,9 +9,11 @@ import {
|
|||
IoSunnyOutline,
|
||||
} from "react-icons/io5";
|
||||
|
||||
import type { SessionUser } from "@/lib/api";
|
||||
import type { Theme } from "@/lib/theme";
|
||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
||||
import { api, type SessionUser } from "@/lib/api";
|
||||
import { useTheme, type Theme } from "@/lib/theme";
|
||||
import { api } from "@/lib/api";
|
||||
import { useTheme } from "@/lib/theme";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const THEME_OPTIONS: Array<{ value: Theme; label: string; icon: typeof IoSunnyOutline }> = [
|
||||
|
|
|
|||
|
|
@ -17,9 +17,9 @@ import type { GitStatus, GitStatusEntry } from "@pierre/trees"
|
|||
|
||||
import type { AgentThread, Message } from "@/lib/agents/types"
|
||||
import type { ThreadPrDiffFile } from "@/lib/agents/api"
|
||||
import type { ChangedFileSummaryItem } from "@/components/agents/messages"
|
||||
import { useAgentThreadPrDiff } from "@/lib/agents/queries"
|
||||
import { buttonVariants } from "@/components/ui/button"
|
||||
import type { ChangedFileSummaryItem } from "@/components/agents/messages"
|
||||
import { useDiffOptions } from "@/components/agents/utils/diffUtils"
|
||||
import { summarizeChangedFiles } from "@/components/agents/ported"
|
||||
import { Z } from "@/components/agents/z-index"
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
import { useEffect, useMemo, useRef, useState } from "react";
|
||||
|
||||
import { ReplyCard } from "@/components/agents/ported/ReplyCard";
|
||||
import { ShellCommand } from "@/components/agents/ported/ShellCommand";
|
||||
import { ToolExecution } from "@/components/agents/ported/ToolExecution";
|
||||
import type { Message } from "@/lib/agents/types";
|
||||
|
||||
import { ChunkRenderer } from "./ChunkRenderer";
|
||||
import { ReasoningBlock } from "./ReasoningBlock";
|
||||
import { buildRenderItems, summarizeExploration, type RenderItem } from "./renderItems";
|
||||
import { SubagentGroup } from "@/components/agents/subagents";
|
||||
import { buildRenderItems, summarizeExploration } from "./renderItems";
|
||||
import { summarizeChangedFiles } from "./summarizeChangedFiles";
|
||||
import { TurnChangedFilesCard } from "./TurnChangedFilesCard";
|
||||
import { WorkSummary } from "./WorkSummary";
|
||||
import type { RenderItem } from "./renderItems";
|
||||
import type { Message } from "@/lib/agents/types";
|
||||
import type { ApprovalCallbacks, ChangedFileSummaryItem } from "./types";
|
||||
import { SubagentGroup } from "@/components/agents/subagents";
|
||||
import { ToolExecution } from "@/components/agents/ported/ToolExecution";
|
||||
import { ShellCommand } from "@/components/agents/ported/ShellCommand";
|
||||
import { ReplyCard } from "@/components/agents/ported/ReplyCard";
|
||||
|
||||
/**
|
||||
* Render-item types kept visible (not collapsed) when a turn finishes — the
|
||||
|
|
@ -24,9 +24,9 @@ const REPLY_ITEM_TYPES = new Set<RenderItem["type"]>(["text-chunk", "reply-item"
|
|||
* Split a finished turn's items into collapsible work and the trailing reply,
|
||||
* where the reply is the maximal suffix made up solely of reply/text items.
|
||||
*/
|
||||
function splitWorkAndReply(items: RenderItem[]): {
|
||||
workItems: RenderItem[];
|
||||
replyItems: RenderItem[];
|
||||
function splitWorkAndReply(items: Array<RenderItem>): {
|
||||
workItems: Array<RenderItem>;
|
||||
replyItems: Array<RenderItem>;
|
||||
} {
|
||||
let splitIndex = items.length;
|
||||
while (splitIndex > 0) {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
import type { Chunk } from "@/lib/agents/types";
|
||||
import type { ApprovalCallbacks } from "./types";
|
||||
import { CodeBlock } from "@/components/agents/ported/CodeBlock";
|
||||
import { Markdown } from "@/components/agents/ported/Markdown";
|
||||
import { ToolExecution } from "@/components/agents/ported/ToolExecution";
|
||||
import type { Chunk } from "@/lib/agents/types";
|
||||
|
||||
import type { ApprovalCallbacks } from "./types";
|
||||
|
||||
export function ChunkRenderer({
|
||||
chunk,
|
||||
|
|
|
|||
|
|
@ -1,13 +1,11 @@
|
|||
// @ts-nocheck — ported from open-swe-app (Electron); strict checks applied when wiring cloud APIs.
|
||||
import { memo, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
||||
import { ChevronDown } from "lucide-react";
|
||||
|
||||
import { useLiveMarkdownMessageId } from "@/lib/agents/provider/useLiveMarkdownMessageId";
|
||||
|
||||
import { AgentMessage } from "./AgentMessage";
|
||||
import { ThinkingSpinner } from "./ThinkingSpinner";
|
||||
import { UserMessage } from "./UserMessage";
|
||||
import type { MessagesProps } from "./types";
|
||||
import { useLiveMarkdownMessageId } from "@/lib/agents/provider/useLiveMarkdownMessageId";
|
||||
|
||||
const BOTTOM_LOCK_THRESHOLD_PX = 24;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { useEffect, useRef, useState } from "react";
|
|||
|
||||
import { formatElapsed } from "@/lib/utils";
|
||||
|
||||
const BUSY_TEXTS: { present: string; past: string }[] = [
|
||||
const BUSY_TEXTS: Array<{ present: string; past: string }> = [
|
||||
{ present: "vibing...", past: "Vibed" },
|
||||
{ present: "noodling...", past: "Noodled" },
|
||||
{ present: "pondering...", past: "Pondered" },
|
||||
|
|
|
|||
|
|
@ -2,9 +2,8 @@ import { memo, useCallback, useEffect, useMemo, useState } from "react";
|
|||
import { ChevronDown, ChevronUp } from "lucide-react";
|
||||
import { MultiFileDiff } from "@pierre/diffs/react";
|
||||
|
||||
import { useDiffOptions, warmDiffHighlighter } from "@/components/agents/utils/diffUtils";
|
||||
|
||||
import type { ChangedFileSummaryItem } from "./types";
|
||||
import { useDiffOptions, warmDiffHighlighter } from "@/components/agents/utils/diffUtils";
|
||||
|
||||
function stripProjectPathForDisplay(path: string, projectPath?: string): string {
|
||||
if (!projectPath) return path;
|
||||
|
|
@ -84,7 +83,7 @@ export const TurnChangedFilesCard = memo(function TurnChangedFilesCard({
|
|||
totals,
|
||||
projectPath,
|
||||
}: {
|
||||
files: ChangedFileSummaryItem[];
|
||||
files: Array<ChangedFileSummaryItem>;
|
||||
totals: { additions: number; deletions: number };
|
||||
projectPath?: string;
|
||||
}) {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import type { Message } from "@/lib/agents/types";
|
|||
export function UserMessage({ message }: { message: Message }) {
|
||||
const text = message.chunks
|
||||
.filter((c) => c.kind === "text")
|
||||
.map((c) => (c as { kind: "text"; text: string }).text)
|
||||
.map((c) => c.text)
|
||||
.join("");
|
||||
|
||||
const images = message.chunks.filter((c) => c.kind === "image");
|
||||
|
|
@ -39,14 +39,12 @@ export function UserMessage({ message }: { message: Message }) {
|
|||
{images.length > 0 && (
|
||||
<div className="flex gap-2 mb-2 flex-wrap justify-end">
|
||||
{images.map((img, i) => (
|
||||
img.kind === "image" && (
|
||||
<img
|
||||
key={i}
|
||||
src={`data:${img.mimeType};base64,${img.base64}`}
|
||||
alt={img.fileName || "image"}
|
||||
className="max-w-48 max-h-48 rounded border border-gray-600"
|
||||
/>
|
||||
)
|
||||
<img
|
||||
key={i}
|
||||
src={`data:${img.mimeType};base64,${img.base64}`}
|
||||
alt={img.fileName || "image"}
|
||||
className="max-w-48 max-h-48 rounded border border-gray-600"
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { useState, type ReactNode } from "react";
|
||||
import { useState } from "react";
|
||||
import { ChevronRight } from "lucide-react";
|
||||
import type { ReactNode } from "react";
|
||||
|
||||
import { formatElapsed } from "@/lib/utils";
|
||||
|
||||
|
|
|
|||
|
|
@ -3,12 +3,12 @@ import type { Chunk, ToolExecutionChunk } from "@/lib/agents/types";
|
|||
export type RenderItem =
|
||||
| { type: "text-chunk"; key: string; chunk: Chunk }
|
||||
| { type: "reasoning-item"; key: string; chunk: Chunk }
|
||||
| { type: "explored-group"; key: string; id: string; chunks: ToolExecutionChunk[] }
|
||||
| { type: "explored-group"; key: string; id: string; chunks: Array<ToolExecutionChunk> }
|
||||
/**
|
||||
* One or more `task` (subagent) tool calls collapsed into a single group so
|
||||
* they can be rendered side by side as a card grid (see subagents/SubagentGroup).
|
||||
*/
|
||||
| { type: "subagent-group"; key: string; id: string; chunks: ToolExecutionChunk[] }
|
||||
| { type: "subagent-group"; key: string; id: string; chunks: Array<ToolExecutionChunk> }
|
||||
| { type: "edit-item"; key: string; chunk: ToolExecutionChunk }
|
||||
| { type: "shell-item"; key: string; chunk: ToolExecutionChunk }
|
||||
| { type: "reply-item"; key: string; chunk: ToolExecutionChunk }
|
||||
|
|
@ -68,11 +68,11 @@ function isSubagentTool(chunk: ToolExecutionChunk): boolean {
|
|||
return chunk.toolKind === "task";
|
||||
}
|
||||
|
||||
export function buildRenderItems(chunks: Chunk[], messageId?: string): RenderItem[] {
|
||||
const items: RenderItem[] = [];
|
||||
let exploredBuffer: ToolExecutionChunk[] = [];
|
||||
export function buildRenderItems(chunks: Array<Chunk>, messageId?: string): Array<RenderItem> {
|
||||
const items: Array<RenderItem> = [];
|
||||
let exploredBuffer: Array<ToolExecutionChunk> = [];
|
||||
let exploredStartIndex = -1;
|
||||
let subagentBuffer: ToolExecutionChunk[] = [];
|
||||
let subagentBuffer: Array<ToolExecutionChunk> = [];
|
||||
let subagentStartIndex = -1;
|
||||
|
||||
const flushExplored = () => {
|
||||
|
|
@ -165,7 +165,7 @@ export function buildRenderItems(chunks: Chunk[], messageId?: string): RenderIte
|
|||
return items;
|
||||
}
|
||||
|
||||
export function summarizeExploration(chunks: ToolExecutionChunk[]): string {
|
||||
export function summarizeExploration(chunks: Array<ToolExecutionChunk>): string {
|
||||
const count = chunks.length;
|
||||
return `Explored ${count} file${count === 1 ? "" : "s"}`;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import { countLineChanges } from "@/components/agents/utils/diffStats";
|
||||
import type { Chunk, DiffData } from "@/lib/agents/types";
|
||||
import type { Chunk } from "@/lib/agents/types";
|
||||
|
||||
import type { ChangedFileSummaryItem } from "./types";
|
||||
import { countLineChanges } from "@/components/agents/utils/diffStats";
|
||||
|
||||
export function summarizeChangedFiles(chunks: Chunk[]): ChangedFileSummaryItem[] {
|
||||
export function summarizeChangedFiles(chunks: Array<Chunk>): Array<ChangedFileSummaryItem> {
|
||||
const byFile = new Map<string, { filePath: string; originalContent: string | null; modifiedContent: string }>();
|
||||
|
||||
for (const chunk of chunks) {
|
||||
|
|
@ -12,7 +12,7 @@ export function summarizeChangedFiles(chunks: Chunk[]): ChangedFileSummaryItem[]
|
|||
const diffEntries = chunk.diffs?.length ? chunk.diffs : (chunk.diffData ? [chunk.diffData] : []);
|
||||
if (diffEntries.length === 0) continue;
|
||||
|
||||
for (const diffData of diffEntries as DiffData[]) {
|
||||
for (const diffData of diffEntries) {
|
||||
const existing = byFile.get(diffData.filePath);
|
||||
|
||||
if (!existing) {
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ export type MessagesScrollControl = {
|
|||
};
|
||||
|
||||
export interface MessagesProps extends ApprovalCallbacks {
|
||||
messages: Message[];
|
||||
messages: Array<Message>;
|
||||
isStreaming: boolean;
|
||||
/** Live run signal from `useStream().isLoading` — drives Streamdown token animation. */
|
||||
streamIsLoading?: boolean;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { useEffect, useMemo, useState } from "react";
|
||||
import { getSingletonHighlighter, type ThemedToken } from "shiki";
|
||||
import { getSingletonHighlighter } from "shiki";
|
||||
import type { ThemedToken } from "shiki";
|
||||
import { useResolvedTheme } from "@/lib/theme";
|
||||
|
||||
interface CodeBlockProps {
|
||||
|
|
@ -9,7 +10,7 @@ interface CodeBlockProps {
|
|||
|
||||
const SHIKI_THEME = { light: "github-light", dark: "github-dark" } as const;
|
||||
|
||||
const TOKEN_CACHE = new Map<string, ThemedToken[][]>();
|
||||
const TOKEN_CACHE = new Map<string, Array<Array<ThemedToken>>>();
|
||||
|
||||
function normalizeLanguage(language?: string): string {
|
||||
const raw = (language || "").toLowerCase().trim();
|
||||
|
|
@ -45,7 +46,7 @@ function languageLabel(language: string): string {
|
|||
}
|
||||
|
||||
export function CodeBlock({ text, language }: CodeBlockProps) {
|
||||
const [tokens, setTokens] = useState<ThemedToken[][] | null>(null);
|
||||
const [tokens, setTokens] = useState<Array<Array<ThemedToken>> | null>(null);
|
||||
const [copied, setCopied] = useState(false);
|
||||
const resolvedTheme = useResolvedTheme();
|
||||
const shikiTheme = SHIKI_THEME[resolvedTheme];
|
||||
|
|
@ -67,13 +68,11 @@ export function CodeBlock({ text, language }: CodeBlockProps) {
|
|||
|
||||
getSingletonHighlighter({
|
||||
themes: [shikiTheme],
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
langs: [normalizedLanguage as any],
|
||||
})
|
||||
.then((highlighter) => {
|
||||
if (cancelled) return;
|
||||
const result = highlighter.codeToTokens(text, {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
lang: normalizedLanguage as any,
|
||||
theme: shikiTheme,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { LoaderCircle } from 'lucide-react';
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
export function CompactingIndicator() {
|
||||
const [dots, setDots] = useState(1);
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import { useMemo } from "react";
|
||||
import { MultiFileDiff } from "@pierre/diffs/react";
|
||||
import type { DiffData } from "@/lib/agents/types";
|
||||
import { diffOptions } from "@/components/agents/utils/diffUtils";
|
||||
import { countLineChanges } from "@/components/agents/utils/diffStats";
|
||||
import type { DiffData } from "@/lib/agents/types";
|
||||
|
||||
interface DiffViewProps {
|
||||
diffData: DiffData;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { memo, type ReactNode } from "react";
|
||||
import { memo } from "react";
|
||||
import { Streamdown } from "streamdown";
|
||||
import type { ReactNode } from "react";
|
||||
import "streamdown/styles.css";
|
||||
|
||||
interface MarkdownProps {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
// @ts-nocheck — ported from open-swe-app (Electron).
|
||||
import { Children, isValidElement, type ReactNode } from 'react';
|
||||
import { Children, isValidElement } from 'react';
|
||||
import type { ReactNode } from 'react';
|
||||
|
||||
type ElementWithChildren = { children?: ReactNode };
|
||||
|
||||
interface MarkdownTableProps {
|
||||
children: ReactNode;
|
||||
|
|
@ -9,17 +11,19 @@ function countCells(node: ReactNode): number {
|
|||
return Children.toArray(node).filter((child) => isValidElement(child) && (child.type === 'th' || child.type === 'td')).length;
|
||||
}
|
||||
|
||||
function collectColumnCounts(node: ReactNode, counts: number[]) {
|
||||
function collectColumnCounts(node: ReactNode, counts: Array<number>) {
|
||||
Children.forEach(node, (child) => {
|
||||
if (!isValidElement(child)) return;
|
||||
|
||||
const childProps = child.props as ElementWithChildren;
|
||||
|
||||
if (child.type === 'tr') {
|
||||
const count = countCells(child.props.children);
|
||||
const count = countCells(childProps.children);
|
||||
if (count > 0) counts.push(count);
|
||||
return;
|
||||
}
|
||||
|
||||
collectColumnCounts(child.props.children, counts);
|
||||
collectColumnCounts(childProps.children, counts);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -29,7 +33,7 @@ function getTableMinWidth(columnCount: number): string {
|
|||
}
|
||||
|
||||
export function MarkdownTable({ children }: MarkdownTableProps) {
|
||||
const columnCounts: number[] = [];
|
||||
const columnCounts: Array<number> = [];
|
||||
collectColumnCounts(children, columnCounts);
|
||||
const columnCount = Math.max(0, ...columnCounts);
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ function isSlackTextObject(value: unknown): value is SlackTextObject {
|
|||
)
|
||||
}
|
||||
|
||||
function isSlackBlockArray(value: unknown): value is SlackBlock[] {
|
||||
function isSlackBlockArray(value: unknown): value is Array<SlackBlock> {
|
||||
return (
|
||||
Array.isArray(value) &&
|
||||
value.every((block) => !!block && typeof block === "object")
|
||||
|
|
@ -96,7 +96,7 @@ function renderSlackBody(text: string): Array<ReactNode> {
|
|||
function blocksFromOptions(
|
||||
message: string,
|
||||
options: unknown
|
||||
): SlackBlock[] | null {
|
||||
): Array<SlackBlock> | null {
|
||||
if (!Array.isArray(options)) return null
|
||||
const cleanOptions = options.filter(
|
||||
(option): option is string =>
|
||||
|
|
@ -115,7 +115,7 @@ function blocksFromOptions(
|
|||
]
|
||||
}
|
||||
|
||||
function renderSlackBlocks(blocks: SlackBlock[]): ReactNode {
|
||||
function renderSlackBlocks(blocks: Array<SlackBlock>): ReactNode {
|
||||
return (
|
||||
<div className="flex flex-col gap-2">
|
||||
{blocks.map((block, index) => {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { memo, useState, useRef, useCallback, useLayoutEffect } from "react";
|
||||
import { memo, useCallback, useLayoutEffect, useRef, useState } from "react";
|
||||
import type { ToolExecutionChunk } from "@/lib/agents/types";
|
||||
|
||||
interface ShellCommandProps {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { useRef, useEffect, useState } from "react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import {
|
||||
CheckCircle2,
|
||||
ChevronDown,
|
||||
|
|
@ -10,7 +10,7 @@ import {
|
|||
import type { TodoItem } from "@/lib/agents/types";
|
||||
|
||||
interface TodoListProps {
|
||||
todos: TodoItem[];
|
||||
todos: Array<TodoItem>;
|
||||
className?: string;
|
||||
runActive?: boolean;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { memo, useState, useCallback, useMemo, useRef, useLayoutEffect } from "react";
|
||||
import { memo, useCallback, useLayoutEffect, useMemo, useRef, useState } from "react";
|
||||
import { MultiFileDiff } from "@pierre/diffs/react";
|
||||
import type { ToolExecutionChunk, AcpToolKind } from "@/lib/agents/types";
|
||||
import { DiffView } from "./DiffView";
|
||||
import type { AcpToolKind, ToolExecutionChunk } from "@/lib/agents/types";
|
||||
import { useDiffOptions } from "@/components/agents/utils/diffUtils";
|
||||
import { countLineChanges } from "@/components/agents/utils/diffStats";
|
||||
|
||||
|
|
@ -204,7 +204,7 @@ export const ToolExecution = memo(function ToolExecution({
|
|||
const editedFileName = editedFilePath ? getFileName(editedFilePath) : "";
|
||||
const diffStats = diffData ? countLineChanges(diffData.originalContent, diffData.newContent, diffData.filePath) : null;
|
||||
|
||||
if (isCompletedEditOp && diffStats && diffData) {
|
||||
if (isCompletedEditOp && diffStats) {
|
||||
return (
|
||||
<InlineDiffCollapsible
|
||||
filePath={editedFilePath || diffData.filePath}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
import { memo } from "react";
|
||||
import { Bot, Loader2 } from "lucide-react";
|
||||
|
||||
import { useIsInAgentThreadStream } from "@/lib/agents/provider/useIsInAgentThreadStream";
|
||||
import type { ToolExecutionChunk } from "@/lib/agents/types";
|
||||
|
||||
import { SubagentActivity } from "./SubagentActivity";
|
||||
import type { ToolExecutionChunk } from "@/lib/agents/types";
|
||||
import { useIsInAgentThreadStream } from "@/lib/agents/provider/useIsInAgentThreadStream";
|
||||
|
||||
/** Coerce an unknown tool-argument value to a trimmed string, or `""`. */
|
||||
function asString(value: unknown): string {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import type { ToolExecutionChunk } from "@/lib/agents/types";
|
||||
|
||||
import { SubagentCard } from "./SubagentCard";
|
||||
import type { ToolExecutionChunk } from "@/lib/agents/types";
|
||||
|
||||
/** Maximum number of subagent cards rendered per row. */
|
||||
const MAX_SUBAGENT_COLUMNS = 4;
|
||||
|
|
@ -11,7 +10,7 @@ const MAX_SUBAGENT_COLUMNS = 4;
|
|||
* {@link MAX_SUBAGENT_COLUMNS}, so 1–4 subagents fill the row evenly and 5+
|
||||
* wrap onto additional rows.
|
||||
*/
|
||||
export function SubagentGroup({ chunks }: { chunks: ToolExecutionChunk[] }) {
|
||||
export function SubagentGroup({ chunks }: { chunks: Array<ToolExecutionChunk> }) {
|
||||
const columns = Math.min(Math.max(chunks.length, 1), MAX_SUBAGENT_COLUMNS);
|
||||
return (
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ const LIVE_MARKDOWN_CLEAR_MS = 2000;
|
|||
* keeps markdown streaming until the run has been idle for a beat.
|
||||
*/
|
||||
export function useLiveMarkdownMessageId(
|
||||
visibleMessages: Message[],
|
||||
visibleMessages: Array<Message>,
|
||||
streamIsLoading: boolean | undefined,
|
||||
isStreaming: boolean,
|
||||
): string | null {
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ function isFormField(target: EventTarget | null): boolean {
|
|||
* (Cmd on macOS, Ctrl elsewhere). Accepts one combo or several aliases.
|
||||
*/
|
||||
export function useHotkey(
|
||||
combo: string | string[],
|
||||
combo: string | Array<string>,
|
||||
handler: (event: KeyboardEvent) => void,
|
||||
options: HotkeyOptions = {}
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,8 @@
|
|||
import { createFileRoute } from "@tanstack/react-router"
|
||||
|
||||
import type { AgentSource, AgentStatus } from "@/lib/agents/types"
|
||||
import {
|
||||
AgentsThreadsPage,
|
||||
type ThreadsPageFilters,
|
||||
} from "@/components/agents/AgentsThreadsPage"
|
||||
import type { ThreadsPageFilters } from "@/components/agents/AgentsThreadsPage";
|
||||
import { AgentsThreadsPage } from "@/components/agents/AgentsThreadsPage"
|
||||
|
||||
const SOURCES: ReadonlyArray<AgentSource> = [
|
||||
"dashboard",
|
||||
|
|
|
|||
|
|
@ -228,7 +228,7 @@ function CloudAgentsPage() {
|
|||
label="Default Repository"
|
||||
description="Used when no repository is specified"
|
||||
control={
|
||||
repos.data?.repositories?.length ? (
|
||||
repos.data?.repositories.length ? (
|
||||
<div className="w-56">
|
||||
<RepoSelector
|
||||
repos={repos.data.repositories}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue