workspace

package
v0.9.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 5, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

@index Workspace filesystem service that owns namespace path validation, traversal-safe resolution, and bulk upload/delete operations.

Index

Constants

View Source
const (
	DefaultMaxFileBytes         = 10 << 20 // 10 MB
	DefaultMaxRequestBytes      = 50 << 20 // 50 MB
	DefaultMaxTotalDecodedBytes = 20 << 20 // 20 MB
)

Default upload size limits applied when callers do not provide their own Limits. @intent expose stable defaults so MCP handlers and other callers stay aligned with historical limits.

Variables

This section is empty.

Functions

func EnsureNoSymlinkInPath

func EnsureNoSymlinkInPath(root, relPath string, allowMissingLeaf bool) (string, error)

EnsureNoSymlinkInPath walks each path segment from root to relPath rejecting symlinks. @intent prevent symlink traversal from escaping the workspace root before any filesystem mutation. @param allowMissingLeaf when true, returns the joined path even when the leaf does not yet exist.

func IsValidationError

func IsValidationError(err error) bool

IsValidationError reports whether err is a ValidationError. @intent allow handlers to map validation failures to MCP user-error responses without leaking other errors.

func SafeWrite

func SafeWrite(path string, data []byte, perm os.FileMode) error

SafeWrite atomically writes data to path using a temp file and rename, refusing to follow symlinks. @intent guarantee partial writes are never visible as the final file contents. @sideEffect creates a temp file in the destination directory and renames it into place.

func ValidatePath

func ValidatePath(namespace, filePath string) error

ValidatePath rejects empty, absolute, or traversal-bearing namespace and file inputs. @intent block path traversal attacks against workspace-scoped tools. @domainRule namespace must be a single safe path segment with no separators or parent-references.

Types

type BulkEntry

type BulkEntry struct {
	Namespace string `json:"namespace"`
	Workspace string `json:"workspace"`
	FilePath  string `json:"file_path"`
	Content   string `json:"content"`
}

BulkEntry is the JSON envelope used by bulk uploads. @intent mirror the historical MCP request shape so handlers can deserialize directly.

type BulkEntryError

type BulkEntryError struct {
	Index int
	Err   error
}

BulkEntryError reports the index of the failing entry alongside the underlying error. @intent let handlers prefix MCP error messages with the offending entry index without re-implementing iteration.

func (*BulkEntryError) Error

func (e *BulkEntryError) Error() string

Error formats the failing bulk entry index with the underlying error text. @intent preserve a user-facing error string that points callers to the exact bad entry. @return returns an error string prefixed with the failing entry index.

func (*BulkEntryError) Unwrap

func (e *BulkEntryError) Unwrap() error

Unwrap returns the underlying entry error. @intent allow callers to inspect the original validation or filesystem failure that broke a bulk upload. @return returns the underlying entry error for errors.Is and errors.As checks.

type Limits

type Limits struct {
	MaxFileBytes         int
	MaxRequestBytes      int
	MaxTotalDecodedBytes int
}

Limits bounds workspace upload payload sizes. @intent let MCP handlers and other callers configure upload caps while sharing the same enforcement code path.

func DefaultLimits

func DefaultLimits() Limits

DefaultLimits returns the historical workspace upload limits. @intent provide a single canonical default so handler code does not duplicate magic numbers.

type Service

type Service struct {
	// Root is the unresolved configured filesystem root for namespace storage.
	Root string
	// Limits bounds the size of accepted upload payloads.
	Limits Limits
}

Service performs workspace filesystem operations under a single root. @intent encapsulate workspace path validation, traversal protection, and atomic file writes for handlers and CLIs.

func NewService

func NewService(root string) *Service

NewService constructs a Service for the supplied root. @intent build a workspace service with the canonical default limits applied when callers omit them.

func (*Service) DeleteFile

func (s *Service) DeleteFile(namespace, filePath string) error

