mirror of
https://github.com/logancyang/obsidian-copilot.git
synced 2026-07-22 07:50:24 +00:00
chore(eslint): enable obsidianmd/prefer-active-doc (#2411)
Flip the rule from "off" to "error" to catch accidental references to the global `document` (which always points at the main window even when the user is interacting with a popout). The only flagged site was a `document` field on the `RelevantNoteEntry` type — not a DOM reference, but the rule pattern-matches the identifier. Rename it to `note` so `entry.note.path/title` reads naturally next to `entry.metadata.*`, and remove the suppression. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
99b3b1e22a
commit
48794ce097
4 changed files with 32 additions and 32 deletions
|
|
@ -74,7 +74,7 @@ export default [
|
|||
|
||||
// obsidianmd: defer to follow-up PRs
|
||||
"obsidianmd/vault/iterate": "error",
|
||||
"obsidianmd/prefer-active-doc": "off",
|
||||
"obsidianmd/prefer-active-doc": "error",
|
||||
"obsidianmd/object-assign": "off",
|
||||
"obsidianmd/ui/sentence-case": "off",
|
||||
"obsidianmd/no-unsupported-api": "off",
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ function RelevantNote({
|
|||
|
||||
const loadContent = useCallback(async () => {
|
||||
if (fileContent) return; // Don't load if we already have content
|
||||
const file = app.vault.getAbstractFileByPath(note.document.path);
|
||||
const file = app.vault.getAbstractFileByPath(note.note.path);
|
||||
if (file instanceof TFile) {
|
||||
const content = await app.vault.cachedRead(file);
|
||||
|
||||
|
|
@ -128,7 +128,7 @@ function RelevantNote({
|
|||
// Take first 1000 characters as preview
|
||||
setFileContent(cleanContent.slice(0, 1000) + (cleanContent.length > 1000 ? "..." : ""));
|
||||
}
|
||||
}, [fileContent, note.document.path]);
|
||||
}, [fileContent, note.note.path]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isOpen) {
|
||||
|
|
@ -161,7 +161,7 @@ function RelevantNote({
|
|||
<a
|
||||
draggable
|
||||
onDragStart={(e) => {
|
||||
const file = app.vault.getAbstractFileByPath(note.document.path);
|
||||
const file = app.vault.getAbstractFileByPath(note.note.path);
|
||||
if (file instanceof TFile) {
|
||||
handleDragStart(e, file);
|
||||
}
|
||||
|
|
@ -179,9 +179,9 @@ function RelevantNote({
|
|||
}
|
||||
}}
|
||||
className="tw-block tw-w-full tw-truncate tw-text-sm tw-font-bold tw-text-normal"
|
||||
title={`${note.document.title} - drag to insert wikilink`}
|
||||
title={`${note.note.title} - drag to insert wikilink`}
|
||||
>
|
||||
{note.document.title}
|
||||
{note.note.title}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
|
@ -198,7 +198,7 @@ function RelevantNote({
|
|||
<CollapsibleContent>
|
||||
<div className="tw-border-[0px] tw-border-t tw-border-solid tw-border-border tw-px-4 tw-py-2">
|
||||
<div className="tw-whitespace-pre-wrap tw-text-wrap tw-break-all tw-text-xs tw-text-muted tw-opacity-75">
|
||||
{note.document.path}
|
||||
{note.note.path}
|
||||
</div>
|
||||
{fileContent && (
|
||||
<div className="tw-overflow-hidden tw-whitespace-pre-wrap tw-border-t tw-border-border tw-pb-4 tw-pt-2 tw-text-xs tw-text-normal">
|
||||
|
|
@ -243,11 +243,11 @@ function RelevantNotePopover({
|
|||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<Popover key={note.document.path}>
|
||||
<Popover key={note.note.path}>
|
||||
<PopoverTrigger asChild>{children}</PopoverTrigger>
|
||||
<PopoverContent className="tw-flex tw-w-fit tw-min-w-72 tw-max-w-96 tw-flex-col tw-gap-2 tw-overflow-hidden">
|
||||
<span className="tw-text-sm tw-text-normal">{note.document.title}</span>
|
||||
<span className="tw-text-xs tw-text-muted">{note.document.path}</span>
|
||||
<span className="tw-text-sm tw-text-normal">{note.note.title}</span>
|
||||
<span className="tw-text-xs tw-text-muted">{note.note.path}</span>
|
||||
<div className="tw-flex tw-gap-2">
|
||||
<button
|
||||
onClick={onAddToChat}
|
||||
|
|
@ -380,27 +380,27 @@ export const RelevantNotes = memo(
|
|||
<div className="tw-flex tw-max-h-6 tw-flex-wrap tw-gap-x-2 tw-gap-y-1 tw-overflow-y-hidden tw-px-1">
|
||||
{relevantNotes.map((note) => (
|
||||
<RelevantNotePopover
|
||||
key={note.document.path}
|
||||
key={note.note.path}
|
||||
note={note}
|
||||
onAddToChat={() => addToChat(note.document.title)}
|
||||
onAddToChat={() => addToChat(note.note.title)}
|
||||
onNavigateToNote={(openInNewLeaf: boolean) =>
|
||||
navigateToNote(note.document.path, openInNewLeaf)
|
||||
navigateToNote(note.note.path, openInNewLeaf)
|
||||
}
|
||||
>
|
||||
<Badge
|
||||
variant="outline"
|
||||
key={note.document.path}
|
||||
key={note.note.path}
|
||||
draggable
|
||||
onDragStart={(e) => {
|
||||
const file = app.vault.getAbstractFileByPath(note.document.path);
|
||||
const file = app.vault.getAbstractFileByPath(note.note.path);
|
||||
if (file instanceof TFile) {
|
||||
handleDragStart(e, file);
|
||||
}
|
||||
}}
|
||||
className="tw-max-w-40 tw-text-xs tw-text-muted hover:tw-cursor-pointer hover:tw-bg-interactive-hover"
|
||||
title={`${note.document.title} - drag to insert wikilink`}
|
||||
title={`${note.note.title} - drag to insert wikilink`}
|
||||
>
|
||||
<span className="tw-truncate">{note.document.title}</span>
|
||||
<span className="tw-truncate">{note.note.title}</span>
|
||||
</Badge>
|
||||
</RelevantNotePopover>
|
||||
))}
|
||||
|
|
@ -411,10 +411,10 @@ export const RelevantNotes = memo(
|
|||
{relevantNotes.map((note) => (
|
||||
<RelevantNote
|
||||
note={note}
|
||||
key={note.document.path}
|
||||
onAddToChat={() => addToChat(note.document.title)}
|
||||
key={note.note.path}
|
||||
onAddToChat={() => addToChat(note.note.title)}
|
||||
onNavigateToNote={(openInNewLeaf: boolean) =>
|
||||
navigateToNote(note.document.path, openInNewLeaf)
|
||||
navigateToNote(note.note.path, openInNewLeaf)
|
||||
}
|
||||
/>
|
||||
))}
|
||||
|
|
|
|||
|
|
@ -177,14 +177,14 @@ describe("findRelevantNotes", () => {
|
|||
|
||||
const result = await findRelevantNotes({ filePath: "source.md" });
|
||||
|
||||
expect(result.map((entry) => entry.document.path)).toEqual([
|
||||
expect(result.map((entry) => entry.note.path)).toEqual([
|
||||
"second.md",
|
||||
"first.md",
|
||||
"linked-only.md",
|
||||
]);
|
||||
expect(
|
||||
result.find((entry) => entry.document.path === "second.md")?.metadata.similarityScore
|
||||
).toBe(0.82);
|
||||
expect(result.find((entry) => entry.note.path === "second.md")?.metadata.similarityScore).toBe(
|
||||
0.82
|
||||
);
|
||||
expect(mockGetDb).toHaveBeenCalledTimes(1);
|
||||
expect(mockGetDocsByEmbedding).toHaveBeenCalledTimes(2);
|
||||
expect(mockSearchRelated).not.toHaveBeenCalled();
|
||||
|
|
@ -224,10 +224,10 @@ describe("findRelevantNotes", () => {
|
|||
|
||||
const result = await findRelevantNotes({ filePath: "source.md" });
|
||||
|
||||
expect(result.map((entry) => entry.document.path)).toEqual(["beta.md", "alpha.md"]);
|
||||
expect(
|
||||
result.find((entry) => entry.document.path === "alpha.md")?.metadata.similarityScore
|
||||
).toBe(0.6);
|
||||
expect(result.map((entry) => entry.note.path)).toEqual(["beta.md", "alpha.md"]);
|
||||
expect(result.find((entry) => entry.note.path === "alpha.md")?.metadata.similarityScore).toBe(
|
||||
0.6
|
||||
);
|
||||
expect(mockGetDb).not.toHaveBeenCalled();
|
||||
expect(mockGetDocumentsByPath).not.toHaveBeenCalled();
|
||||
expect(mockSearchRelated).toHaveBeenCalledTimes(1);
|
||||
|
|
@ -259,7 +259,7 @@ describe("findRelevantNotes", () => {
|
|||
|
||||
const result = await findRelevantNotes({ filePath: "source.md" });
|
||||
|
||||
expect(result.map((e) => e.document.path)).toEqual(["alpha.md"]);
|
||||
expect(result.map((e) => e.note.path)).toEqual(["alpha.md"]);
|
||||
expect(result[0].metadata.similarityScore).toBe(0.75);
|
||||
// Orama path not taken (no embeddings); Miyo called as fallback
|
||||
expect(mockGetDocsByEmbedding).not.toHaveBeenCalled();
|
||||
|
|
@ -289,7 +289,7 @@ describe("findRelevantNotes", () => {
|
|||
const result = await findRelevantNotes({ filePath: "source.md" });
|
||||
|
||||
expect(result).toHaveLength(1);
|
||||
expect(result[0].document.path).toBe("linked-only.md");
|
||||
expect(result[0].note.path).toBe("linked-only.md");
|
||||
expect(result[0].metadata.similarityScore).toBeUndefined();
|
||||
expect(result[0].metadata.hasOutgoingLinks).toBe(true);
|
||||
expect(mockGetDocumentsByPath).not.toHaveBeenCalled();
|
||||
|
|
|
|||
|
|
@ -276,7 +276,7 @@ function mergeScoreMaps(
|
|||
}
|
||||
|
||||
export type RelevantNoteEntry = {
|
||||
document: {
|
||||
note: {
|
||||
path: string;
|
||||
title: string;
|
||||
};
|
||||
|
|
@ -327,7 +327,7 @@ export async function findRelevantNotes({
|
|||
return null;
|
||||
}
|
||||
return {
|
||||
document: {
|
||||
note: {
|
||||
path,
|
||||
title: file.basename,
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in a new issue