mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-08 01:57:31 +01:00
PAP-10287 address teams catalog review feedback
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
df100082e6
commit
7812174f0e
8 files changed
+242
-67
No files matched your search
@@ -502,6 +502,36 @@ describe("teams CLI commands", () => {
|
||||
expect(errorSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("does not request board approval for unrelated forbidden install errors", async () => {
|
||||
fetchMock.mockResolvedValueOnce(jsonResponse({ error: "Agent key cannot access another company" }, 403));
|
||||
vi.spyOn(process, "exit").mockImplementation(((code?: string | number | null) => {
|
||||
throw new Error(`exit:${code ?? 0}`);
|
||||
}) as typeof process.exit);
|
||||
|
||||
await expect(runCommand([
|
||||
"teams",
|
||||
"install",
|
||||
"product-engineering",
|
||||
"--company-id",
|
||||
"company-1",
|
||||
"--request-approval-on-forbidden",
|
||||
"--api-base",
|
||||
"http://paperclip.test",
|
||||
"--api-key",
|
||||
"token",
|
||||
])).rejects.toThrow("exit:1");
|
||||
|
||||
expect(fetchMock).toHaveBeenCalledTimes(1);
|
||||
expect(fetchMock).toHaveBeenCalledWith(
|
||||
"http://paperclip.test/api/companies/company-1/teams/catalog/ref/install?ref=product-engineering",
|
||||
expect.objectContaining({
|
||||
method: "POST",
|
||||
body: JSON.stringify({}),
|
||||
}),
|
||||
);
|
||||
expect(String(errorSpy.mock.calls[0]?.[0])).toContain("Agent key cannot access another company");
|
||||
});
|
||||
|
||||
it("surfaces server blocks for unsafe local-path catalog team sources", async () => {
|
||||
fetchMock.mockResolvedValueOnce(jsonResponse({
|
||||
error: 'Local path skill source "../unsafe" is development-only and is not allowed for catalog team install.',
|
||||
|
||||
@@ -1750,11 +1750,11 @@ async function resolveCurrentCompanyId(ctx: { companyId?: string; api: { get<T>(
|
||||
}
|
||||
|
||||
function isBoardAccessRequiredError(error: unknown): error is ApiRequestError {
|
||||
return error instanceof ApiRequestError && error.status === 403 && error.message.includes("Board access required");
|
||||
return error instanceof ApiRequestError && error.status === 403 && error.message.toLowerCase().includes("board access required");
|
||||
}
|
||||
|
||||
function isInstanceAdminRequiredError(error: unknown): error is ApiRequestError {
|
||||
return error instanceof ApiRequestError && error.status === 403 && error.message.includes("Instance admin");
|
||||
return error instanceof ApiRequestError && error.status === 403 && error.message.toLowerCase().includes("instance admin");
|
||||
}
|
||||
|
||||
function addCompanyJsonPost(parent: Command, name: string, description: string, pathSuffix: string): void {
|
||||
|
||||
@@ -361,12 +361,16 @@ function buildTeamInstallOptions(opts: TeamInstallOptions): CatalogTeamInstallOp
|
||||
return buildTeamOptions(opts);
|
||||
}
|
||||
|
||||
const INSTALL_APPROVAL_FALLBACK_MESSAGES = [
|
||||
"missing permission: agents:create",
|
||||
"missing permission: can create agents",
|
||||
];
|
||||
|
||||
function shouldRequestInstallApproval(error: unknown, opts: TeamInstallOptions): error is ApiRequestError {
|
||||
return Boolean(
|
||||
(opts.requestApprovalOnForbidden || isPaperclipTaskRun()) &&
|
||||
error instanceof ApiRequestError &&
|
||||
error.status === 403,
|
||||
);
|
||||
if (!(opts.requestApprovalOnForbidden || isPaperclipTaskRun())) return false;
|
||||
if (!(error instanceof ApiRequestError) || error.status !== 403) return false;
|
||||
const message = error.message.toLowerCase();
|
||||
return INSTALL_APPROVAL_FALLBACK_MESSAGES.some((expected) => message.includes(expected));
|
||||
}
|
||||
|
||||
function isPaperclipTaskRun(): boolean {
|
||||
|
||||
Reference in new issue
Block a user