Merge pull request #1668 from paperclipai/pr/pap-803-imported-agent-frontmatter
Fix imported agent bundle frontmatter leakage
This commit is contained in:
commit
f92d2c3326
2 changed files with 83 additions and 0 deletions
|
|
@ -2108,5 +2108,78 @@ describe("company portability", () => {
|
||||||
replaceExisting: true,
|
replaceExisting: true,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
const materializedFiles = agentInstructionsSvc.materializeManagedBundle.mock.calls[0]?.[1] as Record<string, string>;
|
||||||
|
expect(materializedFiles["AGENTS.md"]).not.toMatch(/^---\n/);
|
||||||
|
expect(materializedFiles["AGENTS.md"]).not.toContain('name: "ClaudeCoder"');
|
||||||
|
});
|
||||||
|
|
||||||
|
it("strips root AGENTS frontmatter when importing a nested agent entry path", 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 exported = await portability.exportBundle("company-1", {
|
||||||
|
include: {
|
||||||
|
company: true,
|
||||||
|
agents: true,
|
||||||
|
projects: false,
|
||||||
|
issues: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const originalAgentsMarkdown = exported.files["agents/claudecoder/AGENTS.md"];
|
||||||
|
expect(typeof originalAgentsMarkdown).toBe("string");
|
||||||
|
|
||||||
|
const files = {
|
||||||
|
...exported.files,
|
||||||
|
"agents/claudecoder/nested/AGENTS.md": originalAgentsMarkdown!,
|
||||||
|
};
|
||||||
|
|
||||||
|
agentSvc.list.mockResolvedValue([]);
|
||||||
|
|
||||||
|
await portability.importBundle({
|
||||||
|
source: {
|
||||||
|
type: "inline",
|
||||||
|
rootPath: exported.rootPath,
|
||||||
|
files,
|
||||||
|
},
|
||||||
|
include: {
|
||||||
|
company: true,
|
||||||
|
agents: true,
|
||||||
|
projects: false,
|
||||||
|
issues: false,
|
||||||
|
},
|
||||||
|
target: {
|
||||||
|
mode: "new_company",
|
||||||
|
newCompanyName: "Imported Paperclip",
|
||||||
|
},
|
||||||
|
agents: ["claudecoder"],
|
||||||
|
collisionStrategy: "rename",
|
||||||
|
adapterOverrides: {
|
||||||
|
claudecoder: {
|
||||||
|
adapterType: "codex_local",
|
||||||
|
adapterConfig: {
|
||||||
|
dangerouslyBypassApprovalsAndSandbox: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, "user-1");
|
||||||
|
|
||||||
|
const nestedMaterializedFiles = agentInstructionsSvc.materializeManagedBundle.mock.calls
|
||||||
|
.map(([, filesArg]) => filesArg as Record<string, string>)
|
||||||
|
.find((filesArg) => typeof filesArg["nested/AGENTS.md"] === "string");
|
||||||
|
|
||||||
|
expect(nestedMaterializedFiles).toBeDefined();
|
||||||
|
expect(nestedMaterializedFiles?.["nested/AGENTS.md"]).toContain("You are ClaudeCoder.");
|
||||||
|
expect(nestedMaterializedFiles?.["AGENTS.md"]).toContain("You are ClaudeCoder.");
|
||||||
|
expect(nestedMaterializedFiles?.["AGENTS.md"]).not.toMatch(/^---\n/);
|
||||||
|
expect(nestedMaterializedFiles?.["AGENTS.md"]).not.toContain('name: "ClaudeCoder"');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -3864,6 +3864,16 @@ export function companyPortabilityService(db: Db, storage?: StorageService) {
|
||||||
: []),
|
: []),
|
||||||
);
|
);
|
||||||
const markdownRaw = bundleFiles["AGENTS.md"] ?? readPortableTextFile(plan.source.files, manifestAgent.path);
|
const markdownRaw = bundleFiles["AGENTS.md"] ?? readPortableTextFile(plan.source.files, manifestAgent.path);
|
||||||
|
const entryRelativePath = normalizePortablePath(manifestAgent.path).startsWith(bundlePrefix)
|
||||||
|
? normalizePortablePath(manifestAgent.path).slice(bundlePrefix.length)
|
||||||
|
: "AGENTS.md";
|
||||||
|
if (typeof markdownRaw === "string") {
|
||||||
|
const importedInstructionsBody = parseFrontmatterMarkdown(markdownRaw).body;
|
||||||
|
bundleFiles[entryRelativePath] = importedInstructionsBody;
|
||||||
|
if (entryRelativePath !== "AGENTS.md") {
|
||||||
|
bundleFiles["AGENTS.md"] = importedInstructionsBody;
|
||||||
|
}
|
||||||
|
}
|
||||||
const fallbackPromptTemplate = asString((manifestAgent.adapterConfig as Record<string, unknown>).promptTemplate) || "";
|
const fallbackPromptTemplate = asString((manifestAgent.adapterConfig as Record<string, unknown>).promptTemplate) || "";
|
||||||
if (!markdownRaw && fallbackPromptTemplate) {
|
if (!markdownRaw && fallbackPromptTemplate) {
|
||||||
bundleFiles["AGENTS.md"] = fallbackPromptTemplate;
|
bundleFiles["AGENTS.md"] = fallbackPromptTemplate;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue