From b74e049360dac3a809d9b14c99d3a0951c2bfda4 Mon Sep 17 00:00:00 2001 From: murashit Date: Wed, 1 Jul 2026 16:38:29 +0900 Subject: [PATCH] Refine runtime status sections --- .../runtime/permission-sections.ts | 27 +++++++++---------- src/features/chat/ui/toolbar.tsx | 2 +- .../chat/panel/surface/projections.test.ts | 4 ++- tests/features/chat/ui/toolbar.test.ts | 21 ++++++++++----- 4 files changed, 31 insertions(+), 23 deletions(-) diff --git a/src/features/chat/presentation/runtime/permission-sections.ts b/src/features/chat/presentation/runtime/permission-sections.ts index 7cc5f2a9..f538af1e 100644 --- a/src/features/chat/presentation/runtime/permission-sections.ts +++ b/src/features/chat/presentation/runtime/permission-sections.ts @@ -27,27 +27,31 @@ export function runtimePermissionDetails(input: RuntimePermissionSectionsInput): const config = runtimeConfigOrDefault(input.snapshot.runtimeConfig); const resolution = resolveRuntimeControls(input.snapshot, config); return { - title: permissionPanelTitle(resolution.permissions.scope), + title: "Permissions & Approvals", sections: [ { - title: "", - rows: permissionRows(resolution.permissions.effective, resolution.approvalsReviewer.effective, input.vaultPath), + title: "Permissions", + rows: accessRows(resolution.permissions.effective, input.vaultPath), + }, + { + title: "Approvals", + rows: approvalRows(resolution.permissions.effective, resolution.approvalsReviewer.effective), }, ], }; } -function permissionPanelTitle(scope: "new-thread" | "current-thread"): string { - return scope === "current-thread" ? "Permissions: Current Thread" : "Permissions: New Thread"; -} - -function permissionRows(permissions: RuntimePermissionState, reviewer: string | null, vaultPath: string): RuntimePermissionRow[] { +function accessRows(permissions: RuntimePermissionState, vaultPath: string): RuntimePermissionRow[] { return [ { label: "Profile", value: profileLabel(permissions) }, - ...extendsRows(permissions), { label: "Sandbox", value: sandboxLabel(permissions.sandboxPolicy) }, { label: "Network", value: networkLabel(permissions.sandboxPolicy) }, { label: "Extra writable roots", value: writableRootsLabel(permissions.sandboxPolicy, vaultPath) }, + ]; +} + +function approvalRows(permissions: RuntimePermissionState, reviewer: string | null): RuntimePermissionRow[] { + return [ { label: "Approval policy", value: approvalPolicyLabel(permissions.approvalPolicy) }, { label: "Reviewer", @@ -62,11 +66,6 @@ function profileLabel(permissions: RuntimePermissionState): string { return "(not reported)"; } -function extendsRows(permissions: RuntimePermissionState): RuntimePermissionRow[] { - const extendsProfile = permissions.activePermissionProfile?.extends; - return extendsProfile ? [{ label: "Extends", value: extendsProfile }] : []; -} - function sandboxLabel(sandbox: RuntimeSandboxPolicy | null): string { if (!sandbox) return "(not reported)"; switch (sandbox.type) { diff --git a/src/features/chat/ui/toolbar.tsx b/src/features/chat/ui/toolbar.tsx index 4bd65dd7..ca0d5e52 100644 --- a/src/features/chat/ui/toolbar.tsx +++ b/src/features/chat/ui/toolbar.tsx @@ -195,7 +195,7 @@ function StatusPanel({ model, actions }: { model: ToolbarViewModel; actions: Too /> - + diff --git a/tests/features/chat/panel/surface/projections.test.ts b/tests/features/chat/panel/surface/projections.test.ts index a1fee6d0..d154b018 100644 --- a/tests/features/chat/panel/surface/projections.test.ts +++ b/tests/features/chat/panel/surface/projections.test.ts @@ -141,7 +141,9 @@ describe("chat panel surface projections", () => { }), ); - expect(parent.textContent).toContain("Permissions: New Thread"); + expect(parent.textContent).toContain("Permissions & Approvals"); + expect(parent.textContent).toContain("Permissions"); + expect(parent.textContent).toContain("Approvals"); expect( [...parent.querySelectorAll(".codex-panel__connection-diagnostics-section")].map((section) => section.textContent), ).not.toContain("New thread"); diff --git a/tests/features/chat/ui/toolbar.test.ts b/tests/features/chat/ui/toolbar.test.ts index a0c998bb..9496c9bc 100644 --- a/tests/features/chat/ui/toolbar.test.ts +++ b/tests/features/chat/ui/toolbar.test.ts @@ -168,8 +168,8 @@ describe("Toolbar decisions", () => { ); expect([...parent.querySelectorAll(".codex-panel__connection-diagnostics-title")].map((title) => title.textContent)).toEqual([ - "Connection", - "Permissions: Current Thread", + "Connection diagnostics", + "Permissions & Approvals", "Codex capabilities", ]); expect(parent.textContent).toContain("Codex capabilities"); @@ -198,15 +198,20 @@ describe("Toolbar decisions", () => { toolbarModel({ statusPanelOpen: true, openPanel: "status", - runtimePermissionsTitle: "Permissions: Current Thread", + runtimePermissionsTitle: "Permissions & Approvals", runtimePermissions: [ { - title: "", + title: "Permissions", rows: [ { label: "Profile", value: ":workspace" }, { label: "Sandbox", value: "workspace-write" }, { label: "Network", value: "blocked" }, { label: "Extra writable roots", value: "Vault" }, + ], + }, + { + title: "Approvals", + rows: [ { label: "Approval policy", value: "on-request" }, { label: "Reviewer", value: "auto_review" }, ], @@ -217,7 +222,9 @@ describe("Toolbar decisions", () => { toolbarActions(), ); - expect(parent.textContent).toContain("Permissions: Current Thread"); + expect(parent.textContent).toContain("Permissions & Approvals"); + expect(parent.textContent).toContain("Permissions"); + expect(parent.textContent).toContain("Approvals"); expect( [...parent.querySelectorAll(".codex-panel__connection-diagnostics-section")].map((section) => section.textContent), ).not.toContain("Current thread"); @@ -404,8 +411,8 @@ function toolbarModel(overrides: Partial = {}): ToolbarViewMod openPanel: null, threads: [{ title: "Thread", threadId: "thread", selected: true, disabled: false, canArchive: true, rename: null }], connectLabel: "Reconnect", - runtimePermissionsTitle: "Permissions: Current Thread", - runtimePermissions: [{ title: "", rows: [{ label: "Thread", value: "(none)" }] }], + runtimePermissionsTitle: "Permissions & Approvals", + runtimePermissions: [{ title: "Permissions", rows: [{ label: "Thread", value: "(none)" }] }], diagnostics: [{ title: "Process", rows: [{ label: "Codex App Server", value: "codex-cli/test" }] }], toolInventory: [{ title: "Tool providers", rows: [{ label: "Tool providers", value: "not loaded", level: "warning" }] }], ...overrides,