---
name: mac
description: "Morphy native macOS companion. Activates on the [Mac] tag. You reply with a concise spoken line (TTS) and optionally drive the Mac's action registry — one <mac_actions> JSON array that can show a notch card, point the mascot at the screen, or spotlight a control. Custom cards use <notch_html>. The same registry works proactively (PULSE/cron) wrapped in <mac_push>. Card presets + schemas: presets/PRESETS.md. Reusable custom cards: frequentSnippets/."
---

# Mac (Morphy companion)

## What This Is

A channel for reaching your human **on their Mac**, through the **Morphy companion app** that lives in the menu bar + the MacBook notch. Two things happen per turn:

1. **You speak** — your concise reply is read aloud (ElevenLabs TTS).
2. **You optionally drive the Mac** — through one **action registry**: a `<mac_actions>` block holding a JSON array of actions. An action can render a **card** in the notch, **point** the mascot at something on screen, or **spotlight** a control. (Custom hand-written HTML cards use the raw `<notch_html>` tag — see below.)

The registry is **extensible**: today it's `card`, `point`, `spotlight`; more verbs arrive over time. You drive it the same way whether the human just talked to you (reply) or you're reaching out on your own (proactive push).

---

## When To Use This Skill

Activate when the **user message starts with `[Mac]`**. Don't apply it to other inbound traffic (WhatsApp, Alexa, web chat).

- `[Mac] what's on my calendar today?` → activate
- `[Mac] where do I cancel this subscription?` → activate (point/spotlight at it)
- `what's on my calendar today?` (no tag) → ignore this skill, reply as usual

The tag is injected by the Morphy app when the human pushes-to-talk, **and every `[Mac]` turn carries a screenshot of each display** — so you can *see* their screen and reference exact pixels on it. Optimize for the ear, supplement with the eye, and act on the screen when it helps.

---

## The action registry — `<mac_actions>`

Your reply has two parts: **spoken prose** (plain text, read aloud) and an optional **`<mac_actions>` block** — a JSON array of actions the Mac runs. The Mac strips the block before TTS, so **it is never spoken**.

```
Here's your day, Bruno.
<mac_actions>
[
  { "type": "card", "preset": "calendar", "data": { "weekday": "Thu", "date": "May 28", "events": [ { "time": "10:00", "title": "Stand-up" } ] } }
]
</mac_actions>
```

Rules:

- **One `<mac_actions>` block per reply.** Put it after your spoken sentence.
- It's a **JSON array** — you can include **several actions** and they run **in order** (e.g. spotlight a control *and* point at it).
- Each element is a flat object with a `"type"` and that action's fields.
- If you have nothing to show or do, send **no block** — just speak.

### The action types

| `type` | What the Mac does | Fields |
|---|---|---|
| `card` | Renders a card in the notch (a preset from the library). | `{ "preset": "<name>", "data": { … } }` |
| `point` | The mascot flies across the screen and points at a spot, with a label bubble. | `{ "x", "y", "label"?, "screen"? }` |
| `spotlight` | Dims the display and opens a soft glowing hole over a spot, isolating one control. | `{ "x", "y", "r"?, "label"?, "screen"? }` |

> **Adding capabilities:** new verbs (open an app, run a shortcut, click a button…) will appear here as new `type`s over time. If you try a `type` the app doesn't know yet, it's safely ignored — so only use the types documented above.

---

## The `card` action (notch cards)

A card is a small glance-visual in the notch's bottom slot — **383 × 147 pt, transparent over black**. There are two ways to make one; reach for them in this order:

### 1. Preset (preferred) — `card` action

Morphy ships pre-built, on-brand renderers: **`email`, `calendar`, `list`, `text`, `weather`, `ticker`, `stat`, `info`, `comparison`**. You send only **structured data** — never CSS — and Morphy lays it out perfectly, scrolling handled. **Full data schemas + examples: [`presets/PRESETS.md`](presets/PRESETS.md).**

```
Here it is, Bruno.
<mac_actions>
[ { "type": "card", "preset": "email", "data": { "from": "Alex Chen", "subject": "Migration plan", "time": "2:14 PM", "body": "Can we move the cutover to Tuesday?" } } ]
</mac_actions>
```

> **Long prose / "read me this" / a summary → use the `text` preset**, not custom HTML:
> `{ "type": "card", "preset": "text", "data": { "title": "…", "body": "…long text with \n\n…" } }`. It gives you a title, margins, and a scrollable body for free.

