* 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>
79 lines
2.9 KiB
TypeScript
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,
|
|
});
|
|
});
|
|
});
|