# Push and Pull

> Push and pull your secrets to and from Shelve.

`push` and `pull` sync secrets between your local `.env` file and Shelve. For day-to-day development — especially in **AI agent shells** — prefer [`shelve run`](/docs/cli/run) instead of `pull`.

## Push

Upload variables from your local env file to Shelve:

```bash [terminal]
shelve push
shelve push --env staging
shelve --non-interactive --yes push --env staging
shelve --json push --env staging
```

Reads variables from `envFileName` in `shelve.json` (default `.env`).

### Options

<field-group>
<field name="env" type="string">

Target environment. Defaults to `defaultEnv` in `shelve.json` or `SHELVE_DEFAULT_ENV`.

</field>

<field name="path" type="string">

In a monorepo, push only this package instead of every one.

</field>

<field name="yes" type="boolean">

Skip confirmation when `confirmChanges` is `true` in config. Also respects global `--yes`.

</field>
</field-group>

JSON output: `{ "env", "variableCount", "pushed" }` (no secret values).

## Pull

Download variables from Shelve to your local env file:

```bash [terminal]
shelve pull
shelve pull --env production
shelve pull --env production --yes
```

### AI-agent guard

When the CLI detects an AI agent shell (Cursor, Claude Code, Codex, …) or `AI_AGENT` is set, **pull fails with AGENT_BLOCKED** unless you pass `--yes`:

```bash [terminal]
# Explicit opt-in only — secrets will be written to disk
shelve pull --yes --env development
```

<callout type="warning">

Plaintext `.env` files can be read by AI agents. Run [`shelve init`](/docs/cli/init) and prefer [`shelve run`](/docs/cli/run).

</callout>

### Options

<field-group>
<field name="env" type="string">

Source environment.

</field>

<field name="path" type="string">

In a monorepo, pull only this package instead of every one.

</field>

<field name="yes" type="boolean">

Skip the agent disk-write confirmation and `confirmChanges` prompts.

</field>
</field-group>

JSON output: `{ "env", "variableCount", "file", "keys[]", "pullMode", "preservedLocalKeys[]" }` — values are never included.

## Monorepos

Run from the workspace root and both commands visit every package that has its own `shelve.json`:

```bash [terminal]
shelve pull
shelve pull --path apps/web
```

JSON output then becomes `{ "packages": [...] }`, one entry per package with its `path`. See [Monorepo support](/docs/cli#monorepo-support).

## Default environment

Set `defaultEnv` to skip passing `--env` every time:

```json [shelve.json]
{
  "defaultEnv": "development",
  "slug": "my-team",
  "project": "my-app"
}
```

## confirmChanges

When `confirmChanges: true` in `shelve.json`, push and pull ask before writing. Skip with `--yes` or global `--yes` / `--non-interactive` automation flags.

## Sync policies

Configure **who wins** when local and Shelve differ, block pushes to production, or merge on pull. See [Sync policies](/docs/cli/sync-policies).

```bash [terminal]
shelve diff --env staging
shelve push --env staging
shelve sync --dry-run --env production
```