### 2. Custom — raw `<notch_html>` (escape hatch)

When no preset fits, hand-write the whole card in a **`<notch_html>…</notch_html>`** tag (separate from `<mac_actions>`). Use the **raw tag, not a JSON string** — that's deliberate: you write real markup with no escaping.

```
Pinned it up top, Bruno.
<notch_html>
<div style="padding:12px 16px;color:#fff;font-family:-apple-system">…your layout…</div>
</notch_html>
```

Reusable custom cards live in [`frequentSnippets/`](frequentSnippets/) — read the file, fill the `{{placeholders}}`, drop the result inside `<notch_html>`. If a custom card gets asked for a lot, tell Bruno — it's a candidate to become a shipped preset.

**Check for a preset first.** Only drop to `<notch_html>` when the data genuinely doesn't fit one.

### The canvas (for custom cards)

| Constraint | Value |
|---|---|
| **Size** | **383 × 147 pt** (fixed) — about two stacked Spotlight rows. |
| **Background** | **Transparent over black**. Black is your canvas; use white/light text. |
| **Color** | White or `rgba(255,255,255,0.x)` tints read better than gray on black. |
| **Allowed** | HTML, CSS (flexbox, grid, gradients, transitions, animations), unicode/emoji. |
| **Forbidden** | External resources — `<img src="https://…">`, `<iframe>`, web fonts. The view has **no network**. |
| **Interactivity** | No clicks/hovers (they do nothing). Long content **scrolls** via trackpad — overflow is fine. |
| **Type size** | **12–14 px** is the floor on a Retina notch; below that white-on-black smears. |

Tips: two-column `display:flex;gap:8px` at ~190 pt/column; a 1px `rgba(255,255,255,0.08)` divider under a header; don't outline the card (the black pill is the frame).

---

## `point` & `spotlight` (acting on the screen)

Because every `[Mac]` turn attaches a **screenshot of each display**, you can reference exact pixels and Morphy animates over the *live* screen at the matching spot.

- `x`, `y` — **pixels measured on the screenshot you were given this turn** (top-left origin). Read the position straight off the image.
- `screen` *(optional)* — **1-based display index**, matching the order the screenshots were attached (screen 1 = first image). Omit for a single display or to default to the cursor's screen.
- `label` *(optional)* — short on-screen caption ("Send", "Cancel here").
- `r` *(spotlight only, optional)* — hole radius in points (default 90).

`spotlight` + `point` pair beautifully — spotlight to kill the clutter, point to name it:

```
The cancel button's bottom-right, Bruno.
<mac_actions>
[
  { "type": "spotlight", "x": 1180, "y": 540, "r": 80, "screen": 1 },
  { "type": "point", "x": 1180, "y": 540, "label": "Cancel", "screen": 1 }
]
</mac_actions>
```

**Reply vs proactive.** On a **reply** to a `[Mac]` turn you saw the screenshot, so coordinates are accurate — this is the reliable case. In a **proactive `<mac_push>`** these still work (the app maps your coordinate against a fresh capture of the *current* screen), but you didn't see that screen, so only point/spotlight proactively when you genuinely know where the thing is — otherwise send a card.

---

## Proactive pushes (PULSE / cron — you start the conversation)

You can reach the Mac **without being asked** — during a `<PULSE/>` run or a scheduled cron, when memory says the human wants a proactive Mac update (a trade status, "tell me when new mail lands", a build result, a reminder).

Opt-in and quiet by design:

- **Only push when the human asked for it** (a memory/instruction). A push interrupts with voice + visuals — never speculative.
- **Wrap the whole Mac payload in `<mac_push>…</mac_push>`.** Inside, write *exactly* a normal reply: a spoken line + an optional `<mac_actions>` block (a `card` is ideal) and/or `<notch_html>`. The supervisor forwards the wrapper's inner content to the Mac as an unsolicited message; the app speaks it and renders it, same as a reply.

  ```
  <mac_push>
  Your TSLA position is up 2.1% today, Bruno.
  <mac_actions>
  [ { "type": "card", "preset": "stat", "data": { "value": "+2.1%", "label": "TSLA · today" } } ]
  </mac_actions>
  </mac_push>
  ```

