Files
paseo/packages/app/src/hooks/use-acp-provider-catalog.test.ts
T
5a0ea3385e feat(app): add ByteDance TRAE CLI to the ACP provider catalog (#1831)
* feat(app): add ByteDance TRAE CLI to the ACP provider catalog

Adds the official ByteDance TRAE CLI (traecli) to the in-app ACP provider
catalog. traecli is ACP-native, so Paseo drives it over the standard ACP
transport via `traecli acp serve`, reusing the generic ACP client exactly
like Kiro, Qoder, Cursor, and Gemini.

- catalog: traecli entry (command ["traecli","acp","serve"], manual install)
- icon: vendored TRAE monogram SVG + registered icon name
- docs: supported-providers list + CHANGELOG
- tests: focused command + icon-name assertions

Verified against the real traecli ACP surface in multica-ai/multica#4724.

* feat(app): use the real TRAE app logo for the traecli provider icon

* docs: drop TRAE CLI changelog entry

---------

Co-authored-by: Mohamed Boudra <boudra.moha@gmail.com>
2026-07-01 22:50:15 +02:00

79 lines
2.9 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { ACP_PROVIDER_CATALOG } from "@/data/acp-provider-catalog";
import { buildAcpProviderConfigPatch, getAcpProviderCatalog } from "./use-acp-provider-catalog";
function findProvider(id: string) {
const entry = getAcpProviderCatalog().find((provider) => provider.id === id);
if (!entry) {
throw new Error(`Missing ACP provider catalog entry: ${id}`);
}
return entry;
}
describe("ACP provider catalog", () => {
it("vendors provider entries with unique ids and concrete commands", () => {
const ids = new Set<string>();
for (const entry of ACP_PROVIDER_CATALOG) {
expect(ids.has(entry.id)).toBe(false);
ids.add(entry.id);
expect(entry.title).not.toBe("");
expect(entry.description).not.toBe("");
expect(entry.installLink).toMatch(/^https:\/\//);
expect(entry.command.length).toBeGreaterThan(0);
expect(entry.command[0]).not.toBe("");
}
});
it("bundles SVG icons for catalog entries that declare an icon", () => {
const entriesWithIcons = ACP_PROVIDER_CATALOG.filter((entry) => entry.iconSvg !== null);
expect(entriesWithIcons.length).toBeGreaterThan(0);
for (const entry of entriesWithIcons) {
expect(entry.iconSvg).toContain("<svg");
}
});
it("uses PATH commands for entries that were binary distributions upstream", () => {
expect(findProvider("amp-acp").command).toEqual(["amp-acp"]);
expect(findProvider("cursor").command).toEqual(["cursor-agent", "acp"]);
expect(findProvider("codewhale").command).toEqual(["codewhale", "serve", "--acp"]);
expect(findProvider("devin").command).toEqual(["devin", "acp"]);
expect(findProvider("goose").command).toEqual(["goose", "acp"]);
expect(findProvider("junie").command).toEqual(["junie", "--acp", "true"]);
expect(findProvider("kiro").command).toEqual(["kiro-cli", "acp"]);
expect(findProvider("poolside").command).toEqual(["pool", "acp"]);
expect(findProvider("traecli").command).toEqual(["traecli", "acp", "serve"]);
});
it("maps a catalog entry to the daemon provider config patch", () => {
expect(buildAcpProviderConfigPatch(findProvider("amp-acp"))).toEqual({
providers: {
"amp-acp": {
extends: "acp",
label: "Amp",
description: "ACP wrapper for Amp - the frontier coding agent",
command: ["amp-acp"],
env: {},
},
},
});
});
it("preserves provider env in the daemon config patch", () => {
const patch = buildAcpProviderConfigPatch(findProvider("auggie"));
expect(patch.providers?.auggie?.env).toEqual({
AUGMENT_DISABLE_AUTO_UPDATE: "1",
});
});
it("preserves provider params in the daemon config patch", () => {
const droidPatch = buildAcpProviderConfigPatch(findProvider("factory-droid"));
expect(droidPatch.providers?.["factory-droid"]?.params).toEqual({
supportsMcpServers: false,
});
});
});