Files
enkly-ai/api/proto/workspace/v1/workspace.proto
enkly 79ce8dc4c0
Some checks failed
Go CI Pipeline / build_and_test (push) Failing after 22m0s
Init Project
2026-10-30 18:06:55 +01:00

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;
}