chore: fix linting

This commit is contained in:
Anish Sarkar 2026-05-12 04:00:04 +05:30
parent 4dbadbf159
commit 275e2c9e83
16 changed files with 33 additions and 74 deletions

View file

@ -474,7 +474,8 @@ class Config:
# Check if ffmpeg is installed # Check if ffmpeg is installed
if not is_ffmpeg_installed(): if not is_ffmpeg_installed():
allow_static_ffmpeg = ( allow_static_ffmpeg = (
os.getenv("SURFSENSE_ALLOW_STATIC_FFMPEG_DOWNLOAD", "TRUE").upper() == "TRUE" os.getenv("SURFSENSE_ALLOW_STATIC_FFMPEG_DOWNLOAD", "TRUE").upper()
== "TRUE"
) )
if allow_static_ffmpeg: if allow_static_ffmpeg:
import static_ffmpeg import static_ffmpeg

View file

@ -36,9 +36,7 @@ class MintResponse(BaseModel):
def _expected_secret() -> str: def _expected_secret() -> str:
return os.environ.get( return os.environ.get("E2E_MINT_SECRET", "local-e2e-mint-secret-not-for-production")
"E2E_MINT_SECRET", "local-e2e-mint-secret-not-for-production"
)
router = APIRouter(prefix="/__e2e__", tags=["__e2e__"]) router = APIRouter(prefix="/__e2e__", tags=["__e2e__"])

View file

