diff --git a/ui/src/adapters/codex-local/config-fields.test.tsx b/ui/src/adapters/codex-local/config-fields.test.tsx
index 47ca43073d..205634f74c 100644
--- a/ui/src/adapters/codex-local/config-fields.test.tsx
+++ b/ui/src/adapters/codex-local/config-fields.test.tsx
@@ -30,7 +30,7 @@ describe("Paperclip Runner Codex configuration", () => {
expect(html).toContain('');
expect(html).toContain("OpenCode 1.18.32");
- expect(html).toContain("ACPX");
+ expect(html).toContain('');
expect(html).not.toContain("Permission mode");
expect(html).not.toContain("Ask when requested");
expect(html).not.toContain("Ask for untrusted operations");
@@ -54,15 +54,19 @@ describe("Paperclip Runner Codex configuration", () => {
expect(html).not.toContain("Ask for untrusted operations");
});
- it("offers ACPX Claude without a redundant agent selector", () => {
+ it("offers qualified Claude and keeps candidate ACP agents visibly disabled", () => {
const html = renderRunner({
provider: "acpx",
acpxAgent: "claude",
acpxPermissionMode: "approve-reads",
});
- expect(html).toContain('');
- expect(html).not.toContain("ACP agent");
+ expect(html).toContain('');
+ expect(html).toContain("ACP agent");
+ expect(html).toContain('');
+ expect(html).toContain('');
+ expect(html).toContain('');
+ expect(html).toContain('');
expect(html).not.toContain("Codex via ACPX");
expect(html).not.toContain("ACPX Codex");
expect(html).not.toContain("Pi via ACPX");
diff --git a/ui/src/adapters/config-sections.test.tsx b/ui/src/adapters/config-sections.test.tsx
index 42a27e2235..5903e75e40 100644
--- a/ui/src/adapters/config-sections.test.tsx
+++ b/ui/src/adapters/config-sections.test.tsx
@@ -60,13 +60,26 @@ describe("adapter configuration sections", () => {
"runPolicy",
config,
);
- expect(adapter).toContain("ACPX Claude");
+ expect(adapter).toContain('');
expect(adapter).not.toContain("Runner lifecycle");
expect(configuration).not.toContain("Permission mode");
expect(configuration).not.toContain("Runner lifecycle");
expect(policy).toContain("Runner lifecycle");
expect(policy).toContain('value="45000"');
- expect(policy).not.toContain("ACPX Claude");
+ expect(policy).not.toContain("ACP agents");
+ });
+
+ it("keeps ACP agent admission choices in the adapter section", () => {
+ const config = { provider: "acpx", acpxAgent: "claude" };
+ const adapter = renderSection(CodexLocalConfigFields, "paperclip_runner", "adapter", config);
+ const policy = renderSection(CodexLocalConfigFields, "paperclip_runner", "runPolicy", config);
+
+ expect(adapter).toContain('');
+ expect(adapter).toContain('');
+ expect(adapter).not.toContain("Runner lifecycle");
+ expect(policy).toContain("Runner lifecycle");
+ expect(policy).not.toContain("ACP agent");
+ expect(policy).not.toContain("qualification pending");
});
it.each([
diff --git a/ui/src/components/task-chat/TaskChatProtocolActivityRow.test.tsx b/ui/src/components/task-chat/TaskChatProtocolActivityRow.test.tsx
index bb2fb87944..f9e956e2c4 100644
--- a/ui/src/components/task-chat/TaskChatProtocolActivityRow.test.tsx
+++ b/ui/src/components/task-chat/TaskChatProtocolActivityRow.test.tsx
@@ -178,7 +178,7 @@ describe("TaskChatProtocolActivityRow", () => {
expect(row?.querySelector('[data-testid="task-chat-protocol-activity-icon"]')?.querySelectorAll("path")).toHaveLength(3);
});
- it("shows a notice as a warning and full-width message without metadata or a disclosure", () => {
+ it("keeps a notice readable and preserves metadata in a collapsed disclosure", () => {
const summary = "Project-local configuration is disabled.\nTrust the repository to load its hooks.";
render({
id: "notice", kind: "protocol", surface: "provider_activity", family: "provider_notice",
@@ -186,12 +186,26 @@ describe("TaskChatProtocolActivityRow", () => {
details: [
{ label: "Category", value: "configWarning" },
{ label: "Recoverable", value: "Yes" },
+ { label: "Provider", value: "pi" },
+ { label: "Provenance", value: "provider_native" },
{ label: "Summary", value: summary },
], steps: [], links: [], children: [],
});
- expect(container.textContent).toBe(`Warning${summary}`);
+ expect(container.textContent).toContain(`Warning${summary}`);
expect(container.querySelector("p")?.textContent).toBe(summary);
- expect(container.querySelector("dl")).toBeNull();
+ const disclosure = container.querySelector("details");
+ expect(disclosure).not.toBeNull();
+ expect(disclosure?.open).toBe(false);
+ expect(disclosure?.querySelector("summary")?.textContent).toBe("Details");
+ expect(Array.from(disclosure?.querySelectorAll("dt") ?? [], (term) => term.textContent)).toEqual([
+ "Category", "Recoverable", "Provider", "Provenance",
+ ]);
+ expect(Array.from(disclosure?.querySelectorAll("dd") ?? [], (value) => value.textContent)).toEqual([
+ "configWarning", "Yes", "pi", "provider_native",
+ ]);
+ expect(disclosure?.textContent).not.toContain(summary);
+ act(() => disclosure?.querySelector("summary")?.click());
+ expect(disclosure?.open).toBe(true);
expect(container.querySelector("button")).toBeNull();
expect(container.querySelector('[data-testid="task-chat-protocol-activity-icon"]')).not.toBeNull();
});
@@ -214,6 +228,7 @@ describe("TaskChatProtocolActivityRow", () => {
const row = container.querySelector('[data-testid="task-chat-protocol-activity-row"]');
expect(row?.querySelector("button")).toBeNull();
+ expect(row?.querySelector("details")).toBeNull();
expect(row?.querySelector('[aria-expanded]')).toBeNull();
});
});