dsh-locator 0.8.0 → 0.8.2

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/client.js CHANGED
@@ -26,6 +26,34 @@ window.__ModuleLoader__.load({
26
26
  }
27
27
  }
28
28
  const store = createStore()
29
+
30
+ // Transient feedback used after the panel closes (a jump keeps the panel
31
+ // closed, so the panel-local toast would never be seen).
32
+ function createNoticeStore() {
33
+ const listeners = new Set()
34
+ let text = ''
35
+ let timer = 0
36
+ return {
37
+ get: () => text,
38
+ subscribe(listener) {
39
+ listeners.add(listener)
40
+ return () => listeners.delete(listener)
41
+ },
42
+ show(next) {
43
+ text = next
44
+ for (const listener of listeners) listener()
45
+ clearTimeout(timer)
46
+ timer = setTimeout(() => { text = ''; for (const listener of listeners) listener() }, 3200)
47
+ },
48
+ }
49
+ }
50
+ const notices = createNoticeStore()
51
+ function showNotice(text) { notices.show(text) }
52
+ function Notice() {
53
+ const text = useSyncExternalStore(notices.subscribe, notices.get, notices.get)
54
+ return text === '' ? null : h('div', { className: 'dsh-locator-notice', role: 'status' }, text)
55
+ }
56
+
29
57
  function useOpen() {
30
58
  return useSyncExternalStore(store.subscribe, store.isOpen, store.isOpen)
31
59
  }
