# Context Snippets

Context Snippets let you teach Cai **per-app context** that gets injected into every AI action. Tell Cai about your workflow once, and every Summarize, Explain, Reply, or Custom Prompt from that app gets automatically smarter.

**The classic example:** when you select an error in Terminal, you’re probably debugging a specific codebase. When you select from Slack, you want a professional-but-casual reply. Context Snippets make Cai smart enough to know the difference, automatically, based on which app you selected from.

## Quick Start

### 1. Open the config file

The fastest path: **Settings → Personalization → Context Snippets → “Open snippets.json in Finder”**. Cai highlights the file for you — double-click to open in your default editor.

Or open it directly from Terminal:

```
open ~/.config/cai/snippets.json
```

On first launch, Cai creates the file with an empty template:

```
{
  "version": 1,
  "snippets": []
}
```

### 2. Find an app’s bundle ID

Context Snippets match apps by their **bundle ID** (e.g. `com.apple.Terminal`), not their display name. Bundle IDs are stable across macOS languages and app rebrands.

```
osascript -e 'id of app "Terminal"'
# → com.apple.Terminal

osascript -e 'id of app "Slack"'
# → com.tinyspeck.slackmacgap

osascript -e 'id of app "Visual Studio Code"'
# → com.microsoft.VSCode
```

### 3. Add a snippet

Edit `~/.config/cai/snippets.json`. Only three fields are required — `bundleId`, `appName`, and `context`:

```
{
  "version": 1,
  "snippets": [
    {
      "bundleId": "com.apple.Terminal",
      "appName": "Terminal",
      "context": "I'm debugging a Rails 7 app. Errors are usually from `rails logs`, `rspec`, or `bundle exec`. Assume Ruby/Rails context."
    }
  ]
}
```

Save the file.

**Optional fields:**

- `id` — a UUID. Auto-generated if omitted. Only matters once the v1.4 Settings UI ships edit functionality.
- `enabled` — defaults to `true` if omitted. Set to `false` to keep a snippet around without using it.

### 4. Restart Cai

**Important:** v1 reads `snippets.json` once at startup. Quit Cai (right-click menu bar → Quit) and relaunch. The next AI action from Terminal will use your snippet automatically.

## Example Snippets

Copy-paste these as starting points. Each snippet needs just three fields.

### Terminal — Rails/backend debugging

```
{
  "bundleId": "com.apple.Terminal",
  "appName": "Terminal",
  "context": "I work on a Rails 7 e-commerce app with Postgres and Sidekiq. When I copy from Terminal, the content is almost always from `rails logs`, `rspec`, `bundle exec`, or `git`. Assume Ruby/Rails context. Be concise — I just need the gist, not a tutorial."
}
```

### Mail — email replies

```
{
  "bundleId": "com.apple.mail",
  "appName": "Mail",
  "context": "When I copy from Mail, I'm drafting a reply to a coworker or client. Match the sender's tone — casual if they're casual, formal if they're formal. Keep replies to 2-3 short paragraphs max. No greetings or sign-offs unless the original message has them."
}
```

### Slack — team communication

```
{
  "bundleId": "com.tinyspeck.slackmacgap",
  "appName": "Slack",
  "context": "When I copy from Slack, I'm replying to a teammate. Match their tone. Keep it under 3 sentences unless the question needs more. Don't use emoji unless the sender used one first. We use BUG: / FEAT: / CHORE: prefixes when referencing issues."
}
```

### Visual Studio Code — code reviews

```
{
  "bundleId": "com.microsoft.VSCode",
  "appName": "Visual Studio Code",
  "context": "When I copy from VS Code, the content is source code or a code review comment. Explain code in plain English without dumbing it down. For reviews, be direct but constructive — point out real issues, suggest concrete improvements, no softening."
}
```

### GitHub Desktop — issue titles and PR descriptions

```
{
  "bundleId": "com.github.GitHubDesktop",
  "appName": "GitHub Desktop",
  "context": "When I copy from GitHub Desktop, I'm writing an issue title or PR description. Use BUG:, FEAT:, CHORE:, or DOCS: prefixes for titles. Keep titles under 60 characters. Descriptions follow the 'what / why / how' format."
}
```

### Safari — research and reading

```
{
  "bundleId": "com.apple.Safari",
  "appName": "Safari",
  "context": "When I copy from Safari, it's usually a blog post, article, or documentation I'm researching. Summarize for future reference — I want the key takeaway, not a rehash of the whole thing. Bullet points for multiple points, prose for single-idea content."
}
```

## Schema Reference

```
{
  "version": 1,
  "snippets": [
    {
      "bundleId": "<reverse-DNS app identifier>",
      "appName": "<display name shown in AI prompts>",
      "context": "<your instructions, ~500 chars works best>"
    }
  ]
}
```

### Rules

- Each `bundleId` should appear at most once. If you have duplicates, the first **enabled** one wins.
- The whole file loads once at startup. **Restart Cai for changes to take effect.**
- If the file has a JSON error, Cai keeps running normally — you just won’t get per-app enrichment until you fix the file.

## How It Works

When you trigger an AI action (Option+C → Summarize, Translate, Reply, etc.), Cai:

1. Captures the **bundle ID** of whatever app you copied from
2. Looks up an enabled snippet matching that bundle ID
3. If found, injects the snippet into the LLM system prompt as a structured section:

```
About the user: <your "About You" field, if set>

[App context: Terminal]
<your snippet's context text>

<the action's system prompt — e.g., "Output only the summary...">
```

### Layering: “About You” vs Context Snippets

Cai has two layers of personalization:

| Layer              | Where it lives                                   | Scope                     | Best for                                              |
|---------------------|--------------------------------------------------|---------------------------|-------------------------------------------------------|
| **About You**       | Settings → Personalization → About You          | Global (every action, every app)  | “I’m a backend engineer at an e-commerce company”    |
| **Context Snippets**| `~/.config/cai/snippets.json`                    | Per-app                   | ”When I copy from Terminal, assume Rails context”   |

Both layers stack automatically — your “About You” context is always present, and Context Snippets add per-app specifics on top. They never conflict.

## Troubleshooting

### ”I edited the file but nothing changed”

Did you restart Cai? v1 only reads `snippets.json` at startup. Quit Cai (right-click menu bar → Quit) and relaunch.

### ”Cai shows a toast about a JSON error”

Your file has a syntax error. Validate it with:

```
jq . ~/.config/cai/snippets.json
```

If `jq` reports an error, that’s the issue. Common causes:

- Missing comma between fields
- Trailing comma after the last item in an array
- Unquoted strings (every key and string value must be in `"double quotes"`)
- Invalid UUID in the optional `id` field (if present, must be `XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX` format — or omit the field entirely)

Fix the file, restart Cai, and the toast will go away.
