Documentation
¶
Overview ¶
@index Workspace filesystem service that owns namespace path validation, traversal-safe resolution, and bulk upload/delete operations.
Index ¶
- Constants
- func EnsureNoSymlinkInPath(root, relPath string, allowMissingLeaf bool) (string, error)
- func IsValidationError(err error) bool
- func SafeWrite(path string, data []byte, perm os.FileMode) error
- func ValidatePath(namespace, filePath string) error
- type BulkEntry
- type BulkEntryError
- type Limits
- type Service
- func (s *Service) DeleteFile(namespace, filePath string) error
- func (s *Service) ListFiles(namespace string) ([]string, error)
- func (s *Service) ListNamespaces() ([]string, error)
- func (s *Service) RemoveTree(wsDir string) error
- func (s *Service) ResolveExistingNamespace(namespace string) (string, error)
- func (s *Service) ResolvePath(namespace, filePath string, allowMissingLeaf bool) (string, error)
- func (s *Service) SafeRoot() (string, error)
- func (s *Service) UploadFile(req UploadRequest) (*UploadResult, error)
- func (s *Service) UploadFiles(rawJSON string) ([]UploadResult, error)
- type UploadRequest
- type UploadResult
- type ValidationError
Constants ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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.