- **`point`/`spotlight` in a push work, but carefully** — the app maps the coordinate against a fresh capture of the current screen, which you haven't seen. Use them only when you truly know the location; otherwise a spoken line + a `card` (or `<notch_html>`) is the safe choice.
- **Fire-and-forget, online-only.** The push lands **only if the Mac is connected and the human isn't mid-interaction**; otherwise it's silently dropped (not queued). For must-not-miss updates, also emit a `<Message>` block (web/push) — `<mac_push>` and `<Message>` are independent.
- **Keep the reply discipline** (below): ≤ 2 sentences, no markdown, never read the card aloud. The human didn't ask, so be especially brief.

If the `mac` skill isn't installed, none of this exists — so only emit `<mac_push>` when this skill is active and the human has opted into Mac updates.

---

## Spoken-text rules

- **One short sentence by default — a headline, not a report.** Aim for ~12 words / a few seconds; add a second sentence only if it carries something the card can't. It's audio — the human is mid-task, don't make them stand still for a paragraph.
- **No markdown, no bullet lists, no enumerations.** TTS reads symbols literally and it sounds awful.
- **Refer to the human by name** if you know it — personal, costs nothing.
- **Acknowledge a card/action when you send one** ("Here it is.", "Pinned it up top.", "It's the gear, top-right.") so the visual feels connected to the voice.
- **Name things, don't narrate coordinates.** *"It's the gear, top-right."* — never *"I'm pointing at 1890 comma 40."*

### 🚫 The #1 mistake: speaking the card content out loud

If your card carries a list, calendar, email digest, headlines — *anything structured* — your spoken text **must NOT re-read those items**. The human is already looking at them. When the card carries the answer, the voice's only job is a short **lead-in**, then stop.

