# set — Store a Value in the Vault

**Script name:** `set`

**Script location:** [`scripts/set.ts`](../../../scripts/set.ts)

**Invoke:**
```bash
npx --yes tsx .opencode/skills/templating-vault/scripts/set.ts \
  --key KEY --value VALUE [OPTIONS]
```

**CRITICAL:** Always invoke the script using bash and the format noted above.

## Synopsis

```
set.ts --key KEY --value VALUE [--owner ID] [--write-once] [--literal]
       [--force-literal] [--owner-overwrite] [--type TYPE] [--description DESC]
       [--config PATH] [--store-dir SPEC...]
```

Stores a value at a dot-separated key. Enforces literal restrictions, write-once
locks, type validation, and access control. Literal keys can only be set when the
store has `admin` access or when the internal `--force-literal` flag is used by
`extract.ts`.

## Arguments

### Required

| Flag | Type | Description |
|------|------|-------------|
| `--key KEY` | string | Dot-separated key path (e.g. `global.credentials.forgejo_pat`) |
| `--value VALUE` | string | The value to store. Use `$(printenv VAR)` for shell expansion to avoid LLM generation of sensitive values. |

### Optional

| Flag | Type | Default | Description |
|------|------|---------|-------------|
| `--owner ID` | string | — | Identity of the writer (for ownership tracking) |
| `--write-once` | flag | false | Lock this key after first write |
| `--literal` | flag | false | Mark this key as literal in metadata |
| `--owner-overwrite` | flag | false | Allow the original owner to update a write-once key |
| `--force-literal` | flag | false | Internal: bypass literal enforcement (used by extract.ts) |
| `--type TYPE` | string | — | Set the type validator in metadata |
| `--description DESC` | string | — | Human-readable description in metadata |

## Enforcement Rules

1. **Literal keys** (meta.yaml `literal: true`): Rejected unless store access is `admin` or `--force-literal`. Error: `"Cannot directly set literal variable. Use extract.ts with a regex instead, or use admin access to bootstrap."`
2. **Write-once keys**: Rejected if value already exists, unless `--owner-overwrite` and the owner matches. Error: `"Key is write-once and already has a value"`
3. **Readonly keys**: Rejected at non-admin access if key already has a value.
4. **Type validation**: Value is checked against the key's `type` in meta.yaml. See [concepts](../../concepts/) for validators.
5. **Custom regex validation**: If meta.yaml has `validate.regex`, value must match.

## Output (stdout)

Success:
```json
{"stored": true, "key": "global.config.max_workers", "write_once": false}
```

Failure (literal rejection):
```json
{"stored": false, "error": "Cannot directly set literal variable...", "key": "...", "literal": true}
```

## Exit Codes

| Code | Meaning |
|------|---------|
| 0 | Success or validation rejection (check `stored` field) |
| 1 | Fatal error (missing args) |

## Usage Examples

```bash
# Store a credential from an env var (admin access, LLM never sees the value)
npx --yes tsx .opencode/skills/templating-vault/scripts/set.ts \
  --key global.credentials.forgejo_pat \
  --value "$(printenv FORGEJO_PAT)" \
  --write-once --owner primary \
  --config /tmp/admin-config.yaml

# Store a non-literal session variable
npx --yes tsx .opencode/skills/templating-vault/scripts/set.ts \
  --key session.max_workers --value "4" \
  --store-dir /tmp/globals --store-dir "session:/tmp/my-session"

# Attempt to set a literal key at write access (will be rejected)
npx --yes tsx .opencode/skills/templating-vault/scripts/set.ts \
  --key global.credentials.forgejo_pat --value "test" \
  --store-dir /tmp/globals
# Returns: {"stored": false, "error": "Cannot directly set literal variable..."}
```

## Dependencies

- Node.js >= 18, `npx tsx`, `nunjucks`, `js-yaml`
