# Store and share files

import { Steps } from "@astrojs/starlight/components"
import Prereqs from "@docs/Prereqs.astro"
import UiWalkthrough from "@docs/UiWalkthrough.astro"
import ClientTabs from "@docs/ClientTabs.astro"

Create a file store, upload files to it, and attach it to a project so the agent can read and write persistent files across sessions. File stores materialize as real directories in the agent's sandbox. The agent sees them as a normal filesystem path, not an API.

<Prereqs>
  - A Ren account with at least one [project](/docs/deep-dives/concepts/compute/projects/) - [The CLI
  installed](/docs/developers/cli/) and paired, or a personal access token for the API and TypeScript calls
</Prereqs>

## In the UI

<UiWalkthrough>
  {/* TODO(demo): screen recording – creating a file store, uploading a file, and attaching it to a project, ~10s loop */}
</UiWalkthrough>

<Steps>

1. Navigate to your project's **Settings** tab.

2. Under **File stores**, click **Add file store**.

3. Choose an existing store or create a new one by entering a name.

4. Upload files to the store through the file browser.

5. The store is now attached. The next session on this project will see it as a directory.

</Steps>

## Programmatically

Create a file store, upload files, and attach it to a project. Each project can have multiple file stores, and each store can be shared across projects.

<ClientTabs clients={["cli", "api", "typescript"]}>
  <Fragment slot="cli">
    <Steps>
      1. Create a file store:

         ```bash
         ren file-stores create --name "project-data"
         ```

         The response includes the store `id` (e.g. `fst_abc123`).

      2. Upload a file to the store:

         ```bash
         ren file-stores files upload fst_abc123 \
           --path "data/config.json" \
           --file ./config.json
         ```

      3. Attach the store to a project:

         ```bash
         ren projects file-stores add prj_def456 \
           --file-store-id fst_abc123
         ```
    </Steps>

    List stores and their files:

    ```bash
    ren file-stores list
    ren file-stores files list fst_abc123
    ```

    Remove a file from the store:

    ```bash
    ren file-stores files remove fst_abc123 --path "data/config.json"
    ```

    Detach a store from a project:

    ```bash
    ren projects file-stores remove prj_def456 fst_abc123
    ```

  </Fragment>
  <Fragment slot="api">
    <Steps>
      1. Create a file store with `POST /api/file-stores`:

         ```bash
         curl -X POST https://api.renai.build/api/file-stores \
           -H "Authorization: Bearer $REN_PAT_TOKEN" \
           -H "Content-Type: application/json" \
           -d '{"name": "project-data"}'
         ```

         The response includes the store `id`.

      2. Upload a file (two-step: presign, then PUT):

         ```bash
         # Start the upload — get a presigned URL
         curl -X POST https://api.renai.build/api/file-stores/fst_abc123/files/uploads \
           -H "Authorization: Bearer $REN_PAT_TOKEN" \
           -H "Content-Type: application/json" \
           -d '{"path": "data/config.json", "contentType": "application/json"}'

         # PUT the file to the presigned URL returned above, then finalize:
         curl -X POST https://api.renai.build/api/file-stores/fst_abc123/files/finalize \
           -H "Authorization: Bearer $REN_PAT_TOKEN" \
           -H "Content-Type: application/json" \
           -d '{"path": "data/config.json"}'
         ```

      3. Attach the store to a project with `POST /api/projects/{id}/file-stores`:

         ```bash
         curl -X POST https://api.renai.build/api/projects/prj_def456/file-stores \
           -H "Authorization: Bearer $REN_PAT_TOKEN" \
           -H "Content-Type: application/json" \
           -d '{"fileStoreId": "fst_abc123"}'
         ```
    </Steps>

  </Fragment>
  <Fragment slot="typescript">
    Create a file store and attach it to a project:

    ```ts
    import { createRenClient, pat } from "@renai-labs/sdk"

    const client = createRenClient({
      baseUrl: "https://api.renai.build",
      auth: pat(process.env.REN_PAT_TOKEN!),
    })

    const { data: store, error } = await client.fileStore.create({
      body: { name: "project-data" },
    })
    if (error) throw error
    console.log(store.id) // "fst_abc123"

    await client.project.fileStore.add({
      path: { id: "prj_def456" },
      body: { fileStoreId: store.id },
    })
    ```

    Upload files with the CLI (`ren file-stores files upload`), or use the
    two-step presign-and-PUT flow shown in the API tab.

  </Fragment>
</ClientTabs>

File stores are scoped to an owner (org or user). One store per owner can be marked `isDefault`. It's automatically attached to new projects in that scope. When an agent modifies files in a store, the changes persist. The next session on the same project picks up where the last one left off.