workspace

package
v0.2.2 Latest Latest
Warning

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

Go to latest
Published: Apr 27, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Overview

Package workspace provides a file-system sandbox abstraction. Knowledge, Skills, and Memory subsystems share a single Workspace to manage persistent state as a unified file tree.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrPathTraversal = errdefs.Forbidden(errors.New("workspace: path traversal denied"))
	ErrAccessDenied  = errdefs.Forbidden(errors.New("workspace: access denied"))
	ErrNotFound      = errdefs.NotFound(errors.New("workspace: not found"))
)

Common errors.

Functions

func AtomicWrite added in v0.1.13

func AtomicWrite(ctx context.Context, ws Workspace, path string, data []byte) error

AtomicWrite writes data to path via a tmp file + Rename, so concurrent readers never observe a half-written payload. The tmp file is placed in the same directory as path so Rename stays atomic on POSIX filesystems (cross-directory renames are not guaranteed atomic).

On workspaces whose Rename is non-atomic (e.g. object stores) AtomicWrite still runs cleanly; durability/atomicity is then bounded by the underlying store's guarantees, but never weaker than a plain Write.

func Copy

func Copy(ctx context.Context, ws Workspace, src, dst string) error

Copy copies a file from src to dst within the same workspace.

func Glob

func Glob(ctx context.Context, ws Workspace, pattern string) ([]string, error)

Glob returns paths matching a simple pattern relative to the workspace root. It supports patterns like "*.json", "dir/*.yaml", or "**/*.go". The "**" component matches zero or more directory levels.

func Walk

func Walk(ctx context.Context, ws Workspace, dir string, fn WalkFunc) error

Walk recursively traverses the workspace tree rooted at dir, calling fn for each file and directory. Directories are visited before their contents.

func WithWorkspace

func WithWorkspace(ctx context.Context, ws Workspace) context.Context

Types

type CommandOption

type CommandOption func(*LocalCommandRunner)

func WithMaxOutput

func WithMaxOutput(n int64) CommandOption

type CommandRunner

type CommandRunner interface {
	Exec(ctx context.Context, cmd string, args []string, opts ExecOptions) (*ExecResult, error)
}

CommandRunner executes shell commands within or relative to a workspace.

type ExecOptions

type ExecOptions struct {
	WorkDir string
	Env     map[string]string
	Stdin   []byte
	Timeout time.Duration
}

ExecOptions configures a command execution.

type ExecResult

type ExecResult struct {
	ExitCode int    `json:"exit_code"`
	Stdout   string `json:"stdout"`
	Stderr   string `json:"stderr"`
}

ExecResult captures command output.

type GitWorkspace

type GitWorkspace interface {
	Workspace
	GitClone(ctx context.Context, url, dest string) error
	GitPull(ctx context.Context, dir string) error
	GitHead(ctx context.Context, dir string) (string, error)
}

GitWorkspace extends Workspace with Git operations.

type LocalCommandRunner

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

LocalCommandRunner executes commands on the local OS.

func NewLocalCommandRunner

func NewLocalCommandRunner(rootDir string, opts ...CommandOption) *LocalCommandRunner

func (*LocalCommandRunner) Exec

func (r *LocalCommandRunner) Exec(ctx context.Context, cmd string, args []string, opts ExecOptions) (*ExecResult, error)

type LocalWorkspace

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

LocalWorkspace implements Workspace backed by a local directory.

func NewLocalWorkspace

func NewLocalWorkspace(root string) (*LocalWorkspace, error)

NewLocalWorkspace creates a workspace rooted at the given directory. The root path is resolved through EvalSymlinks to prevent the root itself from being a symlink that could be swapped later.

func (*LocalWorkspace) Append

func (w *LocalWorkspace) Append(_ context.Context, path string, data []byte) error

func (*LocalWorkspace) Delete

func (w *LocalWorkspace) Delete(_ context.Context, path string) error

func (*LocalWorkspace) Exists

func (w *LocalWorkspace) Exists(_ context.Context, path string) (bool, error)

func (*LocalWorkspace) GitClone

func (w *LocalWorkspace) GitClone(ctx context.Context, url, dest string) error

func (*LocalWorkspace) GitHead

func (w *LocalWorkspace) GitHead(ctx context.Context, dir string) (string, error)

