yao/tai/docs/workspace.md

93 lines
3 KiB
Markdown

# Package `workspace`
Provides an `fs.FS`-compatible filesystem abstraction over `volume.Volume`. This allows session workspaces to be used with any Go standard library function that accepts `fs.FS`, such as `fs.WalkDir`, `template.ParseFS`, or `http.FS`.
## Interface
```go
type FS interface {
fs.FS // Open(name) (fs.File, error)
fs.StatFS // Stat(name) (fs.FileInfo, error)
fs.ReadFileFS // ReadFile(name) ([]byte, error)
fs.ReadDirFS // ReadDir(name) ([]fs.DirEntry, error)
io.Closer // Close() error
WriteFile(name string, data []byte, perm os.FileMode) error
Remove(name string) error
RemoveAll(name string) error
Rename(oldname, newname string) error
MkdirAll(name string, perm os.FileMode) error
}
```
## Constructor
```go
func New(vol volume.Volume, sessionID string) FS
```
Creates an FS backed by the given Volume for the specified session. The returned FS works transparently whether `vol` is Local or Remote.
Typically accessed through the top-level client:
```go
c, _ := tai.New("tai://host")
ws := c.Workspace("session-123")
```
## Read Operations (fs.FS compatible)
All read operations comply with the `fs.FS` contract. Paths must be valid according to `fs.ValidPath` — forward slashes, no leading slash, no `..` segments.
| Method | Standard Interface | Description |
|--------|--------------------|-------------|
| `Open(name)` | `fs.FS` | Opens a file or directory |
| `Stat(name)` | `fs.StatFS` | Returns file metadata |
| `ReadFile(name)` | `fs.ReadFileFS` | Reads entire file contents |
| `ReadDir(name)` | `fs.ReadDirFS` | Lists directory entries |
`Open` returns an in-memory `fs.File` for regular files (entire content loaded on open) and a directory handle for directories.
## Write Operations
| Method | Description |
|--------|-------------|
| `WriteFile(name, data, perm)` | Write file contents with permissions |
| `Remove(name)` | Delete a single file or empty directory |
| `RemoveAll(name)` | Delete a file or directory tree recursively |
| `Rename(old, new)` | Move/rename a file or directory |
| `MkdirAll(name, perm)` | Create directory tree (perm currently unused) |
## Example
```go
c, _ := tai.New("tai://192.168.1.100")
defer c.Close()
ws := c.Workspace("project-abc")
// Write files
ws.WriteFile("src/main.go", []byte("package main"), 0644)
ws.MkdirAll("src/utils", 0755)
// Read with standard fs.FS
data, _ := fs.ReadFile(ws, "src/main.go")
// Walk the tree
fs.WalkDir(ws, ".", func(path string, d fs.DirEntry, err error) error {
fmt.Println(path)
return nil
})
// Use with Go templates
tmpl, _ := template.ParseFS(ws, "templates/*.html")
// Clean up
ws.RemoveAll("src")
```
## Implementation Notes
- `Open` on a regular file reads the entire content into memory. For large files, prefer `ReadFile` or Volume's `ReadFile` directly.
- `Close()` is a no-op — the underlying Volume's lifecycle is managed by the `tai.Client`.
- Path validation follows `fs.ValidPath` rules. Invalid paths return `fs.ErrInvalid`.