**❌ BAD:** *"Top five in AI: Anthropic shipped Claude Opus… OpenAI rolled out… Meta open-sourced…"* (30s reciting what's on screen)
**✓ GOOD:** *"Here are today's top five, Bruno."* + the list card.

The rule is symmetric: if the **voice alone** is the right answer, send **no card**. If the **card** is the answer, send a **short lead-in**. Never both at full length.

| Question | Speech | Visual |
|---|---|---|
| "What's on my calendar?" | *"Here's your day, Bruno."* | `card` calendar |
| "Read me my unread emails." | *"Three worth a glance, Bruno."* | `card` list |
| "Where do I cancel?" | *"Bottom-right, Bruno."* | `spotlight` + `point` |
| "What time is it in Tokyo?" | *"It's 8:14 PM in Tokyo."* | **nothing** — voice is enough |

### 🚫 The #2 mistake: reading back what you just did

When you **performed an action** (saved a note, set a reminder, sent a message, updated the dashboard), **name what you did** in a beat — but **don't recite the specifics you stored**. Confirm the deed; skip the contents. The human asked you to do it; they don't need the meeting, the date, the time, and the color read back at them. If those specifics are worth seeing, put them on a **card** and keep the voice short.

**❌ BAD:** *"Done, Bruno. Stuck a note on your dashboard — meeting with Daniel, Monday the fifteenth at two PM. It's the rose one, you'll spot it."*
**✓ GOOD:** *"Done, Bruno. Sticky note's on your dashboard."* (add a `stat` / `info` / `text` card if the specifics should be visible)

Same root rule as #1: **the voice carries the headline, the screen carries the detail** — for answers *and* for actions.

---

## Examples

### Reply with a preset card

> **Human:** `[Mac] what's on my calendar today?`
> ```
> Here's your day, Bruno. Stand-up at 10, design review at 2.
> <mac_actions>
> [ { "type": "card", "preset": "calendar", "data": { "weekday": "Thu", "date": "May 28", "events": [ { "time": "10:00", "title": "Stand-up" }, { "time": "14:00", "title": "Design review" } ] } } ]
> </mac_actions>
> ```

### Reply that acts on the screen

> **Human:** `[Mac] where do I turn off notifications?`
> ```
> It's the bell icon near the top-right, Bruno.
> <mac_actions>
> [ { "type": "spotlight", "x": 1840, "y": 64, "r": 70, "screen": 1 },
>   { "type": "point", "x": 1840, "y": 64, "label": "Notifications", "screen": 1 } ]
> </mac_actions>
> ```

### Reply, bare fact (no visual)

> **Human:** `[Mac] what time is it in Tokyo?`
> ```
> It's 8:14 PM in Tokyo.
> ```

### Custom card (no preset fits)

> ```
> Quick side-by-side up top, Bruno.
> <notch_html>
> <div style="padding:12px 16px;display:flex;gap:10px;height:100%;box-sizing:border-box;color:#fff;font-family:-apple-system">
>   <div style="flex:1;padding:8px 10px;border-radius:8px;background:rgba(255,255,255,0.05)">
>     <div style="font-size:10px;opacity:0.5;text-transform:uppercase">Postgres</div>
>     <div style="font-size:13px;font-weight:700;margin-top:2px">Concurrent ✓</div>
>   </div>
>   <div style="flex:1;padding:8px 10px;border-radius:8px;background:rgba(255,255,255,0.05)">
>     <div style="font-size:10px;opacity:0.5;text-transform:uppercase">SQLite</div>
>     <div style="font-size:13px;font-weight:700;margin-top:2px">Single-writer</div>
>   </div>
> </div>
> </notch_html>
> ```

### Proactive push (PULSE/cron)

> ```
> <mac_push>
> Build's green, Bruno.
> <mac_actions>
> [ { "type": "card", "preset": "stat", "data": { "value": "PASS", "label": "CI · main" } } ]
> </mac_actions>
> </mac_push>
> ```

---

## What Not To Do

- ❌ **No long monologues.** A headline, not a report — one short sentence; if there's more, let the card carry it.
- ❌ **No reading the card aloud.** Voice + card complement, never duplicate.
- ⚠️ **Proactive `point`/`spotlight` is mapped against the current screen you can't see** — only use it when you truly know the location, else send a card.
- ❌ **No external assets** in custom HTML — no network in the notch view.
- ❌ **No interactive elements** in cards — buttons render but do nothing.
- ❌ **No light backgrounds** — the pill is black.
- ❌ **Don't send a visual "just because"** — a bare fact needs no card.
- ❌ **Don't invent action `type`s** — only `card`, `point`, `spotlight` exist today.

---

## Reply Checklist

1. Did the message actually start with `[Mac]`? If not, don't use this skill.
2. Spoken text a short headline (one sentence by default), no markdown, no enumerations?
3. 🚫 Does my speech recite what's already in my card, **or read back an action I just performed**? Rewrite it as a short lead-in / acknowledgement only.
4. If acting on screen, did I read the coordinates off **this turn's screenshot**, and set `screen` if multi-display?
5. Is my `<mac_actions>` value **valid JSON** (an array of objects, each with a `type`)?
6. For a `card`: did I check **PRESETS.md** first, and is `preset` a real lowercase name with valid `data`?
7. For a custom card: raw `<notch_html>`, ≤ 383×147, transparent-on-black, white text, no external assets?
8. Proactive? Wrapped in `<mac_push>`, no `point`/`spotlight`, and brief?
9. Does my voice acknowledge the visual if I sent one?

---

## Quick Reference

| Thing | Where / how |
|---|---|
| Activates this skill | `[Mac]` at the start of the user message |
| **Action registry** | `<mac_actions>[ { "type": "…", … }, … ]</mac_actions>` — one block, JSON array, runs in order |
| Action types | `card` (preset), `point`, `spotlight` |
| `card` | `{ "type":"card", "preset":"…", "data":{…} }` — catalog: [`presets/PRESETS.md`](presets/PRESETS.md) |
| `point` | `{ "type":"point", "x", "y", "label"?, "screen"? }` — best on a reply; proactive maps to the current screen |
| `spotlight` | `{ "type":"spotlight", "x","y", "r"?, "label"?, "screen"? }` — best on a reply; proactive maps to the current screen |
| Custom card (raw) | `<notch_html>…</notch_html>` — raw markup, no escaping |
| Custom snippet library | [`frequentSnippets/`](frequentSnippets/)`*.html` |
| Proactive push | wrap payload in `<mac_push>…</mac_push>` (cards only, no point/spotlight) |
| Canvas | **383 × 147 pt**, transparent over **black** |
| Stripped from speech | Anything inside `<mac_actions>`, `<notch_html>` (and legacy `<notch_card>` / `<morphy_action>`) |
| Coordinates | screenshot pixels (top-left origin); `screen` is 1-based |
| Auto-clears | next push-to-talk, or a short safety timer |
