fix: admin UI review round 1 (S47) - Art labels, usage only on success, result fallback
- Art column: only lit/media-delete and lit/divi-delete say "löscht", lit/post-trash "Papierkorb", other destructive tools "überschreibt". - ConnectionUsage records only responses with status < 400 (mcp-oauth answers auth failures with WP_REST_Response 401, not WP_Error). - Log result column: translated "unbekannt" instead of the raw value. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -55,7 +55,7 @@ final class ConnectionUsage
|
||||
public function record(mixed $response, array $handler, WP_REST_Request $request): mixed
|
||||
{
|
||||
$route = '/' . ServerRegistrar::NAMESPACE . '/' . ServerRegistrar::ROUTE;
|
||||
if ($request->get_route() !== $route || is_wp_error($response)) {
|
||||
if ($request->get_route() !== $route || ! self::succeeded($response)) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
@@ -78,4 +78,17 @@ final class ConnectionUsage
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only successful answers count as use: mcp-oauth answers auth failures with a
|
||||
* WP_REST_Response(401), not a WP_Error (OAuthHttpTransport::build_auth_error_response).
|
||||
*/
|
||||
private static function succeeded(mixed $response): bool
|
||||
{
|
||||
if (is_wp_error($response)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ! $response instanceof \WP_HTTP_Response || $response->get_status() < 400;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ final class LogListTable extends \WP_List_Table
|
||||
[$icon, $word] = match ($result) {
|
||||
'ok' => ['yes-alt', __('erfolgreich', 'wp-lit-mcp')],
|
||||
'partial' => ['warning', __('teilweise', 'wp-lit-mcp')],
|
||||
default => ['dismiss', $result],
|
||||
default => ['dismiss', __('unbekannt', 'wp-lit-mcp')],
|
||||
};
|
||||
|
||||
return sprintf(
|
||||
|
||||
+16
-2
@@ -22,6 +22,13 @@ final class ToolsTab implements AdminTab
|
||||
/** More direct tools than this cost noticeable context in every claude.ai conversation. */
|
||||
public const DIRECT_WARNING_THRESHOLD = 25;
|
||||
|
||||
/** Tools that remove something: "delete" (for good) or "trash" (to the trash). */
|
||||
private const DELETING = [
|
||||
'lit/media-delete' => 'delete',
|
||||
'lit/divi-delete' => 'delete',
|
||||
'lit/post-trash' => 'trash',
|
||||
];
|
||||
|
||||
public function __construct(private IntegrationRegistry $registry, private ExposurePolicy $policy)
|
||||
{
|
||||
}
|
||||
@@ -336,12 +343,19 @@ final class ToolsTab implements AdminTab
|
||||
echo '</td></tr>';
|
||||
}
|
||||
|
||||
/** "liest" / "schreibt" / "löscht" from the ability's annotations, with a dashicon. */
|
||||
/**
|
||||
* "liest" / "schreibt" / "überschreibt" / "löscht" / "Papierkorb" with a dashicon. The
|
||||
* "destructive" annotation is a broad hint (deleting, replacing, swapping, ruling S47),
|
||||
* so only the tools in DELETING say "löscht"; other destructive tools "überschreiben".
|
||||
*/
|
||||
private function kind(Ability $ability): string
|
||||
{
|
||||
$annotations = $ability->annotations();
|
||||
[$icon, $text] = match (true) {
|
||||
($annotations['destructive'] ?? false) === true => ['trash', __('löscht', 'wp-lit-mcp')],
|
||||
isset(self::DELETING[$ability->name()]) => ['trash', self::DELETING[$ability->name()] === 'trash'
|
||||
? __('Papierkorb', 'wp-lit-mcp')
|
||||
: __('löscht', 'wp-lit-mcp')],
|
||||
($annotations['destructive'] ?? false) === true => ['update', __('überschreibt', 'wp-lit-mcp')],
|
||||
($annotations['readonly'] ?? false) === true => ['visibility', __('liest', 'wp-lit-mcp')],
|
||||
default => ['edit', __('schreibt', 'wp-lit-mcp')],
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user