{"version":3,"sources":["../src/filesystem/index.ts","../src/blob-store/index.ts","../src/provider.ts"],"names":["MastraFilesystem","S3Client","GetObjectCommand","FileNotFoundError","FileExistsError","PutObjectCommand","DeleteObjectCommand","CopyObjectCommand","ListObjectsV2Command","DeleteObjectsCommand","HeadObjectCommand","HeadBucketCommand","message","trimSlashes","BlobStore","isNotFoundError"],"mappings":"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","file":"index.cjs","sourcesContent":["import {\n  S3Client,\n  GetObjectCommand,\n  PutObjectCommand,\n  DeleteObjectCommand,\n  CopyObjectCommand,\n  ListObjectsV2Command,\n  DeleteObjectsCommand,\n  HeadObjectCommand,\n  HeadBucketCommand,\n} from '@aws-sdk/client-s3';\n\nimport type { AwsCredentialIdentity, AwsCredentialIdentityProvider } from '@aws-sdk/types';\n\nimport type {\n  FileContent,\n  FileStat,\n  FileEntry,\n  ReadOptions,\n  WriteOptions,\n  ListOptions,\n  RemoveOptions,\n  CopyOptions,\n  FilesystemMountConfig,\n  FilesystemIcon,\n  FilesystemInfo,\n  ProviderStatus,\n  MastraFilesystemOptions,\n} from '@mastra/core/workspace';\nimport { MastraFilesystem, FileNotFoundError, FileExistsError } from '@mastra/core/workspace';\n\n/**\n * S3 mount configuration.\n * Returned by S3Filesystem.getMountConfig() for FUSE mounting in sandboxes.\n */\nexport interface S3MountConfig extends FilesystemMountConfig {\n  type: 's3';\n  /** S3 bucket name */\n  bucket: string;\n  /** AWS region (use 'auto' for R2) */\n  region?: string;\n  /** Optional endpoint for S3-compatible storage (MinIO, R2, etc.) */\n  endpoint?: string;\n  /** AWS access key ID */\n  accessKeyId?: string;\n  /** AWS secret access key */\n  secretAccessKey?: string;\n  /** AWS session token for temporary credentials (SSO, AssumeRole, container credentials, etc.) */\n  sessionToken?: string;\n  /**\n   * Optional prefix (subdirectory) to mount instead of the entire bucket.\n   * Uses s3fs `bucket:/prefix` syntax to scope the mount to a specific path.\n   * Leading/trailing slashes are normalized automatically.\n   */\n  prefix?: string;\n  /** Mount as read-only */\n  readOnly?: boolean;\n}\n\n/**\n * Common MIME types by file extension.\n */\nconst MIME_TYPES: Record<string, string> = {\n  // Text\n  '.txt': 'text/plain',\n  '.md': 'text/markdown',\n  '.markdown': 'text/markdown',\n  '.html': 'text/html',\n  '.htm': 'text/html',\n  '.css': 'text/css',\n  '.csv': 'text/csv',\n  '.xml': 'text/xml',\n  // Code\n  '.js': 'text/javascript',\n  '.mjs': 'text/javascript',\n  '.ts': 'text/typescript',\n  '.tsx': 'text/typescript',\n  '.jsx': 'text/javascript',\n  '.json': 'application/json',\n  '.yaml': 'text/yaml',\n  '.yml': 'text/yaml',\n  '.py': 'text/x-python',\n  '.rb': 'text/x-ruby',\n  '.sh': 'text/x-shellscript',\n  '.bash': 'text/x-shellscript',\n  // Images\n  '.png': 'image/png',\n  '.jpg': 'image/jpeg',\n  '.jpeg': 'image/jpeg',\n  '.gif': 'image/gif',\n  '.svg': 'image/svg+xml',\n  '.webp': 'image/webp',\n  '.ico': 'image/x-icon',\n  // Documents\n  '.pdf': 'application/pdf',\n  // Archives\n  '.zip': 'application/zip',\n  '.gz': 'application/gzip',\n  '.tar': 'application/x-tar',\n};\n\n/**\n * Get MIME type from file path extension.\n */\nfunction getMimeType(path: string): string {\n  const ext = path.toLowerCase().match(/\\.[^.]+$/)?.[0];\n  return ext ? (MIME_TYPES[ext] ?? 'application/octet-stream') : 'application/octet-stream';\n}\n\n/** Check if an error is a \"not found\" error from the S3 SDK. */\nfunction isNotFoundError(error: unknown): boolean {\n  if (!error || typeof error !== 'object' || !('name' in error)) return false;\n  const name = (error as { name: string }).name;\n  return name === 'NotFound' || name === 'NoSuchKey' || name === '404';\n}\n\n/** Check if an error is an access denied error from the S3 SDK. */\nfunction isAccessDeniedError(error: unknown): boolean {\n  if (!error || typeof error !== 'object') return false;\n  const err = error as { name?: string; $metadata?: { httpStatusCode?: number } };\n  return err.name === 'AccessDenied' || err.$metadata?.httpStatusCode === 403;\n}\n\n/**\n * S3 filesystem provider configuration.\n */\nexport interface S3FilesystemOptions extends MastraFilesystemOptions {\n  /** Unique identifier for this filesystem instance */\n  id?: string;\n  /** S3 bucket name */\n  bucket: string;\n  /** Human-friendly display name for the UI */\n  displayName?: string;\n  /** Icon identifier for the UI (defaults to 's3') */\n  icon?: FilesystemIcon;\n  /** Description shown in tooltips */\n  description?: string;\n  /** AWS region (use 'auto' for R2) */\n  region: string;\n  /**\n   * AWS credentials or credential provider function.\n   * Accepts static credentials or a provider that auto-refreshes\n   * (e.g. fromNodeProviderChain() from @aws-sdk/credential-providers).\n   * When set, takes precedence over accessKeyId/secretAccessKey/sessionToken.\n   * When ALL credential options are omitted, the SDK default credential\n   * provider chain is used (env vars, ~/.aws, IMDS, ECS container credentials).\n   */\n  credentials?: AwsCredentialIdentity | AwsCredentialIdentityProvider;\n  /**\n   * AWS access key ID.\n   * Optional - omit to use the SDK default credential provider chain.\n   */\n  accessKeyId?: string;\n  /**\n   * AWS secret access key.\n   * Optional - omit to use the SDK default credential provider chain.\n   */\n  secretAccessKey?: string;\n  /**\n   * AWS session token for temporary credentials.\n   * Required when using SSO, AssumeRole, container credentials, or any other\n   * temporary credential provider.\n   */\n  sessionToken?: string;\n  /**\n   * Custom endpoint URL for S3-compatible storage.\n   * Examples:\n   * - Cloudflare R2: 'https://{accountId}.r2.cloudflarestorage.com'\n   * - MinIO: 'http://localhost:9000'\n   * - DigitalOcean Spaces: 'https://{region}.digitaloceanspaces.com'\n   */\n  endpoint?: string;\n  /** Force path-style URLs (required for some S3-compatible services) */\n  forcePathStyle?: boolean;\n  /** Optional prefix for all keys (acts like a subdirectory) */\n  prefix?: string;\n  /** Mount as read-only (blocks write operations, mounts read-only in sandboxes) */\n  readOnly?: boolean;\n}\n\n/**\n * S3 filesystem implementation.\n *\n * Stores files in an S3 bucket or S3-compatible storage service.\n * Supports mounting into E2B sandboxes via s3fs-fuse.\n *\n * @example AWS S3\n * ```typescript\n * import { S3Filesystem } from '@mastra/s3';\n *\n * const fs = new S3Filesystem({\n *   bucket: 'my-bucket',\n *   region: 'us-east-1',\n *   accessKeyId: process.env.AWS_ACCESS_KEY_ID!,\n *   secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,\n * });\n * ```\n *\n * @example Cloudflare R2\n * ```typescript\n * import { S3Filesystem } from '@mastra/s3';\n *\n * const fs = new S3Filesystem({\n *   bucket: 'my-bucket',\n *   region: 'auto',\n *   accessKeyId: process.env.R2_ACCESS_KEY_ID!,\n *   secretAccessKey: process.env.R2_SECRET_ACCESS_KEY!,\n *   endpoint: `https://${process.env.R2_ACCOUNT_ID}.r2.cloudflarestorage.com`,\n * });\n * ```\n *\n * @example MinIO (local)\n * ```typescript\n * import { S3Filesystem } from '@mastra/s3';\n *\n * const fs = new S3Filesystem({\n *   bucket: 'my-bucket',\n *   region: 'us-east-1',\n *   accessKeyId: 'minioadmin',\n *   secretAccessKey: 'minioadmin',\n *   endpoint: 'http://localhost:9000',\n *   forcePathStyle: true,\n * });\n * ```\n */\n\n/** Trim leading and trailing slashes without regex (avoids polynomial regex on user input). */\nfunction trimSlashes(s: string): string {\n  let start = 0;\n  let end = s.length;\n  while (start < end && s[start] === '/') start++;\n  while (end > start && s[end - 1] === '/') end--;\n  return s.slice(start, end);\n}\n\nexport class S3Filesystem extends MastraFilesystem {\n  readonly id: string;\n  readonly name = 'S3Filesystem';\n  readonly provider = 's3';\n  readonly readOnly?: boolean;\n\n  status: ProviderStatus = 'pending';\n\n  // Display metadata for UI\n  readonly displayName?: string;\n  readonly icon: FilesystemIcon = 's3';\n  readonly description?: string;\n\n  private readonly bucket: string;\n  private readonly region: string;\n  private readonly credentials?: AwsCredentialIdentity | AwsCredentialIdentityProvider;\n  private readonly accessKeyId?: string;\n  private readonly secretAccessKey?: string;\n  private readonly sessionToken?: string;\n  private readonly endpoint?: string;\n  private readonly forcePathStyle: boolean;\n  private readonly prefix: string;\n\n  private _client: S3Client | null = null;\n\n  constructor(options: S3FilesystemOptions) {\n    super({ ...options, name: 'S3Filesystem' });\n    this.id = options.id ?? `s3-fs-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;\n    this.bucket = options.bucket;\n    this.region = options.region;\n    this.credentials = options.credentials;\n    this.accessKeyId = options.accessKeyId;\n    this.secretAccessKey = options.secretAccessKey;\n    this.sessionToken = options.sessionToken;\n    this.endpoint = options.endpoint;\n    this.forcePathStyle = options.forcePathStyle ?? !!options.endpoint; // Default true for custom endpoints\n    // Trim leading/trailing slashes from prefix using iterative approach (avoids polynomial regex)\n    const trimmedPrefix = options.prefix ? trimSlashes(options.prefix) : '';\n    this.prefix = trimmedPrefix ? trimmedPrefix + '/' : '';\n\n    // Display metadata - detect icon first, then derive displayName from it\n    this.icon = options.icon ?? this.detectIconFromEndpoint(options.endpoint);\n    this.displayName = options.displayName ?? this.getDefaultDisplayName(this.icon);\n    this.description = options.description;\n    this.readOnly = options.readOnly;\n  }\n\n  /**\n   * Get the underlying S3Client instance for direct access to AWS S3 APIs.\n   *\n   * Use this when you need to access S3 features not exposed through the\n   * WorkspaceFilesystem interface (e.g., presigned URLs, multipart uploads,\n   * custom S3 operations, etc.).\n   *\n   * @example Generate a presigned URL\n   * ```typescript\n   * import { GetObjectCommand } from '@aws-sdk/client-s3';\n   * import { getSignedUrl } from '@aws-sdk/s3-request-presigner';\n   *\n   * const s3Client = fs.client;\n   * const url = await getSignedUrl(s3Client, new GetObjectCommand({\n   *   Bucket: 'my-bucket',\n   *   Key: 'my-file.txt',\n   * }));\n   * ```\n   */\n  get client(): S3Client {\n    return this.getClient();\n  }\n\n  /**\n   * Get mount configuration for E2B sandbox.\n   * Returns S3-compatible config that works with s3fs-fuse.\n   *\n   * Only static `accessKeyId`/`secretAccessKey`/`sessionToken` are included in the\n   * returned config. If credentials are provided only via the `credentials` option\n   * (provider function), the returned config will have no credentials because FUSE\n   * mounts cannot call a provider function. Use static credentials for sandbox\n   * mount compatibility.\n   */\n  getMountConfig(): S3MountConfig {\n    const config: S3MountConfig = {\n      type: 's3',\n      bucket: this.bucket,\n      region: this.region,\n      endpoint: this.endpoint,\n    };\n\n    if (this.accessKeyId && this.secretAccessKey) {\n      config.accessKeyId = this.accessKeyId;\n      config.secretAccessKey = this.secretAccessKey;\n      if (this.sessionToken) {\n        config.sessionToken = this.sessionToken;\n      }\n    }\n\n    if (this.prefix) {\n      config.prefix = this.prefix;\n    }\n\n    if (this.readOnly) {\n      config.readOnly = true;\n    }\n\n    return config;\n  }\n\n  /**\n   * Get filesystem info for status reporting.\n   */\n  getInfo(): FilesystemInfo<{\n    bucket: string;\n    region: string;\n    endpoint?: string;\n    prefix?: string;\n  }> {\n    return {\n      id: this.id,\n      name: this.name,\n      provider: this.provider,\n      status: this.status,\n      error: this.error,\n      readOnly: this.readOnly,\n      icon: this.icon,\n      metadata: {\n        bucket: this.bucket,\n        region: this.region,\n        ...(this.endpoint && { endpoint: this.endpoint }),\n        ...(this.prefix && { prefix: this.prefix }),\n      },\n    };\n  }\n\n  /**\n   * Handle an error, checking for access denied and updating status accordingly.\n   * Returns the error for re-throwing.\n   */\n  private handleError(error: unknown): unknown {\n    if (isAccessDeniedError(error)) {\n      this.status = 'error';\n      this.error = 'Access denied - check credentials and bucket permissions';\n    }\n    return error;\n  }\n\n  /**\n   * Get instructions describing this S3 filesystem.\n   * Used by agents to understand storage semantics.\n   */\n  getInstructions(): string {\n    const providerName = this.displayName || 'S3';\n    const access = this.readOnly ? 'Read-only' : 'Persistent';\n    return `${providerName} storage in bucket \"${this.bucket}\". ${access} storage - files are retained across sessions.`;\n  }\n\n  /**\n   * Detect the appropriate icon based on the S3 endpoint.\n   */\n  private detectIconFromEndpoint(endpoint?: string): FilesystemIcon {\n    if (!endpoint) {\n      // No custom endpoint = AWS S3\n      return 'aws-s3';\n    }\n\n    // Parse hostname from endpoint URL for secure matching\n    let hostname: string;\n    try {\n      const url = new URL(endpoint);\n      hostname = url.hostname.toLowerCase();\n    } catch {\n      // If URL parsing fails, use the endpoint as-is (lowercased)\n      hostname = endpoint.toLowerCase();\n    }\n\n    // Check hostname suffix for known providers (use dot-prefix or exact match to prevent subdomain spoofing)\n    if (\n      hostname === 'r2.cloudflarestorage.com' ||\n      hostname.endsWith('.r2.cloudflarestorage.com') ||\n      hostname.endsWith('.cloudflare.com')\n    ) {\n      return 'r2';\n    }\n\n    if (\n      hostname === 'storage.googleapis.com' ||\n      hostname.endsWith('.storage.googleapis.com') ||\n      hostname.endsWith('.googleapis.com')\n    ) {\n      return 'gcs';\n    }\n\n    if (\n      hostname === 'blob.core.windows.net' ||\n      hostname.endsWith('.blob.core.windows.net') ||\n      hostname.endsWith('.azure.com')\n    ) {\n      return 'azure';\n    }\n\n    if (hostname.includes('minio')) {\n      return 'minio';\n    }\n\n    // Generic S3-compatible (DigitalOcean Spaces, etc.)\n    return 's3';\n  }\n\n  /**\n   * Get a user-friendly display name based on the icon/provider.\n   */\n  private getDefaultDisplayName(icon: FilesystemIcon): string | undefined {\n    switch (icon) {\n      case 'aws-s3':\n        return 'AWS S3';\n      case 'r2':\n      case 'cloudflare':\n      case 'cloudflare-r2':\n        return 'Cloudflare R2';\n      case 'gcs':\n      case 'google-cloud':\n      case 'google-cloud-storage':\n        return 'Google Cloud Storage';\n      case 'azure':\n      case 'azure-blob':\n        return 'Azure Blob';\n      case 'minio':\n        return 'MinIO';\n      case 's3':\n        return 'S3';\n      default:\n        // Unknown icon - don't assume a display name\n        return undefined;\n    }\n  }\n\n  private getClient(): S3Client {\n    if (this._client) return this._client;\n\n    const hasStaticCredentials = this.accessKeyId && this.secretAccessKey;\n\n    let credentials: AwsCredentialIdentity | AwsCredentialIdentityProvider | undefined;\n    if (this.credentials) {\n      credentials = this.credentials;\n    } else if (hasStaticCredentials) {\n      credentials = {\n        accessKeyId: this.accessKeyId!,\n        secretAccessKey: this.secretAccessKey!,\n        ...(this.sessionToken && { sessionToken: this.sessionToken }),\n      };\n    }\n    // When credentials is undefined, SDK uses its default provider chain\n\n    this._client = new S3Client({\n      region: this.region,\n      ...(credentials !== undefined && { credentials }),\n      endpoint: this.endpoint,\n      forcePathStyle: this.forcePathStyle,\n    });\n\n    return this._client;\n  }\n\n  /**\n   * Ensure the filesystem is initialized and return the S3 client.\n   * Uses base class ensureReady() for status management, then returns client.\n   */\n  private async getReadyClient(): Promise<S3Client> {\n    await this.ensureReady();\n    return this.getClient();\n  }\n\n  private toKey(path: string): string {\n    // Remove leading slashes, then resolve \".\" and \"./\" to empty string (root)\n    const cleanPath = path.replace(/^\\/+/, '').replace(/^\\.(?:\\/|$)/, '');\n    return this.prefix + cleanPath;\n  }\n\n  // ---------------------------------------------------------------------------\n  // File Operations\n  // ---------------------------------------------------------------------------\n\n  async readFile(path: string, options?: ReadOptions): Promise<string | Buffer> {\n    const client = await this.getReadyClient();\n\n    try {\n      const response = await client.send(\n        new GetObjectCommand({\n          Bucket: this.bucket,\n          Key: this.toKey(path),\n        }),\n      );\n\n      const body = await response.Body?.transformToByteArray();\n      if (!body) throw new FileNotFoundError(path);\n\n      const buffer = Buffer.from(body);\n      if (options?.encoding) {\n        return buffer.toString(options.encoding);\n      }\n      return buffer;\n    } catch (error: unknown) {\n      if (isNotFoundError(error)) {\n        throw new FileNotFoundError(path);\n      }\n      throw this.handleError(error);\n    }\n  }\n\n  async writeFile(path: string, content: FileContent, options?: WriteOptions): Promise<void> {\n    const client = await this.getReadyClient();\n\n    if (options?.overwrite === false && (await this.exists(path))) {\n      throw new FileExistsError(path);\n    }\n\n    const body = typeof content === 'string' ? Buffer.from(content, 'utf-8') : Buffer.from(content);\n    const contentType = getMimeType(path);\n\n    await client.send(\n      new PutObjectCommand({\n        Bucket: this.bucket,\n        Key: this.toKey(path),\n        Body: body,\n        ContentType: contentType,\n      }),\n    );\n  }\n\n  async appendFile(path: string, content: FileContent): Promise<void> {\n    // S3 doesn't support append, so read + write\n    let existing = '';\n    try {\n      existing = (await this.readFile(path, { encoding: 'utf-8' })) as string;\n    } catch (error) {\n      if (error instanceof FileNotFoundError) {\n        // File doesn't exist, start fresh\n      } else {\n        throw error;\n      }\n    }\n\n    const appendContent = typeof content === 'string' ? content : Buffer.from(content).toString('utf-8');\n    await this.writeFile(path, existing + appendContent);\n  }\n\n  async deleteFile(path: string, options?: RemoveOptions): Promise<void> {\n    // Check if this is a directory - if so, use rmdir instead\n    const isDir = await this.isDirectory(path);\n    if (isDir) {\n      await this.rmdir(path, { recursive: true, force: options?.force });\n      return;\n    }\n\n    const client = await this.getReadyClient();\n\n    try {\n      await client.send(\n        new DeleteObjectCommand({\n          Bucket: this.bucket,\n          Key: this.toKey(path),\n        }),\n      );\n    } catch (error: unknown) {\n      if (options?.force) return;\n      if (isNotFoundError(error)) {\n        throw new FileNotFoundError(path);\n      }\n      throw this.handleError(error);\n    }\n  }\n\n  async copyFile(src: string, dest: string, options?: CopyOptions): Promise<void> {\n    const client = await this.getReadyClient();\n\n    if (options?.overwrite === false && (await this.exists(dest))) {\n      throw new FileExistsError(dest);\n    }\n\n    try {\n      await client.send(\n        new CopyObjectCommand({\n          Bucket: this.bucket,\n          CopySource: `${this.bucket}/${encodeURIComponent(this.toKey(src)).replace(/%2F/g, '/')}`,\n          Key: this.toKey(dest),\n        }),\n      );\n    } catch (error: unknown) {\n      if (isNotFoundError(error)) {\n        throw new FileNotFoundError(src);\n      }\n      throw this.handleError(error);\n    }\n  }\n\n  async moveFile(src: string, dest: string, options?: CopyOptions): Promise<void> {\n    await this.copyFile(src, dest, options);\n    await this.deleteFile(src, { force: true });\n  }\n\n  // ---------------------------------------------------------------------------\n  // Directory Operations\n  // ---------------------------------------------------------------------------\n\n  async mkdir(_path: string, _options?: { recursive?: boolean }): Promise<void> {\n    // S3 doesn't have real directories - they're just key prefixes\n    // No-op, directories are created implicitly when files are written\n  }\n\n  async rmdir(path: string, options?: RemoveOptions): Promise<void> {\n    if (!options?.recursive) {\n      // Check if directory is empty\n      const entries = await this.readdir(path);\n      if (entries.length > 0) {\n        throw new Error(`Directory not empty: ${path}`);\n      }\n      return;\n    }\n\n    // Delete all objects with this prefix\n    const client = await this.getReadyClient();\n\n    const prefix = this.toKey(path).replace(/\\/$/, '') + '/';\n\n    let continuationToken: string | undefined;\n    do {\n      const listResponse = await client.send(\n        new ListObjectsV2Command({\n          Bucket: this.bucket,\n          Prefix: prefix,\n          ContinuationToken: continuationToken,\n        }),\n      );\n\n      if (listResponse.Contents && listResponse.Contents.length > 0) {\n        const deleteResponse = await client.send(\n          new DeleteObjectsCommand({\n            Bucket: this.bucket,\n            Delete: {\n              Objects: listResponse.Contents.filter((obj): obj is { Key: string } => !!obj.Key).map(obj => ({\n                Key: obj.Key,\n              })),\n            },\n          }),\n        );\n        if (deleteResponse.Errors && deleteResponse.Errors.length > 0) {\n          throw new Error(`Failed to delete ${deleteResponse.Errors.length} object(s) in ${path}`);\n        }\n      }\n\n      continuationToken = listResponse.NextContinuationToken;\n    } while (continuationToken);\n  }\n\n  async readdir(path: string, options?: ListOptions): Promise<FileEntry[]> {\n    const client = await this.getReadyClient();\n\n    const prefix = this.toKey(path).replace(/\\/$/, '');\n    const searchPrefix = prefix ? prefix + '/' : '';\n\n    const entries: FileEntry[] = [];\n    const seenDirs = new Set<string>();\n\n    let continuationToken: string | undefined;\n    do {\n      const response = await client.send(\n        new ListObjectsV2Command({\n          Bucket: this.bucket,\n          Prefix: searchPrefix,\n          Delimiter: options?.recursive ? undefined : '/',\n          ContinuationToken: continuationToken,\n        }),\n      );\n\n      // Add files\n      if (response.Contents) {\n        for (const obj of response.Contents) {\n          const key = obj.Key;\n          if (!key || key === searchPrefix) continue;\n\n          const relativePath = key.slice(searchPrefix.length);\n          if (!relativePath) continue;\n\n          // Skip if this looks like a directory marker\n          if (relativePath.endsWith('/')) {\n            const dirName = relativePath.slice(0, -1);\n            if (!seenDirs.has(dirName)) {\n              seenDirs.add(dirName);\n              entries.push({ name: dirName, type: 'directory' });\n            }\n            continue;\n          }\n\n          const name = options?.recursive ? relativePath : relativePath.split('/')[0];\n\n          // Skip if name is undefined or empty\n          if (!name) continue;\n\n          // Filter by extension if specified\n          if (options?.extension) {\n            const extensions = Array.isArray(options.extension) ? options.extension : [options.extension];\n            if (!extensions.some(ext => name.endsWith(ext))) {\n              continue;\n            }\n          }\n\n          entries.push({\n            name,\n            type: 'file',\n            size: obj.Size,\n          });\n        }\n      }\n\n      // Add directories (common prefixes)\n      if (response.CommonPrefixes) {\n        for (const prefixObj of response.CommonPrefixes) {\n          if (!prefixObj.Prefix) continue;\n          const dirName = prefixObj.Prefix.slice(searchPrefix.length).replace(/\\/$/, '');\n          if (dirName && !seenDirs.has(dirName)) {\n            seenDirs.add(dirName);\n            entries.push({ name: dirName, type: 'directory' });\n          }\n        }\n      }\n\n      continuationToken = response.NextContinuationToken;\n    } while (continuationToken);\n\n    return entries;\n  }\n\n  // ---------------------------------------------------------------------------\n  // Path Operations\n  // ---------------------------------------------------------------------------\n\n  async exists(path: string): Promise<boolean> {\n    const key = this.toKey(path);\n    if (!key) return true; // Root always exists\n\n    const client = await this.getReadyClient();\n\n    // Check if it's a file\n    try {\n      await client.send(\n        new HeadObjectCommand({\n          Bucket: this.bucket,\n          Key: key,\n        }),\n      );\n      return true;\n    } catch (error: unknown) {\n      if (!isNotFoundError(error)) throw this.handleError(error);\n      // Not a file, check if it's a \"directory\" (has objects with this prefix)\n    }\n\n    // Check if it's a directory prefix\n    const response: { Contents?: unknown[] } = await client.send(\n      new ListObjectsV2Command({\n        Bucket: this.bucket,\n        Prefix: key.replace(/\\/$/, '') + '/',\n        MaxKeys: 1,\n      }),\n    );\n\n    return (response.Contents?.length ?? 0) > 0;\n  }\n\n  async stat(path: string): Promise<FileStat> {\n    const key = this.toKey(path);\n\n    // Root is always a directory\n    if (!key) {\n      return {\n        name: '',\n        path,\n        type: 'directory',\n        size: 0,\n        createdAt: new Date(),\n        modifiedAt: new Date(),\n      };\n    }\n\n    const client = await this.getReadyClient();\n\n    try {\n      const response: { ContentLength?: number; LastModified?: Date } = await client.send(\n        new HeadObjectCommand({\n          Bucket: this.bucket,\n          Key: key,\n        }),\n      );\n\n      const name = path.split('/').pop() ?? '';\n      return {\n        name,\n        path,\n        type: 'file',\n        size: response.ContentLength ?? 0,\n        createdAt: response.LastModified ?? new Date(),\n        modifiedAt: response.LastModified ?? new Date(),\n      };\n    } catch (error: unknown) {\n      if (!isNotFoundError(error)) throw this.handleError(error);\n      // Check if it's a directory\n      const isDir = await this.isDirectory(path);\n      if (isDir) {\n        const name = path.split('/').filter(Boolean).pop() ?? '';\n        return {\n          name,\n          path,\n          type: 'directory',\n          size: 0,\n          createdAt: new Date(),\n          modifiedAt: new Date(),\n        };\n      }\n      throw new FileNotFoundError(path);\n    }\n  }\n\n  async isFile(path: string): Promise<boolean> {\n    const key = this.toKey(path);\n    if (!key) return false; // Root is a directory, not a file\n\n    const client = await this.getReadyClient();\n\n    try {\n      await client.send(\n        new HeadObjectCommand({\n          Bucket: this.bucket,\n          Key: key,\n        }),\n      );\n      return true;\n    } catch (error: unknown) {\n      if (!isNotFoundError(error)) throw this.handleError(error);\n      return false;\n    }\n  }\n\n  async isDirectory(path: string): Promise<boolean> {\n    const key = this.toKey(path);\n    if (!key) return true; // Root is always a directory\n\n    const client = await this.getReadyClient();\n\n    const response: { Contents?: unknown[] } = await client.send(\n      new ListObjectsV2Command({\n        Bucket: this.bucket,\n        Prefix: key.replace(/\\/$/, '') + '/',\n        MaxKeys: 1,\n      }),\n    );\n\n    return (response.Contents?.length ?? 0) > 0;\n  }\n\n  // ---------------------------------------------------------------------------\n  // Lifecycle (overrides base class protected methods)\n  // ---------------------------------------------------------------------------\n\n  /**\n   * Initialize the S3 client.\n   * Status management is handled by the base class.\n   */\n  async init(): Promise<void> {\n    // Verify we can access the bucket\n    const client = this.getClient();\n    try {\n      await client.send(new HeadBucketCommand({ Bucket: this.bucket }));\n    } catch (error) {\n      // Extract httpStatusCode if available\n      const statusCode = (error as { $metadata?: { httpStatusCode?: number } }).$metadata?.httpStatusCode;\n\n      // Create error with status property for proper HTTP response codes\n      const createError = (message: string) => {\n        const err = new Error(message) as Error & { status?: number };\n        if (statusCode) err.status = statusCode;\n        return err;\n      };\n\n      // Provide better error messages for common S3 errors\n      if (isAccessDeniedError(error)) {\n        throw createError(`Access denied to bucket \"${this.bucket}\" - check credentials and permissions`);\n      }\n      if (isNotFoundError(error)) {\n        throw createError(`Bucket \"${this.bucket}\" not found`);\n      }\n      const message = error instanceof Error ? error.message : String(error);\n      if (statusCode) {\n        throw createError(`Failed to access bucket \"${this.bucket}\" (HTTP ${statusCode}): ${message}`);\n      }\n      throw error;\n    }\n  }\n\n  /**\n   * Clean up the S3 client.\n   * Status management is handled by the base class.\n   */\n  async destroy(): Promise<void> {\n    this._client = null;\n  }\n}\n","import {\n  S3Client,\n  GetObjectCommand,\n  PutObjectCommand,\n  DeleteObjectCommand,\n  HeadObjectCommand,\n  ListObjectsV2Command,\n  DeleteObjectsCommand,\n} from '@aws-sdk/client-s3';\n\nimport type { AwsCredentialIdentity, AwsCredentialIdentityProvider } from '@aws-sdk/types';\n\nimport { BlobStore } from '@mastra/core/storage';\nimport type { StorageBlobEntry } from '@mastra/core/storage';\n\n/**\n * Configuration for S3BlobStore.\n *\n * Compatible with AWS S3, Cloudflare R2, MinIO, DigitalOcean Spaces, etc.\n */\nexport interface S3BlobStoreOptions {\n  /** S3 bucket name */\n  bucket: string;\n  /** AWS region (use 'auto' for R2) */\n  region: string;\n  /**\n   * AWS credentials or credential provider function.\n   * Accepts static credentials or a provider that auto-refreshes\n   * (e.g. fromNodeProviderChain() from @aws-sdk/credential-providers).\n   * When set, takes precedence over accessKeyId/secretAccessKey/sessionToken.\n   * When ALL credential options are omitted, the SDK default credential\n   * provider chain is used (env vars, ~/.aws, IMDS, ECS container credentials).\n   */\n  credentials?: AwsCredentialIdentity | AwsCredentialIdentityProvider;\n  /** AWS access key ID. Optional - omit to use the SDK default credential provider chain. */\n  accessKeyId?: string;\n  /** AWS secret access key. Optional - omit to use the SDK default credential provider chain. */\n  secretAccessKey?: string;\n  /** AWS session token for temporary credentials (SSO, AssumeRole, container credentials, etc.) */\n  sessionToken?: string;\n  /**\n   * Custom endpoint URL for S3-compatible storage.\n   * Examples:\n   * - Cloudflare R2: 'https://{accountId}.r2.cloudflarestorage.com'\n   * - MinIO: 'http://localhost:9000'\n   */\n  endpoint?: string;\n  /** Force path-style URLs (required for some S3-compatible services like MinIO) */\n  forcePathStyle?: boolean;\n  /**\n   * Key prefix for all blob objects.\n   * Defaults to 'mastra_skill_blobs/'.\n   */\n  prefix?: string;\n}\n\n/** Trim leading and trailing slashes. */\nfunction trimSlashes(s: string): string {\n  let start = 0;\n  let end = s.length;\n  while (start < end && s[start] === '/') start++;\n  while (end > start && s[end - 1] === '/') end--;\n  return s.slice(start, end);\n}\n\n/**\n * S3-backed content-addressable blob store for skill versioning.\n *\n * Each blob is stored as an S3 object keyed by its SHA-256 hash.\n * Metadata (size, mimeType, createdAt) is stored in S3 object user metadata.\n *\n * Since blobs are content-addressable, writes are idempotent — the same hash\n * always maps to the same content, so overwrites are safe and equivalent to\n * a no-op.\n *\n * @example AWS S3\n * ```typescript\n * import { S3BlobStore } from '@mastra/s3';\n *\n * const blobs = new S3BlobStore({\n *   bucket: 'my-skill-blobs',\n *   region: 'us-east-1',\n *   accessKeyId: process.env.AWS_ACCESS_KEY_ID!,\n *   secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,\n * });\n * ```\n *\n * @example MinIO (local)\n * ```typescript\n * import { S3BlobStore } from '@mastra/s3';\n *\n * const blobs = new S3BlobStore({\n *   bucket: 'skill-blobs',\n *   region: 'us-east-1',\n *   accessKeyId: 'minioadmin',\n *   secretAccessKey: 'minioadmin',\n *   endpoint: 'http://localhost:9000',\n *   forcePathStyle: true,\n * });\n * ```\n */\nexport class S3BlobStore extends BlobStore {\n  private readonly bucket: string;\n  private readonly prefix: string;\n  private _client: S3Client | null = null;\n\n  private readonly region: string;\n  private readonly credentials?: AwsCredentialIdentity | AwsCredentialIdentityProvider;\n  private readonly accessKeyId?: string;\n  private readonly secretAccessKey?: string;\n  private readonly sessionToken?: string;\n  private readonly endpoint?: string;\n  private readonly forcePathStyle: boolean;\n\n  constructor(options: S3BlobStoreOptions) {\n    super();\n    this.bucket = options.bucket;\n    this.region = options.region;\n    this.credentials = options.credentials;\n    this.accessKeyId = options.accessKeyId;\n    this.secretAccessKey = options.secretAccessKey;\n    this.sessionToken = options.sessionToken;\n    this.endpoint = options.endpoint;\n    this.forcePathStyle = options.forcePathStyle ?? !!options.endpoint;\n    this.prefix = options.prefix ? trimSlashes(options.prefix) + '/' : 'mastra_skill_blobs/';\n  }\n\n  private getClient(): S3Client {\n    if (this._client) return this._client;\n\n    const hasStaticCredentials = this.accessKeyId && this.secretAccessKey;\n\n    let credentials: AwsCredentialIdentity | AwsCredentialIdentityProvider | undefined;\n    if (this.credentials) {\n      credentials = this.credentials;\n    } else if (hasStaticCredentials) {\n      credentials = {\n        accessKeyId: this.accessKeyId!,\n        secretAccessKey: this.secretAccessKey!,\n        ...(this.sessionToken && { sessionToken: this.sessionToken }),\n      };\n    }\n    // When credentials is undefined, SDK uses its default provider chain\n\n    this._client = new S3Client({\n      region: this.region,\n      ...(credentials !== undefined && { credentials }),\n      endpoint: this.endpoint,\n      forcePathStyle: this.forcePathStyle,\n    });\n    return this._client;\n  }\n\n  private toKey(hash: string): string {\n    return this.prefix + hash;\n  }\n\n  async init(): Promise<void> {\n    // S3 doesn't require table creation — the bucket is expected to exist.\n  }\n\n  async put(entry: StorageBlobEntry): Promise<void> {\n    const client = this.getClient();\n    const now = entry.createdAt ?? new Date();\n\n    await client.send(\n      new PutObjectCommand({\n        Bucket: this.bucket,\n        Key: this.toKey(entry.hash),\n        Body: entry.content,\n        ContentType: entry.mimeType ?? 'application/octet-stream',\n        Metadata: {\n          size: String(entry.size),\n          createdat: now.toISOString(),\n          ...(entry.mimeType ? { mimetype: entry.mimeType } : {}),\n        },\n      }),\n    );\n  }\n\n  async get(hash: string): Promise<StorageBlobEntry | null> {\n    const client = this.getClient();\n\n    try {\n      const response = await client.send(\n        new GetObjectCommand({\n          Bucket: this.bucket,\n          Key: this.toKey(hash),\n        }),\n      );\n\n      const body = await response.Body?.transformToString('utf-8');\n      if (body === undefined || body === null) return null;\n\n      const metadata = response.Metadata ?? {};\n      return {\n        hash,\n        content: body,\n        size: metadata.size != null ? Number(metadata.size) : Buffer.byteLength(body, 'utf-8'),\n        mimeType: metadata.mimetype || response.ContentType || undefined,\n        createdAt: metadata.createdat ? new Date(metadata.createdat) : new Date(),\n      };\n    } catch (error: unknown) {\n      if (isNotFoundError(error)) return null;\n      throw error;\n    }\n  }\n\n  async has(hash: string): Promise<boolean> {\n    const client = this.getClient();\n\n    try {\n      await client.send(\n        new HeadObjectCommand({\n          Bucket: this.bucket,\n          Key: this.toKey(hash),\n        }),\n      );\n      return true;\n    } catch (error: unknown) {\n      if (isNotFoundError(error)) return false;\n      throw error;\n    }\n  }\n\n  async delete(hash: string): Promise<boolean> {\n    // Pre-check is intentional: S3 DeleteObject returns 204 regardless of\n    // whether the object existed, so we check first for an accurate return.\n    // The TOCTOU gap is acceptable for content-addressable blobs.\n    const existed = await this.has(hash);\n    if (!existed) return false;\n\n    const client = this.getClient();\n    await client.send(\n      new DeleteObjectCommand({\n        Bucket: this.bucket,\n        Key: this.toKey(hash),\n      }),\n    );\n    return true;\n  }\n\n  async putMany(entries: StorageBlobEntry[]): Promise<void> {\n    if (entries.length === 0) return;\n    // S3 doesn't have a batch PUT, so we parallelize individual puts.\n    // Content-addressable means duplicate writes are idempotent.\n    await Promise.all(entries.map(entry => this.put(entry)));\n  }\n\n  async getMany(hashes: string[]): Promise<Map<string, StorageBlobEntry>> {\n    const result = new Map<string, StorageBlobEntry>();\n    if (hashes.length === 0) return result;\n\n    // Parallelize individual gets\n    const entries = await Promise.all(hashes.map(hash => this.get(hash)));\n    for (const entry of entries) {\n      if (entry) {\n        result.set(entry.hash, entry);\n      }\n    }\n    return result;\n  }\n\n  async dangerouslyClearAll(): Promise<void> {\n    const client = this.getClient();\n\n    let continuationToken: string | undefined;\n    do {\n      const listResponse = await client.send(\n        new ListObjectsV2Command({\n          Bucket: this.bucket,\n          Prefix: this.prefix,\n          ContinuationToken: continuationToken,\n        }),\n      );\n\n      const objects = listResponse.Contents;\n      if (objects && objects.length > 0) {\n        await client.send(\n          new DeleteObjectsCommand({\n            Bucket: this.bucket,\n            Delete: {\n              Objects: objects.filter(obj => obj.Key != null).map(obj => ({ Key: obj.Key! })),\n              Quiet: true,\n            },\n          }),\n        );\n      }\n\n      continuationToken = listResponse.IsTruncated ? listResponse.NextContinuationToken : undefined;\n    } while (continuationToken);\n  }\n}\n\nfunction isNotFoundError(error: unknown): boolean {\n  if (!error || typeof error !== 'object' || !('name' in error)) return false;\n  const name = (error as { name: string }).name;\n  return name === 'NotFound' || name === 'NoSuchKey' || name === '404';\n}\n","/**\n * S3 filesystem provider descriptor for MastraEditor.\n *\n * @example\n * ```typescript\n * import { s3FilesystemProvider } from '@mastra/s3';\n *\n * const editor = new MastraEditor({\n *   filesystems: [s3FilesystemProvider],\n * });\n * ```\n */\nimport type { FilesystemProvider, BlobStoreProvider } from '@mastra/core/editor';\nimport { S3BlobStore } from './blob-store';\nimport type { S3BlobStoreOptions } from './blob-store';\nimport { S3Filesystem } from './filesystem';\nimport type { S3FilesystemOptions } from './filesystem';\n\nexport const s3FilesystemProvider: FilesystemProvider<S3FilesystemOptions> = {\n  id: 's3',\n  name: 'Amazon S3',\n  description: 'S3 or S3-compatible storage (AWS, R2, MinIO, DO Spaces)',\n  configSchema: {\n    type: 'object',\n    required: ['bucket', 'region'],\n    properties: {\n      bucket: { type: 'string', description: 'S3 bucket name' },\n      region: { type: 'string', description: 'AWS region (use \"auto\" for R2)' },\n      accessKeyId: { type: 'string', description: 'AWS access key ID' },\n      secretAccessKey: { type: 'string', description: 'AWS secret access key' },\n      sessionToken: { type: 'string', description: 'AWS session token for temporary credentials' },\n      endpoint: { type: 'string', description: 'Custom endpoint URL for S3-compatible storage' },\n      forcePathStyle: { type: 'boolean', description: 'Force path-style URLs', default: false },\n      prefix: { type: 'string', description: 'Key prefix (acts like a subdirectory)' },\n      readOnly: { type: 'boolean', description: 'Mount as read-only', default: false },\n    },\n  },\n  createFilesystem: config => new S3Filesystem(config),\n};\n\n/**\n * S3 blob store provider descriptor for MastraEditor.\n *\n * @example\n * ```typescript\n * import { s3BlobStoreProvider } from '@mastra/s3';\n *\n * const editor = new MastraEditor({\n *   blobStores: { s3: s3BlobStoreProvider },\n * });\n * ```\n */\nexport const s3BlobStoreProvider: BlobStoreProvider<S3BlobStoreOptions> = {\n  id: 's3',\n  name: 'Amazon S3 Blob Store',\n  description: 'Content-addressable blob storage using S3 or S3-compatible storage (AWS, R2, MinIO, DO Spaces)',\n  configSchema: {\n    type: 'object',\n    required: ['bucket', 'region', 'accessKeyId', 'secretAccessKey'],\n    properties: {\n      bucket: { type: 'string', description: 'S3 bucket name' },\n      region: { type: 'string', description: 'AWS region (use \"auto\" for R2)' },\n      accessKeyId: { type: 'string', description: 'AWS access key ID' },\n      secretAccessKey: { type: 'string', description: 'AWS secret access key' },\n      sessionToken: { type: 'string', description: 'AWS session token for temporary credentials' },\n      endpoint: { type: 'string', description: 'Custom endpoint URL for S3-compatible storage' },\n      forcePathStyle: { type: 'boolean', description: 'Force path-style URLs', default: false },\n      prefix: { type: 'string', description: 'Key prefix for blob objects (default: mastra_skill_blobs/)' },\n    },\n  },\n  createBlobStore: config => new S3BlobStore(config),\n};\n"]}