197 lines
5.2 KiB
Protocol Buffer
197 lines
5.2 KiB
Protocol Buffer
// Package workspace is the Workspace (agent sandbox / files) bounded
|
|
// context: the single shared ENKLY_WORKSPACE directory the coding agent
|
|
// reads, writes and runs commands in, and that the "Files" panel in the
|
|
// UI lets a human upload into / download from. Every path-jailing rule
|
|
// from internal/llm/sandbox.go (ResolvePath, the bash allowlist, the
|
|
// filesystem guards) is enforced here and nowhere else — no other
|
|
// service is allowed to touch the workspace volume directly.
|
|
//
|
|
// Mirrors internal/llm/tools.go (filesystem + bash tools) and
|
|
// internal/handlers/files.go / ui.go (upload, download, tree).
|
|
syntax = "proto3";
|
|
|
|
package enkly.workspace.v1;
|
|
|
|
option go_package = "enkly/gen/workspace/v1;workspacev1";
|
|
|
|
import "google/protobuf/timestamp.proto";
|
|
|
|
service WorkspaceService {
|
|
// --- agent filesystem/bash tools (internal/llm/tools.go, sandbox.go) ---
|
|
rpc ReadFile(ReadFileRequest) returns (ReadFileResponse);
|
|
rpc WriteFile(WriteFileRequest) returns (WriteFileResponse);
|
|
rpc EditFile(EditFileRequest) returns (EditFileResponse);
|
|
rpc MultiEditFile(MultiEditFileRequest) returns (MultiEditFileResponse);
|
|
rpc ListDirectory(ListDirectoryRequest) returns (ListDirectoryResponse);
|
|
rpc GlobSearch(GlobSearchRequest) returns (GlobSearchResponse);
|
|
rpc Grep(GrepRequest) returns (GrepResponse);
|
|
rpc RunBashCommand(RunBashCommandRequest) returns (RunBashCommandResponse);
|
|
|
|
// --- human-facing files panel (internal/handlers/files.go, ui.go) ---
|
|
rpc UploadFile(UploadFileRequest) returns (UploadFileResponse);
|
|
rpc DownloadFile(DownloadFileRequest) returns (DownloadFileResponse);
|
|
rpc Tree(TreeRequest) returns (TreeResponse);
|
|
rpc StatFile(StatFileRequest) returns (StatFileResponse); // backs deliverable cards
|
|
}
|
|
|
|
message ReadFileRequest {
|
|
string path = 1;
|
|
int32 offset = 2; // 0-based line offset
|
|
int32 limit = 3; // 0 = default (maxReadLines)
|
|
}
|
|
|
|
message ReadFileResponse {
|
|
string content = 1;
|
|
bool truncated = 2;
|
|
bool is_error = 3;
|
|
string error_message = 4;
|
|
}
|
|
|
|
message WriteFileRequest {
|
|
string path = 1;
|
|
string content = 2;
|
|
}
|
|
|
|
message WriteFileResponse {
|
|
int64 bytes_written = 1;
|
|
bool is_error = 2;
|
|
string error_message = 3;
|
|
}
|
|
|
|
message EditFileRequest {
|
|
string path = 1;
|
|
string old_string = 2;
|
|
string new_string = 3;
|
|
bool replace_all = 4;
|
|
}
|
|
|
|
message EditFileResponse {
|
|
string diff_preview = 1;
|
|
int32 occurrences = 2;
|
|
bool is_error = 3;
|
|
string error_message = 4;
|
|
}
|
|
|
|
message TextEdit {
|
|
string old_string = 1;
|
|
string new_string = 2;
|
|
bool replace_all = 3;
|
|
}
|
|
|
|
message MultiEditFileRequest {
|
|
string path = 1;
|
|
repeated TextEdit edits = 2;
|
|
}
|
|
|
|
message MultiEditFileResponse {
|
|
string diff_preview = 1;
|
|
bool is_error = 2;
|
|
string error_message = 3;
|
|
}
|
|
|
|
message ListDirectoryRequest {
|
|
string path = 1;
|
|
}
|
|
|
|
message ListDirectoryResponse {
|
|
string listing = 1; // pre-rendered, matching the monolith's tool output format
|
|
bool is_error = 2;
|
|
string error_message = 3;
|
|
}
|
|
|
|
message GlobSearchRequest {
|
|
string pattern = 1;
|
|
string path = 2;
|
|
}
|
|
|
|
message GlobSearchResponse {
|
|
// Pre-rendered exactly like every other tool's text output (a
|
|
// newline-separated path list, "no files matched that pattern", or a
|
|
// truncation notice) — deliberately NOT a repeated string, since that
|
|
// would require guessing which lines are paths vs. a status message,
|
|
// a lossy transformation the original tool output never needed.
|
|
string output = 1;
|
|
bool is_error = 2;
|
|
string error_message = 3;
|
|
}
|
|
|
|
message GrepRequest {
|
|
string pattern = 1;
|
|
string path = 2;
|
|
string glob = 3;
|
|
bool case_insensitive = 4;
|
|
}
|
|
|
|
message GrepResponse {
|
|
string output = 1;
|
|
bool is_error = 2;
|
|
string error_message = 3;
|
|
}
|
|
|
|
message RunBashCommandRequest {
|
|
string command = 1;
|
|
int32 timeout_seconds = 2; // 0 = service default
|
|
}
|
|
|
|
message RunBashCommandResponse {
|
|
string output = 1;
|
|
int32 exit_code = 2;
|
|
bool is_error = 3;
|
|
string error_message = 4;
|
|
}
|
|
|
|
message UploadFileRequest {
|
|
string path = 1; // destination relative path
|
|
bytes content = 2;
|
|
}
|
|
|
|
message UploadFileResponse {
|
|
int64 bytes_written = 1;
|
|
}
|
|
|
|
message DownloadFileRequest {
|
|
string path = 1;
|
|
}
|
|
|
|
message DownloadFileResponse {
|
|
bytes content = 1;
|
|
string filename = 2;
|
|
}
|
|
|
|
message TreeRequest {
|
|
string path = 1; // "" = workspace root
|
|
// one_level: list only the immediate children of path (both files
|
|
// and directories, directories included as entries in their own
|
|
// right) instead of recursing — backs the gateway's lazy-expanding
|
|
// file explorer panel (internal/handlers/ui.go's FileTree), where
|
|
// each folder click fetches just that folder. false (the default)
|
|
// recurses fully and returns only files, for the flat "Workspace
|
|
// files" upload/download panel (internal/handlers/files.go).
|
|
bool one_level = 2;
|
|
}
|
|
|
|
message TreeNode {
|
|
string name = 1;
|
|
string rel_path = 2;
|
|
bool is_dir = 3;
|
|
int64 size = 4;
|
|
google.protobuf.Timestamp modified_at = 5;
|
|
// download_url is left empty by this service — the gateway owns URL
|
|
// construction (it knows its own public route prefix), not workspace.
|
|
}
|
|
|
|
message TreeResponse {
|
|
repeated TreeNode nodes = 1;
|
|
}
|
|
|
|
message StatFileRequest {
|
|
string path = 1;
|
|
}
|
|
|
|
message StatFileResponse {
|
|
bool exists = 1;
|
|
bool is_dir = 2;
|
|
int64 size = 3;
|
|
google.protobuf.Timestamp modified_at = 4;
|
|
}
|