Files
Benjamin Taylor b394f06fdc refactor(channels): rename @copilotkit/bot* packages to @copilotkit/channels* (OSS-438)
Renames the Bots SDK to the Channels SDK. Names only — no behavior change.

- 8 packages @copilotkit/bot* -> @copilotkit/channels* (git mv dirs, names,
  workspace: cross-deps). Now includes @copilotkit/bot-intelligence ->
  @copilotkit/channels-intelligence (landed on main via #5761; unpublished, so
  renamed fresh with the family).
- release.config.json scope keys + versionSource; ReleaseScope union;
  canary/stable-release/publish-release scope dropdowns; verify script
- examples/slack (Kite) + examples/teams: deps, jsxImportSource, imports
- showcase/shell-docs: content dirs docs/bots->docs/channels and
  reference/bot->reference/channels, nav registry, redirects

createBot and other API names unchanged. Old @copilotkit/bot* to be deprecated
after the new packages publish (bot-intelligence was never published).

Re-derived onto latest main (was conflicting after #5761 landed).

Refs OSS-438
2026-07-08 13:27:35 -05:00

118 lines
3.7 KiB
TypeScript

/**
* Render-tool wrappers post the finished JSX component to the thread. We
* drive each tool's handler with a minimal fake `thread` whose `post` records
* the posted `Renderable`, then assert that rendering it through the shared
* `renderToIR` → `renderSlackMessage` path yields the expected Block Kit
* shape — i.e. the tool posted the right component.
*/
import { describe, it, expect } from "vitest";
import { renderToIR } from "@copilotkit/channels-ui";
import { renderSlackMessage } from "@copilotkit/channels-slack";
import { issueCardTool, issueListTool, pageListTool } from "../render-tools.js";
/** A fake `thread` that records each posted Renderable. */
function fakeThread() {
const posts: unknown[] = [];
const thread = {
post: async (ui: unknown) => {
posts.push(ui);
return { id: "m1" };
},
};
return { posts, ctx: { thread, platform: "slack" } as never };
}
describe("issue_card render-tool", () => {
it("posts an IssueCard rendering to a header + linked title", async () => {
const { posts, ctx } = fakeThread();
const result = await issueCardTool.handler(
{
identifier: "CPK-101",
title: "Checkout 500s under load",
url: "https://linear.app/copilotkit/issue/CPK-101",
state: "In Progress",
assignee: "Alem",
priority: "Urgent",
},
ctx,
);
expect(posts).toHaveLength(1);
expect(result).toBe("Displayed the issue card to the user.");
const { blocks } = renderSlackMessage(renderToIR(posts[0] as never));
expect(blocks[0]).toMatchObject({
type: "header",
text: { type: "plain_text", text: "🔵 CPK-101" },
});
expect(JSON.stringify(blocks)).toContain(
"<https://linear.app/copilotkit/issue/CPK-101|*Checkout 500s under load*>",
);
});
});
describe("issue_list render-tool", () => {
it("posts an IssueList rendering to a header + one row per issue", async () => {
const { posts, ctx } = fakeThread();
const result = await issueListTool.handler(
{
heading: "Open CPK issues",
issues: [
{
identifier: "CPK-101",
title: "Checkout 500s under load",
url: "https://linear.app/copilotkit/issue/CPK-101",
state: "In Progress",
},
],
},
ctx,
);
expect(posts).toHaveLength(1);
expect(result).toBe("Displayed the issue list to the user.");
const { blocks } = renderSlackMessage(renderToIR(posts[0] as never));
expect(blocks[0]).toMatchObject({
type: "header",
text: { type: "plain_text", text: "📋 Open CPK issues" },
});
expect(JSON.stringify(blocks)).toContain(
"<https://linear.app/copilotkit/issue/CPK-101|*CPK-101*>",
);
expect(JSON.stringify(blocks)).toContain("1 issue");
});
});
describe("page_list render-tool", () => {
it("posts a PageList rendering to a header + one row per page", async () => {
const { posts, ctx } = fakeThread();
const result = await pageListTool.handler(
{
heading: "Runbooks",
pages: [
{
title: "Auth outage runbook",
url: "https://www.notion.so/abc",
snippet: "Steps to mitigate auth provider downtime.",
},
],
},
ctx,
);
expect(posts).toHaveLength(1);
expect(result).toBe("Displayed the Notion pages to the user.");
const { blocks } = renderSlackMessage(renderToIR(posts[0] as never));
expect(blocks[0]).toMatchObject({
type: "header",
text: { type: "plain_text", text: "📚 Runbooks" },
});
expect(JSON.stringify(blocks)).toContain(
"<https://www.notion.so/abc|*Auth outage runbook*>",
);
expect(JSON.stringify(blocks)).toContain("1 page");
});
});