25GQ5TYGSGL7QED7L2IAPFLZ4WJJ2ZFAM6O6X5AOSTYPVJNCOGPQC package utilsimport ("testing")func TestStripMountPoint(t *testing.T) {tests := []struct {name stringinput stringexpected string}{// macOS{"macOS volume", "/Volumes/ExternalDrive/Audio", "ExternalDrive/Audio"},{"macOS root volume", "/Volumes/Drive", "Drive"},// Linux /media/ with username{"Linux media mount", "/media/david/USB-Drive/Audio", "USB-Drive/Audio"},{"Linux media different user", "/media/john/Backup/Audio", "Backup/Audio"},{"Linux media Pomona", "/media/david/Pomona-4/Pomona/A05/2025-11-08", "Pomona-4/Pomona/A05/2025-11-08"},// Linux /mnt/{"Linux mnt mount", "/mnt/storage/Audio", "storage/Audio"},// No mount point{"Absolute no mount", "/home/user/Audio", "/home/user/Audio"},{"Relative path", "./relative/path", "relative/path"},// Edge cases{"Root", "/", "/"},{"Empty", "", "."},{"Volumes only", "/Volumes/", "."},{"Media with user only", "/media/david/", "."},}for _, tt := range tests {t.Run(tt.name, func(t *testing.T) {result := StripMountPoint(tt.input)if result != tt.expected {t.Errorf("StripMountPoint(%q) = %q, want %q", tt.input, result, tt.expected)}})}}func TestNormalizeFolderPath(t *testing.T) {tests := []struct {name stringinput stringexpected string}{// Full workflow{"Linux media path", "/media/david/Pomona-4/Pomona/A05/2025-11-08/", "Pomona-4/Pomona/A05/2025-11-08"},{"macOS volumes path", "/Volumes/Drive/Audio/Recordings/", "Drive/Audio/Recordings"},{"Linux mnt path", "/mnt/storage/Audio/Files/", "storage/Audio/Files"},// Trailing slashes handled{"With trailing slash", "/media/david/USB/Audio/", "USB/Audio"},{"Without trailing slash", "/media/david/USB/Audio", "USB/Audio"},// Multiple levels{"Deep nested path", "/media/david/Pomona-4/Level1/Level2/Level3/", "Pomona-4/Level1/Level2/Level3"},// Edge cases{"File at mount root", "/media/david/", "."},{"Volumes with drive only", "/Volumes/Drive/", "Drive"},{"Volumes drive no trailing slash", "/Volumes/Drive", "Drive"},{"Root", "/", ""},{"Empty", "", "."},}for _, tt := range tests {t.Run(tt.name, func(t *testing.T) {result := NormalizeFolderPath(tt.input)if result != tt.expected {t.Errorf("NormalizeFolderPath(%q) = %q, want %q", tt.input, result, tt.expected)}})}}
package utilsimport ("path/filepath""runtime""strings")// StripMountPoint removes OS-specific mount point prefixes from a pathfunc StripMountPoint(absPath string) string {// Clean path firstabsPath = filepath.Clean(absPath)// Handle Windows drive lettersif runtime.GOOS == "windows" {volumeName := filepath.VolumeName(absPath)if volumeName != "" {// Remove "C:\" and return restreturn strings.TrimPrefix(absPath, volumeName+string(filepath.Separator))}}// Handle Unix-like mount pointsswitch {case absPath == "/Volumes":// Exact match to mount point rootreturn "."case strings.HasPrefix(absPath, "/Volumes/"):// macOS external volumes: /Volumes/Drive/... → Drive/...return strings.TrimPrefix(absPath, "/Volumes/")case strings.HasPrefix(absPath, "/media/"):// Linux user mounts: /media/username/Drive/... → Drive/...// Strip /media/ and the username directorypathAfterMedia := strings.TrimPrefix(absPath, "/media/")parts := strings.SplitN(pathAfterMedia, string(filepath.Separator), 2)if len(parts) > 1 {return parts[1] // Return everything after username}// Just username, no subdirectory (e.g., /media/david)return "."case strings.HasPrefix(absPath, "/mnt/"):// Linux system mounts: /mnt/storage/... → storage/...return strings.TrimPrefix(absPath, "/mnt/")}// No known mount point detected, return as-isreturn absPath}// NormalizeFolderPath strips mount points and cleans up a folder path// Unlike a file path normalization, this expects a directory pathfunc NormalizeFolderPath(folderPath string) string {// Clean the pathfolderPath = filepath.Clean(folderPath)// Strip mount pointrelativePath := StripMountPoint(folderPath)// Clean up leading/trailing slashesrelativePath = strings.Trim(relativePath, string(filepath.Separator))return relativePath}
package toolsimport ("context""fmt""strings""github.com/modelcontextprotocol/go-sdk/mcp""skraak_mcp/db")// UpdateClusterInput defines input parameterstype UpdateClusterInput struct {ClusterID string `json:"cluster_id" jsonschema:"required,Cluster ID (12 characters)"`Name *string `json:"name,omitempty" jsonschema:"Cluster name (max 140 characters)"`Path *string `json:"path,omitempty" jsonschema:"Normalized folder path (max 255 characters)"`SampleRate *int `json:"sample_rate,omitempty" jsonschema:"Sample rate in Hz"`Description *string `json:"description,omitempty" jsonschema:"Cluster description (max 255 characters)"`}// UpdateClusterOutput defines output structuretype UpdateClusterOutput struct {ClusterID string `json:"cluster_id" jsonschema:"Updated cluster ID"`Success bool `json:"success" jsonschema:"Whether update succeeded"`Message string `json:"message" jsonschema:"Status message"`}// UpdateCluster implements the update_cluster MCP toolfunc UpdateCluster(ctx context.Context,req *mcp.CallToolRequest,input UpdateClusterInput,) (*mcp.CallToolResult, UpdateClusterOutput, error) {// Open writable databasedatabase, err := db.OpenWriteableDB(dbPath)if err != nil {return nil, UpdateClusterOutput{}, fmt.Errorf("failed to open database: %w", err)}defer database.Close()// Verify cluster existsvar exists boolerr = database.QueryRow("SELECT EXISTS(SELECT 1 FROM cluster WHERE id = ?)", input.ClusterID).Scan(&exists)if err != nil {return nil, UpdateClusterOutput{}, fmt.Errorf("failed to query cluster: %w", err)}if !exists {return nil, UpdateClusterOutput{}, fmt.Errorf("cluster not found: %s", input.ClusterID)}// Build dynamic UPDATE query based on provided fieldsupdates := []string{}args := []any{}if input.Name != nil {updates = append(updates, "name = ?")args = append(args, *input.Name)}if input.Path != nil {updates = append(updates, "path = ?")args = append(args, *input.Path)}if input.SampleRate != nil {updates = append(updates, "sample_rate = ?")args = append(args, *input.SampleRate)}if input.Description != nil {updates = append(updates, "description = ?")args = append(args, *input.Description)}if len(updates) == 0 {return nil, UpdateClusterOutput{}, fmt.Errorf("no fields provided to update")}// Always update last_modifiedupdates = append(updates, "last_modified = now()")args = append(args, input.ClusterID)// Execute updatequery := fmt.Sprintf("UPDATE cluster SET %s WHERE id = ?", strings.Join(updates, ", "))_, err = database.Exec(query, args...)if err != nil {return nil, UpdateClusterOutput{}, fmt.Errorf("failed to update cluster: %w", err)}output := UpdateClusterOutput{ClusterID: input.ClusterID,Success: true,Message: "Cluster updated successfully",}return &mcp.CallToolResult{}, output, nil}
}// ensureClusterPath sets the cluster's path field if it's currently emptyfunc ensureClusterPath(dbPath, clusterID, folderPath string) error {database, err := db.OpenWriteableDB(dbPath)if err != nil {return fmt.Errorf("failed to open database: %w", err)}defer database.Close()// Check if cluster already has a pathvar currentPath sql.NullStringerr = database.QueryRow("SELECT path FROM cluster WHERE id = ?", clusterID).Scan(¤tPath)if err != nil {return fmt.Errorf("failed to query cluster: %w", err)}// If path is already set, skipif currentPath.Valid && currentPath.String != "" {return nil}// Normalize folder pathnormalizedPath := utils.NormalizeFolderPath(folderPath)// Update cluster with normalized path_, err = database.Exec("UPDATE cluster SET path = ?, last_modified = now() WHERE id = ?",normalizedPath,clusterID,)if err != nil {return fmt.Errorf("failed to update cluster path: %w", err)}return nil
package dbimport gonanoid "github.com/matoous/go-nanoid/v2"// IDLength is the length of generated IDs (12 characters)const IDLength = 12// GenerateID generates a unique 12-character ID using nanoid// Uses alphanumeric characters (62-character alphabet)func GenerateID() (string, error) {return gonanoid.Generate("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",IDLength,)}