Fix portability import and org chart test blockers

This commit is contained in:
dotta
2026-03-20 14:06:37 -05:00
parent 1830216078
commit 553e7b6b30
5 changed files with 251 additions and 12 deletions

View File

@@ -623,6 +623,124 @@ describe("company portability", () => {
]);
});
it("imports a vendor-neutral package without .paperclip.yaml", async () => {
const portability = companyPortabilityService({} as any);
companySvc.create.mockResolvedValue({
id: "company-imported",
name: "Imported Paperclip",
});
accessSvc.ensureMembership.mockResolvedValue(undefined);
agentSvc.create.mockResolvedValue({
id: "agent-created",
name: "ClaudeCoder",
});
const preview = await portability.previewImport({
source: {
type: "inline",
rootPath: "paperclip-demo",
files: {
"COMPANY.md": [
"---",
'schema: "agentcompanies/v1"',
'name: "Imported Paperclip"',
'description: "Portable company package"',
"---",
"",
"# Imported Paperclip",
"",
].join("\n"),
"agents/claudecoder/AGENTS.md": [
"---",
'name: "ClaudeCoder"',
'title: "Software Engineer"',
"---",
"",
"# ClaudeCoder",
"",
"You write code.",
"",
].join("\n"),
},
},
include: {
company: true,
agents: true,
projects: false,
issues: false,
},
target: {
mode: "new_company",
newCompanyName: "Imported Paperclip",
},
agents: "all",
collisionStrategy: "rename",
});
expect(preview.errors).toEqual([]);
expect(preview.manifest.company?.name).toBe("Imported Paperclip");
expect(preview.manifest.agents).toEqual([
expect.objectContaining({
slug: "claudecoder",
name: "ClaudeCoder",
adapterType: "process",
}),
]);
expect(preview.envInputs).toEqual([]);
await portability.importBundle({
source: {
type: "inline",
rootPath: "paperclip-demo",
files: {
"COMPANY.md": [
"---",
'schema: "agentcompanies/v1"',
'name: "Imported Paperclip"',
'description: "Portable company package"',
"---",
"",
"# Imported Paperclip",
"",
].join("\n"),
"agents/claudecoder/AGENTS.md": [
"---",
'name: "ClaudeCoder"',
'title: "Software Engineer"',
"---",
"",
"# ClaudeCoder",
"",
"You write code.",
"",
].join("\n"),
},
},
include: {
company: true,
agents: true,
projects: false,
issues: false,
},
target: {
mode: "new_company",
newCompanyName: "Imported Paperclip",
},
agents: "all",
collisionStrategy: "rename",
}, "user-1");
expect(companySvc.create).toHaveBeenCalledWith(expect.objectContaining({
name: "Imported Paperclip",
description: "Portable company package",
}));
expect(agentSvc.create).toHaveBeenCalledWith("company-imported", expect.objectContaining({
name: "ClaudeCoder",
adapterType: "process",
}));
});
it("treats no-separator auth and api key env names as secrets during export", async () => {
const portability = companyPortabilityService({} as any);

View File

@@ -3,7 +3,6 @@
* Supports 5 visual styles: monochrome, nebula, circuit, warmth, schematic.
* Pure SVG output — no browser/Playwright needed. PNG via sharp.
*/
import sharp from "sharp";
export interface OrgNode {
id: string;
@@ -546,6 +545,8 @@ export function renderOrgChartSvg(orgTree: OrgNode[], style: OrgChartStyle = "wa
export async function renderOrgChartPng(orgTree: OrgNode[], style: OrgChartStyle = "warmth"): Promise<Buffer> {
const svg = renderOrgChartSvg(orgTree, style);
const sharpModule = await import("sharp");
const sharp = sharpModule.default;
// Render at 2x density for retina quality, resize to exact target dimensions
return sharp(Buffer.from(svg), { density: 144 })
.resize(TARGET_W, TARGET_H)