@bojackduy/opencode-telescope 0.1.29 → 0.1.32
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/package.json +1 -1
- package/search/queries.ts +28 -7
- package/telescope.tsx +6 -3
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "@bojackduy/opencode-telescope",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.32",
|
|
5
5
|
"description": "OpenCode TUI plugin for fuzzy and semantic search across local conversation history, session transcripts, and AI coding chats",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"license": "MIT",
|
package/search/queries.ts
CHANGED
|
@@ -58,10 +58,14 @@ export function recentSessionMessages(options?: { limit?: number; offset?: numbe
|
|
|
58
58
|
const db = getDb(dbPath)
|
|
59
59
|
const limit = options?.limit ?? 40
|
|
60
60
|
const indexed = dbPath === ":memory:" ? undefined : indexedRecentRows(db, dbPath, limit, options?.directory, options?.offset, options?.role)
|
|
61
|
-
if (indexed) return indexed.flatMap((row) => rowToSearchResult(row, "") ?? [])
|
|
61
|
+
if (indexed && !indexed.stale && indexed.rows.length > 0) return indexed.rows.flatMap((row) => rowToSearchResult(row, "") ?? [])
|
|
62
|
+
|
|
62
63
|
if (dbPath !== ":memory:") scheduleBackgroundIndexRebuild(dbPath)
|
|
63
|
-
debug.log("query:recent:index-pending", { limit, offset: options?.offset ?? 0, directory: options?.directory, role: options?.role })
|
|
64
|
-
|
|
64
|
+
if (!indexed) debug.log("query:recent:index-pending", { limit, offset: options?.offset ?? 0, directory: options?.directory, role: options?.role })
|
|
65
|
+
|
|
66
|
+
const sourceRows = sourceRecentRows(db, limit, options?.directory, options?.offset, options?.role)
|
|
67
|
+
if (sourceRows) return sourceRows.flatMap((row) => rowToSearchResult(row, "") ?? [])
|
|
68
|
+
return indexed?.rows.flatMap((row) => rowToSearchResult(row, "") ?? []) ?? []
|
|
65
69
|
}
|
|
66
70
|
|
|
67
71
|
export function loadConversationAround(result: SearchResult, options?: { before?: number; after?: number; dbPath?: string }): ConversationPreviewPage {
|
|
@@ -378,7 +382,12 @@ function indexedTextRows(db: Database, dbPath: string, limit: number, query: str
|
|
|
378
382
|
}
|
|
379
383
|
}
|
|
380
384
|
|
|
381
|
-
|
|
385
|
+
type IndexedRecentRows = {
|
|
386
|
+
rows: Row[]
|
|
387
|
+
stale: boolean
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
function indexedRecentRows(db: Database, dbPath: string, limit: number, directory?: string, offset?: number, role?: SearchRole): IndexedRecentRows | undefined {
|
|
382
391
|
try {
|
|
383
392
|
const index = ensureSearchIndex(db, dbPath, { rebuild: false, useStale: true })
|
|
384
393
|
if (!index) {
|
|
@@ -389,7 +398,7 @@ function indexedRecentRows(db: Database, dbPath: string, limit: number, director
|
|
|
389
398
|
const rowCount = index.query<{ count: number }, []>("SELECT COUNT(*) as count FROM document_index").get()?.count ?? 0
|
|
390
399
|
if (rowCount === 0) {
|
|
391
400
|
debug.log("query:recent:index:empty", { dbPath })
|
|
392
|
-
return
|
|
401
|
+
return { rows: [], stale: true }
|
|
393
402
|
}
|
|
394
403
|
|
|
395
404
|
const state = sourceState(db, dbPath)
|
|
@@ -397,7 +406,8 @@ function indexedRecentRows(db: Database, dbPath: string, limit: number, director
|
|
|
397
406
|
const currentMtimeMs = getMeta(index, "source_mtime_ms")
|
|
398
407
|
const currentPath = getMeta(index, "source_path")
|
|
399
408
|
const currentIndexVersion = getMeta(index, "index_version")
|
|
400
|
-
|
|
409
|
+
const stale = currentPath !== dbPath || currentDataVersion !== String(state.dataVersion) || currentMtimeMs !== String(state.mtimeMs) || currentIndexVersion !== SEARCH_INDEX_VERSION
|
|
410
|
+
if (stale) {
|
|
401
411
|
debug.log("query:recent:index:stale", {
|
|
402
412
|
dbPath,
|
|
403
413
|
expectedDataVersion: state.dataVersion,
|
|
@@ -431,13 +441,24 @@ function indexedRecentRows(db: Database, dbPath: string, limit: number, director
|
|
|
431
441
|
LIMIT ? ${offsetClause}
|
|
432
442
|
`).all(...params as any[])
|
|
433
443
|
debug.timeEnd("query:recent:index:exec")
|
|
434
|
-
return rows
|
|
444
|
+
return { rows, stale }
|
|
435
445
|
} catch (err) {
|
|
436
446
|
debug.log("recent:index:fallback", err instanceof Error ? err.message : String(err))
|
|
437
447
|
return
|
|
438
448
|
}
|
|
439
449
|
}
|
|
440
450
|
|
|
451
|
+
function sourceRecentRows(db: Database, limit: number, directory?: string, offset?: number, role?: SearchRole) {
|
|
452
|
+
try {
|
|
453
|
+
if (!tableExists(db, "part") || !tableExists(db, "message") || !tableExists(db, "session")) return []
|
|
454
|
+
debug.log("query:recent:source-fallback", { limit, offset: offset ?? 0, directory, role })
|
|
455
|
+
return visibleTextRows(db, limit, undefined, directory, offset, role)
|
|
456
|
+
} catch (err) {
|
|
457
|
+
debug.log("query:recent:source-fallback:error", err instanceof Error ? err.message : String(err))
|
|
458
|
+
return
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
|
|
441
462
|
function visibleTextRows(db: Database, limit: number, query?: string, directory?: string, offset?: number, role?: SearchRole) {
|
|
442
463
|
const offsetClause = offset ? "OFFSET ?" : ""
|
|
443
464
|
const conditions: string[] = [
|
package/telescope.tsx
CHANGED
|
@@ -98,7 +98,7 @@ export const Telescope = (props: { api: TuiPluginApi; config: TelescopeConfig; o
|
|
|
98
98
|
let resultPreviousTimer: ReturnType<typeof setTimeout> | undefined
|
|
99
99
|
let searchTimer: ReturnType<typeof setTimeout> | undefined
|
|
100
100
|
let searchWatchdogTimer: ReturnType<typeof setTimeout> | undefined
|
|
101
|
-
let
|
|
101
|
+
let lastFiredSearchKey = ""
|
|
102
102
|
let searchRequestId = 0
|
|
103
103
|
let fallbackSearchRequestId: number | undefined
|
|
104
104
|
let searchWorker: Worker | undefined
|
|
@@ -309,8 +309,11 @@ export const Telescope = (props: { api: TuiPluginApi; config: TelescopeConfig; o
|
|
|
309
309
|
return config.disableVector ? "keyword" as const : "hybrid" as const
|
|
310
310
|
}
|
|
311
311
|
|
|
312
|
+
const searchKey = (q: string, role: SearchRole | undefined, db: string, dir: string) =>
|
|
313
|
+
JSON.stringify([q, role ?? null, db, dir])
|
|
314
|
+
|
|
312
315
|
const executeSearch = (q: string, role: SearchRole | undefined, db: string, dir: string) => {
|
|
313
|
-
|
|
316
|
+
lastFiredSearchKey = searchKey(q, role, db, dir)
|
|
314
317
|
const limit = q ? Math.min(searchBatchSize(), 80) : recentBatchSize()
|
|
315
318
|
setError("")
|
|
316
319
|
setHasMore(true)
|
|
@@ -350,7 +353,7 @@ export const Telescope = (props: { api: TuiPluginApi; config: TelescopeConfig; o
|
|
|
350
353
|
|
|
351
354
|
const scheduleSearch = (q: string, role: SearchRole | undefined, db: string, dir: string) => {
|
|
352
355
|
if (searchTimer) clearTimeout(searchTimer)
|
|
353
|
-
if (q
|
|
356
|
+
if (searchKey(q, role, db, dir) === lastFiredSearchKey) return
|
|
354
357
|
searchTimer = setTimeout(() => {
|
|
355
358
|
searchTimer = undefined
|
|
356
359
|
executeSearch(q, role, db, dir)
|