Saltar al contenido principal

Solicitudes de permiso

Comportamiento por defecto (deny-all)

Cuando permission_approve de config/copilot.php vale "deny-all" (valor por defecto), las solicitudes de permiso en Copilot::run() y Copilot::start() se deniegan automáticamente. En usos centrados en generación de texto no suele hacer falta ningún permiso, así que es un valor seguro por defecto.
// config/copilot.php
'permission_approve' => env('COPILOT_PERMISSION_APPROVE', 'deny-all'),

Valores configurables

ValorComportamiento
"deny-all"Deniega todo automáticamente (por defecto)
"approve-safety"Deniega solo shell y write, aprueba el resto automáticamente
"approve-all"Aprueba todo automáticamente
falseSin handler. onPermissionRequest es obligatorio (igual que en el SDK oficial)
// .env
COPILOT_PERMISSION_APPROVE="approve-safety"
Si aceptas prompts de entrada del usuario, "approve-safety" y "approve-all" son peligrosos. Usa siempre false o "deny-all". Incluso con permisos de solo lectura, es posible que se lea el código de tu proyecto Laravel.

PermissionHandler::approveAll()

PermissionHandler::approveAll() aprueba todas las solicitudes automáticamente.
use Revolution\Copilot\Facades\Copilot;
use Revolution\Copilot\Support\PermissionHandler;
use Revolution\Copilot\Types\SessionConfig;

$config = new SessionConfig(
    onPermissionRequest: PermissionHandler::approveAll(),
);

$response = Copilot::run(prompt: 'Hello', config: $config);

PermissionHandler::approveSafety()

PermissionHandler::approveSafety() deniega únicamente los permisos de alto riesgo (shell, write) y aprueba el resto automáticamente.
use Revolution\Copilot\Facades\Copilot;
use Revolution\Copilot\Support\PermissionHandler;
use Revolution\Copilot\Types\SessionConfig;

$config = new SessionConfig(
    onPermissionRequest: PermissionHandler::approveSafety(),
);

$response = Copilot::run(prompt: 'Hello', config: $config);
Aun así, no es completamente seguro. Si quieres controlar de forma estricta, implementa un handler personalizado y decide inspeccionando $request['kind'].

PermissionHandler::denyAll()

PermissionHandler::denyAll() deniega todo.
use Revolution\Copilot\Support\PermissionHandler;
use Revolution\Copilot\Types\SessionConfig;

$config = new SessionConfig(
    onPermissionRequest: PermissionHandler::denyAll(),
);

Al usar Client directamente

Si utilizas CopilotClient directamente, indicar onPermissionRequest es obligatorio, igual que en el SDK oficial.
use Revolution\Copilot\Client;
use Revolution\Copilot\Support\PermissionHandler;

$client = new Client([
    'cli_path' => 'copilot',
    'cli_args' => [],
    'cwd' => base_path(),
    'log_level' => 'info',
    'env' => null,
]);
$client->start();

// onPermissionRequest es obligatorio
$session = $client->createSession([
    'onPermissionRequest' => PermissionHandler::approveSafety(),
]);

// Si lo omites, se lanza InvalidArgumentException
// $session = $client->createSession([]); // ¡Error!

Handler personalizado

Para controlar autorización/denegación por tipo de solicitud, pasa una clausura. $request e $invocation son arrays como los siguientes.
use Illuminate\Support\Facades\Artisan;
use Revolution\Copilot\Contracts\CopilotSession;
use Revolution\Copilot\Facades\Copilot;
use Revolution\Copilot\Support\PermissionRequestResultKind;
use Revolution\Copilot\Types\SessionConfig;

use function Laravel\Prompts\{confirm, note, spin, text};

Artisan::command('copilot:chat', function () {
    $config = new SessionConfig(
        onPermissionRequest: function (array $request, array $invocation) {
            $confirm = confirm(
                label: 'Do you accept the requested permissions?',
            );
            if ($confirm) {
                return PermissionRequestResultKind::approveOnce();
            } else {
                return PermissionRequestResultKind::reject();
            }
        },
    );

    Copilot::start(function (CopilotSession $session) use ($config) {
        while (true) {
            $prompt = text(
                label: 'Enter your prompt',
                placeholder: 'Ask me anything...',
                required: true,
                hint: 'Ctrl+C to exit',
            );

            $response = spin(
                callback: fn () => $session->sendAndWait($prompt),
                message: 'Waiting for Copilot response...',
            );

            note($response->content());
        }
    }, config: $config);
});

$request

Los campos distintos de kind y toolCallId varían según kind.
kind: "shell" | "write" | "mcp" | "read" | "url" | "custom-tool" | "memory" | "hook"
[
  "kind" => "shell",
  "toolCallId" => "toolu_...",
  "fullCommandText" => "...",
  "intention" => "Run copilot:ping to test permission request",
  "commands" => [
    [
      "identifier" => "bash",
      "readOnly" => false,
    ]
  ]
  "possiblePaths" => [],
  "possibleUrls" => [],
  "hasWriteFileRedirection" => false,
  "canOfferSessionApproval" => false,
]

$invocation

[
  "sessionId" => "...",
]

Response

El resultado de la decisión de permiso se devuelve como array. La clase PermissionRequestResultKind mejora la legibilidad.
return PermissionRequestResultKind::approveOnce();
return PermissionRequestResultKind::reject();

Detalle del protocolo

En Protocol v3 (el valor por defecto actual), las solicitudes de permiso se entregan como eventos de sesión (permission.requested), no como peticiones JSON-RPC. El SDK las procesa internamente y responde con el RPC session.permissions.handlePendingPermissionRequest. El uso de SessionConfig no cambia. Si pasas un handler a onPermissionRequest, el SDK absorbe las diferencias de protocolo.

PermissionRequestResultKind

También puedes devolver directamente algo como ['kind' => 'approve-once'], pero usar PermissionRequestResultKind resulta más claro.
use Revolution\Copilot\Support\PermissionRequestResultKind;

$confirm = confirm(
    label: 'Do you accept the requested permissions?',
);

if ($confirm) {
    return PermissionRequestResultKind::approveOnce();
} else {
    return PermissionRequestResultKind::reject();
}

Métodos disponibles

MétodoValorDescripción
approveOnce()approve-onceAprueba solo esta solicitud
approveForSession()approve-for-sessionAprueba todas las solicitudes del mismo tipo durante esta sesión
approveForLocation()approve-for-locationAprueba todas las solicitudes del mismo tipo desde esta ubicación (ruta de archivo, etc.)
reject()rejectRechaza la solicitud
userNotAvailable()user-not-availableEstado en el que el usuario no puede responder (entornos no interactivos, etc.)
noResult()no-resultCuando el handler no puede devolver un resultado (omite la llamada RPC)
Si quieres usar Laravel\Prompts\select, puedes obtener las opciones con PermissionRequestResultKind::select().
use Revolution\Copilot\Support\PermissionRequestResultKind;
use function Laravel\Prompts\select;

$select = select(
    label: 'Do you accept the requested permissions?',
    options: PermissionRequestResultKind::select(),
);

return ['kind' => $select];

no-result

Si el handler no puede devolver un resultado (por ejemplo, en un entorno no interactivo), puedes devolver no-result. Al hacerlo, se omite la llamada RPC y se aplica la denegación por defecto de Copilot CLI.
return PermissionRequestResultKind::noResult();
// o ['kind' => 'no-result']
Consulta la información más reciente en el repositorio de GitHub.
Última modificación el 13 de julio de 2026