func (*LocalWorkspace) GitPull

func (w *LocalWorkspace) GitPull(ctx context.Context, dir string) error

func (*LocalWorkspace) List

func (w *LocalWorkspace) List(_ context.Context, dir string) ([]fs.DirEntry, error)

func (*LocalWorkspace) Read

func (w *LocalWorkspace) Read(_ context.Context, path string) ([]byte, error)

func (*LocalWorkspace) RemoveAll

func (w *LocalWorkspace) RemoveAll(_ context.Context, path string) error

func (*LocalWorkspace) Rename added in v0.1.13

func (w *LocalWorkspace) Rename(_ context.Context, src, dst string) error

func (*LocalWorkspace) Root

func (w *LocalWorkspace) Root() string

Root returns the absolute path of the workspace root.

func (*LocalWorkspace) Stat

func (w *LocalWorkspace) Stat(_ context.Context, path string) (fs.FileInfo, error)

func (*LocalWorkspace) Write

func (w *LocalWorkspace) Write(_ context.Context, path string, data []byte) error

type MemWorkspace

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

MemWorkspace implements Workspace entirely in memory.

func NewMemWorkspace

func NewMemWorkspace() *MemWorkspace

func (*MemWorkspace) Append

func (m *MemWorkspace) Append(_ context.Context, path string, data []byte) error

func (*MemWorkspace) Contains

func (m *MemWorkspace) Contains(path, substr string) bool

Contains checks if a path contains a substring — intended for tests.

func (*MemWorkspace) Delete

func (m *MemWorkspace) Delete(_ context.Context, path string) error

func (*MemWorkspace) Exists

func (m *MemWorkspace) Exists(_ context.Context, path string) (bool, error)

func (*MemWorkspace) List

func (m *MemWorkspace) List(_ context.Context, dir string) ([]fs.DirEntry, error)

func (*MemWorkspace) MustWrite

func (m *MemWorkspace) MustWrite(path string, data []byte)

MustWrite panics on error — intended for tests.

func (*MemWorkspace) Read

func (m *MemWorkspace) Read(_ context.Context, path string) ([]byte, error)

func (*MemWorkspace) RemoveAll

func (m *MemWorkspace) RemoveAll(_ context.Context, path string) error

func (*MemWorkspace) Rename added in v0.1.13

func (m *MemWorkspace) Rename(_ context.Context, src, dst string) error

func (*MemWorkspace) Stat

func (m *MemWorkspace) Stat(_ context.Context, path string) (fs.FileInfo, error)

func (*MemWorkspace) Write

func (m *MemWorkspace) Write(_ context.Context, path string, data []byte) error

type NoopCommandRunner

type NoopCommandRunner struct{}

NoopCommandRunner always returns an empty successful result.

func (NoopCommandRunner) Exec

type ScopedCommandRunner

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

ScopedCommandRunner wraps a CommandRunner with a command whitelist. Only commands whose base name appears in the whitelist are permitted.

func NewScopedCommandRunner

func NewScopedCommandRunner(inner CommandRunner, allowed []string) *ScopedCommandRunner

NewScopedCommandRunner creates a runner that only allows listed commands.

func (*ScopedCommandRunner) Exec

func (r *ScopedCommandRunner) Exec(ctx context.Context, cmd string, args []string, opts ExecOptions) (*ExecResult, error)

type ScopedGitWorkspace

type ScopedGitWorkspace struct {
	*ScopedWorkspace
	// contains filtered or unexported fields
}

func NewScopedGitWorkspace

func NewScopedGitWorkspace(inner GitWorkspace, opts ...ScopedOption) *ScopedGitWorkspace

func (*ScopedGitWorkspace) GitClone

func (s *ScopedGitWorkspace) GitClone(ctx context.Context, url, dest string) error

func (*ScopedGitWorkspace) GitHead

func (s *ScopedGitWorkspace) GitHead(ctx context.Context, dir string) (string, error)

func (*ScopedGitWorkspace) GitPull

func (s *ScopedGitWorkspace) GitPull(ctx context.Context, dir string) error

type ScopedOption

type ScopedOption func(*ScopedWorkspace)

func WithAllowWrite

func WithAllowWrite(patterns ...string) ScopedOption

func WithDenyRead

