diff --git a/datasets.go b/datasets.go
index 45b665b..c053a26 100644
--- a/datasets.go
+++ b/datasets.go
@@ -1,5 +1,12 @@
 package gptscript
 
+import (
+	"context"
+	"encoding/json"
+	"fmt"
+	"os"
+)
+
 type DatasetElementMeta struct {
 	Name        string `json:"name"`
 	Description string `json:"description"`
@@ -48,3 +55,146 @@ type getDatasetElementArgs struct {
 	DatasetID string `json:"datasetID"`
 	Element   string `json:"element"`
 }
+
+func (g *GPTScript) ListDatasets(ctx context.Context, workspace string) ([]DatasetMeta, error) {
+	if workspace == "" {
+		workspace = os.Getenv("GPTSCRIPT_WORKSPACE_DIR")
+	}
+
+	out, err := g.runBasicCommand(ctx, "datasets", datasetRequest{
+		Input:           "{}",
+		Workspace:       workspace,
+		DatasetToolRepo: g.globalOpts.DatasetToolRepo,
+	})
+	if err != nil {
+		return nil, err
+	}
+
+	var datasets []DatasetMeta
+	if err = json.Unmarshal([]byte(out), &datasets); err != nil {
+		return nil, err
+	}
+	return datasets, nil
+}
+
+func (g *GPTScript) CreateDataset(ctx context.Context, workspace, name, description string) (Dataset, error) {
+	if workspace == "" {
+		workspace = os.Getenv("GPTSCRIPT_WORKSPACE_DIR")
+	}
+
+	args := createDatasetArgs{
+		Name:        name,
+		Description: description,
+	}
+	argsJSON, err := json.Marshal(args)
+	if err != nil {
+		return Dataset{}, fmt.Errorf("failed to marshal dataset args: %w", err)
+	}
+
+	out, err := g.runBasicCommand(ctx, "datasets/create", datasetRequest{
+		Input:           string(argsJSON),
+		Workspace:       workspace,
+		DatasetToolRepo: g.globalOpts.DatasetToolRepo,
+	})
+	if err != nil {
+		return Dataset{}, err
+	}
+
+	var dataset Dataset
+	if err = json.Unmarshal([]byte(out), &dataset); err != nil {
+		return Dataset{}, err
+	}
+	return dataset, nil
+}
+
+func (g *GPTScript) AddDatasetElement(ctx context.Context, workspace, datasetID, elementName, elementDescription, elementContent string) (DatasetElementMeta, error) {
+	if workspace == "" {
+		workspace = os.Getenv("GPTSCRIPT_WORKSPACE_DIR")
+	}
+
+	args := addDatasetElementArgs{
+		DatasetID:          datasetID,
+		ElementName:        elementName,
+		ElementDescription: elementDescription,
+		ElementContent:     elementContent,
+	}
+	argsJSON, err := json.Marshal(args)
+	if err != nil {
+		return DatasetElementMeta{}, fmt.Errorf("failed to marshal element args: %w", err)
+	}
+
+	out, err := g.runBasicCommand(ctx, "datasets/add-element", datasetRequest{
+		Input:           string(argsJSON),
+		Workspace:       workspace,
+		DatasetToolRepo: g.globalOpts.DatasetToolRepo,
+	})
+	if err != nil {
+		return DatasetElementMeta{}, err
+	}
+
+	var element DatasetElementMeta
+	if err = json.Unmarshal([]byte(out), &element); err != nil {
+		return DatasetElementMeta{}, err
+	}
+	return element, nil
+}
+
+func (g *GPTScript) ListDatasetElements(ctx context.Context, workspace, datasetID string) ([]DatasetElementMeta, error) {
+	if workspace == "" {
+		workspace = os.Getenv("GPTSCRIPT_WORKSPACE_DIR")
+	}
+
+	args := listDatasetElementArgs{
+		DatasetID: datasetID,
+	}
+	argsJSON, err := json.Marshal(args)
+	if err != nil {
+		return nil, fmt.Errorf("failed to marshal element args: %w", err)
+	}
+
+	out, err := g.runBasicCommand(ctx, "datasets/list-elements", datasetRequest{
+		Input:           string(argsJSON),
+		Workspace:       workspace,
+		DatasetToolRepo: g.globalOpts.DatasetToolRepo,
+	})
+	if err != nil {
+		return nil, err
+	}
+
+	var elements []DatasetElementMeta
+	if err = json.Unmarshal([]byte(out), &elements); err != nil {
+		return nil, err
+	}
+	return elements, nil
+}
+
+func (g *GPTScript) GetDatasetElement(ctx context.Context, workspace, datasetID, elementName string) (DatasetElement, error) {
+	if workspace == "" {
+		workspace = os.Getenv("GPTSCRIPT_WORKSPACE_DIR")
+	}
+
+	args := getDatasetElementArgs{
+		DatasetID: datasetID,
+		Element:   elementName,
+	}
+	argsJSON, err := json.Marshal(args)
+	if err != nil {
+		return DatasetElement{}, fmt.Errorf("failed to marshal element args: %w", err)
+	}
+
+	out, err := g.runBasicCommand(ctx, "datasets/get-element", datasetRequest{
+		Input:           string(argsJSON),
+		Workspace:       workspace,
+		DatasetToolRepo: g.globalOpts.DatasetToolRepo,
+	})
+	if err != nil {
+		return DatasetElement{}, err
+	}
+
+	var element DatasetElement
+	if err = json.Unmarshal([]byte(out), &element); err != nil {
+		return DatasetElement{}, err
+	}
+
+	return element, nil
+}
diff --git a/datasets_test.go b/datasets_test.go
new file mode 100644
index 0000000..3763982
--- /dev/null
+++ b/datasets_test.go
@@ -0,0 +1,52 @@
+package gptscript
+
+import (
+	"context"
+	"os"
+	"testing"
+
+	"github.com/stretchr/testify/require"
+)
+
+func TestDatasets(t *testing.T) {
+	workspace, err := os.MkdirTemp("", "go-gptscript-test")
+	require.NoError(t, err)
+	defer func() {
+		_ = os.RemoveAll(workspace)
+	}()
+
+	// Create a dataset
+	dataset, err := g.CreateDataset(context.Background(), workspace, "test-dataset", "This is a test dataset")
+	require.NoError(t, err)
+	require.Equal(t, "test-dataset", dataset.Name)
+	require.Equal(t, "This is a test dataset", dataset.Description)
+	require.Equal(t, 0, len(dataset.Elements))
+
+	// Add an element
+	elementMeta, err := g.AddDatasetElement(context.Background(), workspace, dataset.ID, "test-element", "This is a test element", "This is the content")
+	require.NoError(t, err)
+	require.Equal(t, "test-element", elementMeta.Name)
+	require.Equal(t, "This is a test element", elementMeta.Description)
+
+	// Get the element
+	element, err := g.GetDatasetElement(context.Background(), workspace, dataset.ID, "test-element")
+	require.NoError(t, err)
+	require.Equal(t, "test-element", element.Name)
+	require.Equal(t, "This is a test element", element.Description)
+	require.Equal(t, "This is the content", element.Contents)
+
+	// List elements in the dataset
+	elements, err := g.ListDatasetElements(context.Background(), workspace, dataset.ID)
+	require.NoError(t, err)
+	require.Equal(t, 1, len(elements))
+	require.Equal(t, "test-element", elements[0].Name)
+	require.Equal(t, "This is a test element", elements[0].Description)
+
+	// List datasets
+	datasets, err := g.ListDatasets(context.Background(), workspace)
+	require.NoError(t, err)
+	require.Equal(t, 1, len(datasets))
+	require.Equal(t, "test-dataset", datasets[0].Name)
+	require.Equal(t, "This is a test dataset", datasets[0].Description)
+	require.Equal(t, dataset.ID, datasets[0].ID)
+}
diff --git a/gptscript.go b/gptscript.go
index 6178c67..1e30d95 100644
--- a/gptscript.go
+++ b/gptscript.go
@@ -7,7 +7,6 @@ import (
 	"context"
 	"encoding/base64"
 	"encoding/json"
-	"errors"
 	"fmt"
 	"io"
 	"log/slog"
@@ -389,176 +388,6 @@ func (g *GPTScript) DeleteCredential(ctx context.Context, credCtx, name string)
 	return err
 }
 
-// Dataset methods
-
-func (g *GPTScript) ListDatasets(ctx context.Context, workspace string) ([]DatasetMeta, error) {
-	if workspace == "" {
-		workspace = os.Getenv("GPTSCRIPT_WORKSPACE_DIR")
-	}
-
-	out, err := g.runBasicCommand(ctx, "datasets", datasetRequest{
-		Input:           "{}",
-		Workspace:       workspace,
-		DatasetToolRepo: g.globalOpts.DatasetToolRepo,
-	})
-
-	if err != nil {
-		return nil, err
-	}
-
-	if strings.HasPrefix(out, "ERROR:") {
-		return nil, errors.New(out)
-	}
-
-	var datasets []DatasetMeta
-	if err = json.Unmarshal([]byte(out), &datasets); err != nil {
-		return nil, err
-	}
-	return datasets, nil
-}
-
-func (g *GPTScript) CreateDataset(ctx context.Context, workspace, name, description string) (Dataset, error) {
-	if workspace == "" {
-		workspace = os.Getenv("GPTSCRIPT_WORKSPACE_DIR")
-	}
-
-	args := createDatasetArgs{
-		Name:        name,
-		Description: description,
-	}
-	argsJSON, err := json.Marshal(args)
-	if err != nil {
-		return Dataset{}, fmt.Errorf("failed to marshal dataset args: %w", err)
-	}
-
-	out, err := g.runBasicCommand(ctx, "datasets/create", datasetRequest{
-		Input:           string(argsJSON),
-		Workspace:       workspace,
-		DatasetToolRepo: g.globalOpts.DatasetToolRepo,
-	})
-
-	if err != nil {
-		return Dataset{}, err
-	}
-
-	if strings.HasPrefix(out, "ERROR:") {
-		return Dataset{}, errors.New(out)
-	}
-
-	var dataset Dataset
-	if err = json.Unmarshal([]byte(out), &dataset); err != nil {
-		return Dataset{}, err
-	}
-	return dataset, nil
-}
-
-func (g *GPTScript) AddDatasetElement(ctx context.Context, workspace, datasetID, elementName, elementDescription, elementContent string) (DatasetElementMeta, error) {
-	if workspace == "" {
-		workspace = os.Getenv("GPTSCRIPT_WORKSPACE_DIR")
-	}
-
-	args := addDatasetElementArgs{
-		DatasetID:          datasetID,
-		ElementName:        elementName,
-		ElementDescription: elementDescription,
-		ElementContent:     elementContent,
-	}
-	argsJSON, err := json.Marshal(args)
-	if err != nil {
-		return DatasetElementMeta{}, fmt.Errorf("failed to marshal element args: %w", err)
-	}
-
-	out, err := g.runBasicCommand(ctx, "datasets/add-element", datasetRequest{
-		Input:           string(argsJSON),
-		Workspace:       workspace,
-		DatasetToolRepo: g.globalOpts.DatasetToolRepo,
-	})
-
-	if err != nil {
-		return DatasetElementMeta{}, err
-	}
-
-	if strings.HasPrefix(out, "ERROR:") {
-		return DatasetElementMeta{}, errors.New(out)
-	}
-
-	var element DatasetElementMeta
-	if err = json.Unmarshal([]byte(out), &element); err != nil {
-		return DatasetElementMeta{}, err
-	}
-	return element, nil
-}
-
-func (g *GPTScript) ListDatasetElements(ctx context.Context, workspace, datasetID string) ([]DatasetElementMeta, error) {
-	if workspace == "" {
-		workspace = os.Getenv("GPTSCRIPT_WORKSPACE_DIR")
-	}
-
-	args := listDatasetElementArgs{
-		DatasetID: datasetID,
-	}
-	argsJSON, err := json.Marshal(args)
-	if err != nil {
-		return nil, fmt.Errorf("failed to marshal element args: %w", err)
-	}
-
-	out, err := g.runBasicCommand(ctx, "datasets/list-elements", datasetRequest{
-		Input:           string(argsJSON),
-		Workspace:       workspace,
-		DatasetToolRepo: g.globalOpts.DatasetToolRepo,
-	})
-
-	if err != nil {
-		return nil, err
-	}
-
-	if strings.HasPrefix(out, "ERROR:") {
-		return nil, errors.New(out)
-	}
-
-	var elements []DatasetElementMeta
-	if err = json.Unmarshal([]byte(out), &elements); err != nil {
-		return nil, err
-	}
-	return elements, nil
-}
-
-func (g *GPTScript) GetDatasetElement(ctx context.Context, workspace, datasetID, elementName string) (DatasetElement, error) {
-	if workspace == "" {
-		workspace = os.Getenv("GPTSCRIPT_WORKSPACE_DIR")
-	}
-
-	args := getDatasetElementArgs{
-		DatasetID: datasetID,
-		Element:   elementName,
-	}
-	argsJSON, err := json.Marshal(args)
-	if err != nil {
-		return DatasetElement{}, fmt.Errorf("failed to marshal element args: %w", err)
-	}
-
-	out, err := g.runBasicCommand(ctx, "datasets/get-element", datasetRequest{
-		Input:           string(argsJSON),
-		Workspace:       workspace,
-		DatasetToolRepo: g.globalOpts.DatasetToolRepo,
-	})
-
-	if err != nil {
-		return DatasetElement{}, err
-	}
-
-	if strings.HasPrefix(out, "ERROR:") {
-		return DatasetElement{}, errors.New(out)
-	}
-
-	var element DatasetElement
-	if err = json.Unmarshal([]byte(out), &element); err != nil {
-		return DatasetElement{}, err
-	}
-
-	return element, nil
-}
-
 func (g *GPTScript) runBasicCommand(ctx context.Context, requestPath string, body any) (string, error) {
 	run := &Run{
 		url:          g.globalOpts.URL,
diff --git a/gptscript_test.go b/gptscript_test.go
index 82bf735..32adff9 100644
--- a/gptscript_test.go
+++ b/gptscript_test.go
@@ -1560,46 +1560,3 @@ func TestCredentials(t *testing.T) {
 	require.Error(t, err)
 	require.True(t, errors.As(err, &ErrNotFound{}))
 }
-
-func TestDatasets(t *testing.T) {
-	workspace, err := os.MkdirTemp("", "go-gptscript-test")
-	require.NoError(t, err)
-	defer func() {
-		_ = os.RemoveAll(workspace)
-	}()
-
-	// Create a dataset
-	dataset, err := g.CreateDataset(context.Background(), workspace, "test-dataset", "This is a test dataset")
-	require.NoError(t, err)
-	require.Equal(t, "test-dataset", dataset.Name)
-	require.Equal(t, "This is a test dataset", dataset.Description)
-	require.Equal(t, 0, len(dataset.Elements))
-
-	// Add an element
-	elementMeta, err := g.AddDatasetElement(context.Background(), workspace, dataset.ID, "test-element", "This is a test element", "This is the content")
-	require.NoError(t, err)
-	require.Equal(t, "test-element", elementMeta.Name)
-	require.Equal(t, "This is a test element", elementMeta.Description)
-
-	// Get the element
-	element, err := g.GetDatasetElement(context.Background(), workspace, dataset.ID, "test-element")
-	require.NoError(t, err)
-	require.Equal(t, "test-element", element.Name)
-	require.Equal(t, "This is a test element", element.Description)
-	require.Equal(t, "This is the content", element.Contents)
-
-	// List elements in the dataset
-	elements, err := g.ListDatasetElements(context.Background(), workspace, dataset.ID)
-	require.NoError(t, err)
-	require.Equal(t, 1, len(elements))
-	require.Equal(t, "test-element", elements[0].Name)
-	require.Equal(t, "This is a test element", elements[0].Description)
-
-	// List datasets
-	datasets, err := g.ListDatasets(context.Background(), workspace)
-	require.NoError(t, err)
-	require.Equal(t, 1, len(datasets))
-	require.Equal(t, "test-dataset", datasets[0].Name)
-	require.Equal(t, "This is a test dataset", datasets[0].Description)
-	require.Equal(t, dataset.ID, datasets[0].ID)
-}
diff --git a/opts.go b/opts.go
index 283b4ec..6c9e1ab 100644
--- a/opts.go
+++ b/opts.go
@@ -12,6 +12,7 @@ type GlobalOptions struct {
 	CacheDir             string   `json:"CacheDir"`
 	Env                  []string `json:"env"`
 	DatasetToolRepo      string   `json:"DatasetToolRepo"`
+	WorkspaceTool        string   `json:"WorkspaceTool"`
 }
 
 func (g GlobalOptions) toEnv() []string {
diff --git a/workspace.go b/workspace.go
new file mode 100644
index 0000000..86b8c2e
--- /dev/null
+++ b/workspace.go
@@ -0,0 +1,189 @@
+package gptscript
+
+import (
+	"context"
+	"encoding/base64"
+	"encoding/json"
+	"strings"
+)
+
+func (g *GPTScript) CreateWorkspace(ctx context.Context, providerType string) (string, error) {
+	out, err := g.runBasicCommand(ctx, "workspaces/create", map[string]any{
+		"provider":      providerType,
+		"workspaceTool": g.globalOpts.WorkspaceTool,
+	})
+	if err != nil {
+		return "", err
+	}
+
+	return strings.TrimSpace(out), nil
+}
+
+type DeleteWorkspaceOptions struct {
+	IgnoreNotFound bool
+}
+
+func (g *GPTScript) DeleteWorkspace(ctx context.Context, workspaceID string, opts ...DeleteWorkspaceOptions) error {
+	var opt DeleteWorkspaceOptions
+	for _, o := range opts {
+		opt.IgnoreNotFound = opt.IgnoreNotFound || o.IgnoreNotFound
+	}
+	_, err := g.runBasicCommand(ctx, "workspaces/delete", map[string]any{
+		"id":             workspaceID,
+		"ignoreNotFound": opt.IgnoreNotFound,
+		"workspaceTool":  g.globalOpts.WorkspaceTool,
+	})
+
+	return err
+}
+
+type CreateDirectoryInWorkspaceOptions struct {
+	IgnoreExists bool
+}
+
+func (g *GPTScript) CreateDirectoryInWorkspace(ctx context.Context, workspaceID, dir string, opts ...CreateDirectoryInWorkspaceOptions) error {
+	var opt CreateDirectoryInWorkspaceOptions
+	for _, o := range opts {
+		opt.IgnoreExists = opt.IgnoreExists || o.IgnoreExists
+	}
+
+	_, err := g.runBasicCommand(ctx, "workspaces/mkdir", map[string]any{
+		"id":            workspaceID,
+		"directoryName": dir,
+		"ignoreExists":  opt.IgnoreExists,
+		"workspaceTool": g.globalOpts.WorkspaceTool,
+	})
+
+	return err
+}
+
+type DeleteDirectoryInWorkspaceOptions struct {
+	IgnoreNotFound bool
+	MustBeEmpty    bool
+}
+
+func (g *GPTScript) DeleteDirectoryInWorkspace(ctx context.Context, workspaceID, dir string, opts ...DeleteDirectoryInWorkspaceOptions) error {
+	var opt DeleteDirectoryInWorkspaceOptions
+	for _, o := range opts {
+		o.IgnoreNotFound = opt.IgnoreNotFound || o.IgnoreNotFound
+		o.MustBeEmpty = opt.MustBeEmpty || o.MustBeEmpty
+	}
+
+	_, err := g.runBasicCommand(ctx, "workspaces/rmdir", map[string]any{
+		"id":             workspaceID,
+		"directoryName":  dir,
+		"ignoreNotFound": opt.IgnoreNotFound,
+		"mustBeEmpty":    opt.MustBeEmpty,
+		"workspaceTool":  g.globalOpts.WorkspaceTool,
+	})
+
+	return err
+}
+
+type ListFilesInWorkspaceOptions struct {
+	SubDir        string
+	NonRecursive  bool
+	ExcludeHidden bool
+}
+
+type WorkspaceContent struct {
+	ID, Path, FileName string
+	Children           []WorkspaceContent
+}
+
+func (g *GPTScript) ListFilesInWorkspace(ctx context.Context, workspaceID string, opts ...ListFilesInWorkspaceOptions) (*WorkspaceContent, error) {
+	var opt ListFilesInWorkspaceOptions
+	for _, o := range opts {
+		if o.SubDir != "" {
+			opt.SubDir = o.SubDir
+		}
+		opt.NonRecursive = opt.NonRecursive || o.NonRecursive
+		opt.ExcludeHidden = opt.ExcludeHidden || o.ExcludeHidden
+	}
+
+	out, err := g.runBasicCommand(ctx, "workspaces/list", map[string]any{
+		"id":            workspaceID,
+		"subDir":        opt.SubDir,
+		"excludeHidden": opt.ExcludeHidden,
+		"nonRecursive":  opt.NonRecursive,
+		"workspaceTool": g.globalOpts.WorkspaceTool,
+		"json":          true,
+	})
+	if err != nil {
+		return nil, err
+	}
+
+	var content []WorkspaceContent
+	err = json.Unmarshal([]byte(out), &content)
+	if err != nil {
+		return nil, err
+	}
+
+	if len(content) == 0 {
+		return &WorkspaceContent{ID: workspaceID}, nil
+	}
+
+	return &content[0], nil
+}
+
+type CreateFileInWorkspaceOptions struct {
+	MustNotExist  bool
+	WithoutCreate bool
+	CreateDirs    bool
+}
+
+func (g *GPTScript) WriteFileInWorkspace(ctx context.Context, workspaceID, filePath string, contents []byte, opts ...CreateFileInWorkspaceOptions) error {
+	var opt CreateFileInWorkspaceOptions
+	for _, o := range opts {
+		opt.MustNotExist = opt.MustNotExist || o.MustNotExist
+		opt.WithoutCreate = opt.WithoutCreate || o.WithoutCreate
+		opt.CreateDirs = opt.CreateDirs || o.CreateDirs
+	}
+
+	_, err := g.runBasicCommand(ctx, "workspaces/write-file", map[string]any{
+		"id":                 workspaceID,
+		"contents":           base64.StdEncoding.EncodeToString(contents),
+		"filePath":           filePath,
+		"mustNotExist":       opt.MustNotExist,
+		"withoutCreate":      opt.WithoutCreate,
+		"createDirs":         opt.CreateDirs,
+		"workspaceTool":      g.globalOpts.WorkspaceTool,
+		"base64EncodedInput": true,
+	})
+
+	return err
+}
+
+type DeleteFileInWorkspaceOptions struct {
+	IgnoreNotFound bool
+}
+
+func (g *GPTScript) DeleteFileInWorkspace(ctx context.Context, workspaceID, filePath string, opts ...DeleteFileInWorkspaceOptions) error {
+	var opt DeleteFileInWorkspaceOptions
+	for _, o := range opts {
+		opt.IgnoreNotFound = opt.IgnoreNotFound || o.IgnoreNotFound
+	}
+
+	_, err := g.runBasicCommand(ctx, "workspaces/delete-file", map[string]any{
+		"id":             workspaceID,
+		"filePath":       filePath,
+		"ignoreNotFound": opt.IgnoreNotFound,
+		"workspaceTool":  g.globalOpts.WorkspaceTool,
+	})
+
+	return err
+}
+
+func (g *GPTScript) ReadFileInWorkspace(ctx context.Context, workspaceID, filePath string) ([]byte, error) {
+	out, err := g.runBasicCommand(ctx, "workspaces/read-file", map[string]any{
+		"id":                 workspaceID,
+		"filePath":           filePath,
+		"workspaceTool":      g.globalOpts.WorkspaceTool,
+		"base64EncodeOutput": true,
+	})
+	if err != nil {
+		return nil, err
+	}
+
+	return base64.StdEncoding.DecodeString(out)
+}
diff --git a/workspace_test.go b/workspace_test.go
new file mode 100644
index 0000000..cba683f
--- /dev/null
+++ b/workspace_test.go
@@ -0,0 +1,172 @@
+package gptscript
+
+import (
+	"bytes"
+	"context"
+	"testing"
+)
+
+func TestCreateAndDeleteWorkspace(t *testing.T) {
+	id, err := g.CreateWorkspace(context.Background(), "directory")
+	if err != nil {
+		t.Fatalf("Error creating workspace: %v", err)
+	}
+
+	err = g.DeleteWorkspace(context.Background(), id)
+	if err != nil {
+		t.Errorf("Error deleting workspace: %v", err)
+	}
+}
+
+func TestCreateDirectory(t *testing.T) {
+	id, err := g.CreateWorkspace(context.Background(), "directory")
+	if err != nil {
+		t.Fatalf("Error creating workspace: %v", err)
+	}
+
+	t.Cleanup(func() {
+		err := g.DeleteWorkspace(context.Background(), id)
+		if err != nil {
+			t.Errorf("Error deleting workspace: %v", err)
+		}
+	})
+
+	err = g.CreateDirectoryInWorkspace(context.Background(), id, "test")
+	if err != nil {
+		t.Fatalf("Error creating directory: %v", err)
+	}
+
+	err = g.DeleteDirectoryInWorkspace(context.Background(), id, "test")
+	if err != nil {
+		t.Errorf("Error listing files: %v", err)
+	}
+}
+
+func TestWriteReadAndDeleteFileFromWorkspace(t *testing.T) {
+	id, err := g.CreateWorkspace(context.Background(), "directory")
+	if err != nil {
+		t.Fatalf("Error creating workspace: %v", err)
+	}
+
+	t.Cleanup(func() {
+		err := g.DeleteWorkspace(context.Background(), id)
+		if err != nil {
+			t.Errorf("Error deleting workspace: %v", err)
+		}
+	})
+
+	err = g.WriteFileInWorkspace(context.Background(), id, "test.txt", []byte("test"))
+	if err != nil {
+		t.Fatalf("Error creating file: %v", err)
+	}
+
+	content, err := g.ReadFileInWorkspace(context.Background(), id, "test.txt")
+	if err != nil {
+		t.Errorf("Error reading file: %v", err)
+	}
+
+	if !bytes.Equal(content, []byte("test")) {
+		t.Errorf("Unexpected content: %s", content)
+	}
+
+	err = g.DeleteFileInWorkspace(context.Background(), id, "test.txt")
+	if err != nil {
+		t.Errorf("Error deleting file: %v", err)
+	}
+}
+
+func TestLsComplexWorkspace(t *testing.T) {
+	id, err := g.CreateWorkspace(context.Background(), "directory")
+	if err != nil {
+		t.Fatalf("Error creating workspace: %v", err)
+	}
+
+	t.Cleanup(func() {
+		err := g.DeleteWorkspace(context.Background(), id)
+		if err != nil {
+			t.Errorf("Error deleting workspace: %v", err)
+		}
+	})
+
+	err = g.CreateDirectoryInWorkspace(context.Background(), id, "test")
+	if err != nil {
+		t.Fatalf("Error creating directory: %v", err)
+	}
+
+	err = g.WriteFileInWorkspace(context.Background(), id, "test/test1.txt", []byte("hello1"))
+	if err != nil {
+		t.Fatalf("Error creating file: %v", err)
+	}
+
+	err = g.WriteFileInWorkspace(context.Background(), id, "test1/test2.txt", []byte("hello2"), CreateFileInWorkspaceOptions{CreateDirs: true})
+	if err != nil {
+		t.Fatalf("Error creating file: %v", err)
+	}
+
+	err = g.WriteFileInWorkspace(context.Background(), id, "test1/test2.txt", []byte("hello-2"), CreateFileInWorkspaceOptions{MustNotExist: true})
+	if err == nil {
+		t.Fatalf("Expected error creating file that must not exist")
+	}
+
+	err = g.WriteFileInWorkspace(context.Background(), id, "test1/test3.txt", []byte("hello3"), CreateFileInWorkspaceOptions{WithoutCreate: true})
+	if err == nil {
+		t.Fatalf("Expected error creating file that doesn't exist")
+	}
+
+	err = g.WriteFileInWorkspace(context.Background(), id, ".hidden.txt", []byte("hidden"))
+	if err != nil {
+		t.Fatalf("Error creating hidden file: %v", err)
+	}
+
+	// List all files
+	content, err := g.ListFilesInWorkspace(context.Background(), id)
+	if err != nil {
+		t.Fatalf("Error listing files: %v", err)
+	}
+
+	if content.ID != id {
+		t.Errorf("Unexpected ID: %s", content.ID)
+	}
+
+	if content.Path != "" {
+		t.Errorf("Unexpected path: %s", content.Path)
+	}
+
+	if content.FileName != "" {
+		t.Errorf("Unexpected filename: %s", content.FileName)
+	}
+
+	if len(content.Children) != 3 {
+		t.Errorf("Unexpected number of files: %d", len(content.Children))
+	}
+
+	// List files in subdirectory
+	content, err = g.ListFilesInWorkspace(context.Background(), id, ListFilesInWorkspaceOptions{SubDir: "test1"})
+	if err != nil {
+		t.Fatalf("Error listing files: %v", err)
+	}
+
+	if len(content.Children) != 1 {
+		t.Errorf("Unexpected number of files: %d", len(content.Children))
+	}
+
+	// Exclude hidden files
+	content, err = g.ListFilesInWorkspace(context.Background(), id, ListFilesInWorkspaceOptions{ExcludeHidden: true})
+	if err != nil {
+		t.Fatalf("Error listing files: %v", err)
+	}
+
+	if len(content.Children) != 2 {
+		t.Errorf("Unexpected number of files when listing without hidden: %d", len(content.Children))
+	}
+
+	// List non-recursive
+	content, err = g.ListFilesInWorkspace(context.Background(), id, ListFilesInWorkspaceOptions{NonRecursive: true})
+	if err != nil {
+		t.Fatalf("Error listing files: %v", err)
+	}
+
+	if len(content.Children) != 1 {
+		t.Errorf("Unexpected number of files when listing non-recursive: %d", len(content.Children))
+	}
+}