Remove misleading HTTPS prerequisite from Cloud GitHub setup

This commit is contained in:
Dotta committed 2026-10-08 05:10:57 -05:00
1 parent 84b521b4a4
commit b9d5a0e744
6 files changed
+19 -124

No files matched your search

+2 -6
View File
@@ -15,12 +15,6 @@ Enable **GitHub review bots** in instance **Experimental** settings, then open
the GitHub Code Review Bot connector. This default-off setting is independent of
**Chat connectors**. Hiding either feature does not pause existing provider delivery.
On an HTTP instance, setup explains the public HTTPS delivery requirement before
you choose an agent. An enrolled Paperclip Cloud connector supplies that webhook
address, including for localhost; otherwise connect Cloud during setup or provide
a public HTTPS address before creating the App. HTTP localhost alone is not a
delivery failure when Cloud is connected.
1. Choose the bot agent. Prefer a
[low-trust review agent](https://docs.paperclip.ing/administration/trust-and-low-trust-review/)
with an isolated sandbox and a scoped task boundary. Standard-trust agents
@@ -70,6 +64,8 @@ to the App settings list instead of assuming an owner.
Local instances receive public callbacks and signed events through an enrolled
Paperclip Cloud connector, using outbound requests instead of a public tunnel.
Your localhost instance does not need HTTPS or a tunnel for this flow. Setup
asks you to connect Cloud only if the instance is not already enrolled.
The Cloud gateway capability must be deployed before localhost onboarding.
Direct public-HTTPS webhook connections and manual existing-App credential
recovery remain supported. An expired, unconsumed Cloud handoff can be renewed in the same draft after the configuring manager confirms that no App was created on GitHub. Claimed, consumed, and uncertain exchanges still require existing-App recovery. Setup tasks and copied prompts are not part of this
@@ -392,3 +392,18 @@ retain App identity/configuration, and create no agent wakeup. UI/server
typecheck/build, production Storybook build, token gates and diff whitespace
checks pass. This remains connection qualification; the earlier full-suite
failure and outstanding current-head CI/review limits still apply.
### Correction: Cloud-backed localhost needs no HTTPS prerequisite (October 8)
The preceding HTTP prerequisite banner was misleading. Cloud already provides
the public HTTPS receiver, and localhost retrieves signed events through
outbound requests. The user's Paperclip origin does not need HTTPS or a tunnel
for this wizard. Removed the banner, its extra enrollment-status query, and
the two obsolete component stories. Keep the existing conditional Connect
Paperclip Cloud handoff as the actual setup action when enrollment is absent.
The running localhost wizard now shows Choose agent without an HTTPS warning.
No new connection or App was created during this correction. The delayed-ping
waiting and same-draft recovery fixes remain in place. All 30 focused setup and
management UI tests, UI typecheck/build, Storybook build and token gates pass.
The earlier full-suite and current-head CI/review limits still apply.
@@ -83,7 +83,7 @@ vi.mock("@/api/githubChat", () => ({
},
}));
vi.mock("@/api/tools", () => ({
toolsApi: { startCloudConnectorEnrollment: vi.fn(), getCloudConnectorEnrollment: vi.fn() },
toolsApi: { startCloudConnectorEnrollment: vi.fn() },
}));
vi.mock("@/lib/clipboard", () => ({ copyTextToClipboard: vi.fn() }));
@@ -162,14 +162,6 @@ describe("GitHub App wizard", () => {
});
vi.mocked(githubChatApi.saveDraft).mockResolvedValue({ saved: true });
vi.mocked(githubChatApi.personalConnections).mockResolvedValue([]);
vi.mocked(toolsApi.getCloudConnectorEnrollment).mockResolvedValue({
configured: false,
status: "not_configured",
brokerBaseUrl: "https://gateway.example",
instanceId: null,
environment: "staging",
origins: [],
});
vi.mocked(copyTextToClipboard).mockResolvedValue();
client = new QueryClient({
defaultOptions: { queries: { retry: false, gcTime: 0 } },
@@ -188,34 +180,6 @@ describe("GitHub App wizard", () => {
await new Promise((resolve) => setTimeout(resolve, 20));
});
}
it("explains HTTP delivery before choosing an agent without creating an App", async () => {
await render("agentId=reviewer");
expect(container.querySelector('[role="alert"]')?.textContent).toContain(
"publicly reachable HTTPS URL before creating an App",
);
expect(container.textContent).toContain(
"GitHub cannot send webhooks directly to this HTTP address",
);
expect(chatEndpointsApi.create).not.toHaveBeenCalled();
expect(githubChatApi.registration).not.toHaveBeenCalled();
});
it("explains that an enrolled Cloud gateway supports the HTTP instance", async () => {
vi.mocked(toolsApi.getCloudConnectorEnrollment).mockResolvedValue({
configured: true,
status: "active",
brokerBaseUrl: "https://gateway.example",
instanceId: "instance",
environment: "staging",
origins: [window.location.origin],
});
await render("agentId=reviewer");
expect(container.querySelector('[role="note"]')?.textContent).toContain(
"Cloud is connected and provides the HTTPS webhook",
);
expect(container.textContent).not.toContain(
"configure a publicly reachable HTTPS URL before creating",
);
});
it("shows pending signed delivery as waiting, not failed setup", async () => {
fixture.endpoint.botExternalId = "1234";
vi.mocked(githubChatApi.advance).mockResolvedValue({
@@ -315,7 +279,7 @@ describe("GitHub App wizard", () => {
}),
"company-1",
);
expect(container.textContent).not.toContain("Change Reviewer to a low trust agent");
expect(container.querySelector('[role="alert"]')).toBeNull();
await click("Continue");
expect(chatEndpointsApi.create).toHaveBeenCalledWith("company-1", {
provider: "github",
@@ -25,7 +25,6 @@ import { copyTextToClipboard } from "@/lib/clipboard";
import { resolveAgentAppearance } from "@paperclipai/shared";
import { agentAvatarUrl } from "@/lib/agent-avatar-url";
import { GitHubAppBranding, gitHubBotMention } from "./GitHubAppIdentity";
import { GitHubWebhookPrerequisite } from "./GitHubWebhookPrerequisite";
/** Restrict native manifest submission to GitHub registration endpoints. */
export function gitHubAppManifestAction(
@@ -117,12 +116,6 @@ export function GitHubChatSetup() {
refetchInterval: 3000,
});
const bot = current.data;
const cloudEnrollment = useQuery({
queryKey: ["cloud-connector", "enrollment"],
queryFn: () => toolsApi.getCloudConnectorEnrollment(),
enabled: !!selectedCompanyId && !identityOnly && window.location.protocol !== "https:",
retry: false,
});
const progress = useQuery({
queryKey: ["github-wizard", resume],
queryFn: () => githubChatApi.advance(resume!),
@@ -265,14 +258,6 @@ export function GitHubChatSetup() {
? "Connect your account"
: "Connect GitHub"}
</h1>
{!identityOnly && !connected && !bot?.botExternalId && (
<GitHubWebhookPrerequisite
origin={window.location.origin}
cloudState={cloudEnrollment.isPending ? "loading"
: cloudEnrollment.error ? "unavailable"
: cloudEnrollment.data?.status === "active" ? "active" : "required"}
/>
)}
{(error || (!identityOnly && progress.error) || accounts.error) && (
<p role="alert" className="text-sm text-destructive">
{error ||
@@ -1,44 +0,0 @@
import { AlertTriangle, Info } from "lucide-react";
export function GitHubWebhookPrerequisite({
origin,
cloudState,
}: {
origin: string;
cloudState: "loading" | "active" | "required" | "unavailable";
}) {
if (new URL(origin).protocol === "https:") return null;
const warning = cloudState === "required" || cloudState === "unavailable";
const Icon = warning ? AlertTriangle : Info;
return (
<div
role={warning ? "alert" : "note"}
className="flex items-start gap-3 rounded-lg border border-(--status-agent-paused)/30 bg-(--status-agent-paused)/10 p-4"
>
<Icon className="size-5 shrink-0 text-(--status-task-icon-todo)" />
<div className="space-y-2 text-sm">
<p className="font-semibold">
GitHub needs public HTTPS webhook delivery
</p>
<p>
GitHub cannot send webhooks directly to this HTTP address.
{cloudState === "active"
? " Paperclip Cloud is connected and provides the HTTPS webhook. Keep this instance running to receive events."
: cloudState === "loading"
? " Paperclip Cloud can provide HTTPS delivery. Checking its connection…"
: `${cloudState === "unavailable" ? " Couldn’t confirm Cloud delivery." : ""} Connect Paperclip Cloud during setup, or configure a publicly reachable HTTPS URL before creating an App.`}
</p>
{warning && (
<a
href="https://docs.paperclip.ing/reference/deploy/https/"
target="_blank"
rel="noreferrer"
className="underline underline-offset-4"
>
Set up public HTTPS
</a>
)}
</div>
</div>
);
}
@@ -20,7 +20,6 @@ import {
} from "@/pages/apps/chat/GitHubAppIdentity";
import { resolveAgentAppearance } from "@paperclipai/shared";
import { agentAvatarUrl } from "@/lib/agent-avatar-url";
import { GitHubWebhookPrerequisite } from "@/pages/apps/chat/GitHubWebhookPrerequisite";
import {
endpoint,
agent,
@@ -183,26 +182,6 @@ export const AppIdentityAndLogo: Story = {
</div>,
),
};
export const HttpSetupPrerequisite: Story = {
name: "03 Components / HTTP setup requires delivery",
render: () =>
component(
<GitHubWebhookPrerequisite
origin="http://localhost:3110"
cloudState="required"
/>,
),
};
export const HttpSetupWithCloud: Story = {
name: "03 Components / HTTP setup with Cloud connected",
render: () =>
component(
<GitHubWebhookPrerequisite
origin="http://localhost:3110"
cloudState="active"
/>,
),
};
export const ReviewHistory: Story = {
name: "03 Components / Review rows",
render: () =>