From f3b00f94485926d616fdb46de750bfd55676a1dd Mon Sep 17 00:00:00 2001 From: Omkar Tripathi <38633467+triggeredcode@users.noreply.github.com> Date: Mon, 12 Oct 2026 19:36:49 +0530 Subject: [PATCH 1/3] feat: three note formats and a small Blank page button, nothing too specialized Lucid came with five formats, two of them for one subject (inference engineering, benchmarks). Those two are gone: it comes with a concept note, a system design note and a comparison, and a format is still one entry of data for anyone's own subject. New page shows the three as cards and the blank page as a small button under them, not as a fourth card, and its example is general (consistent hashing). The prompts say "a technical subject" instead of inference engineering, the advisor's examples are a concept, a comparison and a system design, the evals pick and place cases use the three formats (a system design page replaces the benchmark one), and the MCP descriptions list three. A page that an earlier version made in one of the two removed formats opens as a plain page with all its words (tested). Co-Authored-By: Claude Sonnet 5.5 --- apps/desktop/e2e/formats.spec.ts | 98 ++++++++++++---- apps/desktop/e2e/mcp.spec.ts | 29 ++--- apps/desktop/electron/appBackend.test.ts | 6 +- apps/desktop/electron/pdf.test.ts | 16 +-- apps/desktop/src/pages/NewPageDialog.tsx | 53 +++++---- apps/desktop/src/styles.css | 40 +++++++ packages/core/src/persistence/format.test.ts | 8 +- packages/evals/src/cases/formats.ts | 60 +++++----- packages/evals/src/fixtures.ts | 2 +- packages/evals/src/matchers.test.ts | 6 +- packages/evals/src/run.test.ts | 4 +- packages/evals/src/types.ts | 2 +- packages/kit/src/formats/formats.test.ts | 45 ++++---- packages/kit/src/formats/index.ts | 112 +------------------ packages/kit/src/latex/compile.test.ts | 9 -- packages/kit/src/latex/latex.test.ts | 10 +- packages/llm/src/advisor.test.ts | 4 +- packages/llm/src/prompts/advisor.ts | 16 +-- packages/llm/src/prompts/input.ts | 2 +- packages/mcp/src/server.test.ts | 5 +- packages/mcp/src/server.ts | 2 +- packages/mcp/src/tools.ts | 2 +- 22 files changed, 260 insertions(+), 271 deletions(-) diff --git a/apps/desktop/e2e/formats.spec.ts b/apps/desktop/e2e/formats.spec.ts index 05073db..80c8ef0 100644 --- a/apps/desktop/e2e/formats.spec.ts +++ b/apps/desktop/e2e/formats.spec.ts @@ -132,12 +132,12 @@ test("what the person chose is not overwritten by a late answer, and the page ca await dialog(page).getByRole("button", { name: "Suggest a format" }).click(); await expect(formatOption(page, "System design note")).toBeChecked(); // The person picks something else before the model has answered. - await formatOption(page, "Benchmark note").check({ force: true }); + await formatOption(page, "Comparison").check({ force: true }); await dialog(page).getByLabel("Title").fill("My own title"); await expect(dialog(page).getByRole("status")).toContainText("Suggested: System design note", { timeout: 30_000, }); - await expect(formatOption(page, "Benchmark note")).toBeChecked(); + await expect(formatOption(page, "Comparison")).toBeChecked(); await expect(dialog(page).getByLabel("Title")).toHaveValue("My own title"); await formatOption(page, "Blank page").check({ force: true }); @@ -159,14 +159,14 @@ test("when the model is not there the keyword pick still works, and Esc closes t await page.getByRole("button", { name: "New from a format…" }).click(); await dialog(page) .getByLabel("What will you write about?") - .fill("benchmarking qwen vs gemma tok/s on my mac"); + .fill("Kafka vs SQS for order events"); await dialog(page).getByRole("button", { name: "Suggest a format" }).click(); - await expect(formatOption(page, "Benchmark note")).toBeChecked(); - await expect(dialog(page).getByRole("status")).toContainText("Looks like a benchmark note."); + await expect(formatOption(page, "Comparison")).toBeChecked(); + await expect(dialog(page).getByRole("status")).toContainText("Looks like a comparison."); await expect(dialog(page).getByRole("status")).not.toContainText("Asking the model", { timeout: 30_000, }); - await expect(formatOption(page, "Benchmark note")).toBeChecked(); + await expect(formatOption(page, "Comparison")).toBeChecked(); await page.keyboard.press("Escape"); await expect(dialog(page)).toBeHidden(); } finally { @@ -215,40 +215,40 @@ test("dictation on a format page goes under the section it belongs to, and the m test("the format chip changes the format and the fields shown under the title, and the PDF prints only what is filled in", async () => { test.setTimeout(180_000); const { app, page, home } = await launch([ - reply("@@ section Goal and hypothesis\nDoes batching raise throughput?"), + reply("@@ section Requirements\n- Create a short link"), ]); try { await page.getByRole("button", { name: "New from a format…" }).click(); - await formatOption(page, "Benchmark note").check({ force: true }); - await dialog(page).getByLabel("Title").fill("Batching"); + await formatOption(page, "System design note").check({ force: true }); + await dialog(page).getByLabel("Title").fill("URL shortener"); await dialog(page).getByRole("button", { name: "Create page" }).click(); - await expect(headings(page)).toHaveCount(6); + await expect(headings(page)).toHaveCount(8); await page.keyboard.press("Escape"); - await page.getByRole("button", { name: /^Benchmark note/ }).click(); + await page.getByRole("button", { name: /^System design note/ }).click(); const pop = page.getByRole("dialog", { name: "Note format" }); - await pop.getByLabel("Hardware").fill("M4 Max, 48 GB"); + await pop.getByLabel("Source").fill("Study group"); await pop.getByLabel("Date").fill("2026-10-11"); await page.keyboard.press("Escape"); await expect(pop).toBeHidden(); const bar = page.getByLabel("Dictate or type your notes"); - await bar.fill("Does batching raise throughput?"); + await bar.fill("It must create a short link."); await bar.press("Enter"); - await expect(page.locator(".page-editor")).toContainText("Does batching raise throughput?", { + await expect(page.locator(".page-editor")).toContainText("Create a short link", { timeout: 30_000, }); await expect(page.getByText("Saved")).toBeVisible({ timeout: 15_000 }); - expect(pageFile(home).meta.info).toEqual({ hardware: "M4 Max, 48 GB", date: "2026-10-11" }); + expect(pageFile(home).meta.info).toEqual({ source: "Study group", date: "2026-10-11" }); const path = await autoSaveDialog(app); const text = await downloadPdf(page, path); if (text !== undefined) { - expect(text).toContain("Hardware: M4 Max, 48 GB"); + expect(text).toContain("Source: Study group"); expect(text).toContain("Date: 2026-10-11"); - expect(text).toContain("Goal and hypothesis"); - expect(text).not.toContain("Next experiments"); - expect(text).not.toContain("Observations"); + expect(text).toContain("Requirements"); + expect(text).not.toContain("Open questions"); + expect(text).not.toContain("Deep dives"); } } finally { await app.close(); @@ -288,3 +288,63 @@ test("a blank page can take a format later, and the missing sections are added i await app.close(); } }); + +test("the new page dialog offers three formats and a small Blank page button, nothing more specialized", async () => { + test.setTimeout(60_000); + const { app, page } = await launch(); + try { + await page.getByRole("button", { name: "New from a format…" }).click(); + const radios = dialog(page).getByRole("radiogroup", { name: "Format" }).getByRole("radio"); + await expect(radios).toHaveCount(4); + await expect( + dialog(page).locator(".np-formats").getByRole("radio"), + "the three formats are the cards", + ).toHaveCount(3); + await expect(formatOption(page, "Concept note")).toBeAttached(); + await expect(formatOption(page, "System design note")).toBeAttached(); + await expect(formatOption(page, "Comparison")).toBeAttached(); + await expect(dialog(page)).not.toContainText("Benchmark"); + await expect(dialog(page)).not.toContainText("Inference"); + // Blank is a small button under the cards, not a card, and it is what is chosen to start with. + await expect(formatOption(page, "Blank page")).toBeChecked(); + const blank = await dialog(page).locator(".np-blank").boundingBox(); + const card = await dialog(page).locator(".np-format").first().boundingBox(); + expect(blank?.height ?? 99).toBeLessThan(40); + expect(blank?.y ?? 0).toBeGreaterThan((card?.y ?? 0) + (card?.height ?? 0)); + } finally { + await app.close(); + } +}); + +test("a page that an earlier version made in a format that is gone opens as a plain page, with its words", async () => { + test.setTimeout(60_000); + const { app, page } = await launch(); + try { + await page.evaluate(async () => { + const file = await window.lucid.pages.create("Old benchmark"); + await window.lucid.pages.save({ + ...file, + doc: { + blocks: [ + { + id: "p1", + type: "paragraph", + props: {}, + content: [{ type: "text", text: "Tokens per second at batch four.", styles: {} }], + }, + ], + }, + meta: { ...file.meta, format: "benchmark", info: { hardware: "M4 Max" } }, + }); + }); + await page.reload(); + await page + .getByRole("navigation", { name: "Pages" }) + .getByRole("button", { name: /Old benchmark/ }) + .click(); + await expect(page.locator(".page-editor")).toContainText("Tokens per second at batch four."); + await expect(page.getByRole("button", { name: /^Blank page/ })).toBeVisible(); + } finally { + await app.close(); + } +}); diff --git a/apps/desktop/e2e/mcp.spec.ts b/apps/desktop/e2e/mcp.spec.ts index 851e109..29e448c 100644 --- a/apps/desktop/e2e/mcp.spec.ts +++ b/apps/desktop/e2e/mcp.spec.ts @@ -185,41 +185,42 @@ test("an agent can see the formats, create a page of one, and put notes under it }), ); const formats = text(await client.callTool({ name: "list_formats", arguments: {} })); - expect(formats).toContain("benchmark: Benchmark note."); - expect(formats).toContain(" - Setup:"); + expect(formats).toContain("concept-note: Concept note."); + expect(formats).toContain(" - Intuition:"); + expect(formats).not.toContain("benchmark"); const made = text( await client.callTool({ name: "create_document", - arguments: { title: "Agent benchmark", format: "benchmark" }, + arguments: { title: "Agent concept", format: "concept-note" }, }), ); - expect(made).toContain("format benchmark"); + expect(made).toContain("format concept-note"); // The page appears in the list at once; opening it shows the format. - const row = page.getByRole("navigation", { name: "Pages" }).getByText("Agent benchmark"); + const row = page.getByRole("navigation", { name: "Pages" }).getByText("Agent concept"); await expect(row).toBeVisible({ timeout: 15_000 }); await row.click(); await expect(page.locator(".page-editor h2")).toHaveCount(6); - await expect(page.getByRole("button", { name: /^Benchmark note/ })).toBeVisible(); + await expect(page.getByRole("button", { name: /^Concept note/ })).toBeVisible(); const outline = text(await client.callTool({ name: "get_outline", arguments: {} })); - expect(outline).toContain("open in Lucid, format benchmark"); - expect(outline).toContain("SECTIONS of this benchmark note"); + expect(outline).toContain("open in Lucid, format concept-note"); + expect(outline).toContain("SECTIONS of this concept note"); const added = await client.callTool({ name: "insert_notes", - arguments: { lmd: "- M4 Max, 48 GB\n- LM Studio", position: "section:Setup" }, + arguments: { lmd: "- Hash the key\n- Set the bits", position: "section:Intuition" }, }); expect(added.isError).toBe(false); const order = await page .locator(".page-editor .bn-block-content") .evaluateAll((els) => els.map((e) => e.textContent.trim()).filter((t) => t.length > 0)); expect(order.slice(0, 5)).toEqual([ - "Goal and hypothesis", - "Setup", - "M4 Max, 48 GB", - "LM Studio", - "Method", + "Definition", + "Intuition", + "Hash the key", + "Set the bits", + "How it works", ]); const bad = await client.callTool({ diff --git a/apps/desktop/electron/appBackend.test.ts b/apps/desktop/electron/appBackend.test.ts index 391ef5f..b6eaa83 100644 --- a/apps/desktop/electron/appBackend.test.ts +++ b/apps/desktop/electron/appBackend.test.ts @@ -204,14 +204,14 @@ describe("AppBackend", () => { const { backend, files, a, compiled } = setup(); files.set(a.id, { ...a, - meta: { vocabulary: [], format: "benchmark", info: { model: "Q" } }, + meta: { vocabulary: [], format: "comparison", info: { source: "Q" } }, }); await backend.exportPdf(a.id); expect(compiled[0]).toMatchObject({ pageId: `agent-${a.id}`, title: "Closed page", - format: { id: "benchmark" }, - info: { model: "Q" }, + format: { id: "comparison" }, + info: { source: "Q" }, }); }); diff --git a/apps/desktop/electron/pdf.test.ts b/apps/desktop/electron/pdf.test.ts index 0d9b062..c8483e0 100644 --- a/apps/desktop/electron/pdf.test.ts +++ b/apps/desktop/electron/pdf.test.ts @@ -400,25 +400,25 @@ shellScripts("PdfCompiler with stand-in tools", () => { title: "Q", doc: { blocks: [ - heading("a", "Goal and hypothesis"), + heading("a", "Context"), { id: "p", type: "paragraph", props: {}, - content: [{ type: "text", text: "Does it?", styles: {} }], + content: [{ type: "text", text: "Which queue?", styles: {} }], }, - heading("b", "Setup"), + heading("b", "Options"), ], }, figures: {}, - format: getFormat("benchmark"), - info: { hardware: "M4 Max", source: "ignored" }, + format: getFormat("comparison"), + info: { date: "2026-10-12", hardware: "ignored" }, }); const tex = await readFile(join(workRoot, "page-7", "main.tex"), "utf8"); - expect(tex).toContain("\\lucidmeta{Hardware}{M4 Max}"); + expect(tex).toContain("\\lucidmeta{Date}{2026-10-12}"); expect(tex).not.toContain("ignored"); - expect(tex).toContain("{Goal and hypothesis}"); - expect(tex).not.toContain("{Setup}"); + expect(tex).toContain("{Context}"); + expect(tex).not.toContain("{Options}"); }); it("writes main.tex, the style and one work folder per page", async () => { diff --git a/apps/desktop/src/pages/NewPageDialog.tsx b/apps/desktop/src/pages/NewPageDialog.tsx index ad0b48e..487aab4 100644 --- a/apps/desktop/src/pages/NewPageDialog.tsx +++ b/apps/desktop/src/pages/NewPageDialog.tsx @@ -95,7 +95,7 @@ export function NewPageDialog({ onCreate, onClose }: Props) { ref={field} rows={2} value={about} - placeholder="notes on how paged attention saves KV memory…" + placeholder="notes on how consistent hashing works…" onChange={(e) => { setAbout(e.target.value); }} @@ -124,33 +124,46 @@ export function NewPageDialog({ onCreate, onClose }: Props) { -
- {[ - { id: BLANK, name: "Blank page", description: "Start empty and write what you like." }, - ...FORMATS, - ].map((f) => ( -