chore(release): bump v4.7.1 → v4.8.0; Prettier pass on overnight-session files

12 commits on master since v4.7.1 baseline, taking tests 524 → 914 across
27 new suites. This commit:
- Bumps package.json + README version to v4.8.0 (additive features → semver minor)
- Applies Prettier formatting to all files touched during the overnight
  session so release build is reproducible from a clean repo

New in v4.8.0:
- PDF encryption close-out (D1)
- KaTeX rendering test coverage
- Autosave buffer + crash recovery banner
- Daily notes + workspace search + doc-aware Q&A
- Search sidebar panel + Ask mode
- Status bar: word count, reading time, Flesch-Kincaid grade
- Footnote hover preview
- Smart paste (URL → link, CSV/TSV → table)
- Daily notes menu item + sidebar panel + Q&A deep-link
- Daily templates gallery
- Pluggable DocQA engine (TF-idF default + lazy neural embeddings)

Amit Haridas
This commit is contained in:
2026-09-14 14:56:05 +05:30
parent c3fe72bcae
commit b1b72f9a60
29 changed files with 186 additions and 136 deletions
+1 -1
View File
@@ -168,4 +168,4 @@ describe('DailyNotesTemplates.deleteTemplate', () => {
expect(DailyNotesTemplates.deleteTemplate({ name: 'x', fs, pathUtil: path })).toBe(false);
expect(DailyNotesTemplates.deleteTemplate({ dir: tmpDir, fs, pathUtil: path })).toBe(false);
});
});
});
+1 -3
View File
@@ -144,9 +144,7 @@ describe('DocQA.ask with a custom engine', () => {
test('passes the question + chunks to a custom engine.rank()', async () => {
const customEngine = {
isNeural: true,
rank: jest.fn().mockResolvedValue([
{ filePath: '/x.md#0', snippet: 'ranked', score: 0.9 },
]),
rank: jest.fn().mockResolvedValue([{ filePath: '/x.md#0', snippet: 'ranked', score: 0.9 }]),
};
const r = await DocQA.ask({ question: 'rust', files, engine: customEngine });
expect(customEngine.rank).toHaveBeenCalled();
+1 -2
View File
@@ -54,8 +54,7 @@ describe('PDFOperations - Task 15 new operations', () => {
expect(result.success).toBe(true);
expect(result.text).toContain('Hello Task 15 Page One');
expect(result.text).toContain('Second Page Content');
}, // CI runners (observed on windows-latest) // First pdfjs-dist legacy import can exceed the 5s default on slower
30000);
}, 30000); // CI runners (observed on windows-latest) // First pdfjs-dist legacy import can exceed the 5s default on slower
it('returns failure for a nonexistent file', async () => {
const result = await PDFOperations.pdfExtractText({
+1 -1
View File
@@ -85,4 +85,4 @@ describe('SemanticEngine — WorkspaceSearch parity', () => {
expect(engineResult.map((r) => r.filePath)).toEqual(directResult.map((r) => r.filePath));
expect(engineResult[0].score).toBe(directResult[0].score);
});
});
});
+7 -3
View File
@@ -57,7 +57,9 @@ describe('UrlTitle.decodeTitle', () => {
describe('UrlTitle.extractTitleFromHtml', () => {
test('extracts the first <title> in the body', () => {
expect(
UrlTitle.extractTitleFromHtml('<html><head><title>Hello World</title></head><body></body></html>')
UrlTitle.extractTitleFromHtml(
'<html><head><title>Hello World</title></head><body></body></html>'
)
).toBe('Hello World');
});
@@ -174,7 +176,9 @@ describe('UrlTitle.fetchTitle — failure paths', () => {
headers: { get: () => 'text/html' },
text: async () => '<title>t</title>' + 'x'.repeat(200),
});
expect(await UrlTitle.fetchTitle({ url: 'https://x.com', fetch: fakeFetch, maxBytes: 100 })).toBeNull();
expect(
await UrlTitle.fetchTitle({ url: 'https://x.com', fetch: fakeFetch, maxBytes: 100 })
).toBeNull();
});
test('respects a streaming body that exceeds maxBytes (cancels the reader)', async () => {
@@ -195,4 +199,4 @@ describe('UrlTitle.fetchTitle — failure paths', () => {
expect(r).toBeNull();
expect(cancel).toHaveBeenCalled();
});
});
});