mirror of
https://github.com/amitwh/markdown-converter.git
synced 2026-10-01 09:19:34 +05:30
feat(search): sidebar panel + Ask mode for workspace Q&A
The workspace-search:query and doc-qa:ask IPC channels were reachable
from the renderer but had no UI. This commit wires them into a sidebar
panel that consumes both backends through a single input.
- src/sidebar/search-panel.js — one input, two modes:
Search (default): routes to workspace-search:query, returns file hits
Ask: routes to doc-qa:ask, returns chunk-level passages with offsets
Click a result → open the file (offset passed through for Q&A hits).
All dynamic content is escaped before innerHTML — hostile filenames
or snippets stay as text instead of becoming script/img nodes.
- src/renderer.js — registers the panel; reads the explorer's folder
input on each open so the search dir stays in sync.
- src/index.html — search sidebar icon (magnifier) next to the others.
Tests (18 new, tests/search-panel.test.js):
- mount + DOM structure
- Enter / click run → search() with query + dir
- result rendering (filePath, snippet, tag facet)
- onOpenFile receives (filePath, offset)
- Ask tab switches placeholder + routes to ask()
- Ask chunks carry +offset in the meta line
- empty query, no folder, search error → handled
- XSS: filename/snippet/tag with <script>, <img>, <unsafe> are escaped
- Escape clears, Clear button resets, host API (setDir/focus/clear)
Full suite: 67 suites, 766 tests, lint+format clean.
Amit Haridas
This commit is contained in:
@@ -2197,6 +2197,32 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||
currentDir: explorerCurrentDir,
|
||||
}),
|
||||
});
|
||||
|
||||
// Search + Q&A panel — wires the workspace-search:query / doc-qa:ask IPC
|
||||
// channels that the WorkspaceSearch + DocQA main-process modules back. The
|
||||
// panel defaults its folder to whatever folder the Explorer last loaded;
|
||||
// the user can override the input.
|
||||
sidebarManager.registerPanel('search', {
|
||||
title: 'Search',
|
||||
icon:
|
||||
'<svg viewBox="0 0 24 24" width="16" height="16"><path fill="currentColor" d="M10 2a8 8 0 1 1-5.3 14L1 19.7 2.3 21l3.7-3.7A8 8 0 0 1 10 2zm0 2a6 6 0 1 0 0 12A6 6 0 0 0 10 4z"/></svg>',
|
||||
render: (container) =>
|
||||
require('./sidebar/search-panel').renderSearchPanel(container, {
|
||||
search: ({ query, dir, limit }) =>
|
||||
ipcRenderer.invoke('workspace-search:query', { query, dir, limit }),
|
||||
ask: ({ question, dir, topK }) =>
|
||||
ipcRenderer.invoke('doc-qa:ask', { question, dir, topK }),
|
||||
getCurrentDir: () => {
|
||||
// Re-read the explorer's path input each time the user opens the
|
||||
// search panel; survives the explorer being remounted.
|
||||
const el = document.getElementById('explorer-path');
|
||||
return el ? el.value.trim() || null : null;
|
||||
},
|
||||
onOpenFile: (filePath /* , offset */) => {
|
||||
ipcRenderer.send('open-file-path', filePath);
|
||||
},
|
||||
}),
|
||||
});
|
||||
sidebarManager.registerPanel('git', {
|
||||
title: 'Git',
|
||||
render: (container) =>
|
||||
|
||||
Reference in New Issue
Block a user