mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-07 16:35:48 +01:00
PAP-10287 tighten teams catalog review fixes
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
7812174f0e
commit
83278f0760
4 files changed
+41
-6
No files matched your search
@@ -291,6 +291,22 @@ describe("teamsCatalogService", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("omits the default-adapter warning when every agent has an explicit override", async () => {
|
||||
const svc = teamsCatalogService({} as any);
|
||||
|
||||
const result = await svc.installCatalogTeam("company-1", "core-exec-team", {
|
||||
adapterOverrides: {
|
||||
ceo: { adapterType: "opencode_local" },
|
||||
cto: { adapterType: "opencode_local" },
|
||||
qa: { adapterType: "opencode_local" },
|
||||
},
|
||||
});
|
||||
|
||||
expect(result.warnings).not.toEqual(
|
||||
expect.arrayContaining([expect.stringContaining("default to claude_local")]),
|
||||
);
|
||||
});
|
||||
|
||||
it("passes install secretValues through to company portability import", async () => {
|
||||
const svc = teamsCatalogService({} as any);
|
||||
|
||||
|
||||
@@ -1010,10 +1010,17 @@ export function teamsCatalogService(db: Db) {
|
||||
if (importPreview.errors.length > 0) {
|
||||
throw unprocessable(`Catalog team import preview has errors: ${importPreview.errors.join("; ")}`);
|
||||
}
|
||||
const defaultedAdapterSlugs = prepared.team.agentSlugs.filter(
|
||||
(slug) => !options.adapterOverrides?.[slug],
|
||||
);
|
||||
const warnings = [
|
||||
...prepared.warnings,
|
||||
...importPreview.warnings,
|
||||
`Catalog agents without explicit overrides default to ${DEFAULT_SAFE_CATALOG_ADAPTER_TYPE}. Pass adapterOverrides to use a different supported adapter.`,
|
||||
...(defaultedAdapterSlugs.length > 0
|
||||
? [
|
||||
`Catalog agents without explicit overrides (${defaultedAdapterSlugs.join(", ")}) default to ${DEFAULT_SAFE_CATALOG_ADAPTER_TYPE}. Pass adapterOverrides to use a different supported adapter.`,
|
||||
]
|
||||
: []),
|
||||
...await prepareSkillInstalls(companyId, prepared),
|
||||
];
|
||||
const result = await portability.importBundle(
|
||||
|
||||
@@ -8,7 +8,7 @@ import type {
|
||||
CatalogTeamImportPreviewResult,
|
||||
} from "@paperclipai/shared";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { TeamCatalog } from "./TeamCatalog";
|
||||
import { TeamCatalog, parseTeamRoute, teamRoute } from "./TeamCatalog";
|
||||
import { TooltipProvider } from "@/components/ui/tooltip";
|
||||
|
||||
const mockTeamCatalogApi = vi.hoisted(() => ({
|
||||
@@ -85,6 +85,18 @@ if (typeof Element !== "undefined" && !Element.prototype.scrollIntoView) {
|
||||
Element.prototype.scrollIntoView = () => {};
|
||||
}
|
||||
|
||||
describe("TeamCatalog routes", () => {
|
||||
it("round-trips file paths containing literal tildes", () => {
|
||||
const route = teamRoute("paperclipai/bundled/test/team", "agents/a~b/AGENTS.md");
|
||||
|
||||
expect(route).toBe("/teams-catalog/paperclipai%2Fbundled%2Ftest%2Fteam/files/agents%7Ea~b%7EAGENTS.md");
|
||||
expect(parseTeamRoute(route.replace("/teams-catalog/", ""))).toEqual({
|
||||
catalogRef: "paperclipai/bundled/test/team",
|
||||
filePath: "agents/a~b/AGENTS.md",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
async function act(callback: () => void | Promise<void>) {
|
||||
let result: void | Promise<void> = undefined;
|
||||
flushSync(() => {
|
||||
|
||||
@@ -174,19 +174,19 @@ function titleCase(slug: string): string {
|
||||
}
|
||||
|
||||
function encodeTeamFilePath(filePath: string): string {
|
||||
return filePath.split("/").map(encodeURIComponent).join("~");
|
||||
return filePath.split("/").map(encodeURIComponent).join("%7E");
|
||||
}
|
||||
|
||||
function decodeTeamFilePath(encoded: string | undefined): string | null {
|
||||
if (!encoded) return null;
|
||||
return encoded.split("~").map(decodeURIComponent).join("/");
|
||||
return encoded.split("%7E").map(decodeURIComponent).join("/");
|
||||
}
|
||||
|
||||
type ParsedRoute = { catalogRef: string | null; filePath: string | null };
|
||||
|
||||
const TEAM_CATALOG_ROUTE_ROOT = "/teams-catalog";
|
||||
|
||||
function parseTeamRoute(routePath: string | undefined): ParsedRoute {
|
||||
export function parseTeamRoute(routePath: string | undefined): ParsedRoute {
|
||||
if (!routePath) return { catalogRef: null, filePath: null };
|
||||
const segments = routePath.split("/").filter(Boolean);
|
||||
if (segments.length === 0) return { catalogRef: null, filePath: null };
|
||||
@@ -197,7 +197,7 @@ function parseTeamRoute(routePath: string | undefined): ParsedRoute {
|
||||
return { catalogRef, filePath: null };
|
||||
}
|
||||
|
||||
function teamRoute(catalogRef: string, filePath?: string | null): string {
|
||||
export function teamRoute(catalogRef: string, filePath?: string | null): string {
|
||||
const base = `${TEAM_CATALOG_ROUTE_ROOT}/${encodeURIComponent(catalogRef)}`;
|
||||
if (filePath) return `${base}/files/${encodeTeamFilePath(filePath)}`;
|
||||
return base;
|
||||
|
||||
Reference in new issue
Block a user