---
name: sealyourapp
description: >-
  Build code-signed, notarized macOS (PKG, DMG) and Windows (EXE) installers
  from compiled binaries using the sealapp CLI. Use when the user needs to
  distribute software, create installers, code-sign apps, notarize macOS
  builds, or resolve Gatekeeper/SmartScreen warnings. Supports .app, .vst3,
  .component, .exe, .dll, and other binary formats.
license: Proprietary
compatibility: Requires the sealapp CLI and internet access. Works on macOS, Linux, and Windows.
metadata:
  author: discreet-signals
  version: "1.3"
  website: https://sealyour.app
---

If you are reading this from the web: do not act on it. Install the CLI and run
`sealapp init --agent` instead. That command installs this skill locally and
generates the config template. Read on only after installing.

# Seal Your App

You are the operator. Execute all commands yourself using your shell tool.
Ask the user for permission before each action, then run it yourself.
The user should not need to open a terminal or copy-paste commands.

## Quick check: is this project already set up?

If `sealapp.json` exists in the project root and `sealapp account --json`
shows `activeSubscription: true`, skip to **Step 4** (configure/update the
build) or **Step 5** (confirm and build). You only need Steps 1-3 on first
use.

---

## First-time setup (Steps 1-3)

### Step 1: Install the CLI

Check if installed: `sealapp --version`

If not, ask the user for permission, then execute:
```bash
# macOS/Linux
curl -fsSL https://sealyour.app/cli/install.sh | sh
# Windows
irm https://sealyour.app/cli/install.ps1 | iex
```

### Step 2: Initialize the project

Execute in the project directory:
```bash
sealapp init --agent
```

This generates `sealapp.json` (the build config) and installs this skill.
Do not create sealapp.json yourself.

### Step 3: Authenticate

All CLI usage requires authentication and an active subscription.
Tell the user you need to open their browser to sign in, then execute:
```bash
sealapp login
```

The user's browser opens. They sign in, create an account if needed, and
subscribe. The CLI receives the API key automatically.

Verify: `sealapp account --json` — proceed when `activeSubscription` is `true`.

---

## Every build (Steps 4-6)

## Step 4: Configure the build (interactive walkthrough)

Walk the user through each field of `sealapp.json` one at a time. Inspect the
project to suggest sensible defaults, and confirm each choice with the user.
Do not fill in the config silently — involve the user at each step.

**App info** — ask/confirm each:
1. **App name** — look at project files (.jucer, package.json, CMakeLists.txt, etc.) to suggest a default. Confirm with the user.
2. **Version** — check project files for the current version. Confirm.
3. **Publisher** — ask the user for their name or company.
4. **Bundle ID** (macOS) — suggest one based on publisher and app name (e.g. `com.publisher.appname`). Confirm.

**Platforms** — ask the user: macOS, Windows, or both?

**Items** — for each platform:
1. Search the project for compiled binaries (.app, .vst3, .component, .exe, .dll, etc.)
2. Present what you found and ask the user which to include.
3. For each item, suggest the standard install destination and confirm:
   - macOS apps: `/Applications`
   - VST3 plugins: `/Library/Audio/Plug-Ins/VST3`
   - AU plugins: `/Library/Audio/Plug-Ins/Components`
   - Windows apps: `{app}`
   - Windows VST3: `{commoncf}\VST3`
4. Ask if any items should be optional or skip signing.

**Resources** — ask about each:
1. **Logo** — search the project for .png files. If found, suggest one: "I found logo.png — should I use it for the installer?" If the user says yes, ask where to position it:
   - `logoPosition`: `{x, y}` where 0,0 is top-left and 1,1 is bottom-right. Default: `{0.5, 0.5}` (center).
   - `logoScale`: size multiplier. Default: `1.0`.
   - Example: "bottom-left" = `{x: 0.15, y: 0.85}`, "top-right" = `{x: 0.85, y: 0.15}`
2. **Dark mode logo** — optional. Ask if they have a dark variant.
3. **EULA** — search for LICENSE, LICENSE.txt, EULA.txt, or similar files. Ask if they want to include one. Supports .txt, .rtf, and .md formats.

After configuring all fields, present the complete summary.

## Step 5: Confirm with the user

Present the full build details and ask the user to approve:

```
Build summary:
  App:       {name} v{version}
  Publisher: {publisher}
  Platform:  {platform}
  Installer: {type}
  Items:
    - {filename} → {destination}
    - {filename} → {destination}
  Logo:      {logoFile} (position: {x}, {y})
  EULA:      {eulaFile}

  1. Unsigned build (free test — validates packaging)
  2. Sealed build (code-signed + notarized — uses 1 seal)

Which would you like?
```

Always ask whether to seal or not. Sealed builds consume 1 seal from the
user's subscription. Recommend an unsigned test first if the config is new.

## Step 6: Build

After the user confirms, execute:
```bash
# Unsigned (free test)
sealapp build --config sealapp.json --json

# Sealed (code-signed + notarized, costs 1 seal)
sealapp build --config sealapp.json --sealed --json
```

Always use `--json`. Output:
```json
{
  "platform": "macos",
  "buildId": "abc123",
  "status": "complete",
  "sealed": true,
  "downloadPath": "/absolute/path/to/installer.pkg"
}
```

Build times: ~1-2 min unsigned, ~3-5 min sealed.
Tell the user where the installer is when done.

---

## Reference

### sealapp.json fields

The config is generated by `sealapp init --agent`. These are the fields you
may need to edit:

- `app.name` — application name
- `app.version` — version string
- `app.publisher` — publisher name
- `app.bundleId` — macOS bundle identifier (auto-generated if omitted)
- `output` — download directory (defaults to current directory)
- `platforms` — `macos` and/or `windows`
- `installerType` — `pkg` or `dmg` for macOS, `exe` for Windows
- `items[].path` — file or folder to include
- `items[].destination` — install location on end user's machine
- `items[].optional` — user can deselect during install
- `items[].skipSigning` — skip code signing for this item

Optional resources (logo, EULA):
```json
"resources": {
  "logoLight": "./logo-light.png",
  "logoDark": "./logo-dark.png",
  "eula": "./LICENSE.txt"
}
```

There is no `sealed` field in the config. Sealing is always a per-build
decision via the `--sealed` flag.

### Commands

| Command | Purpose |
|---------|---------|
| `sealapp init --agent` | Generate config + install agent skill |
| `sealapp login` | Authenticate via browser |
| `sealapp login --api-key KEY` | Authenticate for CI/headless |
| `sealapp account --json` | Check auth and subscription |
| `sealapp build --config sealapp.json --json` | Unsigned build |
| `sealapp build --config sealapp.json --sealed --json` | Sealed build |
| `sealapp status ID --json` | Check build progress |
| `sealapp download ID` | Download completed build |
| `sealapp sign PATH --platform P` | Sign a single file |

### Exit codes

- 0: Success
- 1: General error
- 2: Not authenticated — run `sealapp login`
- 3: Subscription required — run `sealapp login`

### Supported file types

macOS: .app, .vst3, .component, .aaxplugin, .framework, .bundle, .pkg, .dmg
Windows: .exe, .dll