@ -92,7 +92,9 @@ async def fake_process_document(
# Empty fallback so the indexing pipeline does not error out on # Empty fallback so the indexing pipeline does not error out on
# an unexpected payload. A failing canary assertion is a much # an unexpected payload. A failing canary assertion is a much
# clearer failure mode than a hard parser exception. # clearer failure mode than a hard parser exception.
content = f"# {display_name}\n\n(empty docling fake — no text-show operators found)\n" content = (
f"# {display_name}\n\n(empty docling fake — no text-show operators found)\n"
)
logger.info( logger.info(
"[fake-docling] returning %d chars for %s", "[fake-docling] returning %d chars for %s",

View file

@ -164,9 +164,7 @@ def _install_synthetic_global_llm_config() -> None:
import shutil import shutil
src = os.path.join(_THIS_DIR, "fixtures", "global_llm_config.yaml") src = os.path.join(_THIS_DIR, "fixtures", "global_llm_config.yaml")
dst = os.path.join( dst = os.path.join(_BACKEND_ROOT, "app", "config", "global_llm_config.yaml")
_BACKEND_ROOT, "app", "config", "global_llm_config.yaml"
)
if not os.path.exists(src): if not os.path.exists(src):
raise RuntimeError( raise RuntimeError(

View file

@ -142,9 +142,7 @@ def _install_synthetic_global_llm_config() -> None:
import shutil import shutil
src = os.path.join(_THIS_DIR, "fixtures", "global_llm_config.yaml") src = os.path.join(_THIS_DIR, "fixtures", "global_llm_config.yaml")
dst = os.path.join( dst = os.path.join(_BACKEND_ROOT, "app", "config", "global_llm_config.yaml")
_BACKEND_ROOT, "app", "config", "global_llm_config.yaml"
)
if not os.path.exists(src): if not os.path.exists(src):
raise RuntimeError( raise RuntimeError(

View file

@ -208,7 +208,10 @@ const MentionedDocumentInfoSchema = z.object({
id: z.number(), id: z.number(),
title: z.string(), title: z.string(),
document_type: z.string(), document_type: z.string(),
kind: z.union([z.literal("doc"), z.literal("folder")]).optional().default("doc"), kind: z
.union([z.literal("doc"), z.literal("folder")])
.optional()
.default("doc"),
}); });
const MentionedDocumentsPartSchema = z.object({ const MentionedDocumentsPartSchema = z.object({
@ -1029,9 +1032,7 @@ export default function NewChatPage() {
mentioned_surfsense_doc_ids: hasSurfsenseDocIds mentioned_surfsense_doc_ids: hasSurfsenseDocIds
? mentionedDocumentIds.surfsense_doc_ids ? mentionedDocumentIds.surfsense_doc_ids
: undefined, : undefined,
mentioned_folder_ids: hasFolderIds mentioned_folder_ids: hasFolderIds ? mentionedDocumentIds.folder_ids : undefined,
? mentionedDocumentIds.folder_ids
: undefined,
// Full mention metadata (docs + folders, with // Full mention metadata (docs + folders, with
// ``kind`` discriminator) so the BE can embed a // ``kind`` discriminator) so the BE can embed a
// ``mentioned-documents`` ContentPart on the // ``mentioned-documents`` ContentPart on the
@ -1900,12 +1901,10 @@ export default function NewChatPage() {
filesystem_mode: selection.filesystem_mode, filesystem_mode: selection.filesystem_mode,
client_platform: selection.client_platform, client_platform: selection.client_platform,
local_filesystem_mounts: selection.local_filesystem_mounts, local_filesystem_mounts: selection.local_filesystem_mounts,
mentioned_document_ids: mentioned_document_ids: regenerateDocIds.length > 0 ? regenerateDocIds : undefined,
regenerateDocIds.length > 0 ? regenerateDocIds : undefined,
mentioned_surfsense_doc_ids: mentioned_surfsense_doc_ids:
regenerateSurfsenseDocIds.length > 0 ? regenerateSurfsenseDocIds : undefined, regenerateSurfsenseDocIds.length > 0 ? regenerateSurfsenseDocIds : undefined,
mentioned_folder_ids: mentioned_folder_ids: regenerateFolderIds.length > 0 ? regenerateFolderIds : undefined,
regenerateFolderIds.length > 0 ? regenerateFolderIds : undefined,
// Full mention metadata for the regenerate-specific // Full mention metadata for the regenerate-specific
// source list. Only meaningful for edit (the BE only // source list. Only meaningful for edit (the BE only
// re-persists a user row when ``user_query`` is set); // re-persists a user row when ``user_query`` is set);

View file

@ -97,9 +97,7 @@ export const mentionedDocumentIdsAtom = atom((get) => {
surfsense_doc_ids: docs surfsense_doc_ids: docs
.filter((doc) => doc.document_type === "SURFSENSE_DOCS") .filter((doc) => doc.document_type === "SURFSENSE_DOCS")
.map((doc) => doc.id), .map((doc) => doc.id),
document_ids: docs document_ids: docs.filter((doc) => doc.document_type !== "SURFSENSE_DOCS").map((doc) => doc.id),
.filter((doc) => doc.document_type !== "SURFSENSE_DOCS")
.map((doc) => doc.id),
folder_ids: folders.map((f) => f.id), folder_ids: folders.map((f) => f.id),
}; };
}); });

View file

@ -47,10 +47,7 @@ export interface InlineMentionEditorRef {
setText: (text: string) => void; setText: (text: string) => void;
getText: () => string; getText: () => string;
getMentionedDocuments: () => MentionedDocument[]; getMentionedDocuments: () => MentionedDocument[];
insertMentionChip: ( insertMentionChip: (mention: MentionChipInput, options?: { removeTriggerText?: boolean }) => void;
mention: MentionChipInput,
options?: { removeTriggerText?: boolean }
) => void;
/** /**
* @deprecated Use ``insertMentionChip``. Kept for one transition * @deprecated Use ``insertMentionChip``. Kept for one transition
* cycle so we don't break ad-hoc callers; prefer the new name. * cycle so we don't break ad-hoc callers; prefer the new name.
@ -364,8 +361,7 @@ export const InlineMentionEditor = forwardRef<InlineMentionEditorRef, InlineMent
const selection = editor.selection; const selection = editor.selection;
const kind: MentionKind = mention.kind ?? "doc"; const kind: MentionKind = mention.kind ?? "doc";
const document_type = const document_type =
mention.document_type ?? mention.document_type ?? (kind === "folder" ? FOLDER_MENTION_DOCUMENT_TYPE : undefined);
(kind === "folder" ? FOLDER_MENTION_DOCUMENT_TYPE : undefined);
const mentionNode: MentionElementNode = { const mentionNode: MentionElementNode = {
type: MENTION_TYPE, type: MENTION_TYPE,
id: mention.id, id: mention.id,

View file

@ -33,8 +33,8 @@ import {
} from "@/components/ui/table"; } from "@/components/ui/table";
import { useElectronAPI } from "@/hooks/use-platform"; import { useElectronAPI } from "@/hooks/use-platform";
import { documentsApiService } from "@/lib/apis/documents-api.service"; import { documentsApiService } from "@/lib/apis/documents-api.service";
import { type CitationUrlMap, preprocessCitationMarkdown } from "@/lib/citations/citation-parser";
import { getVirtualPathDisplay } from "@/lib/chat/virtual-path-display"; import { getVirtualPathDisplay } from "@/lib/chat/virtual-path-display";
import { type CitationUrlMap, preprocessCitationMarkdown } from "@/lib/citations/citation-parser";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
function MarkdownCodeBlockSkeleton() { function MarkdownCodeBlockSkeleton() {
@ -222,11 +222,7 @@ function FilePathLink({ path, className }: { path: string; className?: string })
: undefined; : undefined;
const { displayName, isFolder } = getVirtualPathDisplay(path); const { displayName, isFolder } = getVirtualPathDisplay(path);
const icon = isFolder ? ( const icon = isFolder ? <FolderIcon className="size-3.5" /> : <FileIcon className="size-3.5" />;
<FolderIcon className="size-3.5" />
) : (
<FileIcon className="size-3.5" />
);
const handleClick = useCallback( const handleClick = useCallback(
(event: React.MouseEvent<HTMLButtonElement>) => { (event: React.MouseEvent<HTMLButtonElement>) => {

View file

@ -111,11 +111,7 @@ const UserTextPart: FC = () => {
icon={icon} icon={icon}
label={segment.doc.title} label={segment.doc.title}
tooltip={isFolder ? `Folder: ${segment.doc.title}` : segment.doc.title} tooltip={isFolder ? `Folder: ${segment.doc.title}` : segment.doc.title}
onClick={ onClick={isFolder ? undefined : () => handleOpenDoc(segment.doc.id, segment.doc.title)}
isFolder
? undefined
: () => handleOpenDoc(segment.doc.id, segment.doc.title)
}
className="mx-0.5" className="mx-0.5"
/> />
); );

View file

@ -170,16 +170,10 @@ export function PlateEditor({
: markdown : markdown
? (editor) => { ? (editor) => {
if (!enableCitations) { if (!enableCitations) {
return safeDeserializeMarkdown( return safeDeserializeMarkdown(editor, escapeMdxExpressions(markdown)) as Value;
editor,
escapeMdxExpressions(markdown)
) as Value;
} }
const { content: rewritten, urlMap } = preprocessCitationMarkdown(markdown); const { content: rewritten, urlMap } = preprocessCitationMarkdown(markdown);
const value = safeDeserializeMarkdown( const value = safeDeserializeMarkdown(editor, escapeMdxExpressions(rewritten));
editor,
escapeMdxExpressions(rewritten)
);
return injectCitationNodes(value, urlMap) as Value; return injectCitationNodes(value, urlMap) as Value;
} }
: undefined, : undefined,
@ -203,10 +197,7 @@ export function PlateEditor({
let newValue: Descendant[]; let newValue: Descendant[];
if (enableCitations) { if (enableCitations) {
const { content: rewritten, urlMap } = preprocessCitationMarkdown(markdown); const { content: rewritten, urlMap } = preprocessCitationMarkdown(markdown);
const deserialized = safeDeserializeMarkdown( const deserialized = safeDeserializeMarkdown(editor, escapeMdxExpressions(rewritten));
editor,
escapeMdxExpressions(rewritten)
);
newValue = injectCitationNodes(deserialized, urlMap); newValue = injectCitationNodes(deserialized, urlMap);
} else { } else {
newValue = safeDeserializeMarkdown(editor, escapeMdxExpressions(markdown)); newValue = safeDeserializeMarkdown(editor, escapeMdxExpressions(markdown));

View file

@ -49,10 +49,7 @@ export function safeDeserializeMarkdown(
return api.deserialize(markdown, { remarkPlugins: STRICT_PLUGINS }) as Descendant[]; return api.deserialize(markdown, { remarkPlugins: STRICT_PLUGINS }) as Descendant[];
} catch (mdxError) { } catch (mdxError) {
if (process.env.NODE_ENV !== "production") { if (process.env.NODE_ENV !== "production") {
console.warn( console.warn("[plate-editor] MDX parse failed, retrying without remark-mdx:", mdxError);
"[plate-editor] MDX parse failed, retrying without remark-mdx:",
mdxError
);
} }
try { try {
return api.deserialize(markdown, { remarkPlugins: LENIENT_PLUGINS }) as Descendant[]; return api.deserialize(markdown, { remarkPlugins: LENIENT_PLUGINS }) as Descendant[];

View file

@ -24,10 +24,7 @@ import type React from "react";
import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { toast } from "sonner"; import { toast } from "sonner";
import { agentFlagsAtom } from "@/atoms/agent/agent-flags-query.atom"; import { agentFlagsAtom } from "@/atoms/agent/agent-flags-query.atom";
import { import { makeFolderMention, mentionedDocumentsAtom } from "@/atoms/chat/mentioned-documents.atom";
makeFolderMention,
mentionedDocumentsAtom,
} from "@/atoms/chat/mentioned-documents.atom";
import { connectorDialogOpenAtom } from "@/atoms/connector-dialog/connector-dialog.atoms"; import { connectorDialogOpenAtom } from "@/atoms/connector-dialog/connector-dialog.atoms";
import { connectorsAtom } from "@/atoms/connectors/connector-query.atoms"; import { connectorsAtom } from "@/atoms/connectors/connector-query.atoms";
import { deleteDocumentMutationAtom } from "@/atoms/documents/document-mutation.atoms"; import { deleteDocumentMutationAtom } from "@/atoms/documents/document-mutation.atoms";

View file

@ -301,8 +301,7 @@ export const DocumentMentionPicker = forwardRef<
// folder entries lift the existing kind-aware key so the same // folder entries lift the existing kind-aware key so the same
// matchers used by the chip atom apply unchanged. // matchers used by the chip atom apply unchanged.
const selectedKeys = useMemo( const selectedKeys = useMemo(
() => () => new Set(initialSelectedDocuments.map((d) => getMentionDocKey(d))),
new Set(initialSelectedDocuments.map((d) => getMentionDocKey(d))),
[initialSelectedDocuments] [initialSelectedDocuments]
); );
@ -583,9 +582,7 @@ export const DocumentMentionPicker = forwardRef<
{(surfsenseDocsList.length > 0 || userDocsList.length > 0) && ( {(surfsenseDocsList.length > 0 || userDocsList.length > 0) && (
<div className="mx-2 my-4 border-t border-border dark:border-white/5" /> <div className="mx-2 my-4 border-t border-border dark:border-white/5" />
)} )}
<div className="px-3 py-2 text-xs font-bold text-muted-foreground/55"> <div className="px-3 py-2 text-xs font-bold text-muted-foreground/55">Folders</div>
Folders
</div>
{folderMentions.map((folder) => { {folderMentions.map((folder) => {
const folderKey = getMentionDocKey(folder); const folderKey = getMentionDocKey(folder);
const isAlreadySelected = selectedKeys.has(folderKey); const isAlreadySelected = selectedKeys.has(folderKey);

View file

@ -59,19 +59,15 @@ export default defineConfig({
? undefined ? undefined
: { : {
// Local stays on webpack dev (Turbopack caused stale-lock panics in E2E). // Local stays on webpack dev (Turbopack caused stale-lock panics in E2E).
command: process.env.CI command: process.env.CI ? "pnpm build && pnpm start" : "pnpm exec next dev",
? "pnpm build && pnpm start"
: "pnpm exec next dev",
url: `http://localhost:${PORT}`, url: `http://localhost:${PORT}`,
reuseExistingServer: !process.env.CI, reuseExistingServer: !process.env.CI,
timeout: process.env.CI ? 300_000 : 180_000, timeout: process.env.CI ? 300_000 : 180_000,
stdout: "pipe", stdout: "pipe",
stderr: "pipe", stderr: "pipe",
env: { env: {
NEXT_PUBLIC_FASTAPI_BACKEND_URL: NEXT_PUBLIC_FASTAPI_BACKEND_URL: process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL,
process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL, NEXT_PUBLIC_FASTAPI_BACKEND_AUTH_TYPE: process.env.NEXT_PUBLIC_FASTAPI_BACKEND_AUTH_TYPE,
NEXT_PUBLIC_FASTAPI_BACKEND_AUTH_TYPE:
process.env.NEXT_PUBLIC_FASTAPI_BACKEND_AUTH_TYPE,
}, },
}, },
}); });

View file

@ -13,8 +13,7 @@ export const BACKEND_URL = process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL || "http:
const TEST_USER_EMAIL = process.env.PLAYWRIGHT_TEST_EMAIL || "e2e-test@surfsense.net"; const TEST_USER_EMAIL = process.env.PLAYWRIGHT_TEST_EMAIL || "e2e-test@surfsense.net";
const TEST_USER_PASSWORD = process.env.PLAYWRIGHT_TEST_PASSWORD || "E2eTestPassword123!"; const TEST_USER_PASSWORD = process.env.PLAYWRIGHT_TEST_PASSWORD || "E2eTestPassword123!";
const E2E_MINT_SECRET = const E2E_MINT_SECRET = process.env.E2E_MINT_SECRET || "local-e2e-mint-secret-not-for-production";
process.env.E2E_MINT_SECRET || "local-e2e-mint-secret-not-for-production";
/** /**
* Mints a JWT for the seeded e2e user via the test-only endpoint mounted * Mints a JWT for the seeded e2e user via the test-only endpoint mounted