syntax = "proto3";
package steer.remote_workspace.v1;

import "google/protobuf/timestamp.proto";
import "steer/common/v1/common.proto";

// Agent service for remote workspace tool execution
service RemoteWorkspaceService {
  // Execute a tool call on the agent
  rpc ExecuteTool(ExecuteToolRequest) returns (ExecuteToolResponse);

  // Get information about the agent and available tools
  rpc GetAgentInfo(GetAgentInfoRequest) returns (GetAgentInfoResponse);

  // Health check
  rpc Health(HealthRequest) returns (HealthResponse);

  // Get detailed tool schemas including approval requirements
  rpc GetToolSchemas(GetToolSchemasRequest) returns (GetToolSchemasResponse);

  // Get tool approval requirements
  rpc GetToolApprovalRequirements(GetToolApprovalRequirementsRequest)
      returns (GetToolApprovalRequirementsResponse);

  // Get environment information for the remote workspace
  rpc GetEnvironmentInfo(GetEnvironmentInfoRequest)
      returns (GetEnvironmentInfoResponse);

  // List files in the workspace for fuzzy finding
  rpc ListFiles(ListFilesRequest) returns (stream ListFilesResponse);

  // Read file content with optional offset/limit
  rpc ReadFile(ReadFileRequest) returns (steer.common.v1.FileContentResult);

  // List a directory (ls-style)
  rpc ListDirectory(ListDirectoryRequest) returns (steer.common.v1.FileListResult);

  // Glob search
  rpc Glob(GlobRequest) returns (steer.common.v1.GlobResult);

  // Text search (grep)
  rpc Grep(GrepRequest) returns (steer.common.v1.SearchResult);

  // AST search (astgrep)
  rpc AstGrep(AstGrepRequest) returns (steer.common.v1.SearchResult);

  // Apply one or more edits to a file
  rpc ApplyEdits(ApplyEditsRequest) returns (steer.common.v1.EditResult);

  // Write/replace file contents
  rpc WriteFile(WriteFileRequest) returns (steer.common.v1.EditResult);
}

message ExecuteToolRequest {
  string tool_call_id = 1;
  string tool_name = 2;
  string parameters_json = 3;
  string context_json = 4;
  optional uint64 timeout_ms = 5;
}

message ExecuteToolResponse {
  bool success = 1;

  oneof result {
    string string_result = 2;         // Legacy/simple tools
    TypedToolResult typed_result = 3; // External tools with JSON
    steer.common.v1.SearchResult search_result = 4;
    steer.common.v1.FileListResult file_list_result = 5;
    steer.common.v1.FileContentResult file_content_result = 6;
    steer.common.v1.EditResult edit_result = 7;
    steer.common.v1.BashResult bash_result = 8;
    steer.common.v1.GlobResult glob_result = 9;
    steer.common.v1.TodoListResult todo_list_result = 10;
    steer.common.v1.TodoWriteResult todo_write_result = 11;
  }

  string error = 12;
  google.protobuf.Timestamp started_at = 13;
  google.protobuf.Timestamp completed_at = 14;
  map<string, string> metadata = 15;

  // Typed tool error details for domain failures (success=false)
  optional ToolErrorDetail error_detail = 16;
}

// Generic typed result for external tools
message TypedToolResult {
  bytes json_data = 1;         // JSON-encoded result implementing ToolOutput
  string type_name = 2;        // Type name (e.g., "CustomSearchResult")
  optional string summary = 3; // Optional brief summary for display
}

// Typed error payload for tool failures
message ToolErrorDetail {
  enum Kind {
    KIND_UNSET = 0;
    EXECUTION = 1;
    IO = 2;
    INVALID_PARAMS = 3;
    CANCELLED = 4;
    TIMEOUT = 5;
    UNKNOWN_TOOL = 6;
    DENIED_BY_USER = 7;
    INTERNAL = 8;
    DENIED_BY_POLICY = 9;
  }
  Kind kind = 1;
  string tool_name = 2;
  string message = 3;
}

// Request messages
message GetAgentInfoRequest {}
message GetAgentInfoResponse {
  string version = 1;
  repeated string supported_tools = 2;
  map<string, string> metadata = 4;
}

message HealthRequest {}

message HealthResponse {
  HealthStatus status = 1;
  string message = 2;
  map<string, string> details = 3;
}

enum HealthStatus {
  HEALTH_STATUS_UNSPECIFIED = 0;
  HEALTH_STATUS_SERVING = 1;
  HEALTH_STATUS_NOT_SERVING = 2;
  HEALTH_STATUS_SERVICE_UNKNOWN = 3;
}

