diff --git a/.claude/worktrees/agent-a09c3d7c b/.claude/worktrees/agent-a09c3d7c new file mode 160000 index 0000000..a1e75e6 --- /dev/null +++ b/.claude/worktrees/agent-a09c3d7c @@ -0,0 +1 @@ +Subproject commit a1e75e6b76f9ada4369d969c397d6c5aed6255f6 diff --git a/.claude/worktrees/agent-a327b0c2 b/.claude/worktrees/agent-a327b0c2 new file mode 160000 index 0000000..b61747f --- /dev/null +++ b/.claude/worktrees/agent-a327b0c2 @@ -0,0 +1 @@ +Subproject commit b61747fb164909e9d8d79955685eb4d130f9dbe9 diff --git a/.claude/worktrees/agent-a462be71/.claude/worktrees/agent-a5e65331 b/.claude/worktrees/agent-a462be71/.claude/worktrees/agent-a5e65331 new file mode 160000 index 0000000..061b963 --- /dev/null +++ b/.claude/worktrees/agent-a462be71/.claude/worktrees/agent-a5e65331 @@ -0,0 +1 @@ +Subproject commit 061b96336a0a1971e82737d42b3278a38eb576c6 diff --git a/.claude/worktrees/agent-a51ac752 b/.claude/worktrees/agent-a51ac752 new file mode 160000 index 0000000..13c9a44 --- /dev/null +++ b/.claude/worktrees/agent-a51ac752 @@ -0,0 +1 @@ +Subproject commit 13c9a44967435ac4e4dd08680597602c127b2985 diff --git a/.claude/worktrees/agent-a662428a b/.claude/worktrees/agent-a662428a new file mode 160000 index 0000000..edf3802 --- /dev/null +++ b/.claude/worktrees/agent-a662428a @@ -0,0 +1 @@ +Subproject commit edf380273e98942deeec978d9e773e73ec96a02c diff --git a/.claude/worktrees/agent-a802499a b/.claude/worktrees/agent-a802499a new file mode 160000 index 0000000..3f27bbf --- /dev/null +++ b/.claude/worktrees/agent-a802499a @@ -0,0 +1 @@ +Subproject commit 3f27bbf38eaad7bb9d9a0f7191abc62e7b8ce685 diff --git a/.claude/worktrees/agent-a886725f b/.claude/worktrees/agent-a886725f new file mode 160000 index 0000000..bf6e1be --- /dev/null +++ b/.claude/worktrees/agent-a886725f @@ -0,0 +1 @@ +Subproject commit bf6e1bebc6d6d30bb553cfdb98801488efae56bf diff --git a/.claude/worktrees/agent-a8d7741c b/.claude/worktrees/agent-a8d7741c new file mode 160000 index 0000000..7f4c339 --- /dev/null +++ b/.claude/worktrees/agent-a8d7741c @@ -0,0 +1 @@ +Subproject commit 7f4c33968fcc94268e1281b0b23335abc5c2ea85 diff --git a/.claude/worktrees/agent-a8f0cb8d b/.claude/worktrees/agent-a8f0cb8d new file mode 160000 index 0000000..49f9da1 --- /dev/null +++ b/.claude/worktrees/agent-a8f0cb8d @@ -0,0 +1 @@ +Subproject commit 49f9da196c3650575eba0f1ab93aac8efe327137 diff --git a/.claude/worktrees/agent-ab455ec1 b/.claude/worktrees/agent-ab455ec1 new file mode 160000 index 0000000..5f35206 --- /dev/null +++ b/.claude/worktrees/agent-ab455ec1 @@ -0,0 +1 @@ +Subproject commit 5f3520658d949372276bf27be0aa8b2ff0d9193c diff --git a/.claude/worktrees/agent-abffe11f b/.claude/worktrees/agent-abffe11f new file mode 160000 index 0000000..bf6e1be --- /dev/null +++ b/.claude/worktrees/agent-abffe11f @@ -0,0 +1 @@ +Subproject commit bf6e1bebc6d6d30bb553cfdb98801488efae56bf diff --git a/.claude/worktrees/agent-aca555c0 b/.claude/worktrees/agent-aca555c0 new file mode 160000 index 0000000..f8ae7c2 --- /dev/null +++ b/.claude/worktrees/agent-aca555c0 @@ -0,0 +1 @@ +Subproject commit f8ae7c2badfc4b27660afcc3dec28a23c0b723cf diff --git a/.claude/worktrees/agent-af29ee1c b/.claude/worktrees/agent-af29ee1c new file mode 160000 index 0000000..015b533 --- /dev/null +++ b/.claude/worktrees/agent-af29ee1c @@ -0,0 +1 @@ +Subproject commit 015b533d3e65b8e3e7ca866c3265b0627dca0ca6 diff --git a/.claude/worktrees/agent-af8e138d b/.claude/worktrees/agent-af8e138d new file mode 160000 index 0000000..bf6e1be --- /dev/null +++ b/.claude/worktrees/agent-af8e138d @@ -0,0 +1 @@ +Subproject commit bf6e1bebc6d6d30bb553cfdb98801488efae56bf diff --git a/.claude/worktrees/feat-integration-tests b/.claude/worktrees/feat-integration-tests new file mode 160000 index 0000000..3c5364e --- /dev/null +++ b/.claude/worktrees/feat-integration-tests @@ -0,0 +1 @@ +Subproject commit 3c5364e49e2a7071eb68167c72efa8b0e0b058d4 diff --git a/.claude/worktrees/feat-provider-tests b/.claude/worktrees/feat-provider-tests new file mode 160000 index 0000000..35faeb1 --- /dev/null +++ b/.claude/worktrees/feat-provider-tests @@ -0,0 +1 @@ +Subproject commit 35faeb1247ab25ce9914e1ef2041ceeeb69f0d19 diff --git a/.claude/worktrees/feat-spider b/.claude/worktrees/feat-spider new file mode 160000 index 0000000..71b1cab --- /dev/null +++ b/.claude/worktrees/feat-spider @@ -0,0 +1 @@ +Subproject commit 71b1cab873f737d746a0bfd9d5d2bc6d57d86cc1 diff --git a/.claude/worktrees/fix-error-handling b/.claude/worktrees/fix-error-handling new file mode 160000 index 0000000..f1c1b19 --- /dev/null +++ b/.claude/worktrees/fix-error-handling @@ -0,0 +1 @@ +Subproject commit f1c1b19de378ca5382785485cbd522c4ccb14500 diff --git a/.claude/worktrees/fix-performance b/.claude/worktrees/fix-performance new file mode 160000 index 0000000..9a33416 --- /dev/null +++ b/.claude/worktrees/fix-performance @@ -0,0 +1 @@ +Subproject commit 9a33416de914953a21ef7725666c016fc309a9e5 diff --git a/.claude/worktrees/fix-quick-wins b/.claude/worktrees/fix-quick-wins new file mode 160000 index 0000000..9ac1262 --- /dev/null +++ b/.claude/worktrees/fix-quick-wins @@ -0,0 +1 @@ +Subproject commit 9ac1262e9914f1e365152919a40735f515bfccd9 diff --git a/.claude/worktrees/fix-security b/.claude/worktrees/fix-security new file mode 160000 index 0000000..cc2df04 --- /dev/null +++ b/.claude/worktrees/fix-security @@ -0,0 +1 @@ +Subproject commit cc2df047a397c2ce9fff2a4b15431a035c01b0aa diff --git a/.claude/worktrees/fix-type-safety b/.claude/worktrees/fix-type-safety new file mode 160000 index 0000000..26f2c4b --- /dev/null +++ b/.claude/worktrees/fix-type-safety @@ -0,0 +1 @@ +Subproject commit 26f2c4b36b77cb9b6541434f6cdfe44d84512fa9 diff --git a/.claude/worktrees/issue-330-cli-logging-pack-perf b/.claude/worktrees/issue-330-cli-logging-pack-perf new file mode 160000 index 0000000..d5dae05 --- /dev/null +++ b/.claude/worktrees/issue-330-cli-logging-pack-perf @@ -0,0 +1 @@ +Subproject commit d5dae051782aa368b9c9ddfefd6771598e6ba349 diff --git a/.claude/worktrees/passthrough-mode b/.claude/worktrees/passthrough-mode new file mode 160000 index 0000000..b3f6965 --- /dev/null +++ b/.claude/worktrees/passthrough-mode @@ -0,0 +1 @@ +Subproject commit b3f6965499448eaf098d87ed1bd74077106aedfd diff --git a/.claude/worktrees/refactor-cli-decompose b/.claude/worktrees/refactor-cli-decompose new file mode 160000 index 0000000..bb0b1e3 --- /dev/null +++ b/.claude/worktrees/refactor-cli-decompose @@ -0,0 +1 @@ +Subproject commit bb0b1e3b899de34dc642b88fc3d1f7645a671047 diff --git a/.claude/worktrees/refactor-mcp-decompose b/.claude/worktrees/refactor-mcp-decompose new file mode 160000 index 0000000..9892601 --- /dev/null +++ b/.claude/worktrees/refactor-mcp-decompose @@ -0,0 +1 @@ +Subproject commit 98926016be2d607a9ce1c545f6d50e494fa42236 diff --git a/src/cli/index.ts b/src/cli/index.ts index 58031c0..ef71e9f 100644 --- a/src/cli/index.ts +++ b/src/cli/index.ts @@ -69,15 +69,16 @@ import { syncOneNote, disconnectOneNote, } from "../connectors/onenote.js"; -import { loadConnectorConfig, saveConnectorConfig } from "../connectors/index.js"; -import { syncNotion, disconnectNotion } from "../connectors/notion.js"; -import type { NotionConfig } from "../connectors/notion.js"; -import { syncSlack, disconnectSlack, type SlackConfig } from "../connectors/slack.js"; import { + loadConnectorConfig, + saveConnectorConfig, saveNamedConnectorConfig, loadNamedConnectorConfig, hasNamedConnectorConfig, } from "../connectors/index.js"; +import { syncNotion, disconnectNotion } from "../connectors/notion.js"; +import type { NotionConfig } from "../connectors/notion.js"; +import { syncSlack, disconnectSlack, type SlackConfig } from "../connectors/slack.js"; import { createSavedSearch, listSavedSearches, diff --git a/src/core/dedup.ts b/src/core/dedup.ts index 0166353..a2653de 100644 --- a/src/core/dedup.ts +++ b/src/core/dedup.ts @@ -77,7 +77,7 @@ export async function checkDuplicate( if (row) { log.debug({ existingDocId: row.id }, "Exact duplicate detected via content hash"); - return { isDuplicate: true, matchType: "exact", existingDocId: row.id, similarity: 1.0 }; + return { isDuplicate: true, matchType: "exact", existingDocId: row.id, similarity: 1 }; } } diff --git a/src/core/indexing.ts b/src/core/indexing.ts index 07c08b3..72bb485 100644 --- a/src/core/indexing.ts +++ b/src/core/indexing.ts @@ -59,7 +59,7 @@ function startChunkAtHeading( line: string, ): { lines: string[]; length: number } { const level = (headingMatch[1] ?? "").length; - while (headingStack.length > 0 && (headingStack[headingStack.length - 1]?.level ?? 0) >= level) { + while (headingStack.length > 0 && (headingStack.at(-1)?.level ?? 0) >= level) { headingStack.pop(); } const breadcrumb = headingStack.map((h) => h.text).join(" > "); diff --git a/src/core/parsers/csv.ts b/src/core/parsers/csv.ts index c974250..9fd8bd5 100644 --- a/src/core/parsers/csv.ts +++ b/src/core/parsers/csv.ts @@ -22,8 +22,10 @@ export class CsvParser implements DocumentParser { cell.replace(/\\/g, "\\\\").replace(/\|/g, "\\|").replace(/\n/g, " "); const lines: string[] = []; - lines.push("| " + header.map(escapeCell).join(" | ") + " |"); - lines.push("| " + header.map(() => "---").join(" | ") + " |"); + lines.push( + "| " + header.map(escapeCell).join(" | ") + " |", + "| " + header.map(() => "---").join(" | ") + " |", + ); for (const row of rows) { // Normalize row length to match header const normalized = Array.from({ length: colCount }, (_, i) => row[i] ?? ""); diff --git a/src/core/search.ts b/src/core/search.ts index 254d430..293d965 100644 --- a/src/core/search.ts +++ b/src/core/search.ts @@ -718,8 +718,7 @@ function keywordSearch( const baseParams = [...params]; sql += " LIMIT ? OFFSET ?"; - params.push(limit); - params.push(offset); + params.push(limit, offset); const KeywordRowSchema = z.object({ chunk_id: z.string(), @@ -1086,8 +1085,7 @@ function fts5Search( let baseParams = [...params]; sql += " ORDER BY rank LIMIT ? OFFSET ?"; - params.push(limit); - params.push(offset); + params.push(limit, offset); const Fts5RowSchema = z.object({ chunk_id: z.string(), @@ -1140,8 +1138,7 @@ function fts5Search( baseParams = [...orParams]; orSql += " ORDER BY rank LIMIT ? OFFSET ?"; - orParams.push(limit); - orParams.push(offset); + orParams.push(limit, offset); rows = validateRows(Fts5RowSchema, db.prepare(orSql).all(...orParams), "fts5Search.orRows"); } diff --git a/src/core/tags.ts b/src/core/tags.ts index 1dc38e1..2f85b69 100644 --- a/src/core/tags.ts +++ b/src/core/tags.ts @@ -462,7 +462,7 @@ export function suggestTags( for (const [term, count] of tf) { if (existingTags.has(term)) continue; const normalizedTf = count / maxTf; - const knownBoost = knownTags.has(term) ? 2.0 : 1.0; + const knownBoost = knownTags.has(term) ? 2 : 1; scored.push({ term, score: normalizedTf * knownBoost }); } diff --git a/tests/unit/batch-search.test.ts b/tests/unit/batch-search.test.ts index 023a5e0..b887d80 100644 --- a/tests/unit/batch-search.test.ts +++ b/tests/unit/batch-search.test.ts @@ -2,8 +2,7 @@ import { describe, it, expect, beforeEach, afterEach } from "vitest"; import type Database from "better-sqlite3"; import { createTestDbWithVec } from "../fixtures/test-db.js"; import { MockEmbeddingProvider } from "../fixtures/mock-provider.js"; -import { seedTestDocument } from "../fixtures/helpers.js"; -import { insertChunk } from "../fixtures/helpers.js"; +import { seedTestDocument, insertChunk } from "../fixtures/helpers.js"; import { searchBatch, BATCH_SEARCH_MAX_REQUESTS, diff --git a/tests/unit/dedup.test.ts b/tests/unit/dedup.test.ts index 31d1ab8..56e7b30 100644 --- a/tests/unit/dedup.test.ts +++ b/tests/unit/dedup.test.ts @@ -43,7 +43,7 @@ describe("dedup", () => { expect(result.isDuplicate).toBe(true); expect(result.matchType).toBe("exact"); - expect(result.similarity).toBe(1.0); + expect(result.similarity).toBe(1); expect(result.existingDocId).toBeDefined(); }); diff --git a/tests/unit/obsidian.test.ts b/tests/unit/obsidian.test.ts index 42af44a..4787d18 100644 --- a/tests/unit/obsidian.test.ts +++ b/tests/unit/obsidian.test.ts @@ -1,5 +1,9 @@ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"; -import { parseObsidianMarkdown } from "../../src/connectors/obsidian.js"; +import { + parseObsidianMarkdown, + syncObsidianVault, + disconnectVault, +} from "../../src/connectors/obsidian.js"; import { createTestDb, createTestDbWithVec } from "../fixtures/test-db.js"; import { MockEmbeddingProvider } from "../fixtures/mock-provider.js"; import type Database from "better-sqlite3"; @@ -29,7 +33,6 @@ vi.mock("node:fs/promises", async (importOriginal) => { }); import { readdirSync, readFileSync, statSync, existsSync, writeFileSync } from "node:fs"; -import { syncObsidianVault, disconnectVault } from "../../src/connectors/obsidian.js"; import { initLogger } from "../../src/logger.js"; const mockedReaddirSync = vi.mocked(readdirSync);