Files
zero/internal/tools/request_permissions.go
Anandan 2cf6fd2334 Add request permissions flow (#248)
* Add request permissions flow

Adds a runtime-handled request_permissions tool that can ask for turn or session filesystem/network grants and return the granted profile as structured JSON.

Temporary turn grants update the shared sandbox scope and effective policy, then clean up at run end; session grants persist in memory for the session.

Read grants now stay read-only through tool path resolution, policy evaluation, and native sandbox profile construction.

The TUI renders request_permissions with grant-specific choices, including strict review, and Esc continues without granting permissions.

Tested: GOCACHE=/tmp/zero-go-cache go test ./...

* Align request permission grants with prompts

Display and return the normalized grant roots that the sandbox actually applies, so file-like permission requests no longer show a narrower path than the directory root being granted.

Also makes the network prompt explicit about all outbound access and relabels the strict option as a model review request instead of implying enforced command review.

Tested: GOCACHE=/tmp/zero-go-cache go test ./...

* Retry transient OAuth secret read locks

Windows can briefly deny reads of the freshly published token secret while concurrent OAuth secret creation converges. Treat Windows sharing and lock violations as transient and retry those reads before returning an error.

Tested: GOCACHE=/tmp/zero-go-cache go test ./internal/oauth

Tested: GOCACHE=/tmp/zero-go-cache GOOS=windows GOARCH=amd64 go test -c ./internal/oauth -o /tmp/zero-oauth-windows.test.exe

Tested: GOCACHE=/tmp/zero-go-cache go test ./internal/sandbox ./internal/agent ./internal/tui ./internal/tools ./internal/specialist ./internal/oauth

Tested: GOCACHE=/tmp/zero-go-cache go test ./...
2026-06-18 20:00:35 +05:30

112 lines
3.3 KiB
Go

package tools
import "context"
const RequestPermissionsToolName = "request_permissions"
type requestPermissionsTool struct {
baseTool
}
func NewRequestPermissionsTool() Tool {
return requestPermissionsTool{
baseTool: baseTool{
name: RequestPermissionsToolName,
description: "Request additional filesystem or network permissions from the user. Granted permissions apply to later tool calls in this task, or for the rest of the session when approved with session scope.",
parameters: Schema{
Type: "object",
Properties: map[string]PropertySchema{
"reason": {
Type: "string",
Description: "Optional short explanation for why additional permissions are needed.",
},
"environment_id": {
Type: "string",
Description: "Environment id from the active environment context. Omit to use the current workspace.",
},
"permissions": requestPermissionsProfileSchema(),
},
Required: []string{"permissions"},
AdditionalProperties: false,
},
safety: Safety{
SideEffect: SideEffectNone,
Permission: PermissionAllow,
Reason: "Requests a user permission decision but does not read, write, run commands, or use the network.",
},
},
}
}
func (tool requestPermissionsTool) Run(context.Context, map[string]any) Result {
return errorResult("Error: request_permissions must be handled by the agent runtime.")
}
func requestPermissionsProfileSchema() PropertySchema {
return PropertySchema{
Type: "object",
Properties: map[string]PropertySchema{
"network": {
Type: "object",
Properties: map[string]PropertySchema{
"enabled": {
Type: "boolean",
Description: "Set true to request network access.",
},
},
},
"file_system": {
Type: "object",
Properties: map[string]PropertySchema{
"read": {
Type: "array",
Description: "Filesystem paths to read. Relative paths resolve against the workspace.",
Items: &PropertySchema{Type: "string"},
},
"write": {
Type: "array",
Description: "Filesystem paths to write. Relative paths resolve against the workspace.",
Items: &PropertySchema{Type: "string"},
},
"deny_read": {
Type: "array",
Description: "Filesystem paths to keep unreadable.",
Items: &PropertySchema{Type: "string"},
},
"entries": {
Type: "array",
Description: "Canonical filesystem permission entries.",
Items: &PropertySchema{
Type: "object",
Properties: map[string]PropertySchema{
"path": {
Type: "object",
Properties: map[string]PropertySchema{
"type": {
Type: "string",
Description: "Use path for normal filesystem paths.",
Enum: []string{"path"},
},
"path": {
Type: "string",
Description: "Filesystem path. Relative paths resolve against the workspace.",
},
},
Required: []string{"type", "path"},
},
"access": {
Type: "string",
Description: "Permission for this path.",
Enum: []string{"read", "write", "deny"},
},
},
Required: []string{"path", "access"},
},
},
},
},
},
Required: []string{},
}
}