{
  "id": "com.lattice.notifications",
  "name": "Notifications",
  "icon": "🔔",
  "color": "#f59e0b",
  "description": "Log notifications and forward them to the desktop.",
  "requested_permissions": {
    "storage": [
      "kv",
      "sql"
    ],
    "network": {
      "allowlist": []
    },
    "notifications": true,
    "events": {
      "notification-logged": {
        "description": "A notification was logged and desktop delivery attempted.",
        "schema": {
          "type": "object",
          "properties": {
            "id": {
              "type": "integer",
              "description": "Notification ID."
            },
            "title": {
              "type": "string",
              "description": "Notification title; defaults to Notification."
            },
            "body": {
              "type": "string",
              "description": "Notification body; empty means none."
            },
            "app_id": {
              "type": "string",
              "description": "Source app ID; empty means unknown source."
            },
            "logged_at": {
              "type": "string",
              "description": "Log time, UTC YYYY-MM-DD HH:MM:SS."
            },
            "desktop_delivered": {
              "type": "boolean",
              "description": "Whether desktop notification delivery succeeded; may be absent."
            }
          },
          "required": [
            "id",
            "title",
            "body",
            "app_id",
            "logged_at"
          ]
        }
      }
    },
    "listeners": {
      "receive-notification": {
        "description": "Log a notification and forward it to the desktop.",
        "schema": {
          "type": "object",
          "properties": {
            "title": {
              "type": "string",
              "description": "Notification title; omitted or empty defaults to Notification."
            },
            "body": {
              "type": "string",
              "description": "Notification body; omitted or empty means none."
            }
          },
          "required": []
        }
      }
    }
  },
  "source": {
    "assets": [
      "index.html",
      "app.js",
      "ui.css",
      "emits.js",
      "listens.js"
    ]
  }
}