func WithDenyRead(patterns ...string) ScopedOption

func WithMandatoryDeny

func WithMandatoryDeny(patterns ...string) ScopedOption

func WithViolationLogger

func WithViolationLogger(l ViolationLogger) ScopedOption

type ScopedWorkspace

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

ScopedWorkspace wraps a Workspace with dual-mode permission enforcement:

  • Read: deny-only mode — everything readable unless path matches denyRead
  • Write: allow-only mode — nothing writable unless path matches allowWrite
  • Mandatory deny paths are always blocked for both read and write

func NewScopedWorkspace

func NewScopedWorkspace(inner Workspace, opts ...ScopedOption) *ScopedWorkspace

func (*ScopedWorkspace) Append

func (s *ScopedWorkspace) Append(ctx context.Context, path string, data []byte) error

func (*ScopedWorkspace) Delete

func (s *ScopedWorkspace) Delete(ctx context.Context, path string) error

func (*ScopedWorkspace) Exists

func (s *ScopedWorkspace) Exists(ctx context.Context, path string) (bool, error)

func (*ScopedWorkspace) List

func (s *ScopedWorkspace) List(ctx context.Context, dir string) ([]fs.DirEntry, error)

func (*ScopedWorkspace) Read

func (s *ScopedWorkspace) Read(ctx context.Context, path string) ([]byte, error)

func (*ScopedWorkspace) RemoveAll

func (s *ScopedWorkspace) RemoveAll(ctx context.Context, path string) error

func (*ScopedWorkspace) Rename added in v0.1.13

func (s *ScopedWorkspace) Rename(ctx context.Context, src, dst string) error

func (*ScopedWorkspace) Stat

func (s *ScopedWorkspace) Stat(ctx context.Context, path string) (fs.FileInfo, error)

func (*ScopedWorkspace) Write

func (s *ScopedWorkspace) Write(ctx context.Context, path string, data []byte) error

type ViolationLogger

type ViolationLogger interface {
	LogViolation(ctx context.Context, record ViolationRecord)
}

ViolationLogger receives violation records from ScopedWorkspace.

type ViolationRecord

type ViolationRecord struct {
	Time      time.Time `json:"time"`
	Operation string    `json:"operation"`
	Path      string    `json:"path"`
	Reason    string    `json:"reason"`
}

ViolationRecord captures a rejected operation for audit logging.

type WalkFunc

type WalkFunc func(path string, entry fs.DirEntry) error

WalkFunc is the callback for Walk. Return filepath.SkipDir to skip a directory subtree, or any other non-nil error to abort the walk.

type Workspace

type Workspace interface {
	Read(ctx context.Context, path string) ([]byte, error)
	Write(ctx context.Context, path string, data []byte) error
	Append(ctx context.Context, path string, data []byte) error
	// Rename moves src to dst within the same workspace. Implementations
	// MUST be atomic when the underlying medium supports it (e.g. POSIX
	// rename(2) on a local filesystem). When the medium cannot rename
	// atomically (e.g. object stores) the implementation MAY fall back
	// to copy + delete, but callers should treat Rename as the canonical
	// "publish a finalized payload" operation: write to a tmp path then
	// Rename to the live path so readers never observe a half-written file.
	//
	// Returns ErrNotFound if src does not exist. Overwriting an existing
	// dst is allowed; on local filesystems this is atomic.
	Rename(ctx context.Context, src, dst string) error
	Delete(ctx context.Context, path string) error
	RemoveAll(ctx context.Context, path string) error
	List(ctx context.Context, dir string) ([]fs.DirEntry, error)
	Exists(ctx context.Context, path string) (bool, error)
	Stat(ctx context.Context, path string) (fs.FileInfo, error)
}

Workspace abstracts file operations over a sandboxed directory tree. All paths are relative to the workspace root; absolute paths and path traversals ("..") are rejected.

func MustWorkspaceFrom

func MustWorkspaceFrom(ctx context.Context) Workspace

MustWorkspaceFrom extracts the Workspace from ctx or panics. Intended for use in code paths where a Workspace is guaranteed to be present (e.g. after middleware injection).

func WorkspaceFrom

func WorkspaceFrom(ctx context.Context) (Workspace, bool)

Jump to

Keyboard shortcuts

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