DeleteFile removes a single namespaced file after path validation. @intent allow targeted cleanup of namespace contents without exposing raw filesystem paths. @sideEffect deletes the file from the filesystem.

func (*Service) ListFiles

func (s *Service) ListFiles(namespace string) ([]string, error)

ListFiles walks the namespace directory returning relative file paths sorted alphabetically. @intent surface the current file inventory of a namespace for clients that need to plan further operations. @sideEffect performs a recursive filesystem walk that skips symlinks defensively.

func (*Service) ListNamespaces

func (s *Service) ListNamespaces() ([]string, error)

ListNamespaces returns the alphabetically sorted directories under the workspace root. @intent expose available namespaces so callers can pick an upload target. @sideEffect reads the workspace root directory.

func (*Service) RemoveTree

func (s *Service) RemoveTree(wsDir string) error

RemoveTree recursively deletes a previously resolved namespace directory. @intent provide the final filesystem step of namespace deletion after upstream cleanup succeeds. @sideEffect recursively deletes the namespace directory tree.

func (*Service) ResolveExistingNamespace

func (s *Service) ResolveExistingNamespace(namespace string) (string, error)

ResolveExistingNamespace returns the validated namespace directory ensuring it currently exists. @intent let callers stat or remove an entire namespace without duplicating validation logic.

func (*Service) ResolvePath

func (s *Service) ResolvePath(namespace, filePath string, allowMissingLeaf bool) (string, error)

ResolvePath resolves a workspace-relative file path under the trusted workspace root. @intent reject path traversal and symlink escapes before any filesystem mutation reaches the path. @param namespace single-segment workspace name. @param filePath relative path inside the workspace ("" returns the workspace dir). @param allowMissingLeaf when true, allow the leaf to not yet exist (used before atomic writes).

func (*Service) SafeRoot

func (s *Service) SafeRoot() (string, error)

SafeRoot returns the absolute, symlink-resolved workspace root, creating the root directory if needed. @intent ensure all workspace operations resolve paths under a trusted, real filesystem location. @sideEffect creates the workspace root directory when it does not yet exist.

func (*Service) UploadFile

func (s *Service) UploadFile(req UploadRequest) (*UploadResult, error)

UploadFile validates, decodes, and atomically writes a single workspace file. @intent provide the canonical single-file upload primitive shared with bulk uploads. @domainRule decoded payloads cannot exceed the configured MaxFileBytes. @sideEffect creates the destination directory and writes the file atomically.

func (*Service) UploadFiles

func (s *Service) UploadFiles(rawJSON string) ([]UploadResult, error)

UploadFiles parses a bulk upload JSON payload, validates every entry, and writes them sequentially. @intent batch workspace uploads with the same validation rules as single uploads while keeping atomicity per file. @domainRule rejects the request when raw bytes exceed MaxRequestBytes, when the array is empty, or when any entry fails validation. @sideEffect creates directories and writes each accepted file atomically.

type UploadRequest

type UploadRequest struct {
	Namespace string
	FilePath  string
	// ContentBase64 is the base64-encoded payload as supplied by callers.
	ContentBase64 string
}

UploadRequest describes one file payload destined for a workspace. @intent provide a typed input shared by single and bulk upload paths.

type UploadResult

type UploadResult struct {
	Namespace string
	FilePath  string
	Size      int
}

UploadResult reports the outcome of one accepted file upload. @intent expose the decoded byte size so handlers can report it back to callers.

type ValidationError

type ValidationError struct {
	// contains filtered or unexported fields
}

ValidationError is returned for caller-fixable input issues so handlers can map them to user errors. @intent distinguish bad-input errors from genuine I/O or system errors at the API boundary.

func (*ValidationError) Error

func (e *ValidationError) Error() string

Error returns the validation message. @intent expose the caller-fixable validation message without wrapping it in transport-specific formatting. @return returns the original validation message stored on the error.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL