Official
sidebar
Built-in sidebar UI (JavaScript UI plugin).
The app opens the listing; nothing installs until an agent in your Plugins workspace has read the files and you enable the plugin. In a terminal: cvg install convergence/sidebar@0.2.0
Permissions in 0.2.0
Files
preview.test.ts3.7 KB
import assert from "node:assert/strict";
import test from "node:test";
import type { TranscriptItem } from "convergence";
import { createPreview, transcriptPreview, updatePreview } from "./preview.ts";
test("preview follows streamed lines, tools, and the final answer", () => {
const preview = createPreview();
updatePreview(preview, { event: "text_delta", itemId: "a", text: "Checking the\nconfiguration", mode: "append" });
assert.equal(preview.line, "configuration");
updatePreview(preview, { event: "text_delta", itemId: "a", text: " now.\n", mode: "append" });
assert.equal(preview.line, "configuration now.");
updatePreview(preview, {
event: "tool_call_started",
id: "tool",
name: "read",
kind: "read",
title: "Read settings.json",
status: "running",
});
assert.equal(preview.line, "Read settings.json");
updatePreview(preview, { event: "tool_call_updated", id: "tool", title: "Read config/settings.json" });
assert.equal(preview.line, "Read config/settings.json");
updatePreview(preview, { event: "text_delta", itemId: "b", text: "Fixed the configuration.", mode: "append" });
assert.equal(preview.line, "Fixed the configuration.");
assert.equal(
updatePreview(preview, { event: "tool_call_updated", id: "tool", status: "completed", title: "Read complete" }),
false,
);
assert.equal(preview.line, "Fixed the configuration.");
assert.equal(updatePreview(preview, { event: "run_finished", outcome: { status: "completed" } }), false);
});
test("replacement snapshots and reasoning retain the latest non-empty line", () => {
const preview = createPreview();
updatePreview(preview, { event: "reasoning_delta", itemId: "r", text: "Considering options", mode: "append" });
assert.equal(preview.line, "Considering options");
updatePreview(preview, {
event: "reasoning_delta",
itemId: "r",
text: "Revised\nA simpler approach\n",
mode: "replace",
});
assert.equal(preview.line, "A simpler approach");
updatePreview(preview, { event: "text_delta", itemId: "a", text: "", mode: "append" });
assert.equal(preview.line, "A simpler approach");
updatePreview(preview, { event: "text_delta", itemId: "a", text: "x".repeat(2000), mode: "append" });
assert.equal(preview.text.length, 512);
});
test("history restores activity without letting user messages or notices replace it", () => {
const items: TranscriptItem[] = [
{ id: "a", role: "assistant", text: "First line\nFinal line\n" },
{
id: "tool",
role: "tool",
call: { id: "tool", name: "edit", kind: "edit", title: "Edit app.rs", status: "failed" },
},
{ id: "notice", role: "notice", text: "Error" },
{ id: "user", role: "user", blocks: [] },
];
assert.equal(transcriptPreview(items).line, "Edit app.rs");
assert.equal(
transcriptPreview([...items, { id: "answer", role: "assistant", text: "Done\nTests pass" }]).line,
"Tests pass",
);
assert.equal(transcriptPreview([]).line, "");
const other = createPreview();
assert.equal(other.line, "");
});
test("a message's line is shown without its Markdown marks", () => {
const line = (text: string) => {
const preview = createPreview();
updatePreview(preview, { event: "text_delta", itemId: "a", text, mode: "replace" });
return preview.line;
};
assert.equal(line("**There are 8 files.**"), "There are 8 files.");
assert.equal(line("Files: `index.html`, `style.css`, `pool.js`."), "Files: index.html, style.css, pool.js.");
assert.equal(line("Done.\n- See [the guide](https://example.com) for **more**"), "See the guide for more");
assert.equal(line("## Summary"), "Summary");
// Mid-stream, an unclosed mark goes too.
assert.equal(line("**Checking the con"), "Checking the con");
});Versions
| Version | Published | Plugin API | Size | Permissions | Status |
|---|---|---|---|---|---|
| 0.2.0latest | Oct 5, 2026 | >=2 <3 | 20.2 KB | 3 permissions | Listed |
No comments yet.