Bots can now show a concept as a visual: create_graphic (with update_graphic, read_graphic and list_graphics, on every run, no computer needed) stores one HTML document in bot_graphics, per user like the conversation, and the chat renders its [graphic:ID] ref as an inline card sized to fit, with a large view and a page of its own (no rail). Graphic HTML is treated as hostile: it is only served at /graphics/<id> with a CSP sandbox allowing scripts under an origin of its own and no network, loading only the vendored Chart.js and Mermaid from /graphics-lib/. The document carries the app's theme vars and scrollbars, reports its height to the thread, and a frame that navigates away is closed. Co-Authored-By: Claude Opus 5.5 <[email protected]>
45 lines
1.9 KiB
TypeScript
45 lines
1.9 KiB
TypeScript
import { describe, expect, test } from "bun:test";
|
|
import exportMessageText from "./export-message-text";
|
|
|
|
const names = { bot_names: { 3: "Ada" }, workspace_names: { 2: "Launch" } };
|
|
|
|
describe("exportMessageText", () => {
|
|
test("words refs, naming what is known", () => {
|
|
expect(
|
|
exportMessageText({
|
|
text: "[bot:3] and [bot:9] in [workspace:2] on [computer:4], see [file:12] and [folder:computer:4:seo/raw]. [take-over:4:browser]",
|
|
...names,
|
|
heading_offset: 0,
|
|
}),
|
|
).toBe("@Ada and a bot in #Launch on computer 4, see file 12 and `seo/raw`. (take over computer 4, browser)");
|
|
});
|
|
|
|
test("words secrets and secret requests by number, never a value", () => {
|
|
expect(exportMessageText({ text: "Here: [secret:12]. [secret-request:4]", ...names, heading_offset: 0 })).toBe(
|
|
"Here: (secret 12, hidden). (secret request 4)",
|
|
);
|
|
});
|
|
|
|
test("words graphics by number", () => {
|
|
expect(exportMessageText({ text: "See [graphic:5]", ...names, heading_offset: 0 })).toBe("See (graphic 5)");
|
|
});
|
|
|
|
test("leaves refs that are already links alone", () => {
|
|
expect(exportMessageText({ text: "[bot:3](#x)", ...names, heading_offset: 0 })).toBe("[bot:3](#x)");
|
|
});
|
|
|
|
test("drops headings, capped at six", () => {
|
|
expect(
|
|
exportMessageText({ text: "# Top\n## Next\n##### Deep\n#nottag", ...names, heading_offset: 3 }),
|
|
).toBe("#### Top\n##### Next\n###### Deep\n#nottag");
|
|
});
|
|
|
|
test("leaves code blocks exactly as they are", () => {
|
|
const text = "```bash\n# comment [bot:3]\n```\n# Title\n~~~~\n## also code\n~~~\n~~~~";
|
|
|
|
expect(exportMessageText({ text, ...names, heading_offset: 3 })).toBe(
|
|
"```bash\n# comment [bot:3]\n```\n#### Title\n~~~~\n## also code\n~~~\n~~~~",
|
|
);
|
|
});
|
|
});
|