@@ -90,6 +118,11 @@ window.__ModuleLoader__.load({
90
118
  body[data-ds-dark-theme] .dsh-locator-panel{box-shadow:0 24px 64px rgba(0,0,0,.6)}
91
119
  body[data-ds-dark-theme] .dsh-locator-overlay{background:var(--dsw-alias-bg-mask-1,rgba(0,0,0,.55))}
92
120
  .dsh-locator-target{outline:2px solid rgba(245,158,11,.75);outline-offset:2px;border-radius:6px}
121
+ .dsh-locator-notice{position:fixed;left:50%;bottom:28px;transform:translateX(-50%);z-index:90;pointer-events:none;
122
+ padding:7px 12px;border-radius:8px;font:12px/1.4 system-ui,-apple-system,"Segoe UI",sans-serif;
123
+ background:var(--dsw-alias-bg-layer-2,rgba(30,32,38,.92));color:var(--dsw-alias-label-primary,#fff);
124
+ border:1px solid var(--dsw-alias-border-base,rgba(120,125,135,.3));box-shadow:0 8px 24px rgba(0,0,0,.25);
125
+ animation:dsh-locator-in 120ms ease-out}
93
126
  ::highlight(dsh-locator-find){background-color:rgba(245,158,11,.28);color:inherit}
94
127
  ::highlight(dsh-locator-find-active){background-color:rgba(245,158,11,.45);color:inherit}
95
128
  `
@@ -413,25 +446,39 @@ body[data-ds-dark-theme] .dsh-locator-overlay{background:var(--dsw-alias-bg-mask
413
446
  CSS.highlights.set(HL_ACTIVE, new Highlight(ranges[0]))
414
447
  }
415
448
 
449
+ function isVisible(element) {
450
+ if (element.getClientRects().length === 0) return false
451
+ return getComputedStyle(element).visibility !== 'hidden'
452
+ }
453
+
416
454
  function conversationScope(sessionId) {
417
455
  const id = sessionId === undefined || sessionId === null ? '' : String(sessionId)
418
- let embedded = null
456
+ let visibleMain = null
457
+ let visibleEmbedded = null
419
458
  for (const element of document.querySelectorAll('[data-conversation-content][data-conversation-session]')) {
420
459
  if (id !== '' && element.getAttribute('data-conversation-session') !== id) continue
421
- if (element.closest('[data-sidebar-chat]') === null) return element
422
- embedded = element
460
+ if (!isVisible(element)) continue
461
+ if (element.closest('[data-sidebar-chat]') === null) visibleMain = element
462
+ else visibleEmbedded = element
423
463
  }
424
- return embedded
464
+ return visibleMain ?? visibleEmbedded
425
465
  }
426
466
 
427
467
  function chatFlow(scope) {
428
468
  return scope === null ? null : scope.querySelector('[data-chat-flow]')
429
469
  }
430
470
 
431
- function findMessageRow(flow, messageId) {
432
- if (flow === null || !messageId) return null
471
+ function findMessageRow(flow, messageId, nodeKey) {
472
+ if (flow === null) return null
473
+ const rows = flow.querySelectorAll('[data-chat-node-key]')
474
+ if (nodeKey) {
475
+ for (const row of rows) {
476
+ if (row.getAttribute('data-chat-node-key') === String(nodeKey)) return row
477
+ }
478
+ }
479
+ if (!messageId) return null
433
480
  const id = String(messageId)
434
- for (const row of flow.querySelectorAll('[data-chat-node-key]')) {
481
+ for (const row of rows) {
435
482
  const key = row.getAttribute('data-chat-node-key') || ''
436
483
  if (key === id || key.endsWith(id)) return row
437
484
  }
@@ -630,29 +677,38 @@ body[data-ds-dark-theme] .dsh-locator-overlay{background:var(--dsw-alias-bg-mask
630
677
  return true
631
678
  }
632
679
 
633
- let activeJump = null
680
+ let jumpSeq = 0
681
+ let activeHighlight = null
634
682
 
635
- function cancelJump() {
683
+ function clearJumpHighlight() {
636
684
  clearFindHighlight()
637
- if (activeJump !== null) {
638
- const cancel = activeJump
639
- activeJump = null
640
- cancel()
685
+ if (activeHighlight !== null) {
686
+ const clear = activeHighlight
687
+ activeHighlight = null
688
+ clear()
641
689
  }
642
690
  }
643
691
 
692
+ function cancelJump() {
693
+ jumpSeq++
694
+ clearJumpHighlight()
695
+ }
696
+
644
697
  async function jumpToContentHit(hit, query, notify) {
645
698
  cancelJump()
699
+ const token = jumpSeq
700
+ const stale = () => token !== jumpSeq
646
701
  if (!hit || hit.kind !== 'session' || !hit.sessionId) return false
647
702
  if (!workspaceService || typeof workspaceService.openSession !== 'function') return false
648
703
  try { workspaceService.openSession(hit.sessionId) } catch { return false }
649
704
  const scope = await waitForScope(hit.sessionId, 10_000)
650
- if (scope === null) { notify?.(t('jumpFailed')); return false }
705
+ if (stale()) return false
706
+ if (scope === null) { showNotice(t('jumpFailed')); return false }
651
707
  const flow = chatFlow(scope)
652
- if (flow === null) { notify?.(t('jumpFailed')); return false }
708
+ if (flow === null) { showNotice(t('jumpFailed')); return false }
653
709
  const needles = needlesFromQuery(query)
654
710
  const finder = () => {
655
- const row = findMessageRow(flow, hit.messageId)
711
+ const row = findMessageRow(flow, hit.messageId, hit.nodeKey)
656
712
  if (row !== null) {
657
713
  expandHidden(row)
658
714
  const ranges = rangesForNeedles(row, needles)
@@ -663,73 +719,91 @@ body[data-ds-dark-theme] .dsh-locator-overlay{background:var(--dsw-alias-bg-mask
663
719
  }
664
720
  const phrase = phraseRange(flow, hit.snippet)
665
721
  if (phrase === null) return null
722
+ expandHidden(phrase.startContainer)
666
723
  const phraseRow = phrase.startContainer instanceof Element
667
724
  ? phrase.startContainer.closest('[data-chat-node-key]')
668
725
  : phrase.startContainer.parentElement?.closest('[data-chat-node-key]') ?? null
669
- if (phraseRow !== null) expandHidden(phraseRow)
670
726
  const ranges = phraseRow === null ? [phrase] : rangesForNeedles(phraseRow, needles)
671
727
  return { row: phraseRow, ranges: ranges.length > 0 ? ranges : [phrase] }
672
728
  }
673
729
  let target = await waitFor(flow, finder, 6_000, 120)
674
730
  for (let attempt = 0; target === null && attempt < 10; attempt++) {
731
+ if (stale()) return false
732
+ for (const hidden of flow.querySelectorAll('[hidden="until-found"]')) hidden.dispatchEvent(new Event('beforematch'))
675
733
  if (!revealOlder(scope)) break
676
734
  target = await waitFor(flow, finder, 1_500, 150)
677
735
  }
678
- if (target === null) { notify?.(t('phraseNotFound')); return false }
736
+ if (stale()) return false
737
+ if (target === null) { showNotice(t('phraseNotFound')); return false }
679
738
  setFindHighlight(target.ranges)
680
739
  centerRange(target.ranges[0])
681
740
  const start = target.ranges[0].startContainer
682
741
  const chain = scrollChain(start instanceof Element ? start : start.parentElement)
683
742
  const scroller = chain.length > 0 ? chain[chain.length - 1] : null
684
- const cleanup = []
685
- const release = () => {
686
- while (cleanup.length > 0) {
687
- const fn = cleanup.pop()
743
+ const lockCleanup = []
744
+ const highlightCleanup = []
745
+ const unlock = () => {
746
+ while (lockCleanup.length > 0) {
747
+ const fn = lockCleanup.pop()
748
+ try { fn() } catch { /* ignore */ }
749
+ }
750
+ }
751
+ const clearHighlight = () => {
752
+ while (highlightCleanup.length > 0) {
753
+ const fn = highlightCleanup.pop()
688
754
  try { fn() } catch { /* ignore */ }
689
755
  }
756
+ clearFindHighlight()
690
757
  }
691
- activeJump = release
758
+ // Cancelling must drop the scroll lock too, not only the paint: the lock
759
+ // owns timers and scroll/pointer listeners that would otherwise outlive
760
+ // the highlight.
761
+ activeHighlight = () => { unlock(); clearHighlight() }
692
762
  if (scroller !== null) {
693
763
  let writing = false
694
- const expected = scroller.scrollTop
764
+ let expected = scroller.scrollTop
695
765
  const recenter = () => {
696
- if (activeJump !== release) return
766
+ if (token !== jumpSeq) return
697
767
  const rect = rangeRect(target.ranges[0])
698
- if (rect === null) { release(); clearFindHighlight(); activeJump = null; return }
768
+ if (rect === null) { cancelJump(); return }
699
769
  writing = true
700
770
  centerRange(target.ranges[0])
771
+ expected = scroller.scrollTop
701
772
  requestAnimationFrame(() => { writing = false })
702
773
  }
703
774
  for (const delay of [80, 240, 800, 1600]) {
704
775
  const id = setTimeout(recenter, delay)
705
- cleanup.push(() => clearTimeout(id))
776
+ lockCleanup.push(() => clearTimeout(id))
706
777
  }
707
- const onUser = () => { if (!writing) release() }
778
+ const onUser = () => { if (!writing) unlock() }
708
779
  for (const type of GESTURES) {
709
780
  scroller.addEventListener(type, onUser, true)
710
- cleanup.push(() => scroller.removeEventListener(type, onUser, true))
781
+ lockCleanup.push(() => scroller.removeEventListener(type, onUser, true))
711
782
  }
712
783
  const onScroll = event => {
713
784
  if (writing) return
714
785
  if (event.target === scroller && Math.abs(scroller.scrollTop - expected) <= 2) return
715
- release()
786
+ unlock()
716
787
  }
717
788
  scroller.addEventListener('scroll', onScroll, true)
718
- cleanup.push(() => scroller.removeEventListener('scroll', onScroll, true))
789
+ lockCleanup.push(() => scroller.removeEventListener('scroll', onScroll, true))
719
790
  }
720
791
  const onKey = event => {
721
- if (event.key !== 'Escape') return
722
- cancelJump()
792
+ if (event.key === 'Escape') cancelJump()
723
793
  }
724
794
  document.addEventListener('keydown', onKey, true)
725
- cleanup.push(() => document.removeEventListener('keydown', onKey, true))
795
+ highlightCleanup.push(() => document.removeEventListener('keydown', onKey, true))
726
796
  const sessionWatch = setInterval(() => {
727
- const still = target.ranges[0].startContainer.isConnected && conversationScope(hit.sessionId) !== null
728
- if (!still) cancelJump()
797
+ if (conversationScope(hit.sessionId) === null) { cancelJump(); return }
798
+ if (target.ranges[0].startContainer.isConnected) return
799
+ const next = finder()
800
+ if (next === null) { cancelJump(); return }
801
+ target = next
802
+ setFindHighlight(target.ranges)
803
+ centerRange(target.ranges[0])
729
804
  }, 1_000)
730
- cleanup.push(() => clearInterval(sessionWatch))
731
- cleanup.push(() => clearFindHighlight())
732
- notify?.(t('jumped'))
805
+ highlightCleanup.push(() => clearInterval(sessionWatch))
806
+ showNotice(t('jumped'))
733
807
  return true
734
808
  }
735
809
 
@@ -834,7 +908,7 @@ body[data-ds-dark-theme] .dsh-locator-overlay{background:var(--dsw-alias-bg-mask
834
908
  files: data.files,
835
909
  dirs: data.dirs,
836
910
  })
837
- if (typeof data.availableContent === 'boolean') setAvailableContent(data.availableContent)
911
+ if (typeof data.contentEnabled === 'boolean') setAvailableContent(data.contentEnabled)
838
912
  setTook(typeof data.tookMs === 'number' ? data.tookMs : 0)
839
913
  setLoading(false)
840
914
  }).catch(cause => {
@@ -857,11 +931,12 @@ body[data-ds-dark-theme] .dsh-locator-overlay{background:var(--dsw-alias-bg-mask
857
931
  if (groups === null) return []
858
932
  const out = []
859
933
  for (const group of ['content', 'files', 'dirs']) {
934
+ if (!scopes[group]) continue
860
935
  const hits = groups[group] && Array.isArray(groups[group].hits) ? groups[group].hits : []
861
936
  for (const hit of hits) out.push({ group, hit })
862
937
  }
863
938
  return out
864
- }, [groups])
939
+ }, [groups, scopes])
865
940
 
866
941
  useEffect(() => {
867
942
  setSelected(value => Math.min(Math.max(0, value), Math.max(0, rows.length - 1)))
@@ -878,34 +953,34 @@ body[data-ds-dark-theme] .dsh-locator-overlay{background:var(--dsw-alias-bg-mask
878
953
  }, [notify])
879
954
 
880
955
  const reveal = useCallback(hit => {
881
- if (!hit) return
956
+ if (!hit || loading) return
882
957
  post('/dsh-locator/reveal', { path: hit.path }).then(() => notify(t('revealed'))).catch(() => copy(hit))
883
- }, [copy, notify])
958
+ }, [copy, loading, notify])
884
959
 
885
960
  const openFile = useCallback(hit => {
886
- if (!hit || hit.dir) return
961
+ if (!hit || hit.dir || loading) return
887
962
  post('/dsh-locator/open', { path: hit.path }).then(() => notify(t('opened'))).catch(() => copy(hit))
888
- }, [copy, notify])
963
+ }, [copy, loading, notify])
889
964
 
890
965
  const activate = useCallback(hit => {
891
- if (!hit) return
966
+ if (!hit || loading) return
892
967
  if (hit.kind === 'session' && hit.sessionId) {
893
968
  close()
894
969
  void jumpToContentHit(hit, query, notify)
895
970
  return
896
971
  }
897
972
  reveal(hit)
898
- }, [close, notify, query, reveal])
973
+ }, [close, loading, notify, query, reveal])
899
974
 
900
975
  const insert = useCallback(hit => {
901
- if (!hit || hit.kind === 'session') return
976
+ if (!hit || hit.kind === 'session' || loading) return
902
977
  const mention = '@"' + hit.path.replace(/"/g, '') + '" '
903
978
  close()
904
979
  setTimeout(() => {
905
980
  if (insertIntoComposer(mention)) notify(t('inserted'))
906
981
  else copyText(mention).then(() => notify(t('insertFailed'))).catch(() => {})
907
982
  }, 80)
908
- }, [close, notify])
983
+ }, [close, loading, notify])
909
984
 
910
985
  const toggleScope = useCallback(key => {
911
986
  if (key === 'content' && !availableContent) return
@@ -913,7 +988,6 @@ body[data-ds-dark-theme] .dsh-locator-overlay{background:var(--dsw-alias-bg-mask
913
988
  }, [availableContent])
914
989
 
915
990
  const onKeyDown = useCallback(event => {
916
- if (event.target instanceof HTMLSelectElement) return
917
991
  if (event.key === 'Escape') {
918
992
  event.preventDefault()
919
993
  close()
@@ -930,9 +1004,16 @@ body[data-ds-dark-theme] .dsh-locator-overlay{background:var(--dsw-alias-bg-mask
930
1004
  if (event.shiftKey && document.activeElement === first) { event.preventDefault(); last.focus() }
931
1005
  return
932
1006
  }
933
- if (event.altKey && ['1', '2', '3'].includes(event.key)) {
1007
+ const interactive = event.target instanceof HTMLElement
1008
+ && (event.target.tagName === 'BUTTON' || event.target.tagName === 'SELECT'
1009
+ || (event.target.tagName === 'INPUT' && event.target.type !== 'text'))
1010
+ if (interactive) return
1011
+ const scopeDigit = event.altKey
1012
+ ? (event.code === 'Digit1' ? '1' : event.code === 'Digit2' ? '2' : event.code === 'Digit3' ? '3' : ['1', '2', '3'].includes(event.key) ? event.key : '')
1013
+ : ''
1014
+ if (scopeDigit !== '') {
934
1015
  event.preventDefault()
935
- toggleScope(event.key === '1' ? 'content' : event.key === '2' ? 'files' : 'dirs')
1016
+ toggleScope(scopeDigit === '1' ? 'content' : scopeDigit === '2' ? 'files' : 'dirs')
936
1017
  return
937
1018
  }
938
1019
  if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
@@ -940,6 +1021,7 @@ body[data-ds-dark-theme] .dsh-locator-overlay{background:var(--dsw-alias-bg-mask
940
1021
  setSelected(value => Math.max(0, Math.min(rows.length - 1, value + (event.key === 'ArrowDown' ? 1 : -1))))
941
1022
  return
942
1023
  }
1024
+ if ((event.key === 'Home' || event.key === 'End') && event.target === inputRef.current) return
943
1025
  if (event.key === 'Home' || event.key === 'End') {
944
1026
  event.preventDefault()
945
1027
  setSelected(event.key === 'Home' ? 0 : Math.max(0, rows.length - 1))
@@ -975,7 +1057,7 @@ body[data-ds-dark-theme] .dsh-locator-overlay{background:var(--dsw-alias-bg-mask
975
1057
  event.preventDefault()
976
1058
  insert(rows[selected]?.hit)
977
1059
  }
978
- }, [activate, close, copy, insert, openFile, reveal, rows, selected, toggleScope])
1060
+ }, [activate, close, copy, insert, loading, openFile, reveal, rows, selected, toggleScope])
979
1061
 
980
1062
  useEffect(() => {
981
1063
  const list = listRef.current
@@ -1060,6 +1142,13 @@ body[data-ds-dark-theme] .dsh-locator-overlay{background:var(--dsw-alias-bg-mask
1060
1142
  ? (contentBuilding ? t('contentBuilding', { files: content?.files ?? 0, messages: content?.messages ?? 0 })
1061
1143
  : (content?.capped ? t('contentCapped', { n: count }) : (query.trim() !== '' ? t('relevance') : null)))
1062
1144
  : (group.deduped > 0 ? t('deduped', { n: group.deduped }) : (group.truncated ? t('showing', { n: hits.length }) : null))
1145
+ if (typeof group.error === 'string' && group.error !== '') {
1146
+ return h('div', { className: 'dsh-locator-group', role: 'group', 'aria-labelledby': 'dsh-locator-group-' + key },
1147
+ groupHead(key, label, count, null),
1148
+ h('div', { className: 'dsh-locator-groupempty', role: 'alert' }, t('errorPrefix') + group.error,
1149
+ h('button', { className: 'dsh-locator-dirbtn dsh-locator-retry', onClick: () => setRefreshTick(v => v + 1) }, t('retry'))),
1150
+ )
1151
+ }
1063
1152
  return h('div', { className: 'dsh-locator-group', role: 'group', 'aria-labelledby': 'dsh-locator-group-' + key },
1064
1153
  groupHead(key, label, count, note),
1065
1154
  extra === undefined ? null : extra,
@@ -1136,21 +1225,22 @@ body[data-ds-dark-theme] .dsh-locator-overlay{background:var(--dsw-alias-bg-mask
1136
1225
  })),
1137
1226
  ),
1138
1227
  h('div', { id: 'dsh-locator-results', className: 'dsh-locator-scroll', ref: listRef, role: 'listbox', 'aria-busy': loading ? 'true' : 'false' },
1228
+ error !== ''
1229
+ ? h('div', { className: 'dsh-locator-empty', role: 'alert' }, t('errorPrefix') + error,
1230
+ h('button', { className: 'dsh-locator-dirbtn dsh-locator-retry', onClick: () => setRefreshTick(v => v + 1) }, t('retry')))
1231
+ : null,
1139
1232
  !anyScope
1140
1233
  ? h('div', { className: 'dsh-locator-empty' }, t('emptyScopes'))
1141
- : error !== ''
1142
- ? h('div', { className: 'dsh-locator-empty', role: 'alert' }, t('errorPrefix') + error,
1143
- h('button', { className: 'dsh-locator-dirbtn dsh-locator-retry', onClick: () => setRefreshTick(v => v + 1) }, t('retry')))
1144
- : groups === null
1145
- ? h('div', { className: 'dsh-locator-empty' }, t('loading'))
1146
- : [
1147
- renderGroup('content', t('groupContent'), content),
1148
- renderGroup('files', t('groupFiles'), files),
1149
- renderGroup('dirs', t('groupDirs'), dirs),
1150
- ],
1234
+ : groups === null
1235
+ ? (error === '' ? h('div', { className: 'dsh-locator-empty' }, t('loading')) : null)
1236
+ : [
1237
+ renderGroup('content', t('groupContent'), content),
1238
+ renderGroup('files', t('groupFiles'), files),
1239
+ renderGroup('dirs', t('groupDirs'), dirs),
1240
+ ],
1151
1241
  ),
1152
1242
  h('div', { className: 'dsh-locator-foot' },
1153
- h('span', null, t('results', { content: contentCount, files: filesCount, dirs: dirsCount, ms: took.toFixed(1) })
1243
+ h('span', null, (loading ? t('loading') + ' · ' : '') + t('results', { content: contentCount, files: filesCount, dirs: dirsCount, ms: took.toFixed(1) })
1154
1244
  + (status && status.scanning ? ' · ' + t('indexing') : '')
1155
1245
  + (contentBuilding ? ' · ' + t('indexing') : '')),
1156
1246
  h('span', { className: 'grow' }),
@@ -1191,7 +1281,17 @@ body[data-ds-dark-theme] .dsh-locator-overlay{background:var(--dsw-alias-bg-mask
1191
1281
  }, 'dsh-locator: search hotkey')
1192
1282
  ctx.effect(() => () => { cancelJump() }, 'dsh-locator: find highlight')
1193
1283
  try {
1194
- ctx.slots.inject('shell.overlay', () => ctx.slots.register({ name: 'shell.overlay', id: 'dsh-locator-panel', order: 60 }, Panel))
1284
+ ctx.slots.inject('shell.overlay', () => {
1285
+ const disposers = [
1286
+ ctx.slots.register({ name: 'shell.overlay', id: 'dsh-locator-panel', order: 60 }, Panel),
1287
+ ctx.slots.register({ name: 'shell.overlay', id: 'dsh-locator-notice', order: 61 }, Notice),
1288
+ ]
1289
+ return () => {
1290
+ for (const dispose of disposers.reverse()) {
1291
+ if (typeof dispose === 'function') dispose()
1292
+ }
1293
+ }
1294
+ })
1195
1295
  } catch (error) {
1196
1296
  console.error('dsh-locator: overlay slot unavailable', error)
1197
1297
  }
package/lib/combined.js CHANGED
@@ -141,7 +141,13 @@ async function nameGroup(deps, request, files) {
141
141
  async function contentGroup(deps, request, ask) {
142
142
  const started = Date.now();
143
143
  const empty = () => {
144
- const state = deps.contentStatus?.();
144
+ let state;
145
+ try {
146
+ state = deps.contentStatus?.();
147
+ }
148
+ catch {
149
+ state = undefined;
150
+ }
145
151
  return {
146
152
  hits: [],
147
153
  returned: 0,
@@ -1 +1 @@
1
- {"version":3,"file":"combined.js","sourceRoot":"","sources":["../src/combined.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAsEH;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CAAC,IAA6B;IACtD,OAAO;QACL,OAAO,EAAE,IAAI,CAAC,OAAO,KAAK,KAAK;QAC/B,KAAK,EAAE,IAAI,CAAC,KAAK,KAAK,KAAK;QAC3B,IAAI,EAAE,IAAI,CAAC,IAAI,KAAK,KAAK;KAC1B,CAAA;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAA6B,EAAE,UAAkB;IACnF,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC,CAAA;IACnE,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,CAAA;IACzD,OAAO;QACL,KAAK,EAAE,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;QACvD,KAAK,EAAE,SAAS;QAChB,YAAY;QACZ,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;QACxB,IAAI,EAAE,IAAI,CAAC,IAAI,KAAK,IAAI;QACxB,MAAM,EAAE,UAAU,CAAC,IAAI,CAAC;KACzB,CAAA;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAC5B,WAAkC,EAClC,QAA8B;IAE9B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAA;IAC9B,KAAK,MAAM,GAAG,IAAI,WAAW;QAAE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IACjD,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,CAAC,GAAG,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAA;IAC/D,MAAM,IAAI,GAAgB,EAAE,CAAA;IAC5B,IAAI,OAAO,GAAG,CAAC,CAAA;IACf,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACnC,OAAO,EAAE,CAAA;YACT,SAAQ;QACV,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAChB,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;AAC1B,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAAkB,EAAE,OAAwB;IAClF,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IAC1B,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAA;IACjC,MAAM,cAAc,GAAG,IAAI,CAAC,aAAa,KAAK,SAAS,CAAA;IACvD,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,IAAI,cAAc,CAAA;IACrD,4EAA4E;IAC5E,4EAA4E;IAC5E,MAAM,UAAU,GAAG,YAAY,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,IAAI,CAAC,CAAA;IAE3D,MAAM,cAAc,GAAG,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IAC1G,MAAM,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IAC/F,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IAC9F,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,cAAc,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC,CAAA;IAE7F,MAAM,YAAY,GAAG,KAAK,KAAK,SAAS;QACtC,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,CAAC,GAAG,EAAE;YACJ,MAAM,MAAM,GAAG,cAAc,CAAC,OAAO,EAAE,IAAI,IAAI,EAAE,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA;YAC9D,OAAO;gBACL,GAAG,KAAK;gBACR,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM;gBAC5B,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,MAAM,CAAC,OAAO,GAAG,CAAC;aACjD,CAAA;QACH,CAAC,CAAC,EAAE,CAAA;IAER,OAAO;QACL,MAAM;QACN,cAAc;QACd,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;QAC7C,GAAG,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC;QAC9D,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;QACvC,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO;KAC7B,CAAA;AACH,CAAC;AAED,kDAAkD;AAClD,KAAK,UAAU,SAAS,CAAC,IAAkB,EAAE,OAAwB,EAAE,KAAc;IACnF,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IAC1B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC;YAC/B,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,MAAM,EAAE,CAAC;YACT,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,KAAK,EAAE,KAAK;YACZ,aAAa,EAAE,KAAK;YACpB,SAAS,EAAE,KAAK;YAChB,SAAS,EAAE,KAAK;YAChB,QAAQ,EAAE,CAAC,KAAK;SACjB,CAAC,CAAA;QACF,OAAO;YACL,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM;YAC5B,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,OAAO,EAAE,CAAC;YACV,MAAM,EAAE,MAAM,CAAC,MAAM,GAAG,GAAG;SAC5B,CAAA;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,CAAA;IACjI,CAAC;AACH,CAAC;AAED,6EAA6E;AAC7E,KAAK,UAAU,YAAY,CAAC,IAAkB,EAAE,OAAwB,EAAE,GAAY;IACpF,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IAC1B,MAAM,KAAK,GAAG,GAAiB,EAAE;QAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,EAAE,EAAE,CAAA;QACpC,OAAO;YACL,IAAI,EAAE,EAAE;YACR,QAAQ,EAAE,CAAC;YACX,MAAM,EAAE,KAAK;YACb,QAAQ,EAAE,KAAK,EAAE,QAAQ,IAAI,KAAK;YAClC,KAAK,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC;YACxB,QAAQ,EAAE,KAAK,EAAE,QAAQ,IAAI,CAAC;YAC9B,QAAQ,EAAE,KAAK,EAAE,QAAQ,IAAI,CAAC;YAC9B,SAAS,EAAE,KAAK,EAAE,SAAS,IAAI,KAAK;YACpC,MAAM,EAAE,CAAC;SACV,CAAA;IACH,CAAC,CAAA;IACD,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,aAAa,KAAK,SAAS;QAAE,OAAO,KAAK,EAAE,CAAA;IAC5D,IAAI,CAAC;QACH,IAAI,CAAC,MAAM,EAAE,EAAE,CAAA;QACf,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,YAAY,CAAC,CAAA;QAC1E,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,EAAE,EAAE,CAAA;QACpC,OAAO;YACL,IAAI;YACJ,QAAQ,EAAE,IAAI,CAAC,MAAM;YACrB,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,YAAY;YAC3C,QAAQ,EAAE,KAAK,EAAE,QAAQ,IAAI,KAAK;YAClC,KAAK,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC;YACxB,QAAQ,EAAE,KAAK,EAAE,QAAQ,IAAI,CAAC;YAC9B,QAAQ,EAAE,KAAK,EAAE,QAAQ,IAAI,CAAC;YAC9B,SAAS,EAAE,KAAK,EAAE,SAAS,IAAI,KAAK;YACpC,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO;SAC7B,CAAA;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,EAAE,CAAA;IAC9E,CAAC;AACH,CAAC;AAED,SAAS,KAAK,CAAC,KAAc,EAAE,GAAW,EAAE,GAAW,EAAE,QAAgB;IACvE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAA;IACzE,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;AACxD,CAAC;AAED,SAAS,OAAO,CAAC,KAAc;IAC7B,OAAO,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAA;AAC3H,CAAC;AAED,SAAS,SAAS,CAAC,KAAc;IAC/B,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AAC/D,CAAC"}
1
+ {"version":3,"file":"combined.js","sourceRoot":"","sources":["../src/combined.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"content-search.d.ts","sourceRoot":"","sources":["../src/content-search.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAE9C;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,UAAU,EAAE,CA6B1F"}
1
+ {"version":3,"file":"content-search.d.ts","sourceRoot":"","sources":["../src/content-search.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAE9C;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,UAAU,EAAE,CAgC1F"}
@@ -19,6 +19,7 @@ export function searchContent(db, query, limit) {
19
19
  // A one- or two-character query cannot use the trigram index, so bound the
20
20
  // payload as well as the row count: never ship a whole megabyte body.
21
21
  rows = db.prepare(`SELECT kind, path, title, session_id, message_id,
22
+ (SELECT node_key FROM docs_meta WHERE docs_meta.rowid = docs.rowid) AS node_key,
22
23
  substr(body, 1, 400) AS snippet, 0 AS score
23
24
  FROM docs WHERE body LIKE '%' || ? || '%' LIMIT ?`).all(text, capped);
24
25
  }
@@ -28,6 +29,7 @@ export function searchContent(db, query, limit) {
28
29
  // inside a matching query (a rowid subquery silently degrades both). The
29
30
  // query runs in the search worker, so its cost stays off the host thread.
30
31
  rows = db.prepare(`SELECT kind, path, title, session_id, message_id,
32
+ (SELECT node_key FROM docs_meta WHERE docs_meta.rowid = docs.rowid) AS node_key,
31
33
  snippet(docs, 0, char(1), char(2), '…', 16) AS snippet, bm25(docs) AS score
32
34
  FROM docs WHERE docs MATCH ? ORDER BY score LIMIT ?`).all(match, capped);
33
35
  }
@@ -38,6 +40,7 @@ export function searchContent(db, query, limit) {
38
40
  snippet: String(row.snippet ?? row.body ?? '').replace(/[\u0001\u0002]/g, ''),
39
41
  ...(row.session_id ? { sessionId: String(row.session_id) } : {}),
40
42
  ...(row.message_id ? { messageId: String(row.message_id) } : {}),
43
+ ...(row.node_key ? { nodeKey: String(row.node_key) } : {}),
41
44
  score: Number(row.score ?? 0),
42
45
  }));
43
46
  }
@@ -1 +1 @@
1
- {"version":3,"file":"content-search.js","sourceRoot":"","sources":["../src/content-search.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,EAAgB,EAAE,KAAa,EAAE,KAAa;IAC1E,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,CAAA;IACzB,IAAI,IAAI,KAAK,EAAE;QAAE,OAAO,EAAE,CAAA;IAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAA;IAChD,IAAI,IAAoC,CAAA;IACxC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,2EAA2E;QAC3E,sEAAsE;QACtE,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC;;wDAEkC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAmC,CAAA;IAC3G,CAAC;SAAM,CAAC;QACN,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QAC7G,2EAA2E;QAC3E,yEAAyE;QACzE,0EAA0E;QAC1E,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC;;0DAEoC,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAmC,CAAA;IAC9G,CAAC;IACD,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACtB,IAAI,EAAE,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM;QACjD,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC;QAC5B,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;QAC9B,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC;QAC7E,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC;KAC9B,CAAC,CAAC,CAAA;AACL,CAAC"}
1
+ {"version":3,"file":"content-search.js","sourceRoot":"","sources":["../src/content-search.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,EAAgB,EAAE,KAAa,EAAE,KAAa;IAC1E,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,CAAA;IACzB,IAAI,IAAI,KAAK,EAAE;QAAE,OAAO,EAAE,CAAA;IAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAA;IAChD,IAAI,IAAoC,CAAA;IACxC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,2EAA2E;QAC3E,sEAAsE;QACtE,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC;;;wDAGkC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAmC,CAAA;IAC3G,CAAC;SAAM,CAAC;QACN,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QAC7G,2EAA2E;QAC3E,yEAAyE;QACzE,0EAA0E;QAC1E,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC;;;0DAGoC,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAmC,CAAA;IAC9G,CAAC;IACD,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACtB,IAAI,EAAE,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM;QACjD,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC;QAC5B,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;QAC9B,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC;QAC7E,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1D,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC;KAC9B,CAAC,CAAC,CAAA;AACL,CAAC"}
package/lib/content.d.ts CHANGED
@@ -23,6 +23,8 @@ export interface ContentHit {
23
23
  snippet: string;
24
24
  sessionId?: string;
25
25
  messageId?: string;
26
+ /** Exact `data-chat-node-key` of the rendered row, when the host has one. */
27
+ nodeKey?: string;
26
28
  score: number;
27
29
  }
28
30
  export interface ContentState {
@@ -1 +1 @@
1
- {"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../src/content.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../src/content.ts"],"names":[],"mappings":"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"}
package/lib/content.js CHANGED
@@ -27,7 +27,7 @@ import { randomUUID } from 'node:crypto';
27
27
  import { fileURLToPath } from 'node:url';
28
28
  import { Worker } from 'node:worker_threads';
29
29
  import { searchContent } from "./content-search.js";
30
- const SCHEMA_VERSION = 2;
30
+ const SCHEMA_VERSION = 3;
31
31
  /** Work budget between two event-loop yields; keeps host latency low. */
32
32
  const SLICE_MS = 8;
33
33
  /** Wall-clock start of this process; distinguishes a reused pid from a live sibling. */
@@ -302,7 +302,7 @@ export class ContentIndex {
302
302
  body, kind UNINDEXED, path UNINDEXED, title UNINDEXED,
303
303
  session_id UNINDEXED, message_id UNINDEXED, tokenize = 'trigram'
304
304
  )`);
305
- this.db.exec('CREATE TABLE IF NOT EXISTS docs_meta (rowid INTEGER PRIMARY KEY, doc_key TEXT UNIQUE, path TEXT, mtime INTEGER, kind TEXT)');
305
+ this.db.exec('CREATE TABLE IF NOT EXISTS docs_meta (rowid INTEGER PRIMARY KEY, doc_key TEXT UNIQUE, path TEXT, mtime INTEGER, kind TEXT, node_key TEXT)');
306
306
  this.db.exec('CREATE TABLE IF NOT EXISTS sources (path TEXT PRIMARY KEY, mtime INTEGER)');
307
307
  this.db.exec('CREATE INDEX IF NOT EXISTS docs_meta_path ON docs_meta(path)');
308
308
  if (fresh) {
@@ -486,7 +486,7 @@ export class ContentIndex {
486
486
  return false;
487
487
  }
488
488
  this.deleteDoc(row.key);
489
- const meta = this.db.prepare('INSERT INTO docs_meta (doc_key, path, mtime, kind) VALUES (?, ?, ?, ?)').run(row.key, row.path, row.mtime, row.kind);
489
+ const meta = this.db.prepare('INSERT INTO docs_meta (doc_key, path, mtime, kind, node_key) VALUES (?, ?, ?, ?, ?)').run(row.key, row.path, row.mtime, row.kind, row.nodeKey);
490
490
  const rowid = meta.lastInsertRowid;
491
491
  this.db.prepare('INSERT INTO docs (rowid, body, kind, path, title, session_id, message_id) VALUES (?, ?, ?, ?, ?, ?, ?)').run(rowid, row.body, row.kind, row.path, row.title, row.sessionId, row.messageId);
492
492
  this.totalBytes += row.body.length;
@@ -632,7 +632,7 @@ export class ContentIndex {
632
632
  if (buffer.includes(0))
633
633
  return null;
634
634
  const body = buffer.toString('utf8').slice(0, this.options.maxFileBytes);
635
- return { key: `file:${path}`, body, kind: 'file', path, title: name, sessionId: null, messageId: null, mtime };
635
+ return { key: `file:${path}`, body, kind: 'file', path, title: name, sessionId: null, messageId: null, nodeKey: null, mtime };
636
636
  }
637
637
  async indexSessions(generation) {
638
638
  const files = (await this.sessionCandidates()).filter(file => this.settled(file.mtime));
@@ -709,7 +709,7 @@ export class ContentIndex {
709
709
  if (title === '')
710
710
  title = extracted.text.replace(/\s+/g, ' ').slice(0, 90);
711
711
  const body = extracted.text.slice(0, SESSION_BODY_BYTES);
712
- const row = { key: `session:${sessionId}:${extracted.id}`, body, kind: 'session', path: file.path, title: title || sessionId, sessionId, messageId: extracted.id, mtime: file.mtime };
712
+ const row = { key: `session:${sessionId}:${extracted.id}`, body, kind: 'session', path: file.path, title: title || sessionId, sessionId, messageId: extracted.id, nodeKey: extracted.nodeKey, mtime: file.mtime };
713
713
  if (!this.addDoc(row))
714
714
  return false;
715
715
  }
@@ -801,6 +801,10 @@ async function archivedSessionIds() {
801
801
  return new Set();
802
802
  }
803
803
  }
804
+ /** Conversation node key format used by the host DOM (`${kind.length}:${kind}${id}`). */
805
+ function conversationNodeKey(kind, id) {
806
+ return `${kind.length}:${kind}${id}`;
807
+ }
804
808
  function messageText(event) {
805
809
  if (event.type !== 'user/message' && event.type !== 'assistant/message')
806
810
  return undefined;
@@ -822,7 +826,18 @@ function messageText(event) {
822
826
  if (text === '')
823
827
  return undefined;
824
828
  const id = event.type === 'user/message' ? String(data.id ?? '') : String(message.id ?? '');
825
- return { text, id: id || `seq-${String(data.seq ?? '')}` };
829
+ const safeId = id || `seq-${String(data.seq ?? '')}`;
830
+ let nodeKey = null;
831
+ if (event.type === 'user/message' && id !== '') {
832
+ nodeKey = conversationNodeKey('input-message', id);
833
+ }
834
+ else if (event.type === 'assistant/message') {
835
+ const turn = Number(data.turn);
836
+ const step = Number(data.step);
837
+ if (Number.isInteger(turn) && Number.isInteger(step))
838
+ nodeKey = conversationNodeKey('assistant-step', `${turn}:${step}`);
839
+ }
840
+ return { text, id: safeId, nodeKey };
826
841
  }
827
842
  async function sessionFiles(roots) {
828
843
  const out = [];