# Skill: templating-vault

Secure variable storage, Nunjucks template rendering, and prompt-by-reference
protocol for LLM agent systems. Guarantees literal values (credentials, tokens)
cannot be corrupted by LLM text generation.

## Quick Reference

```
Scripts dir:     .opencode/skills/templating-vault/scripts/
Invoke pattern:  npx --yes tsx .opencode/skills/templating-vault/scripts/<name>.ts [flags]
Key separator:   dots  (global.credentials.forgejo_pat)
Template engine: Nunjucks (Jinja2-like: {{ var | default('x') }})
Default store:   /tmp/templating-vault/
```

## Decision Trees

### "I need to store or retrieve a value"

```
Store / retrieve a value?
│
├─ Store a value
│   ├─ Is the variable literal (credential, token, URL)?
│   │   ├─ YES, and I have the source text → use extract.ts
│   │   │   → [extract reference](./references/scripts/extract/)
│   │   ├─ YES, but I'm bootstrapping from env vars (admin access)
│   │   │   → use set.ts with admin config and $(printenv)
│   │   │   → [set reference](./references/scripts/set/)
│   │   └─ YES, but I only have the value in my context → BLOCKED
│   │       You must use extract.ts with a regex. Provide a regex
│   │       pattern and let the script extract from source text.
│   │
│   └─ NO (non-literal, inferred, or computed)
│       → use set.ts directly
│       → [set reference](./references/scripts/set/)
│
├─ Retrieve a value
│   → use get.ts
│   → [get reference](./references/scripts/get/)
│
├─ List keys under a prefix
│   → use list.ts
│   → [list reference](./references/scripts/list/)
│
└─ Delete a value
    → use delete.ts
    → [delete reference](./references/scripts/delete/)
```

### "I need to render a template or pass a prompt to a subagent"

```
Render a template / pass a prompt?
│
├─ Does the child agent know the templating-vault skill?
│   │
│   ├─ YES (vault-aware) → Prompt-by-reference protocol
│   │   │
│   │   │  Parent side:
│   │   ├─ 1. Store variables (set.ts / extract.ts)
│   │   ├─ 2. Prepare prompt: render.ts --prepare
│   │   │     → returns only an ID, prompt stored in vault
│   │   │     → [render reference](./references/scripts/render/)
│   │   └─ 3. Launch child with just the ID string
│   │
│   │      Child side:
│   │   ├─ 4. retrieve.ts --id → get prompt text + variable schema
│   │   │     → [retrieve reference](./references/scripts/retrieve/)
│   │   ├─ 5. For literal vars: extract.ts --source-key prepared.<id>
│   │   │     → [extract reference](./references/scripts/extract/)
│   │   ├─ 6. For non-literal vars: set.ts directly
│   │   └─ 7. Use get.ts to read values during execution
│   │
│   │   → Full workflow: [prompt-by-reference](./references/workflows/)
│   │
│   └─ NO (vault-unaware) → File mode
│       ├─ render.ts --output-file /tmp/prompt.txt
│       └─ Pass the file via --prompt-file to session_start.ts
│          (credentials in the file; corruption possible but unavoidable)
│
└─ I just need to evaluate a Nunjucks expression inline
    → Store it as a key with template: true in meta.yaml
    → get.ts evaluates it lazily on read
    → [concepts: computed values](./references/concepts/)
```

### "I need to configure data stores"

```
Configure stores?
│
├─ Quick: one default store
│   → --store-dir /tmp/my-store
│
├─ Multiple stores with prefix isolation
│   → --store-dir /tmp/default --store-dir "session:/tmp/agent-session"
│   → [configuration reference](./references/configuration/)
│
├─ Different agents need isolated session stores
│   → Same default store, different session: prefix per agent
│   → [agent isolation pattern](./references/configuration/)
│
├─ Bootstrap a store with metadata from a definition
│   → init.ts --source definition.yaml --target /tmp/store
│   → [init reference](./references/scripts/init/)
│
└─ Export a store's structure to YAML
    → export.ts --store-dir /tmp/store --output def.yaml
    → [export reference](./references/scripts/export/)
```

### "I need to understand a concept"

```
Concept?
│
├─ Key structure and on-disk layout       → [concepts](./references/concepts/)
├─ Metadata (literal, write_once, type)   → [concepts](./references/concepts/)
├─ Access levels (readonly/write/admin)   → [concepts](./references/concepts/)
├─ Type validators                        → [concepts](./references/concepts/)
├─ Literal vs non-literal enforcement     → [concepts](./references/concepts/)
├─ Computed values (template keys)        → [concepts](./references/concepts/)
├─ Template schema (schema.yaml)          → [concepts](./references/concepts/)
├─ Nunjucks syntax                        → [concepts](./references/concepts/)
│
├─ --store-dir syntax and prefix rules    → [configuration](./references/configuration/)
├─ Config cascading                       → [configuration](./references/configuration/)
├─ Prefix resolution (longest match)      → [configuration](./references/configuration/)
├─ Obscuring behavior                     → [configuration](./references/configuration/)
│
└─ Full prompt-by-reference workflow      → [workflows](./references/workflows/)
```

## Script Index

| Script | Purpose | Reference |
|--------|---------|-----------|
| `set.ts` | Store a value | [set/](./references/scripts/set/) |
| `get.ts` | Retrieve a value | [get/](./references/scripts/get/) |
| `extract.ts` | Extract via regex | [extract/](./references/scripts/extract/) |
| `list.ts` | List keys | [list/](./references/scripts/list/) |
| `render.ts` | Render template | [render/](./references/scripts/render/) |
| `retrieve.ts` | Get prepared prompt | [retrieve/](./references/scripts/retrieve/) |
| `delete.ts` | Delete a key | [delete/](./references/scripts/delete/) |
| `init.ts` | Bootstrap store | [init/](./references/scripts/init/) |
| `export.ts` | Export store | [export/](./references/scripts/export/) |
| `api.ts` | Shared module | [scripts overview](./references/scripts/) |