message GetToolSchemasRequest {}

// Tool schema information
message ToolSchema {
  string name = 1;
  string description = 2;
  string input_schema_json = 3;
  string display_name = 4;
}

// Response containing all tool schemas
message GetToolSchemasResponse { repeated ToolSchema tools = 1; }

// Request for tool approval requirements
message GetToolApprovalRequirementsRequest { repeated string tool_names = 1; }

// Response containing tool approval requirements
message GetToolApprovalRequirementsResponse {
  // Map from tool name to whether it requires approval
  map<string, bool> approval_requirements = 1;
}

// Request for environment information
message GetEnvironmentInfoRequest {
  // Optional working directory override
  optional string working_directory = 1;
}

// Supported version control systems
enum VcsKind {
  VCS_KIND_UNSPECIFIED = 0;
  VCS_KIND_GIT = 1;
  VCS_KIND_JJ = 2;
}

enum GitHeadKind {
  GIT_HEAD_KIND_UNSPECIFIED = 0;
  GIT_HEAD_KIND_BRANCH = 1;
  GIT_HEAD_KIND_DETACHED = 2;
  GIT_HEAD_KIND_UNBORN = 3;
}

message GitHead {
  GitHeadKind kind = 1;
  optional string branch = 2;
}

enum GitStatusSummary {
  GIT_STATUS_SUMMARY_UNSPECIFIED = 0;
  GIT_STATUS_SUMMARY_ADDED = 1;
  GIT_STATUS_SUMMARY_REMOVED = 2;
  GIT_STATUS_SUMMARY_MODIFIED = 3;
  GIT_STATUS_SUMMARY_TYPE_CHANGE = 4;
  GIT_STATUS_SUMMARY_RENAMED = 5;
  GIT_STATUS_SUMMARY_COPIED = 6;
  GIT_STATUS_SUMMARY_INTENT_TO_ADD = 7;
  GIT_STATUS_SUMMARY_CONFLICT = 8;
}

message GitStatusEntry {
  GitStatusSummary summary = 1;
  string path = 2;
}

message GitCommitSummary {
  string id = 1;
  string summary = 2;
}

message GitStatus {
  GitHead head = 1;
  repeated GitStatusEntry entries = 2;
  repeated GitCommitSummary recent_commits = 3;
  optional string error = 4;
}

enum JjChangeType {
  JJ_CHANGE_TYPE_UNSPECIFIED = 0;
  JJ_CHANGE_TYPE_ADDED = 1;
  JJ_CHANGE_TYPE_REMOVED = 2;
  JJ_CHANGE_TYPE_MODIFIED = 3;
}

message JjChange {
  JjChangeType change_type = 1;
  string path = 2;
}

message JjCommitSummary {
  string change_id = 1;
  string commit_id = 2;
  string description = 3;
}

message JjStatus {
  repeated JjChange changes = 1;
  JjCommitSummary working_copy = 2;
  repeated JjCommitSummary parents = 3;
  optional string error = 4;
}

// Version control information
message VcsInfo {
  VcsKind kind = 1;
  string root = 2;
  oneof status {
    GitStatus git_status = 3;
    JjStatus jj_status = 4;
  }
}

// Response containing environment information
message GetEnvironmentInfoResponse {
  string working_directory = 1;
  VcsInfo vcs = 2;
  string platform = 3;
  string date = 4;
  string directory_structure = 5;
  optional string readme_content = 6;
  optional string memory_file_content = 7;
  optional string memory_file_name = 8;
}

// File listing for fuzzy finder
message ListFilesRequest {
  string query = 1;       // optional fuzzy query (empty = full list)
  uint32 max_results = 2; // 0 = unlimited
}

message ListFilesResponse {
  repeated string paths = 1; // workspace-relative paths
}

message ReadFileRequest {
  string file_path = 1;
  optional uint64 offset = 2;
  optional uint64 limit = 3;
}

message ListDirectoryRequest {
  string path = 1;
  repeated string ignore = 2;
}

message GlobRequest {
  string pattern = 1;
  optional string path = 2;
}

message GrepRequest {
  string pattern = 1;
  optional string include = 2;
  optional string path = 3;
}

message AstGrepRequest {
  string pattern = 1;
  optional string lang = 2;
  optional string include = 3;
  optional string exclude = 4;
  optional string path = 5;
}

message EditOperation {
  string old_string = 1;
  string new_string = 2;
}

message ApplyEditsRequest {
  string file_path = 1;
  repeated EditOperation edits = 2;
}

message WriteFileRequest {
  string file_path = 1;
  string content = 2;
}
