@mastra/s3 0.2.0-alpha.0 → 0.2.1-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,109 @@
1
1
  # @mastra/s3
2
2
 
3
+ ## 0.2.1-alpha.0
4
+
5
+ ### Patch Changes
6
+
7
+ - Temporary AWS credentials (SSO, AssumeRole, container credentials) no longer cause "Access denied" errors. Both `S3Filesystem` and `S3BlobStore` now accept an optional `sessionToken` field that is forwarded to the AWS SDK. ([#13707](https://github.com/mastra-ai/mastra/pull/13707))
8
+
9
+ ```ts
10
+ new S3Filesystem({ bucket, region, accessKeyId, secretAccessKey, sessionToken });
11
+ ```
12
+
13
+ - Updated dependencies [[`504fc8b`](https://github.com/mastra-ai/mastra/commit/504fc8b9d0ddab717577ad3bf9c95ea4bd5377bd), [`f9c150b`](https://github.com/mastra-ai/mastra/commit/f9c150b7595ad05ad9cc9a11098e2944361e8c22), [`88de7e8`](https://github.com/mastra-ai/mastra/commit/88de7e8dfe4b7e1951a9e441bb33136e705ce24e), [`edee4b3`](https://github.com/mastra-ai/mastra/commit/edee4b37dff0af515fc7cc0e8d71ee39e6a762f0), [`3790c75`](https://github.com/mastra-ai/mastra/commit/3790c7578cc6a47d854eb12d89e6b1912867fe29), [`e7a235b`](https://github.com/mastra-ai/mastra/commit/e7a235be6472e0c870ed6c791ddb17c492dc188b), [`d51d298`](https://github.com/mastra-ai/mastra/commit/d51d298953967aab1f58ec965b644d109214f085), [`6dbeeb9`](https://github.com/mastra-ai/mastra/commit/6dbeeb94a8b1eebb727300d1a98961f882180794), [`d5f0d8d`](https://github.com/mastra-ai/mastra/commit/d5f0d8d6a03e515ddaa9b5da19b7e44b8357b07b), [`09c3b18`](https://github.com/mastra-ai/mastra/commit/09c3b1802ff14e243a8a8baea327440bc8cc2e32), [`b896379`](https://github.com/mastra-ai/mastra/commit/b8963791c6afa79484645fcec596a201f936b9a2), [`85c84eb`](https://github.com/mastra-ai/mastra/commit/85c84ebb78aebfcba9d209c8e152b16d7a00cb71), [`a89272a`](https://github.com/mastra-ai/mastra/commit/a89272a5d71939b9fcd284e6a6dc1dd091a6bdcf), [`ee9c8df`](https://github.com/mastra-ai/mastra/commit/ee9c8df644f19d055af5f496bf4942705f5a47b7), [`77b4a25`](https://github.com/mastra-ai/mastra/commit/77b4a254e51907f8ff3a3ba95596a18e93ae4b35), [`276246e`](https://github.com/mastra-ai/mastra/commit/276246e0b9066a1ea48bbc70df84dbe528daaf99), [`08ecfdb`](https://github.com/mastra-ai/mastra/commit/08ecfdbdad6fb8285deef86a034bdf4a6047cfca), [`d5f628c`](https://github.com/mastra-ai/mastra/commit/d5f628ca86c6f6f3ff1035d52f635df32dd81cab), [`524c0f3`](https://github.com/mastra-ai/mastra/commit/524c0f3c434c3d9d18f66338dcef383d6161b59c), [`c18a0e9`](https://github.com/mastra-ai/mastra/commit/c18a0e9cef1e4ca004b2963d35e4cfc031971eac), [`4bd21ea`](https://github.com/mastra-ai/mastra/commit/4bd21ea43d44d0a0427414fc047577f9f0aa3bec), [`115a7a4`](https://github.com/mastra-ai/mastra/commit/115a7a47db5e9896fec12ae6507501adb9ec89bf), [`22a48ae`](https://github.com/mastra-ai/mastra/commit/22a48ae2513eb54d8d79dad361fddbca97a155e8), [`3c6ef79`](https://github.com/mastra-ai/mastra/commit/3c6ef798481e00d6d22563be2de98818fd4dd5e0), [`9311c17`](https://github.com/mastra-ai/mastra/commit/9311c17d7a0640d9c4da2e71b814dc67c57c6369), [`7edf78f`](https://github.com/mastra-ai/mastra/commit/7edf78f80422c43e84585f08ba11df0d4d0b73c5), [`1c4221c`](https://github.com/mastra-ai/mastra/commit/1c4221cf6032ec98d0e094d4ee11da3e48490d96), [`d25b9ea`](https://github.com/mastra-ai/mastra/commit/d25b9eabd400167255a97b690ffbc4ee4097ded5), [`fe1ce5c`](https://github.com/mastra-ai/mastra/commit/fe1ce5c9211c03d561606fda95cbfe7df1d9a9b5), [`b03c0e0`](https://github.com/mastra-ai/mastra/commit/b03c0e0389a799523929a458b0509c9e4244d562), [`0a8366b`](https://github.com/mastra-ai/mastra/commit/0a8366b0a692fcdde56c4d526e4cf03c502ae4ac), [`85664e9`](https://github.com/mastra-ai/mastra/commit/85664e9fd857320fbc245e301f764f45f66f32a3), [`bc79650`](https://github.com/mastra-ai/mastra/commit/bc796500c6e0334faa158a96077e3fb332274869), [`9257d01`](https://github.com/mastra-ai/mastra/commit/9257d01d1366d81f84c582fe02b5e200cf9621f4), [`3a3a59e`](https://github.com/mastra-ai/mastra/commit/3a3a59e8ffaa6a985fe3d9a126a3f5ade11a6724), [`3108d4e`](https://github.com/mastra-ai/mastra/commit/3108d4e649c9fddbf03253a6feeb388a5fa9fa5a), [`0c33b2c`](https://github.com/mastra-ai/mastra/commit/0c33b2c9db537f815e1c59e2c898ffce2e395a79), [`191e5bd`](https://github.com/mastra-ai/mastra/commit/191e5bd29b82f5bda35243945790da7bc7b695c2), [`f77cd94`](https://github.com/mastra-ai/mastra/commit/f77cd94c44eabed490384e7d19232a865e13214c), [`e8135c7`](https://github.com/mastra-ai/mastra/commit/e8135c7e300dac5040670eec7eab896ac6092e30), [`daca48f`](https://github.com/mastra-ai/mastra/commit/daca48f0fb17b7ae0b62a2ac40cf0e491b2fd0b7), [`257d14f`](https://github.com/mastra-ai/mastra/commit/257d14faca5931f2e4186fc165b6f0b1f915deee), [`352f25d`](https://github.com/mastra-ai/mastra/commit/352f25da316b24cdd5b410fd8dddf6a8b763da2a), [`93477d0`](https://github.com/mastra-ai/mastra/commit/93477d0769b8a13ea5ed73d508d967fb23eaeed9), [`31c78b3`](https://github.com/mastra-ai/mastra/commit/31c78b3eb28f58a8017f1dcc795c33214d87feac), [`0bc0720`](https://github.com/mastra-ai/mastra/commit/0bc07201095791858087cc56f353fcd65e87ab54), [`36516ac`](https://github.com/mastra-ai/mastra/commit/36516aca1021cbeb42e74751b46a2614101f37c8), [`e947652`](https://github.com/mastra-ai/mastra/commit/e9476527fdecb4449e54570e80dfaf8466901254), [`3c6ef79`](https://github.com/mastra-ai/mastra/commit/3c6ef798481e00d6d22563be2de98818fd4dd5e0), [`9257d01`](https://github.com/mastra-ai/mastra/commit/9257d01d1366d81f84c582fe02b5e200cf9621f4), [`ec248f6`](https://github.com/mastra-ai/mastra/commit/ec248f6b56e8a037c066c49b2178e2507471d988)]:
14
+ - @mastra/core@1.9.0-alpha.0
15
+
16
+ ## 0.2.0
17
+
18
+ ### Minor Changes
19
+
20
+ - Added workspace and skill storage domains with full CRUD, versioning, and implementations across LibSQL, Postgres, and MongoDB. Added `editor.workspace` and `editor.skill` namespaces for managing workspace configurations and skill definitions through the editor. Agents stored in the editor can now reference workspaces (by ID or inline config) and skills, with full hydration to runtime `Workspace` instances during agent resolution. ([#13156](https://github.com/mastra-ai/mastra/pull/13156))
21
+
22
+ **Filesystem-native skill versioning (draft → publish model):**
23
+
24
+ Skills are versioned as filesystem trees with content-addressable blob storage. The editing surface (live filesystem) is separated from the serving surface (versioned blob store), enabling a `draft → publish` workflow:
25
+ - `editor.skill.publish(skillId, source, skillPath)` — Snapshots a skill directory from the filesystem into blob storage, creates a new version with a tree manifest, and sets `activeVersionId`
26
+ - Version switching via `editor.skill.update({ id, activeVersionId })` — Points the skill to a previous version without re-publishing
27
+ - Publishing a skill automatically invalidates cached agents that reference it, so they re-hydrate with the updated version on next access
28
+
29
+ **Agent skill resolution strategies:**
30
+
31
+ Agents can reference skills with different resolution strategies:
32
+ - `strategy: 'latest'` — Resolves the skill's active version (honors `activeVersionId` for rollback)
33
+ - `pin: '<versionId>'` — Pins to a specific version, immune to publishes
34
+ - `strategy: 'live'` — Reads directly from the live filesystem (no blob store)
35
+
36
+ **Blob storage infrastructure:**
37
+ - `BlobStore` abstract class for content-addressable storage keyed by SHA-256 hash
38
+ - `InMemoryBlobStore` for testing
39
+ - LibSQL, Postgres, and MongoDB implementations
40
+ - `S3BlobStore` for storing blobs in S3 or S3-compatible storage (AWS, R2, MinIO, DO Spaces)
41
+ - `BlobStoreProvider` interface and `MastraEditorConfig.blobStores` registry for pluggable blob storage
42
+ - `VersionedSkillSource` and `CompositeVersionedSkillSource` for reading skill files from the blob store at runtime
43
+
44
+ **New storage types:**
45
+ - `StorageWorkspaceSnapshotType` and `StorageSkillSnapshotType` with corresponding input/output types
46
+ - `StorageWorkspaceRef` for ID-based or inline workspace references on agents
47
+ - `StorageSkillConfig` for per-agent skill overrides (`pin`, `strategy`, description, instructions)
48
+ - `SkillVersionTree` and `SkillVersionTreeEntry` for tree manifests
49
+ - `StorageBlobEntry` for content-addressable blob entries
50
+ - `SKILL_BLOBS_SCHEMA` for the `mastra_skill_blobs` table
51
+
52
+ **New editor namespaces:**
53
+ - `editor.workspace` — CRUD for workspace configs, plus `hydrateSnapshotToWorkspace()` for resolving to runtime `Workspace` instances
54
+ - `editor.skill` — CRUD for skill definitions, plus `publish()` for filesystem-to-blob snapshots
55
+
56
+ **Provider registries:**
57
+ - `MastraEditorConfig` accepts `filesystems`, `sandboxes`, and `blobStores` provider registries (keyed by provider ID)
58
+ - Built-in `local` filesystem and sandbox providers are auto-registered
59
+ - `editor.resolveBlobStore()` resolves from provider registry or falls back to the storage backend's blobs domain
60
+ - Providers expose `id`, `name`, `description`, `configSchema` (JSON Schema for UI form rendering), and a factory method
61
+
62
+ **Storage adapter support:**
63
+ - LibSQL: Full `workspaces`, `skills`, and `blobs` domain implementations
64
+ - Postgres: Full `workspaces`, `skills`, and `blobs` domain implementations
65
+ - MongoDB: Full `workspaces`, `skills`, and `blobs` domain implementations
66
+ - All three include `workspace`, `skills`, and `skillsFormat` fields on agent versions
67
+
68
+ **Server endpoints:**
69
+ - `GET/POST/PATCH/DELETE /stored/workspaces` — CRUD for stored workspaces
70
+ - `GET/POST/PATCH/DELETE /stored/skills` — CRUD for stored skills
71
+ - `POST /stored/skills/:id/publish` — Publish a skill from a filesystem source
72
+
73
+ ```ts
74
+ import { MastraEditor } from '@mastra/editor';
75
+ import { s3FilesystemProvider, s3BlobStoreProvider } from '@mastra/s3';
76
+ import { e2bSandboxProvider } from '@mastra/e2b';
77
+
78
+ const editor = new MastraEditor({
79
+ filesystems: { s3: s3FilesystemProvider },
80
+ sandboxes: { e2b: e2bSandboxProvider },
81
+ blobStores: { s3: s3BlobStoreProvider },
82
+ });
83
+
84
+ // Create a skill and publish it
85
+ const skill = await editor.skill.create({
86
+ name: 'Code Review',
87
+ description: 'Reviews code for best practices',
88
+ instructions: 'Analyze the code and provide feedback...',
89
+ });
90
+ await editor.skill.publish(skill.id, source, 'skills/code-review');
91
+
92
+ // Agents resolve skills by strategy
93
+ await editor.agent.create({
94
+ name: 'Dev Assistant',
95
+ model: { provider: 'openai', name: 'gpt-4' },
96
+ workspace: { type: 'id', workspaceId: workspace.id },
97
+ skills: { [skill.id]: { strategy: 'latest' } },
98
+ skillsFormat: 'xml',
99
+ });
100
+ ```
101
+
102
+ ### Patch Changes
103
+
104
+ - Updated dependencies [[`252580a`](https://github.com/mastra-ai/mastra/commit/252580a71feb0e46d0ccab04a70a79ff6a2ee0ab), [`f8e819f`](https://github.com/mastra-ai/mastra/commit/f8e819fabdfdc43d2da546a3ad81ba23685f603d), [`5c75261`](https://github.com/mastra-ai/mastra/commit/5c7526120d936757d4ffb7b82232e1641ebd45cb), [`e27d832`](https://github.com/mastra-ai/mastra/commit/e27d83281b5e166fd63a13969689e928d8605944), [`e37ef84`](https://github.com/mastra-ai/mastra/commit/e37ef8404043c94ca0c8e35ecdedb093b8087878), [`6fdd3d4`](https://github.com/mastra-ai/mastra/commit/6fdd3d451a07a8e7e216c62ac364f8dd8e36c2af), [`10cf521`](https://github.com/mastra-ai/mastra/commit/10cf52183344743a0d7babe24cd24fd78870c354), [`efdb682`](https://github.com/mastra-ai/mastra/commit/efdb682887f6522149769383908f9790c188ab88), [`0dee7a0`](https://github.com/mastra-ai/mastra/commit/0dee7a0ff4c2507e6eb6e6ee5f9738877ebd4ad1), [`04c2c8e`](https://github.com/mastra-ai/mastra/commit/04c2c8e888984364194131aecb490a3d6e920e61), [`02dc07a`](https://github.com/mastra-ai/mastra/commit/02dc07acc4ad42d93335825e3308f5b42266eba2), [`bb7262b`](https://github.com/mastra-ai/mastra/commit/bb7262b7c0ca76320d985b40510b6ffbbb936582), [`cf1c6e7`](https://github.com/mastra-ai/mastra/commit/cf1c6e789b131f55638fed52183a89d5078b4876), [`5ffadfe`](https://github.com/mastra-ai/mastra/commit/5ffadfefb1468ac2612b20bb84d24c39de6961c0), [`1e1339c`](https://github.com/mastra-ai/mastra/commit/1e1339cc276e571a48cfff5014487877086bfe68), [`d03df73`](https://github.com/mastra-ai/mastra/commit/d03df73f8fe9496064a33e1c3b74ba0479bf9ee6), [`79b8f45`](https://github.com/mastra-ai/mastra/commit/79b8f45a6767e1a5c3d56cd3c5b1214326b81661), [`9bbf08e`](https://github.com/mastra-ai/mastra/commit/9bbf08e3c20731c79dea13a765895b9fcf29cbf1), [`0a25952`](https://github.com/mastra-ai/mastra/commit/0a259526b5e1ac11e6efa53db1f140272962af2d), [`ffa5468`](https://github.com/mastra-ai/mastra/commit/ffa546857fc4821753979b3a34e13b4d76fbbcd4), [`3264a04`](https://github.com/mastra-ai/mastra/commit/3264a04e30340c3c5447433300a035ea0878df85), [`6fdd3d4`](https://github.com/mastra-ai/mastra/commit/6fdd3d451a07a8e7e216c62ac364f8dd8e36c2af), [`088d9ba`](https://github.com/mastra-ai/mastra/commit/088d9ba2577518703c52b0dccd617178d9ee6b0d), [`74fbebd`](https://github.com/mastra-ai/mastra/commit/74fbebd918a03832a2864965a8bea59bf617d3a2), [`aea6217`](https://github.com/mastra-ai/mastra/commit/aea621790bfb2291431b08da0cc5e6e150303ae7), [`b6a855e`](https://github.com/mastra-ai/mastra/commit/b6a855edc056e088279075506442ba1d6fa6def9), [`ae408ea`](https://github.com/mastra-ai/mastra/commit/ae408ea7128f0d2710b78d8623185198e7cb19c1), [`17e942e`](https://github.com/mastra-ai/mastra/commit/17e942eee2ba44985b1f807e6208cdde672f82f9), [`2015cf9`](https://github.com/mastra-ai/mastra/commit/2015cf921649f44c3f5bcd32a2c052335f8e49b4), [`7ef454e`](https://github.com/mastra-ai/mastra/commit/7ef454eaf9dcec6de60021c8f42192052dd490d6), [`2be1d99`](https://github.com/mastra-ai/mastra/commit/2be1d99564ce79acc4846071082bff353035a87a), [`2708fa1`](https://github.com/mastra-ai/mastra/commit/2708fa1055ac91c03e08b598869f6b8fb51fa37f), [`ba74aef`](https://github.com/mastra-ai/mastra/commit/ba74aef5716142dbbe931351f5243c9c6e4128a9), [`ba74aef`](https://github.com/mastra-ai/mastra/commit/ba74aef5716142dbbe931351f5243c9c6e4128a9), [`ec53e89`](https://github.com/mastra-ai/mastra/commit/ec53e8939c76c638991e21af762e51378eff7543), [`9b5a8cb`](https://github.com/mastra-ai/mastra/commit/9b5a8cb13e120811b0bf14140ada314f1c067894), [`607e66b`](https://github.com/mastra-ai/mastra/commit/607e66b02dc7f531ee37799f3456aa2dc0ca7ac5), [`a215d06`](https://github.com/mastra-ai/mastra/commit/a215d06758dcf590eabfe0b7afd4ae39bdbf082c), [`6909c74`](https://github.com/mastra-ai/mastra/commit/6909c74a7781e0447d475e9dbc1dc871b700f426), [`192438f`](https://github.com/mastra-ai/mastra/commit/192438f8a90c4f375e955f8ff179bf8dc6821a83)]:
105
+ - @mastra/core@1.5.0
106
+
3
107
  ## 0.2.0-alpha.0
4
108
 
5
109
  ### Minor Changes
package/LICENSE.md CHANGED
@@ -1,3 +1,18 @@
1
+ Portions of this software are licensed as follows:
2
+
3
+ - All content that resides under any directory named "ee/" within this
4
+ repository, including but not limited to:
5
+ - `packages/core/src/auth/ee/`
6
+ - `packages/server/src/server/auth/ee/`
7
+ is licensed under the license defined in `ee/LICENSE`.
8
+
9
+ - All third-party components incorporated into the Mastra Software are
10
+ licensed under the original license provided by the owner of the
11
+ applicable component.
12
+
13
+ - Content outside of the above-mentioned directories or restrictions is
14
+ available under the "Apache License 2.0" as defined below.
15
+
1
16
  # Apache License 2.0
2
17
 
3
18
  Copyright (c) 2025 Kepler Software, Inc.
@@ -14,6 +14,8 @@ export interface S3BlobStoreOptions {
14
14
  accessKeyId: string;
15
15
  /** AWS secret access key */
16
16
  secretAccessKey: string;
17
+ /** AWS session token for temporary credentials (SSO, AssumeRole, container credentials, etc.) */
18
+ sessionToken?: string;
17
19
  /**
18
20
  * Custom endpoint URL for S3-compatible storage.
19
21
  * Examples:
@@ -72,6 +74,7 @@ export declare class S3BlobStore extends BlobStore {
72
74
  private readonly region;
73
75
  private readonly accessKeyId;
74
76
  private readonly secretAccessKey;
77
+ private readonly sessionToken?;
75
78
  private readonly endpoint?;
76
79
  private readonly forcePathStyle;
77
80
  constructor(options: S3BlobStoreOptions);
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/blob-store/index.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE7D;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,qBAAqB;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,wBAAwB;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,4BAA4B;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kFAAkF;IAClF,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAWD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,qBAAa,WAAY,SAAQ,SAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,OAAO,CAAyB;IAExC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAU;gBAE7B,OAAO,EAAE,kBAAkB;IAWvC,OAAO,CAAC,SAAS;IAcjB,OAAO,CAAC,KAAK;IAIP,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,GAAG,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB3C,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IA4BnD,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAiBnC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAiBtC,OAAO,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAOnD,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAcjE,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;CA6B3C"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/blob-store/index.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE7D;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,qBAAqB;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,wBAAwB;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,4BAA4B;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,iGAAiG;IACjG,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kFAAkF;IAClF,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAWD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,qBAAa,WAAY,SAAQ,SAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,OAAO,CAAyB;IAExC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAU;gBAE7B,OAAO,EAAE,kBAAkB;IAYvC,OAAO,CAAC,SAAS;IAejB,OAAO,CAAC,KAAK;IAIP,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,GAAG,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB3C,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IA4BnD,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAiBnC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAiBtC,OAAO,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAOnD,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAcjE,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;CA6B3C"}
@@ -16,6 +16,8 @@ export interface S3MountConfig extends FilesystemMountConfig {
16
16
  accessKeyId?: string;
17
17
  /** AWS secret access key */
18
18
  secretAccessKey?: string;
19
+ /** AWS session token for temporary credentials (SSO, AssumeRole, container credentials, etc.) */
20
+ sessionToken?: string;
19
21
  /** Mount as read-only */
20
22
  readOnly?: boolean;
21
23
  }
@@ -45,6 +47,12 @@ export interface S3FilesystemOptions extends MastraFilesystemOptions {
45
47
  * Optional - omit for public buckets (read-only access).
46
48
  */
47
49
  secretAccessKey?: string;
50
+ /**
51
+ * AWS session token for temporary credentials.
52
+ * Required when using SSO, AssumeRole, container credentials, or any other
53
+ * temporary credential provider.
54
+ */
55
+ sessionToken?: string;
48
56
  /**
49
57
  * Custom endpoint URL for S3-compatible storage.
50
58
  * Examples:
@@ -73,6 +81,7 @@ export declare class S3Filesystem extends MastraFilesystem {
73
81
  private readonly region;
74
82
  private readonly accessKeyId?;
75
83
  private readonly secretAccessKey?;
84
+ private readonly sessionToken?;
76
85
  private readonly endpoint?;
77
86
  private readonly forcePathStyle;
78
87
  private readonly prefix;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/filesystem/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/filesystem/index.ts"],"names":[],"mappings":"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"}
package/dist/index.cjs CHANGED
@@ -78,6 +78,7 @@ var S3Filesystem = class extends workspace.MastraFilesystem {
78
78
  region;
79
79
  accessKeyId;
80
80
  secretAccessKey;
81
+ sessionToken;
81
82
  endpoint;
82
83
  forcePathStyle;
83
84
  prefix;
@@ -89,6 +90,7 @@ var S3Filesystem = class extends workspace.MastraFilesystem {
89
90
  this.region = options.region;
90
91
  this.accessKeyId = options.accessKeyId;
91
92
  this.secretAccessKey = options.secretAccessKey;
93
+ this.sessionToken = options.sessionToken;
92
94
  this.endpoint = options.endpoint;
93
95
  this.forcePathStyle = options.forcePathStyle ?? !!options.endpoint;
94
96
  this.prefix = options.prefix ? trimSlashes(options.prefix) + "/" : "";
@@ -111,6 +113,9 @@ var S3Filesystem = class extends workspace.MastraFilesystem {
111
113
  if (this.accessKeyId && this.secretAccessKey) {
112
114
  config.accessKeyId = this.accessKeyId;
113
115
  config.secretAccessKey = this.secretAccessKey;
116
+ if (this.sessionToken) {
117
+ config.sessionToken = this.sessionToken;
118
+ }
114
119
  }
115
120
  if (this.readOnly) {
116
121
  config.readOnly = true;
@@ -218,7 +223,8 @@ var S3Filesystem = class extends workspace.MastraFilesystem {
218
223
  region: this.region,
219
224
  credentials: hasCredentials ? {
220
225
  accessKeyId: this.accessKeyId,
221
- secretAccessKey: this.secretAccessKey
226
+ secretAccessKey: this.secretAccessKey,
227
+ ...this.sessionToken && { sessionToken: this.sessionToken }
222
228
  } : (
223
229
  // Anonymous access for public buckets - use empty credentials
224
230
  // to prevent SDK from trying to find credentials elsewhere
@@ -602,6 +608,7 @@ var S3BlobStore = class extends storage.BlobStore {
602
608
  region;
603
609
  accessKeyId;
604
610
  secretAccessKey;
611
+ sessionToken;
605
612
  endpoint;
606
613
  forcePathStyle;
607
614
  constructor(options) {
@@ -610,6 +617,7 @@ var S3BlobStore = class extends storage.BlobStore {
610
617
  this.region = options.region;
611
618
  this.accessKeyId = options.accessKeyId;
612
619
  this.secretAccessKey = options.secretAccessKey;
620
+ this.sessionToken = options.sessionToken;
613
621
  this.endpoint = options.endpoint;
614
622
  this.forcePathStyle = options.forcePathStyle ?? !!options.endpoint;
615
623
  this.prefix = options.prefix ? trimSlashes2(options.prefix) + "/" : "mastra_skill_blobs/";
@@ -620,7 +628,8 @@ var S3BlobStore = class extends storage.BlobStore {
620
628
  region: this.region,
621
629
  credentials: {
622
630
  accessKeyId: this.accessKeyId,
623
- secretAccessKey: this.secretAccessKey
631
+ secretAccessKey: this.secretAccessKey,
632
+ ...this.sessionToken && { sessionToken: this.sessionToken }
624
633
  },
625
634
  endpoint: this.endpoint,
626
635
  forcePathStyle: this.forcePathStyle
@@ -761,6 +770,7 @@ var s3FilesystemProvider = {
761
770
  region: { type: "string", description: 'AWS region (use "auto" for R2)' },
762
771
  accessKeyId: { type: "string", description: "AWS access key ID" },
763
772
  secretAccessKey: { type: "string", description: "AWS secret access key" },
773
+ sessionToken: { type: "string", description: "AWS session token for temporary credentials" },
764
774
  endpoint: { type: "string", description: "Custom endpoint URL for S3-compatible storage" },
765
775
  forcePathStyle: { type: "boolean", description: "Force path-style URLs", default: false },
766
776
  prefix: { type: "string", description: "Key prefix (acts like a subdirectory)" },
@@ -781,6 +791,7 @@ var s3BlobStoreProvider = {
781
791
  region: { type: "string", description: 'AWS region (use "auto" for R2)' },
782
792
  accessKeyId: { type: "string", description: "AWS access key ID" },
783
793
  secretAccessKey: { type: "string", description: "AWS secret access key" },
794
+ sessionToken: { type: "string", description: "AWS session token for temporary credentials" },
784
795
  endpoint: { type: "string", description: "Custom endpoint URL for S3-compatible storage" },
785
796
  forcePathStyle: { type: "boolean", description: "Force path-style URLs", default: false },
786
797
  prefix: { type: "string", description: "Key prefix for blob objects (default: mastra_skill_blobs/)" }
@@ -1 +1 @@
1
- {"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 {\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 /** 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 access key ID.\n * Optional - omit for public buckets (read-only access).\n */\n accessKeyId?: string;\n /**\n * AWS secret access key.\n * Optional - omit for public buckets (read-only access).\n */\n secretAccessKey?: 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 accessKeyId?: string;\n private readonly secretAccessKey?: 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.accessKeyId = options.accessKeyId;\n this.secretAccessKey = options.secretAccessKey;\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 this.prefix = options.prefix ? trimSlashes(options.prefix) + '/' : '';\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 mount configuration for E2B sandbox.\n * Returns S3-compatible config that works with s3fs-fuse.\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 }\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 hasCredentials = this.accessKeyId && this.secretAccessKey;\n\n this._client = new S3Client({\n region: this.region,\n credentials: hasCredentials\n ? {\n accessKeyId: this.accessKeyId!,\n secretAccessKey: this.secretAccessKey!,\n }\n : // Anonymous access for public buckets - use empty credentials\n // to prevent SDK from trying to find credentials elsewhere\n { accessKeyId: '', secretAccessKey: '' },\n endpoint: this.endpoint,\n forcePathStyle: this.forcePathStyle,\n // Skip signing for anonymous access (public buckets).\n // No-op signer passes the request through unsigned. Uses `any` because\n // the correct type (HttpRequest from @smithy/types) is not a direct dependency.\n\n ...(hasCredentials ? {} : { signer: { sign: async (request: any) => request } }),\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 slash and add prefix\n const cleanPath = path.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 { 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 /** AWS access key ID */\n accessKeyId: string;\n /** AWS secret access key */\n secretAccessKey: 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 accessKeyId: string;\n private readonly secretAccessKey: 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.accessKeyId = options.accessKeyId;\n this.secretAccessKey = options.secretAccessKey;\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 this._client = new S3Client({\n region: this.region,\n credentials: {\n accessKeyId: this.accessKeyId,\n secretAccessKey: this.secretAccessKey,\n },\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 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 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"]}
1
+ {"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 {\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 /** 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 access key ID.\n * Optional - omit for public buckets (read-only access).\n */\n accessKeyId?: string;\n /**\n * AWS secret access key.\n * Optional - omit for public buckets (read-only access).\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 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.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 this.prefix = options.prefix ? trimSlashes(options.prefix) + '/' : '';\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 mount configuration for E2B sandbox.\n * Returns S3-compatible config that works with s3fs-fuse.\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.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 hasCredentials = this.accessKeyId && this.secretAccessKey;\n\n this._client = new S3Client({\n region: this.region,\n credentials: hasCredentials\n ? {\n accessKeyId: this.accessKeyId!,\n secretAccessKey: this.secretAccessKey!,\n ...(this.sessionToken && { sessionToken: this.sessionToken }),\n }\n : // Anonymous access for public buckets - use empty credentials\n // to prevent SDK from trying to find credentials elsewhere\n { accessKeyId: '', secretAccessKey: '' },\n endpoint: this.endpoint,\n forcePathStyle: this.forcePathStyle,\n // Skip signing for anonymous access (public buckets).\n // No-op signer passes the request through unsigned. Uses `any` because\n // the correct type (HttpRequest from @smithy/types) is not a direct dependency.\n\n ...(hasCredentials ? {} : { signer: { sign: async (request: any) => request } }),\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 slash and add prefix\n const cleanPath = path.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 { 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 /** 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 * 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 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.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 this._client = new S3Client({\n region: this.region,\n credentials: {\n accessKeyId: this.accessKeyId,\n secretAccessKey: this.secretAccessKey,\n ...(this.sessionToken && { sessionToken: this.sessionToken }),\n },\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"]}
package/dist/index.js CHANGED
@@ -76,6 +76,7 @@ var S3Filesystem = class extends MastraFilesystem {
76
76
  region;
77
77
  accessKeyId;
78
78
  secretAccessKey;
79
+ sessionToken;
79
80
  endpoint;
80
81
  forcePathStyle;
81
82
  prefix;
@@ -87,6 +88,7 @@ var S3Filesystem = class extends MastraFilesystem {
87
88
  this.region = options.region;
88
89
  this.accessKeyId = options.accessKeyId;
89
90
  this.secretAccessKey = options.secretAccessKey;
91
+ this.sessionToken = options.sessionToken;
90
92
  this.endpoint = options.endpoint;
91
93
  this.forcePathStyle = options.forcePathStyle ?? !!options.endpoint;
92
94
  this.prefix = options.prefix ? trimSlashes(options.prefix) + "/" : "";
@@ -109,6 +111,9 @@ var S3Filesystem = class extends MastraFilesystem {
109
111
  if (this.accessKeyId && this.secretAccessKey) {
110
112
  config.accessKeyId = this.accessKeyId;
111
113
  config.secretAccessKey = this.secretAccessKey;
114
+ if (this.sessionToken) {
115
+ config.sessionToken = this.sessionToken;
116
+ }
112
117
  }
113
118
  if (this.readOnly) {
114
119
  config.readOnly = true;
@@ -216,7 +221,8 @@ var S3Filesystem = class extends MastraFilesystem {
216
221
  region: this.region,
217
222
  credentials: hasCredentials ? {
218
223
  accessKeyId: this.accessKeyId,
219
- secretAccessKey: this.secretAccessKey
224
+ secretAccessKey: this.secretAccessKey,
225
+ ...this.sessionToken && { sessionToken: this.sessionToken }
220
226
  } : (
221
227
  // Anonymous access for public buckets - use empty credentials
222
228
  // to prevent SDK from trying to find credentials elsewhere
@@ -600,6 +606,7 @@ var S3BlobStore = class extends BlobStore {
600
606
  region;
601
607
  accessKeyId;
602
608
  secretAccessKey;
609
+ sessionToken;
603
610
  endpoint;
604
611
  forcePathStyle;
605
612
  constructor(options) {
@@ -608,6 +615,7 @@ var S3BlobStore = class extends BlobStore {
608
615
  this.region = options.region;
609
616
  this.accessKeyId = options.accessKeyId;
610
617
  this.secretAccessKey = options.secretAccessKey;
618
+ this.sessionToken = options.sessionToken;
611
619
  this.endpoint = options.endpoint;
612
620
  this.forcePathStyle = options.forcePathStyle ?? !!options.endpoint;
613
621
  this.prefix = options.prefix ? trimSlashes2(options.prefix) + "/" : "mastra_skill_blobs/";
@@ -618,7 +626,8 @@ var S3BlobStore = class extends BlobStore {
618
626
  region: this.region,
619
627
  credentials: {
620
628
  accessKeyId: this.accessKeyId,
621
- secretAccessKey: this.secretAccessKey
629
+ secretAccessKey: this.secretAccessKey,
630
+ ...this.sessionToken && { sessionToken: this.sessionToken }
622
631
  },
623
632
  endpoint: this.endpoint,
624
633
  forcePathStyle: this.forcePathStyle
@@ -759,6 +768,7 @@ var s3FilesystemProvider = {
759
768
  region: { type: "string", description: 'AWS region (use "auto" for R2)' },
760
769
  accessKeyId: { type: "string", description: "AWS access key ID" },
761
770
  secretAccessKey: { type: "string", description: "AWS secret access key" },
771
+ sessionToken: { type: "string", description: "AWS session token for temporary credentials" },
762
772
  endpoint: { type: "string", description: "Custom endpoint URL for S3-compatible storage" },
763
773
  forcePathStyle: { type: "boolean", description: "Force path-style URLs", default: false },
764
774
  prefix: { type: "string", description: "Key prefix (acts like a subdirectory)" },
@@ -779,6 +789,7 @@ var s3BlobStoreProvider = {
779
789
  region: { type: "string", description: 'AWS region (use "auto" for R2)' },
780
790
  accessKeyId: { type: "string", description: "AWS access key ID" },
781
791
  secretAccessKey: { type: "string", description: "AWS secret access key" },
792
+ sessionToken: { type: "string", description: "AWS session token for temporary credentials" },
782
793
  endpoint: { type: "string", description: "Custom endpoint URL for S3-compatible storage" },
783
794
  forcePathStyle: { type: "boolean", description: "Force path-style URLs", default: false },
784
795
  prefix: { type: "string", description: "Key prefix for blob objects (default: mastra_skill_blobs/)" }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/filesystem/index.ts","../src/blob-store/index.ts","../src/provider.ts"],"names":["message","trimSlashes","S3Client","PutObjectCommand","GetObjectCommand","isNotFoundError","HeadObjectCommand","DeleteObjectCommand","ListObjectsV2Command","DeleteObjectsCommand"],"mappings":"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","file":"index.js","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 {\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 /** 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 access key ID.\n * Optional - omit for public buckets (read-only access).\n */\n accessKeyId?: string;\n /**\n * AWS secret access key.\n * Optional - omit for public buckets (read-only access).\n */\n secretAccessKey?: 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 accessKeyId?: string;\n private readonly secretAccessKey?: 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.accessKeyId = options.accessKeyId;\n this.secretAccessKey = options.secretAccessKey;\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 this.prefix = options.prefix ? trimSlashes(options.prefix) + '/' : '';\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 mount configuration for E2B sandbox.\n * Returns S3-compatible config that works with s3fs-fuse.\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 }\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 hasCredentials = this.accessKeyId && this.secretAccessKey;\n\n this._client = new S3Client({\n region: this.region,\n credentials: hasCredentials\n ? {\n accessKeyId: this.accessKeyId!,\n secretAccessKey: this.secretAccessKey!,\n }\n : // Anonymous access for public buckets - use empty credentials\n // to prevent SDK from trying to find credentials elsewhere\n { accessKeyId: '', secretAccessKey: '' },\n endpoint: this.endpoint,\n forcePathStyle: this.forcePathStyle,\n // Skip signing for anonymous access (public buckets).\n // No-op signer passes the request through unsigned. Uses `any` because\n // the correct type (HttpRequest from @smithy/types) is not a direct dependency.\n\n ...(hasCredentials ? {} : { signer: { sign: async (request: any) => request } }),\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 slash and add prefix\n const cleanPath = path.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 { 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 /** AWS access key ID */\n accessKeyId: string;\n /** AWS secret access key */\n secretAccessKey: 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 accessKeyId: string;\n private readonly secretAccessKey: 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.accessKeyId = options.accessKeyId;\n this.secretAccessKey = options.secretAccessKey;\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 this._client = new S3Client({\n region: this.region,\n credentials: {\n accessKeyId: this.accessKeyId,\n secretAccessKey: this.secretAccessKey,\n },\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 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 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"]}
1
+ {"version":3,"sources":["../src/filesystem/index.ts","../src/blob-store/index.ts","../src/provider.ts"],"names":["message","trimSlashes","S3Client","PutObjectCommand","GetObjectCommand","isNotFoundError","HeadObjectCommand","DeleteObjectCommand","ListObjectsV2Command","DeleteObjectsCommand"],"mappings":"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","file":"index.js","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 {\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 /** 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 access key ID.\n * Optional - omit for public buckets (read-only access).\n */\n accessKeyId?: string;\n /**\n * AWS secret access key.\n * Optional - omit for public buckets (read-only access).\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 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.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 this.prefix = options.prefix ? trimSlashes(options.prefix) + '/' : '';\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 mount configuration for E2B sandbox.\n * Returns S3-compatible config that works with s3fs-fuse.\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.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 hasCredentials = this.accessKeyId && this.secretAccessKey;\n\n this._client = new S3Client({\n region: this.region,\n credentials: hasCredentials\n ? {\n accessKeyId: this.accessKeyId!,\n secretAccessKey: this.secretAccessKey!,\n ...(this.sessionToken && { sessionToken: this.sessionToken }),\n }\n : // Anonymous access for public buckets - use empty credentials\n // to prevent SDK from trying to find credentials elsewhere\n { accessKeyId: '', secretAccessKey: '' },\n endpoint: this.endpoint,\n forcePathStyle: this.forcePathStyle,\n // Skip signing for anonymous access (public buckets).\n // No-op signer passes the request through unsigned. Uses `any` because\n // the correct type (HttpRequest from @smithy/types) is not a direct dependency.\n\n ...(hasCredentials ? {} : { signer: { sign: async (request: any) => request } }),\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 slash and add prefix\n const cleanPath = path.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 { 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 /** 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 * 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 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.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 this._client = new S3Client({\n region: this.region,\n credentials: {\n accessKeyId: this.accessKeyId,\n secretAccessKey: this.secretAccessKey,\n ...(this.sessionToken && { sessionToken: this.sessionToken }),\n },\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"]}
@@ -1 +1 @@
1
- {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAEjF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAEvD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAExD,eAAO,MAAM,oBAAoB,EAAE,kBAAkB,CAAC,mBAAmB,CAmBxE,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,EAAE,iBAAiB,CAAC,kBAAkB,CAkBrE,CAAC"}
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAEjF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAEvD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAExD,eAAO,MAAM,oBAAoB,EAAE,kBAAkB,CAAC,mBAAmB,CAoBxE,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,EAAE,iBAAiB,CAAC,kBAAkB,CAmBrE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/s3",
3
- "version": "0.2.0-alpha.0",
3
+ "version": "0.2.1-alpha.0",
4
4
  "description": "S3-compatible filesystem provider for Mastra workspaces (AWS S3, Cloudflare R2, MinIO)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -25,16 +25,16 @@
25
25
  "devDependencies": {
26
26
  "@types/node": "22.19.7",
27
27
  "dotenv": "^17.2.3",
28
- "@vitest/coverage-v8": "4.0.12",
29
- "@vitest/ui": "4.0.12",
28
+ "@vitest/coverage-v8": "4.0.18",
29
+ "@vitest/ui": "4.0.18",
30
30
  "eslint": "^9.37.0",
31
31
  "tsup": "^8.5.1",
32
32
  "typescript": "^5.9.3",
33
- "vitest": "4.0.16",
34
- "@internal/lint": "0.0.59",
35
- "@internal/workspace-test-utils": "0.0.3",
36
- "@internal/types-builder": "0.0.34",
37
- "@mastra/core": "1.5.0-alpha.0"
33
+ "vitest": "4.0.18",
34
+ "@internal/lint": "0.0.63",
35
+ "@internal/types-builder": "0.0.38",
36
+ "@internal/workspace-test-utils": "0.0.7",
37
+ "@mastra/core": "1.9.0-alpha.0"
38
38
  },
39
39
  "peerDependencies": {
40
40
  "@mastra/core": ">=1.4.0-0 <2.0.0-0"