@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 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.29",
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
- return []
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
- function indexedRecentRows(db: Database, dbPath: string, limit: number, directory?: string, offset?: number, role?: SearchRole) {
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
- if (currentPath !== dbPath || currentDataVersion !== String(state.dataVersion) || currentMtimeMs !== String(state.mtimeMs) || currentIndexVersion !== SEARCH_INDEX_VERSION) {
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 lastFiredQuery = ""
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
- lastFiredQuery = q
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 === lastFiredQuery && results().length > 0) return
356
+ if (searchKey(q, role, db, dir) === lastFiredSearchKey) return
354
357
  searchTimer = setTimeout(() => {
355
358
  searchTimer = undefined
356
359
  executeSearch(q, role, db, dir)