refactor(ax): replace placeholder doc comments
Some checks failed
CI / auto-fix (push) Failing after 0s
CI / test (push) Failing after 2s
CI / auto-merge (push) Failing after 0s

This commit is contained in:
Virgil 2026-03-30 20:31:12 +00:00
parent 0cb59850f5
commit d900a785e7
12 changed files with 26 additions and 352 deletions

View file

@ -70,10 +70,8 @@ func FromTar(data []byte) (*Medium, error) {
}, nil
}
// Snapshot serialises the entire filesystem to a tarball.
// Example: snapshot, _ := medium.Snapshot()
// Use this for crash reports, workspace packaging, or TIM creation.
//
// result := m.Snapshot(...)
func (m *Medium) Snapshot() ([]byte, error) {
m.mu.RLock()
defer m.mu.RUnlock()
@ -84,9 +82,7 @@ func (m *Medium) Snapshot() ([]byte, error) {
return data, nil
}
// Restore replaces the filesystem contents from a tarball.
//
// result := m.Restore(...)
// Example: _ = medium.Restore(snapshot)
func (m *Medium) Restore(data []byte) error {
dataNode, err := borgdatanode.FromTar(data)
if err != nil {
@ -99,10 +95,8 @@ func (m *Medium) Restore(data []byte) error {
return nil
}
// DataNode returns the underlying Borg DataNode.
// Example: dataNode := medium.DataNode()
// Use this to wrap the filesystem in a TIM container.
//
// result := m.DataNode(...)
func (m *Medium) DataNode() *borgdatanode.DataNode {
m.mu.RLock()
defer m.mu.RUnlock()

64
io.go
View file

@ -142,51 +142,37 @@ func NewSandboxed(root string) (Medium, error) {
// --- Helper Functions ---
// Read retrieves the content of a file from the given medium.
//
// result := io.Read(...)
// Example: content, _ := io.Read(medium, "config/app.yaml")
func Read(m Medium, path string) (string, error) {
return m.Read(path)
}
// Write saves the given content to a file in the given medium.
//
// result := io.Write(...)
// Example: _ = io.Write(medium, "config/app.yaml", "port: 8080")
func Write(m Medium, path, content string) error {
return m.Write(path, content)
}
// ReadStream returns a reader for the file content from the given medium.
//
// result := io.ReadStream(...)
// Example: reader, _ := io.ReadStream(medium, "logs/app.log")
func ReadStream(m Medium, path string) (goio.ReadCloser, error) {
return m.ReadStream(path)
}
// WriteStream returns a writer for the file content in the given medium.
//
// result := io.WriteStream(...)
// Example: writer, _ := io.WriteStream(medium, "logs/app.log")
func WriteStream(m Medium, path string) (goio.WriteCloser, error) {
return m.WriteStream(path)
}
// EnsureDir makes sure a directory exists in the given medium.
//
// result := io.EnsureDir(...)
// Example: _ = io.EnsureDir(medium, "config")
func EnsureDir(m Medium, path string) error {
return m.EnsureDir(path)
}
// IsFile checks if a path exists and is a regular file in the given medium.
//
// result := io.IsFile(...)
// Example: ok := io.IsFile(medium, "config/app.yaml")
func IsFile(m Medium, path string) bool {
return m.IsFile(path)
}
// Copy copies a file from one medium to another.
//
// result := io.Copy(...)
// Example: _ = io.Copy(source, "input.txt", destination, "backup/input.txt")
func Copy(source Medium, sourcePath string, destination Medium, destinationPath string) error {
content, err := source.Read(sourcePath)
if err != nil {
@ -221,8 +207,6 @@ func NewMockMedium() *MockMedium {
}
// Read retrieves the content of a file from the mock filesystem.
//
// result := m.Read(...)
func (m *MockMedium) Read(path string) (string, error) {
content, ok := m.Files[path]
if !ok {
@ -232,8 +216,6 @@ func (m *MockMedium) Read(path string) (string, error) {
}
// Write saves the given content to a file in the mock filesystem.
//
// result := m.Write(...)
func (m *MockMedium) Write(path, content string) error {
m.Files[path] = content
m.ModTimes[path] = time.Now()
@ -245,38 +227,28 @@ func (m *MockMedium) WriteMode(path, content string, mode fs.FileMode) error {
}
// EnsureDir records that a directory exists in the mock filesystem.
//
// result := m.EnsureDir(...)
func (m *MockMedium) EnsureDir(path string) error {
m.Dirs[path] = true
return nil
}
// IsFile checks if a path exists as a file in the mock filesystem.
//
// result := m.IsFile(...)
func (m *MockMedium) IsFile(path string) bool {
_, ok := m.Files[path]
return ok
}
// FileGet is a convenience function that reads a file from the mock filesystem.
//
// result := m.FileGet(...)
func (m *MockMedium) FileGet(path string) (string, error) {
return m.Read(path)
}
// FileSet is a convenience function that writes a file to the mock filesystem.
//
// result := m.FileSet(...)
func (m *MockMedium) FileSet(path, content string) error {
return m.Write(path, content)
}
// Delete removes a file or empty directory from the mock filesystem.
//
// result := m.Delete(...)
func (m *MockMedium) Delete(path string) error {
if _, ok := m.Files[path]; ok {
delete(m.Files, path)
@ -305,8 +277,6 @@ func (m *MockMedium) Delete(path string) error {
}
// DeleteAll removes a file or directory and all contents from the mock filesystem.
//
// result := m.DeleteAll(...)
func (m *MockMedium) DeleteAll(path string) error {
found := false
if _, ok := m.Files[path]; ok {
@ -343,8 +313,6 @@ func (m *MockMedium) DeleteAll(path string) error {
}
// Rename moves a file or directory in the mock filesystem.
//
// result := m.Rename(...)
func (m *MockMedium) Rename(oldPath, newPath string) error {
if content, ok := m.Files[oldPath]; ok {
m.Files[newPath] = content
@ -404,8 +372,6 @@ func (m *MockMedium) Rename(oldPath, newPath string) error {
}
// Open opens a file from the mock filesystem.
//
// result := m.Open(...)
func (m *MockMedium) Open(path string) (fs.File, error) {
content, ok := m.Files[path]
if !ok {
@ -418,8 +384,6 @@ func (m *MockMedium) Open(path string) (fs.File, error) {
}
// Create creates a file in the mock filesystem.
//
// result := m.Create(...)
func (m *MockMedium) Create(path string) (goio.WriteCloser, error) {
return &MockWriteCloser{
medium: m,
@ -428,8 +392,6 @@ func (m *MockMedium) Create(path string) (goio.WriteCloser, error) {
}
// Append opens a file for appending in the mock filesystem.
//
// result := m.Append(...)
func (m *MockMedium) Append(path string) (goio.WriteCloser, error) {
content := m.Files[path]
return &MockWriteCloser{
@ -440,15 +402,11 @@ func (m *MockMedium) Append(path string) (goio.WriteCloser, error) {
}
// ReadStream returns a reader for the file content in the mock filesystem.
//
// result := m.ReadStream(...)
func (m *MockMedium) ReadStream(path string) (goio.ReadCloser, error) {
return m.Open(path)
}
// WriteStream returns a writer for the file content in the mock filesystem.
//
// result := m.WriteStream(...)
func (m *MockMedium) WriteStream(path string) (goio.WriteCloser, error) {
return m.Create(path)
}
@ -499,8 +457,6 @@ func (w *MockWriteCloser) Close() error {
}
// List returns directory entries for the mock filesystem.
//
// result := m.List(...)
func (m *MockMedium) List(path string) ([]fs.DirEntry, error) {
if _, ok := m.Dirs[path]; !ok {
// Check if it's the root or has children
@ -610,8 +566,6 @@ func (m *MockMedium) List(path string) ([]fs.DirEntry, error) {
}
// Stat returns file information for the mock filesystem.
//
// result := m.Stat(...)
func (m *MockMedium) Stat(path string) (fs.FileInfo, error) {
if content, ok := m.Files[path]; ok {
modTime, ok := m.ModTimes[path]
@ -636,8 +590,6 @@ func (m *MockMedium) Stat(path string) (fs.FileInfo, error) {
}
// Exists checks if a path exists in the mock filesystem.
//
// result := m.Exists(...)
func (m *MockMedium) Exists(path string) bool {
if _, ok := m.Files[path]; ok {
return true
@ -649,8 +601,6 @@ func (m *MockMedium) Exists(path string) bool {
}
// IsDir checks if a path is a directory in the mock filesystem.
//
// result := m.IsDir(...)
func (m *MockMedium) IsDir(path string) bool {
_, ok := m.Dirs[path]
return ok

View file

@ -241,8 +241,6 @@ func (m *Medium) validatePath(path string) (string, error) {
}
// Read returns file contents as string.
//
// result := m.Read(...)
func (m *Medium) Read(path string) (string, error) {
resolvedPath, err := m.validatePath(path)
if err != nil {
@ -254,16 +252,12 @@ func (m *Medium) Read(path string) (string, error) {
// Write saves content to file, creating parent directories as needed.
// Files are created with mode 0644. For sensitive files (keys, secrets),
// use WriteMode with 0600.
//
// result := m.Write(...)
func (m *Medium) Write(path, content string) error {
return m.WriteMode(path, content, 0644)
}
// WriteMode saves content to file with explicit permissions.
// Use 0600 for sensitive files (encryption output, private keys, auth hashes).
//
// result := m.WriteMode(...)
func (m *Medium) WriteMode(path, content string, mode fs.FileMode) error {
resolvedPath, err := m.validatePath(path)
if err != nil {
@ -273,8 +267,6 @@ func (m *Medium) WriteMode(path, content string, mode fs.FileMode) error {
}
// EnsureDir creates directory if it doesn't exist.
//
// result := m.EnsureDir(...)
func (m *Medium) EnsureDir(path string) error {
resolvedPath, err := m.validatePath(path)
if err != nil {
@ -284,8 +276,6 @@ func (m *Medium) EnsureDir(path string) error {
}
// IsDir returns true if path is a directory.
//
// result := m.IsDir(...)
func (m *Medium) IsDir(path string) bool {
if path == "" {
return false
@ -298,8 +288,6 @@ func (m *Medium) IsDir(path string) bool {
}
// IsFile returns true if path is a regular file.
//
// result := m.IsFile(...)
func (m *Medium) IsFile(path string) bool {
if path == "" {
return false
@ -312,8 +300,6 @@ func (m *Medium) IsFile(path string) bool {
}
// Exists returns true if path exists.
//
// result := m.Exists(...)
func (m *Medium) Exists(path string) bool {
resolvedPath, err := m.validatePath(path)
if err != nil {
@ -323,8 +309,6 @@ func (m *Medium) Exists(path string) bool {
}
// List returns directory entries.
//
// result := m.List(...)
func (m *Medium) List(path string) ([]fs.DirEntry, error) {
resolvedPath, err := m.validatePath(path)
if err != nil {
@ -334,8 +318,6 @@ func (m *Medium) List(path string) ([]fs.DirEntry, error) {
}
// Stat returns file info.
//
// result := m.Stat(...)
func (m *Medium) Stat(path string) (fs.FileInfo, error) {
resolvedPath, err := m.validatePath(path)
if err != nil {
@ -345,8 +327,6 @@ func (m *Medium) Stat(path string) (fs.FileInfo, error) {
}
// Open opens the named file for reading.
//
// result := m.Open(...)
func (m *Medium) Open(path string) (fs.File, error) {
resolvedPath, err := m.validatePath(path)
if err != nil {
@ -356,8 +336,6 @@ func (m *Medium) Open(path string) (fs.File, error) {
}
// Create creates or truncates the named file.
//
// result := m.Create(...)
func (m *Medium) Create(path string) (goio.WriteCloser, error) {
resolvedPath, err := m.validatePath(path)
if err != nil {
@ -367,8 +345,6 @@ func (m *Medium) Create(path string) (goio.WriteCloser, error) {
}
// Append opens the named file for appending, creating it if it doesn't exist.
//
// result := m.Append(...)
func (m *Medium) Append(path string) (goio.WriteCloser, error) {
resolvedPath, err := m.validatePath(path)
if err != nil {
@ -383,8 +359,6 @@ func (m *Medium) Append(path string) (goio.WriteCloser, error) {
// API, as required by the io.Medium interface, while Open provides the more
// general filesystem-level operation. Both methods are kept for semantic
// clarity and backward compatibility.
//
// result := m.ReadStream(...)
func (m *Medium) ReadStream(path string) (goio.ReadCloser, error) {
return m.Open(path)
}
@ -395,15 +369,11 @@ func (m *Medium) ReadStream(path string) (goio.ReadCloser, error) {
// API, as required by the io.Medium interface, while Create provides the more
// general filesystem-level operation. Both methods are kept for semantic
// clarity and backward compatibility.
//
// result := m.WriteStream(...)
func (m *Medium) WriteStream(path string) (goio.WriteCloser, error) {
return m.Create(path)
}
// Delete removes a file or empty directory.
//
// result := m.Delete(...)
func (m *Medium) Delete(path string) error {
resolvedPath, err := m.validatePath(path)
if err != nil {
@ -416,8 +386,6 @@ func (m *Medium) Delete(path string) error {
}
// DeleteAll removes a file or directory recursively.
//
// result := m.DeleteAll(...)
func (m *Medium) DeleteAll(path string) error {
resolvedPath, err := m.validatePath(path)
if err != nil {
@ -430,8 +398,6 @@ func (m *Medium) DeleteAll(path string) error {
}
// Rename moves a file or directory.
//
// result := m.Rename(...)
func (m *Medium) Rename(oldPath, newPath string) error {
oldResolvedPath, err := m.validatePath(oldPath)
if err != nil {

View file

@ -41,8 +41,6 @@ func New() *Node {
// ---------- Node-specific methods ----------
// AddData stages content in the in-memory filesystem.
//
// result := n.AddData(...)
func (n *Node) AddData(name string, content []byte) {
name = core.TrimPrefix(name, "/")
if name == "" {
@ -60,8 +58,6 @@ func (n *Node) AddData(name string, content []byte) {
}
// ToTar serialises the entire in-memory tree to a tar archive.
//
// result := n.ToTar(...)
func (n *Node) ToTar() ([]byte, error) {
buf := new(bytes.Buffer)
tw := tar.NewWriter(buf)
@ -89,8 +85,6 @@ func (n *Node) ToTar() ([]byte, error) {
}
// FromTar creates a new Node from a tar archive.
//
// result := node.FromTar(...)
func FromTar(data []byte) (*Node, error) {
n := New()
if err := n.LoadTar(data); err != nil {
@ -100,8 +94,6 @@ func FromTar(data []byte) (*Node, error) {
}
// LoadTar replaces the in-memory tree with the contents of a tar archive.
//
// result := n.LoadTar(...)
func (n *Node) LoadTar(data []byte) error {
newFiles := make(map[string]*dataFile)
tr := tar.NewReader(bytes.NewReader(data))
@ -137,8 +129,6 @@ func (n *Node) LoadTar(data []byte) error {
}
// WalkNode walks the in-memory tree, calling fn for each entry.
//
// result := n.WalkNode(...)
func (n *Node) WalkNode(root string, fn fs.WalkDirFunc) error {
return fs.WalkDir(n, root, fn)
}
@ -156,8 +146,6 @@ type WalkOptions struct {
}
// Walk walks the in-memory tree with optional WalkOptions.
//
// result := n.Walk(...)
func (n *Node) Walk(root string, fn fs.WalkDirFunc, opts ...WalkOptions) error {
var opt WalkOptions
if len(opts) > 0 {
@ -200,8 +188,6 @@ func (n *Node) Walk(root string, fn fs.WalkDirFunc, opts ...WalkOptions) error {
// ReadFile returns the content of the named file as a byte slice.
// Implements fs.ReadFileFS.
//
// result := n.ReadFile(...)
func (n *Node) ReadFile(name string) ([]byte, error) {
name = core.TrimPrefix(name, "/")
f, ok := n.files[name]
@ -215,8 +201,6 @@ func (n *Node) ReadFile(name string) ([]byte, error) {
}
// CopyFile copies a file from the in-memory tree to the local filesystem.
//
// result := n.CopyFile(...)
func (n *Node) CopyFile(sourcePath, destinationPath string, perm fs.FileMode) error {
sourcePath = core.TrimPrefix(sourcePath, "/")
f, ok := n.files[sourcePath]
@ -285,8 +269,6 @@ func (n *Node) CopyTo(target coreio.Medium, sourcePath, destPath string) error {
// ---------- Medium interface: fs.FS methods ----------
// Open opens a file from the Node. Implements fs.FS.
//
// result := n.Open(...)
func (n *Node) Open(name string) (fs.File, error) {
name = core.TrimPrefix(name, "/")
if file, ok := n.files[name]; ok {
@ -306,8 +288,6 @@ func (n *Node) Open(name string) (fs.File, error) {
}
// Stat returns file information for the given path.
//
// result := n.Stat(...)
func (n *Node) Stat(name string) (fs.FileInfo, error) {
name = core.TrimPrefix(name, "/")
if file, ok := n.files[name]; ok {
@ -327,8 +307,6 @@ func (n *Node) Stat(name string) (fs.FileInfo, error) {
}
// ReadDir reads and returns all directory entries for the named directory.
//
// result := n.ReadDir(...)
func (n *Node) ReadDir(name string) ([]fs.DirEntry, error) {
name = core.TrimPrefix(name, "/")
if name == "." {
@ -381,8 +359,6 @@ func (n *Node) ReadDir(name string) ([]fs.DirEntry, error) {
// ---------- Medium interface: read/write ----------
// Read retrieves the content of a file as a string.
//
// result := n.Read(...)
func (n *Node) Read(filePath string) (string, error) {
filePath = core.TrimPrefix(filePath, "/")
f, ok := n.files[filePath]
@ -393,16 +369,12 @@ func (n *Node) Read(filePath string) (string, error) {
}
// Write saves the given content to a file, overwriting it if it exists.
//
// result := n.Write(...)
func (n *Node) Write(filePath, content string) error {
n.AddData(filePath, []byte(content))
return nil
}
// WriteMode saves content with explicit permissions (no-op for in-memory node).
//
// result := n.WriteMode(...)
func (n *Node) WriteMode(filePath, content string, mode fs.FileMode) error {
return n.Write(filePath, content)
}
@ -416,8 +388,6 @@ func (n *Node) FileSet(filePath, content string) error {
}
// EnsureDir is a no-op because directories are implicit in Node.
//
// result := n.EnsureDir(...)
func (n *Node) EnsureDir(_ string) error {
return nil
}
@ -425,16 +395,12 @@ func (n *Node) EnsureDir(_ string) error {
// ---------- Medium interface: existence checks ----------
// Exists checks if a path exists (file or directory).
//
// result := n.Exists(...)
func (n *Node) Exists(filePath string) bool {
_, err := n.Stat(filePath)
return err == nil
}
// IsFile checks if a path exists and is a regular file.
//
// result := n.IsFile(...)
func (n *Node) IsFile(filePath string) bool {
filePath = core.TrimPrefix(filePath, "/")
_, ok := n.files[filePath]
@ -442,8 +408,6 @@ func (n *Node) IsFile(filePath string) bool {
}
// IsDir checks if a path exists and is a directory.
//
// result := n.IsDir(...)
func (n *Node) IsDir(filePath string) bool {
info, err := n.Stat(filePath)
if err != nil {
@ -455,8 +419,6 @@ func (n *Node) IsDir(filePath string) bool {
// ---------- Medium interface: mutations ----------
// Delete removes a single file.
//
// result := n.Delete(...)
func (n *Node) Delete(filePath string) error {
filePath = core.TrimPrefix(filePath, "/")
if _, ok := n.files[filePath]; ok {
@ -467,8 +429,6 @@ func (n *Node) Delete(filePath string) error {
}
// DeleteAll removes a file or directory and all children.
//
// result := n.DeleteAll(...)
func (n *Node) DeleteAll(filePath string) error {
filePath = core.TrimPrefix(filePath, "/")
@ -493,8 +453,6 @@ func (n *Node) DeleteAll(filePath string) error {
}
// Rename moves a file from oldPath to newPath.
//
// result := n.Rename(...)
func (n *Node) Rename(oldPath, newPath string) error {
oldPath = core.TrimPrefix(oldPath, "/")
newPath = core.TrimPrefix(newPath, "/")
@ -511,8 +469,6 @@ func (n *Node) Rename(oldPath, newPath string) error {
}
// List returns directory entries for the given path.
//
// result := n.List(...)
func (n *Node) List(filePath string) ([]fs.DirEntry, error) {
filePath = core.TrimPrefix(filePath, "/")
if filePath == "" || filePath == "." {
@ -525,8 +481,6 @@ func (n *Node) List(filePath string) ([]fs.DirEntry, error) {
// Create creates or truncates the named file, returning a WriteCloser.
// Content is committed to the Node on Close.
//
// result := n.Create(...)
func (n *Node) Create(filePath string) (goio.WriteCloser, error) {
filePath = core.TrimPrefix(filePath, "/")
return &nodeWriter{node: n, path: filePath}, nil
@ -534,8 +488,6 @@ func (n *Node) Create(filePath string) (goio.WriteCloser, error) {
// Append opens the named file for appending, creating it if needed.
// Content is committed to the Node on Close.
//
// result := n.Append(...)
func (n *Node) Append(filePath string) (goio.WriteCloser, error) {
filePath = core.TrimPrefix(filePath, "/")
var existing []byte
@ -547,8 +499,6 @@ func (n *Node) Append(filePath string) (goio.WriteCloser, error) {
}
// ReadStream returns a ReadCloser for the file content.
//
// result := n.ReadStream(...)
func (n *Node) ReadStream(filePath string) (goio.ReadCloser, error) {
f, err := n.Open(filePath)
if err != nil {
@ -558,8 +508,6 @@ func (n *Node) ReadStream(filePath string) (goio.ReadCloser, error) {
}
// WriteStream returns a WriteCloser for the file content.
//
// result := n.WriteStream(...)
func (n *Node) WriteStream(filePath string) (goio.WriteCloser, error) {
return n.Create(filePath)
}

View file

@ -128,8 +128,6 @@ func (m *Medium) key(filePath string) string {
}
// Read retrieves the content of a file as a string.
//
// result := m.Read(...)
func (m *Medium) Read(filePath string) (string, error) {
key := m.key(filePath)
if key == "" {
@ -153,8 +151,6 @@ func (m *Medium) Read(filePath string) (string, error) {
}
// Write saves the given content to a file, overwriting it if it exists.
//
// result := m.Write(...)
func (m *Medium) Write(filePath, content string) error {
key := m.key(filePath)
if key == "" {
@ -173,22 +169,16 @@ func (m *Medium) Write(filePath, content string) error {
}
// WriteMode ignores the requested mode because S3 objects do not store POSIX permissions.
//
// result := m.WriteMode(...)
func (m *Medium) WriteMode(filePath, content string, _ fs.FileMode) error {
return m.Write(filePath, content)
}
// EnsureDir is a no-op for S3 (S3 has no real directories).
//
// result := m.EnsureDir(...)
func (m *Medium) EnsureDir(_ string) error {
return nil
}
// IsFile checks if a path exists and is a regular file (not a "directory" prefix).
//
// result := m.IsFile(...)
func (m *Medium) IsFile(filePath string) bool {
key := m.key(filePath)
if key == "" {
@ -206,22 +196,16 @@ func (m *Medium) IsFile(filePath string) bool {
}
// FileGet is a convenience function that reads a file from the medium.
//
// result := m.FileGet(...)
func (m *Medium) FileGet(filePath string) (string, error) {
return m.Read(filePath)
}
// FileSet is a convenience function that writes a file to the medium.
//
// result := m.FileSet(...)
func (m *Medium) FileSet(filePath, content string) error {
return m.Write(filePath, content)
}
// Delete removes a single object.
//
// result := m.Delete(...)
func (m *Medium) Delete(filePath string) error {
key := m.key(filePath)
if key == "" {
@ -239,8 +223,6 @@ func (m *Medium) Delete(filePath string) error {
}
// DeleteAll removes all objects under the given prefix.
//
// result := m.DeleteAll(...)
func (m *Medium) DeleteAll(filePath string) error {
key := m.key(filePath)
if key == "" {
@ -306,8 +288,6 @@ func (m *Medium) DeleteAll(filePath string) error {
}
// Rename moves an object by copying then deleting the original.
//
// result := m.Rename(...)
func (m *Medium) Rename(oldPath, newPath string) error {
oldKey := m.key(oldPath)
newKey := m.key(newPath)
@ -338,8 +318,6 @@ func (m *Medium) Rename(oldPath, newPath string) error {
}
// List returns directory entries for the given path using ListObjectsV2 with delimiter.
//
// result := m.List(...)
func (m *Medium) List(filePath string) ([]fs.DirEntry, error) {
prefix := m.key(filePath)
if prefix != "" && !core.HasSuffix(prefix, "/") {
@ -413,8 +391,6 @@ func (m *Medium) List(filePath string) ([]fs.DirEntry, error) {
}
// Stat returns file information for the given path using HeadObject.
//
// result := m.Stat(...)
func (m *Medium) Stat(filePath string) (fs.FileInfo, error) {
key := m.key(filePath)
if key == "" {
@ -448,8 +424,6 @@ func (m *Medium) Stat(filePath string) (fs.FileInfo, error) {
}
// Open opens the named file for reading.
//
// result := m.Open(...)
func (m *Medium) Open(filePath string) (fs.File, error) {
key := m.key(filePath)
if key == "" {
@ -489,8 +463,6 @@ func (m *Medium) Open(filePath string) (fs.File, error) {
// Create creates or truncates the named file. Returns a writer that
// uploads the content on Close.
//
// result := m.Create(...)
func (m *Medium) Create(filePath string) (goio.WriteCloser, error) {
key := m.key(filePath)
if key == "" {
@ -504,8 +476,6 @@ func (m *Medium) Create(filePath string) (goio.WriteCloser, error) {
// Append opens the named file for appending. It downloads the existing
// content (if any) and re-uploads the combined content on Close.
//
// result := m.Append(...)
func (m *Medium) Append(filePath string) (goio.WriteCloser, error) {
key := m.key(filePath)
if key == "" {
@ -530,8 +500,6 @@ func (m *Medium) Append(filePath string) (goio.WriteCloser, error) {
}
// ReadStream returns a reader for the file content.
//
// result := m.ReadStream(...)
func (m *Medium) ReadStream(filePath string) (goio.ReadCloser, error) {
key := m.key(filePath)
if key == "" {
@ -549,15 +517,11 @@ func (m *Medium) ReadStream(filePath string) (goio.ReadCloser, error) {
}
// WriteStream returns a writer for the file content. Content is uploaded on Close.
//
// result := m.WriteStream(...)
func (m *Medium) WriteStream(filePath string) (goio.WriteCloser, error) {
return m.Create(filePath)
}
// Exists checks if a path exists (file or directory prefix).
//
// result := m.Exists(...)
func (m *Medium) Exists(filePath string) bool {
key := m.key(filePath)
if key == "" {
@ -590,8 +554,6 @@ func (m *Medium) Exists(filePath string) bool {
}
// IsDir checks if a path exists and is a directory (has objects under it as a prefix).
//
// result := m.IsDir(...)
func (m *Medium) IsDir(filePath string) bool {
key := m.key(filePath)
if key == "" {

View file

@ -62,8 +62,6 @@ type PreObfuscator interface {
type XORObfuscator struct{}
// Obfuscate XORs the data with a key stream derived from the entropy.
//
// result := x.Obfuscate(...)
func (x *XORObfuscator) Obfuscate(data []byte, entropy []byte) []byte {
if len(data) == 0 {
return data
@ -72,8 +70,6 @@ func (x *XORObfuscator) Obfuscate(data []byte, entropy []byte) []byte {
}
// Deobfuscate reverses the XOR transformation (XOR is symmetric).
//
// result := x.Deobfuscate(...)
func (x *XORObfuscator) Deobfuscate(data []byte, entropy []byte) []byte {
if len(data) == 0 {
return data
@ -128,8 +124,6 @@ func (x *XORObfuscator) deriveKeyStream(entropy []byte, length int) []byte {
type ShuffleMaskObfuscator struct{}
// Obfuscate shuffles bytes and applies a mask derived from entropy.
//
// result := s.Obfuscate(...)
func (s *ShuffleMaskObfuscator) Obfuscate(data []byte, entropy []byte) []byte {
if len(data) == 0 {
return data
@ -157,8 +151,6 @@ func (s *ShuffleMaskObfuscator) Obfuscate(data []byte, entropy []byte) []byte {
}
// Deobfuscate reverses the shuffle and mask operations.
//
// result := s.Deobfuscate(...)
func (s *ShuffleMaskObfuscator) Deobfuscate(data []byte, entropy []byte) []byte {
if len(data) == 0 {
return data
@ -291,8 +283,6 @@ func NewChaChaPolySigilWithObfuscator(key []byte, obfuscator PreObfuscator) (*Ch
// In encrypts the data with pre-obfuscation.
// The flow is: plaintext -> obfuscate -> encrypt
//
// result := s.In(...)
func (s *ChaChaPolySigil) In(data []byte) ([]byte, error) {
if s.Key == nil {
return nil, ErrNoKeyConfigured
@ -332,8 +322,6 @@ func (s *ChaChaPolySigil) In(data []byte) ([]byte, error) {
// Out decrypts the data and reverses obfuscation.
// The flow is: decrypt -> deobfuscate -> plaintext
//
// result := s.Out(...)
func (s *ChaChaPolySigil) Out(data []byte) ([]byte, error) {
if s.Key == nil {
return nil, ErrNoKeyConfigured
@ -378,8 +366,6 @@ func (s *ChaChaPolySigil) Out(data []byte) ([]byte, error) {
// GetNonceFromCiphertext extracts the nonce from encrypted output.
// This is provided for debugging/logging purposes only.
// The nonce should NOT be stored separately in headers.
//
// result := sigil.GetNonceFromCiphertext(...)
func GetNonceFromCiphertext(ciphertext []byte) ([]byte, error) {
nonceSize := chacha20poly1305.NonceSizeX
if len(ciphertext) < nonceSize {

View file

@ -45,8 +45,6 @@ type Sigil interface {
// stops immediately and returns nil with that error.
//
// To reverse a transmutation, call each sigil's Out method in reverse order.
//
// result := sigil.Transmute(...)
func Transmute(data []byte, sigils []Sigil) ([]byte, error) {
var err error
for _, s := range sigils {
@ -63,8 +61,6 @@ func Transmute(data []byte, sigils []Sigil) ([]byte, error) {
// Each sigil's Out method is called in reverse order, with the output of one sigil
// becoming the input of the next. If any sigil returns an error, Untransmute
// stops immediately and returns nil with that error.
//
// result := sigil.Untransmute(...)
func Untransmute(data []byte, sigils []Sigil) ([]byte, error) {
var err error
for i := len(sigils) - 1; i >= 0; i-- {

View file

@ -25,8 +25,6 @@ import (
type ReverseSigil struct{}
// In reverses the bytes of the data.
//
// result := s.In(...)
func (s *ReverseSigil) In(data []byte) ([]byte, error) {
if data == nil {
return nil, nil
@ -39,8 +37,6 @@ func (s *ReverseSigil) In(data []byte) ([]byte, error) {
}
// Out reverses the bytes of the data.
//
// result := s.Out(...)
func (s *ReverseSigil) Out(data []byte) ([]byte, error) {
return s.In(data)
}
@ -50,8 +46,6 @@ func (s *ReverseSigil) Out(data []byte) ([]byte, error) {
type HexSigil struct{}
// In encodes the data to hexadecimal.
//
// result := s.In(...)
func (s *HexSigil) In(data []byte) ([]byte, error) {
if data == nil {
return nil, nil
@ -62,8 +56,6 @@ func (s *HexSigil) In(data []byte) ([]byte, error) {
}
// Out decodes the data from hexadecimal.
//
// result := s.Out(...)
func (s *HexSigil) Out(data []byte) ([]byte, error) {
if data == nil {
return nil, nil
@ -78,8 +70,6 @@ func (s *HexSigil) Out(data []byte) ([]byte, error) {
type Base64Sigil struct{}
// In encodes the data to base64.
//
// result := s.In(...)
func (s *Base64Sigil) In(data []byte) ([]byte, error) {
if data == nil {
return nil, nil
@ -90,8 +80,6 @@ func (s *Base64Sigil) In(data []byte) ([]byte, error) {
}
// Out decodes the data from base64.
//
// result := s.Out(...)
func (s *Base64Sigil) Out(data []byte) ([]byte, error) {
if data == nil {
return nil, nil
@ -108,8 +96,6 @@ type GzipSigil struct {
}
// In compresses the data using gzip.
//
// result := s.In(...)
func (s *GzipSigil) In(data []byte) ([]byte, error) {
if data == nil {
return nil, nil
@ -130,8 +116,6 @@ func (s *GzipSigil) In(data []byte) ([]byte, error) {
}
// Out decompresses the data using gzip.
//
// result := s.Out(...)
func (s *GzipSigil) Out(data []byte) ([]byte, error) {
if data == nil {
return nil, nil
@ -153,8 +137,6 @@ func (s *GzipSigil) Out(data []byte) ([]byte, error) {
type JSONSigil struct{ Indent bool }
// In compacts or indents the JSON data.
//
// result := s.In(...)
func (s *JSONSigil) In(data []byte) ([]byte, error) {
if data == nil {
return nil, nil
@ -177,8 +159,6 @@ func (s *JSONSigil) In(data []byte) ([]byte, error) {
}
// Out is a no-op for JSONSigil.
//
// result := s.Out(...)
func (s *JSONSigil) Out(data []byte) ([]byte, error) {
// For simplicity, Out is a no-op. The primary use is formatting.
return data, nil
@ -199,8 +179,6 @@ func NewHashSigil(h crypto.Hash) *HashSigil {
}
// In hashes the data.
//
// result := s.In(...)
func (s *HashSigil) In(data []byte) ([]byte, error) {
var h io.Writer
switch s.Hash {
@ -250,16 +228,12 @@ func (s *HashSigil) In(data []byte) ([]byte, error) {
}
// Out is a no-op for HashSigil.
//
// result := s.Out(...)
func (s *HashSigil) Out(data []byte) ([]byte, error) {
return data, nil
}
// NewSigil is a factory function that returns a Sigil based on a string name.
// It is the primary way to create Sigil instances.
//
// result := sigil.NewSigil(...)
func NewSigil(name string) (Sigil, error) {
switch name {
case "reverse":

View file

@ -81,8 +81,6 @@ func New(options Options) (*Medium, error) {
}
// Close closes the underlying database connection.
//
// result := m.Close(...)
func (m *Medium) Close() error {
if m.database != nil {
return m.database.Close()
@ -101,8 +99,6 @@ func cleanPath(filePath string) string {
}
// Read retrieves the content of a file as a string.
//
// result := m.Read(...)
func (m *Medium) Read(filePath string) (string, error) {
key := cleanPath(filePath)
if key == "" {
@ -127,15 +123,11 @@ func (m *Medium) Read(filePath string) (string, error) {
}
// Write saves the given content to a file, overwriting it if it exists.
//
// result := m.Write(...)
func (m *Medium) Write(filePath, content string) error {
return m.WriteMode(filePath, content, 0644)
}
// WriteMode saves the given content with explicit permissions.
//
// result := m.WriteMode(...)
func (m *Medium) WriteMode(filePath, content string, mode fs.FileMode) error {
key := cleanPath(filePath)
if key == "" {
@ -154,8 +146,6 @@ func (m *Medium) WriteMode(filePath, content string, mode fs.FileMode) error {
}
// EnsureDir makes sure a directory exists, creating it if necessary.
//
// result := m.EnsureDir(...)
func (m *Medium) EnsureDir(filePath string) error {
key := cleanPath(filePath)
if key == "" {
@ -175,8 +165,6 @@ func (m *Medium) EnsureDir(filePath string) error {
}
// IsFile checks if a path exists and is a regular file.
//
// result := m.IsFile(...)
func (m *Medium) IsFile(filePath string) bool {
key := cleanPath(filePath)
if key == "" {
@ -194,22 +182,16 @@ func (m *Medium) IsFile(filePath string) bool {
}
// FileGet is a convenience function that reads a file from the medium.
//
// result := m.FileGet(...)
func (m *Medium) FileGet(filePath string) (string, error) {
return m.Read(filePath)
}
// FileSet is a convenience function that writes a file to the medium.
//
// result := m.FileSet(...)
func (m *Medium) FileSet(filePath, content string) error {
return m.Write(filePath, content)
}
// Delete removes a file or empty directory.
//
// result := m.Delete(...)
func (m *Medium) Delete(filePath string) error {
key := cleanPath(filePath)
if key == "" {
@ -255,8 +237,6 @@ func (m *Medium) Delete(filePath string) error {
}
// DeleteAll removes a file or directory and all its contents recursively.
//
// result := m.DeleteAll(...)
func (m *Medium) DeleteAll(filePath string) error {
key := cleanPath(filePath)
if key == "" {
@ -281,8 +261,6 @@ func (m *Medium) DeleteAll(filePath string) error {
}
// Rename moves a file or directory from oldPath to newPath.
//
// result := m.Rename(...)
func (m *Medium) Rename(oldPath, newPath string) error {
oldKey := cleanPath(oldPath)
newKey := cleanPath(newPath)
@ -381,8 +359,6 @@ func (m *Medium) Rename(oldPath, newPath string) error {
}
// List returns the directory entries for the given path.
//
// result := m.List(...)
func (m *Medium) List(filePath string) ([]fs.DirEntry, error) {
prefix := cleanPath(filePath)
if prefix != "" {
@ -459,8 +435,6 @@ func (m *Medium) List(filePath string) ([]fs.DirEntry, error) {
}
// Stat returns file information for the given path.
//
// result := m.Stat(...)
func (m *Medium) Stat(filePath string) (fs.FileInfo, error) {
key := cleanPath(filePath)
if key == "" {
@ -492,8 +466,6 @@ func (m *Medium) Stat(filePath string) (fs.FileInfo, error) {
}
// Open opens the named file for reading.
//
// result := m.Open(...)
func (m *Medium) Open(filePath string) (fs.File, error) {
key := cleanPath(filePath)
if key == "" {
@ -526,8 +498,6 @@ func (m *Medium) Open(filePath string) (fs.File, error) {
}
// Create creates or truncates the named file.
//
// result := m.Create(...)
func (m *Medium) Create(filePath string) (goio.WriteCloser, error) {
key := cleanPath(filePath)
if key == "" {
@ -540,8 +510,6 @@ func (m *Medium) Create(filePath string) (goio.WriteCloser, error) {
}
// Append opens the named file for appending, creating it if it doesn't exist.
//
// result := m.Append(...)
func (m *Medium) Append(filePath string) (goio.WriteCloser, error) {
key := cleanPath(filePath)
if key == "" {
@ -564,8 +532,6 @@ func (m *Medium) Append(filePath string) (goio.WriteCloser, error) {
}
// ReadStream returns a reader for the file content.
//
// result := m.ReadStream(...)
func (m *Medium) ReadStream(filePath string) (goio.ReadCloser, error) {
key := cleanPath(filePath)
if key == "" {
@ -591,15 +557,11 @@ func (m *Medium) ReadStream(filePath string) (goio.ReadCloser, error) {
}
// WriteStream returns a writer for the file content. Content is stored on Close.
//
// result := m.WriteStream(...)
func (m *Medium) WriteStream(filePath string) (goio.WriteCloser, error) {
return m.Create(filePath)
}
// Exists checks if a path exists (file or directory).
//
// result := m.Exists(...)
func (m *Medium) Exists(filePath string) bool {
key := cleanPath(filePath)
if key == "" {
@ -618,8 +580,6 @@ func (m *Medium) Exists(filePath string) bool {
}
// IsDir checks if a path exists and is a directory.
//
// result := m.IsDir(...)
func (m *Medium) IsDir(filePath string) bool {
key := cleanPath(filePath)
if key == "" {

View file

@ -34,23 +34,17 @@ func NewMedium(dbPath string) (*Medium, error) {
return &Medium{store: store}, nil
}
// AsMedium returns a Medium adapter for an existing Store.
//
// result := s.AsMedium(...)
// Example: medium := kvStore.AsMedium()
func (s *Store) AsMedium() *Medium {
return &Medium{store: s}
}
// Store returns the underlying KV store for direct access.
//
// result := m.Store(...)
// Example: kvStore := medium.Store()
func (m *Medium) Store() *Store {
return m.store
}
// Close closes the underlying store.
//
// result := m.Close(...)
// Example: _ = medium.Close()
func (m *Medium) Close() error {
return m.store.Close()
}
@ -71,8 +65,6 @@ func splitPath(entryPath string) (group, key string) {
}
// Read retrieves the value at group/key.
//
// result := m.Read(...)
func (m *Medium) Read(entryPath string) (string, error) {
group, key := splitPath(entryPath)
if key == "" {
@ -82,8 +74,6 @@ func (m *Medium) Read(entryPath string) (string, error) {
}
// Write stores a value at group/key.
//
// result := m.Write(...)
func (m *Medium) Write(entryPath, content string) error {
group, key := splitPath(entryPath)
if key == "" {
@ -93,22 +83,16 @@ func (m *Medium) Write(entryPath, content string) error {
}
// WriteMode ignores the requested mode because key-value entries do not store POSIX permissions.
//
// result := m.WriteMode(...)
func (m *Medium) WriteMode(entryPath, content string, _ fs.FileMode) error {
return m.Write(entryPath, content)
}
// EnsureDir is a no-op — groups are created implicitly on Set.
//
// result := m.EnsureDir(...)
func (m *Medium) EnsureDir(_ string) error {
return nil
}
// IsFile returns true if a group/key pair exists.
//
// result := m.IsFile(...)
func (m *Medium) IsFile(entryPath string) bool {
group, key := splitPath(entryPath)
if key == "" {
@ -127,8 +111,6 @@ func (m *Medium) FileSet(entryPath, content string) error {
}
// Delete removes a key, or checks that a group is empty.
//
// result := m.Delete(...)
func (m *Medium) Delete(entryPath string) error {
group, key := splitPath(entryPath)
if group == "" {
@ -148,8 +130,6 @@ func (m *Medium) Delete(entryPath string) error {
}
// DeleteAll removes a key, or all keys in a group.
//
// result := m.DeleteAll(...)
func (m *Medium) DeleteAll(entryPath string) error {
group, key := splitPath(entryPath)
if group == "" {
@ -162,8 +142,6 @@ func (m *Medium) DeleteAll(entryPath string) error {
}
// Rename moves a key from one path to another.
//
// result := m.Rename(...)
func (m *Medium) Rename(oldPath, newPath string) error {
oldGroup, oldKey := splitPath(oldPath)
newGroup, newKey := splitPath(newPath)
@ -182,8 +160,6 @@ func (m *Medium) Rename(oldPath, newPath string) error {
// List returns directory entries. Empty path returns groups.
// A group path returns keys in that group.
//
// result := m.List(...)
func (m *Medium) List(entryPath string) ([]fs.DirEntry, error) {
group, key := splitPath(entryPath)
@ -221,8 +197,6 @@ func (m *Medium) List(entryPath string) ([]fs.DirEntry, error) {
}
// Stat returns file info for a group (dir) or key (file).
//
// result := m.Stat(...)
func (m *Medium) Stat(entryPath string) (fs.FileInfo, error) {
group, key := splitPath(entryPath)
if group == "" {
@ -246,8 +220,6 @@ func (m *Medium) Stat(entryPath string) (fs.FileInfo, error) {
}
// Open opens a key for reading.
//
// result := m.Open(...)
func (m *Medium) Open(entryPath string) (fs.File, error) {
group, key := splitPath(entryPath)
if key == "" {
@ -261,8 +233,6 @@ func (m *Medium) Open(entryPath string) (fs.File, error) {
}
// Create creates or truncates a key. Content is stored on Close.
//
// result := m.Create(...)
func (m *Medium) Create(entryPath string) (goio.WriteCloser, error) {
group, key := splitPath(entryPath)
if key == "" {
@ -272,8 +242,6 @@ func (m *Medium) Create(entryPath string) (goio.WriteCloser, error) {
}
// Append opens a key for appending. Content is stored on Close.
//
// result := m.Append(...)
func (m *Medium) Append(entryPath string) (goio.WriteCloser, error) {
group, key := splitPath(entryPath)
if key == "" {
@ -284,8 +252,6 @@ func (m *Medium) Append(entryPath string) (goio.WriteCloser, error) {
}
// ReadStream returns a reader for the value.
//
// result := m.ReadStream(...)
func (m *Medium) ReadStream(entryPath string) (goio.ReadCloser, error) {
group, key := splitPath(entryPath)
if key == "" {
@ -299,15 +265,11 @@ func (m *Medium) ReadStream(entryPath string) (goio.ReadCloser, error) {
}
// WriteStream returns a writer. Content is stored on Close.
//
// result := m.WriteStream(...)
func (m *Medium) WriteStream(entryPath string) (goio.WriteCloser, error) {
return m.Create(entryPath)
}
// Exists returns true if a group or key exists.
//
// result := m.Exists(...)
func (m *Medium) Exists(entryPath string) bool {
group, key := splitPath(entryPath)
if group == "" {
@ -322,8 +284,6 @@ func (m *Medium) Exists(entryPath string) bool {
}
// IsDir returns true if the path is a group with entries.
//
// result := m.IsDir(...)
func (m *Medium) IsDir(entryPath string) bool {
group, key := splitPath(entryPath)
if key != "" || group == "" {

View file

@ -43,16 +43,12 @@ func New(dbPath string) (*Store, error) {
return &Store{database: database}, nil
}
// Close closes the underlying database.
//
// result := s.Close(...)
// Example: _ = kvStore.Close()
func (s *Store) Close() error {
return s.database.Close()
}
// Get retrieves a value by group and key.
//
// result := s.Get(...)
// Example: theme, _ := kvStore.Get("app", "theme")
func (s *Store) Get(group, key string) (string, error) {
var value string
err := s.database.QueryRow("SELECT value FROM kv WHERE grp = ? AND key = ?", group, key).Scan(&value)
@ -65,9 +61,7 @@ func (s *Store) Get(group, key string) (string, error) {
return value, nil
}
// Set stores a value by group and key, overwriting if exists.
//
// result := s.Set(...)
// Example: _ = kvStore.Set("app", "theme", "midnight")
func (s *Store) Set(group, key, value string) error {
_, err := s.database.Exec(
`INSERT INTO kv (grp, key, value) VALUES (?, ?, ?)
@ -80,9 +74,7 @@ func (s *Store) Set(group, key, value string) error {
return nil
}
// Delete removes a single key from a group.
//
// result := s.Delete(...)
// Example: _ = kvStore.Delete("app", "theme")
func (s *Store) Delete(group, key string) error {
_, err := s.database.Exec("DELETE FROM kv WHERE grp = ? AND key = ?", group, key)
if err != nil {
@ -91,9 +83,7 @@ func (s *Store) Delete(group, key string) error {
return nil
}
// Count returns the number of keys in a group.
//
// result := s.Count(...)
// Example: count, _ := kvStore.Count("app")
func (s *Store) Count(group string) (int, error) {
var count int
err := s.database.QueryRow("SELECT COUNT(*) FROM kv WHERE grp = ?", group).Scan(&count)
@ -103,9 +93,7 @@ func (s *Store) Count(group string) (int, error) {
return count, nil
}
// DeleteGroup removes all keys in a group.
//
// result := s.DeleteGroup(...)
// Example: _ = kvStore.DeleteGroup("app")
func (s *Store) DeleteGroup(group string) error {
_, err := s.database.Exec("DELETE FROM kv WHERE grp = ?", group)
if err != nil {
@ -114,9 +102,7 @@ func (s *Store) DeleteGroup(group string) error {
return nil
}
// GetAll returns all key-value pairs in a group.
//
// result := s.GetAll(...)
// Example: values, _ := kvStore.GetAll("app")
func (s *Store) GetAll(group string) (map[string]string, error) {
rows, err := s.database.Query("SELECT key, value FROM kv WHERE grp = ?", group)
if err != nil {

View file

@ -77,11 +77,9 @@ func New(options Options) (*Service, error) {
return s, nil
}
// CreateWorkspace creates a new encrypted workspace.
// Example: workspaceID, _ := service.CreateWorkspace("alice", "pass123")
// Identifier is hashed (SHA-256) to create the directory name.
// A PGP keypair is generated using the password.
//
// result := s.CreateWorkspace(...)
func (s *Service) CreateWorkspace(identifier, password string) (string, error) {
s.mu.Lock()
defer s.mu.Unlock()
@ -119,9 +117,7 @@ func (s *Service) CreateWorkspace(identifier, password string) (string, error) {
return workspaceID, nil
}
// SwitchWorkspace changes the active workspace.
//
// result := s.SwitchWorkspace(...)
// Example: _ = service.SwitchWorkspace(workspaceID)
func (s *Service) SwitchWorkspace(name string) error {
s.mu.Lock()
defer s.mu.Unlock()
@ -155,9 +151,7 @@ func (s *Service) activeFilePath(operation, filename string) (string, error) {
return filePath, nil
}
// WorkspaceFileGet retrieves the content of a file from the active workspace.
//
// result := s.WorkspaceFileGet(...)
// Example: content, _ := service.WorkspaceFileGet("notes/todo.txt")
func (s *Service) WorkspaceFileGet(filename string) (string, error) {
s.mu.RLock()
defer s.mu.RUnlock()
@ -169,9 +163,7 @@ func (s *Service) WorkspaceFileGet(filename string) (string, error) {
return s.medium.Read(filePath)
}
// WorkspaceFileSet saves content to a file in the active workspace.
//
// result := s.WorkspaceFileSet(...)
// Example: _ = service.WorkspaceFileSet("notes/todo.txt", "ship it")
func (s *Service) WorkspaceFileSet(filename, content string) error {
s.mu.Lock()
defer s.mu.Unlock()
@ -186,12 +178,12 @@ func (s *Service) WorkspaceFileSet(filename, content string) error {
// HandleIPCEvents handles workspace-related IPC messages.
//
// service, _ := workspace.New(workspace.Options{Core: core.New(), Crypt: myCryptProvider})
// result := service.HandleIPCEvents(core.New(), map[string]any{
// ipcResult := service.HandleIPCEvents(core.New(), map[string]any{
// "action": "workspace.create",
// "identifier": "alice",
// "password": "pass123",
// })
// _ = result.OK
// _ = ipcResult.OK
func (s *Service) HandleIPCEvents(_ *core.Core, message core.Message) core.Result {
switch payload := message.(type) {
case map[string]any: