Preserve explicit local adapter import bypasses

This commit is contained in:
Dotta committed 2026-05-05 15:01:26 -05:00
1 parent 66f05a1086
commit dcaddf42a3
2 files changed
+93 -10

No files matched your search

@@ -2343,6 +2343,99 @@ describe("company portability", () => {
expect(materializedFiles["AGENTS.md"]).not.toContain('name: "ClaudeCoder"');
});
it("does not silently add local adapter permission bypasses on import", async () => {
const portability = companyPortabilityService({} as any);
companySvc.create.mockResolvedValue({
id: "company-imported",
name: "Imported Paperclip",
});
accessSvc.ensureMembership.mockResolvedValue(undefined);
agentSvc.create.mockImplementation(async (_companyId: string, input: Record<string, unknown>) => ({
id: "agent-created",
name: String(input.name),
adapterType: input.adapterType,
adapterConfig: input.adapterConfig,
}));
const exported = await portability.exportBundle("company-1", {
include: {
company: true,
agents: true,
projects: false,
issues: false,
},
});
agentSvc.list.mockResolvedValue([]);
await portability.importBundle({
source: {
type: "inline",
rootPath: exported.rootPath,
files: exported.files,
},
include: {
company: true,
agents: true,
projects: false,
issues: false,
},
target: {
mode: "new_company",
newCompanyName: "Imported Paperclip",
},
agents: ["claudecoder"],
collisionStrategy: "rename",
}, "user-1");
expect(agentSvc.create).toHaveBeenCalledWith("company-imported", expect.objectContaining({
adapterType: "claude_local",
adapterConfig: expect.not.objectContaining({
dangerouslySkipPermissions: expect.anything(),
}),
}));
await portability.importBundle({
source: {
type: "inline",
rootPath: exported.rootPath,
files: exported.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: {},
},
},
}, "user-1");
expect(agentSvc.create).toHaveBeenLastCalledWith("company-imported", expect.objectContaining({
adapterType: "codex_local",
adapterConfig: expect.objectContaining({
extraArgs: ["--skip-git-repo-check"],
}),
}));
expect(agentSvc.create).toHaveBeenLastCalledWith("company-imported", expect.objectContaining({
adapterConfig: expect.not.objectContaining({
dangerouslyBypassApprovalsAndSandbox: expect.anything(),
dangerouslyBypassSandbox: expect.anything(),
}),
}));
});
it("preserves issue labelIds through export and import round-trip", async () => {
const portability = companyPortabilityService({} as any);
@@ -732,19 +732,9 @@ function applyImportAdapterRunDefaults(
adapterConfig: Record<string, unknown>,
) {
const next = { ...adapterConfig };
if (
adapterType === "codex_local"
&& !hasOwn(next, "dangerouslyBypassApprovalsAndSandbox")
&& !hasOwn(next, "dangerouslyBypassSandbox")
) {
next.dangerouslyBypassApprovalsAndSandbox = true;
}
if (adapterType === "codex_local") {
appendCodexImportArg(next, "--skip-git-repo-check");
}
if (adapterType === "claude_local" && !hasOwn(next, "dangerouslySkipPermissions")) {
next.dangerouslySkipPermissions = true;
}
return next;
}