Official

chat

Built-in chat 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/chat@0.2.0

Permissions in 0.2.0

  • Control chats chats.controlHighCreates chats, sends prompts and cancels runs.Send prompts, answer agent questions, and create, change, fork, revert, stop and group chats
  • Run other plugins' commands commands.runHighRuns commands of other plugins.Run the sidebar's New chat command from the title bar
  • Read chats chats.readMediumReads your transcripts and chat lists.Show workspaces, tasks, chats and transcripts, and follow them as agents work
  • Read files fs.readMediumReads files in the listed places.Suggest workspace files for @ mentionsPlaces: the open workspace
  • Show panels ui.slotsLowShows views in the listed parts of the window.Draw the chat grid and the title barSlots: centertitle

Files

questions.test.ts1.6 KB
// Regression coverage for questions using the real chat modules.
// Fixtures exercise the same behavior and assertions as the JavaScript tests.
import assert from "node:assert/strict";
import test from "node:test";
import { renderQuestion } from "./views/questions.ts";
import { harness, nodes, transcript } from "./ui-for-tests.test.ts";
import type { Question } from "./state.ts";
const h = harness();
const opened = h.opened;
const responses: unknown[] = [];
test("a URL question opens its web page and accepts the elicitation", async () => {
  const req: Question = {
    responseMode: "tool",
    id: "q1",
    message: "Sign in to continue",
    url: "https://example.com/oauth/start",
    fields: [],
  };
  const t = transcript();
  t.questions = [req];
  h.controller.state.transcripts["chat-1"] = t;
  const card = renderQuestion(h.v, "chat-1", t, req);
  assert.ok(
    nodes(card).some((node) => node.type === "text" && node.text === req.url),
    "the destination is visible",
  );
  const button = nodes(card).find((node) => node.type === "button" && node.label === "Open link");
  assert.ok(button, "the external action is explicit");

  await button.onClick();
  await h.settle();
  responses.push(...h.calls.filter((call) => call.method === "host/chats.respond_question").map((call) => call.params));

  assert.deepEqual(opened, ["https://example.com/oauth/start"]);
  assert.deepEqual(responses, [{ chatId: "chat-1", questionId: "q1", answer: { values: {}, cancelled: false } }]);
  assert.deepEqual(t.questions, []);
});

assert.equal(typeof renderQuestion, "function", "the imported implementation is available");

Versions

VersionPublishedPlugin APISizePermissionsStatus
0.2.0latestOct 5, 2026>=2 <3105.1 KB5 permissionsListed

Reviews and comments

0 threads · 0 reviews

No comments yet.