Merge verified Claude setup recovery and CI deadline fixes

Co-Authored-By: Paperclip <noreply@paperclip.ing>

* codex/claude-runner-default:
  fix: unlock Claude setup when automatic runner discovery changes
  test: allow the configured snapshot worker deadline in CI
This commit is contained in:
DottaandPaperclip committed 2026-10-15 07:12:30 -05:00
commit 84592191eb
3 files changed
+32 -2

No files matched your search

@@ -444,7 +444,7 @@ describe("sandbox managed runtime", () => {
await prepared.restoreWorkspace();
expect(await readFile(path.join(local, "file.txt"), "utf8")).toBe("after");
} finally { capture.mockRestore(); }
});
}, 30_000);
it.each(["host_current", "adopt_remote", "durable_seed"] as const)("stages and restores both project repositories with independent Git histories (%s)", async (mode) => {
const root = await mkdtemp(path.join(os.tmpdir(), "paperclip-multi-repo-"));
@@ -3485,6 +3485,36 @@ describe("OnboardingWizard restore-gate (stale localStorage across accounts)", (
} finally { await act(async () => root.unmount()); }
});
it("unlocks Claude setup when automatic runner availability changes during verification", async () => {
mockAdapterBuild.buildAdapterConfig.mockImplementation(values => buildClaudeLocalConfig(values!));
mockAdaptersApi.list.mockResolvedValue([setupAdapterInfo({ type: "claude_local", defaultRunner: "paperclip" })]);
const finishes: Array<(value: typeof passed) => void> = [];
mockAgentsApi.testEnvironment.mockImplementation(() => new Promise(resolve => finishes.push(resolve)));
const { root, queryClient } = await openStep4({ adapterType: "claude_local" });
try {
await pickSource(/Claude/);
await detected();
expect(mockAgentsApi.testEnvironment).toHaveBeenCalledTimes(1);
expectTesting();
mockAdaptersApi.list.mockResolvedValue([setupAdapterInfo({ type: "claude_local", defaultRunner: "legacy" })]);
await act(async () => queryClient.setQueryData(queryKeys.adapters.availability("company-new", LOCAL_ENVIRONMENT.id), [setupAdapterInfo({ type: "claude_local", defaultRunner: "legacy" })]));
await settle();
expect(document.body.textContent).toContain("Configuration changed during setup");
expect(button("Connect").disabled).toBe(false);
expect(mockAgentsApi.testEnvironment).toHaveBeenCalledTimes(1);
await act(async () => finishes[0](passed));
await settle();
expect(mockAgentsApi.hire).not.toHaveBeenCalled();
await click("Connect");
expect(mockAgentsApi.testEnvironment).toHaveBeenCalledTimes(2);
await act(async () => finishes[1](passed));
await settle();
expect(mockAgentsApi.hire).toHaveBeenCalledTimes(1);
const hired = mockAgentsApi.hire.mock.calls[0] as unknown as [string, { adapterConfig: Record<string, unknown> }];
expect(hired[1].adapterConfig.maxTurnsPerRun).toBe(1000);
} finally { await act(async () => root.unmount()); }
});
it("fails closed on Claude discovery rejection and retries availability before verification", async () => {
mockAdaptersApi.list.mockRejectedValue(new Error("Discovery unavailable"));
const { root, queryClient } = await openStep4({ adapterType: "claude_local" });
+1 -1
View File
@@ -1032,7 +1032,7 @@ function OnboardingWizardInner({
null,
[loginEnvironmentList, resolvedLoginEnvironmentId],
);
const claudeSetupSelectionKey = JSON.stringify([createdCompanyId, adapterType, runner, model, command,
const claudeSetupSelectionKey = JSON.stringify([createdCompanyId, adapterType, runner, resolvedRunner, model, command,
args, url, credentialMode, apiKey, selectedSavedKey, selectedApiKey?.binding, savedSubscription?.binding,
resolvedLoginEnvironmentId, resolvedLoginEnvironment?.config]);
const claudeSetupSelectionRef = useRef(claudeSetupSelectionKey);