Plugin Packaging And Market

Prepare a DynamicLake plugin for review, signed catalog distribution, and updates.

Overview

DynamicLake plugins are distributed as .dynamiclakeplugin packages. A package contains a manifest, one executable, optional helper files, and an optional icon.

DynamicLake Market lists reviewed plugins from a signed catalog. The app verifies the catalog signature, downloads the selected package, checks package hashes, validates the manifest, and installs the package into DynamicLake's managed plugin folder.

!DynamicLake Market verifies the signed catalog, downloaded archive, and extracted package before install.

Package Layout

Use one package folder per plugin.

TimerStatus.dynamiclakeplugin
  plugin.json
  icon.png
  timer-status.py
  README.md

Keep the package focused. Put caches, generated logs, user data, and large assets outside the package.

Package Limits

DynamicLake enforces these limits during local install and Market install:

| Item | Limit | | --- | --- | | Archive | 7 MB max | | Extracted package folder | 20 MB max | | plugin.json | 128 KB max | | Icon | 1.5 MB max |

Icon guidance:

Runtime JSON limits:

| Item | Limit | | --- | --- | | JSON message payload | 64 KB max | | Inline image data | 48 KB max decoded bytes |

Use sfSymbol or appIcon image components before inline image data. Inline images are for small status artwork, not screenshots or large previews.

Manifest Rules

plugin.json must live at the package root.

{
  "schemaVersion": 1,
  "identifier": "com.example.plugins.timer-status",
  "name": "Timer Status",
  "version": "1.0.0",
  "developerName": "Example Studio",
  "executable": "timer-status.py",
  "arguments": [],
  "icon": "icon.png",
  "autoStart": true,
  "settings": [
    {
      "id": "showTimer",
      "type": "switch",
      "title": "Show Timer",
      "systemImage": "timer",
      "tint": "cyan",
      "default": true
    }
  ]
}

Validation rules:

Archive The Package

Zip the package folder itself, not only its contents.

ditto -c -k --keepParent TimerStatus.dynamiclakeplugin TimerStatus-1.0.0.zip

The archive should extract to:

TimerStatus.dynamiclakeplugin/

and not to loose files at the archive root.

Generate Hashes

Market catalog entries use SHA-256 hashes so DynamicLake can verify what it downloads and installs.

Generate the archive hash:

shasum -a 256 TimerStatus-1.0.0.zip

Generate a stable package hash from the extracted package contents. The exact catalog signing flow is managed by DynamicLake, but review needs the package that will be published to match the submitted archive.

Market Catalog Entry

Approved plugins are published in the signed catalog.

{
  "identifier": "com.example.plugins.timer-status",
  "name": "Timer Status",
  "version": "1.0.0",
  "developerName": "Ada Example & Lin Example",
  "developers": [
    { "name": "Ada Example", "profileURL": "https://github.com/ada" },
    { "name": "Lin Example", "profileURL": "https://github.com/lin" }
  ],
  "description": "Shows timer progress in DynamicLake",
  "category": "Productivity",
  "iconURL": "https://example.com/timer-status/icon.png",
  "packageURL": "https://example.com/timer-status/TimerStatus-1.0.0.zip",
  "packageSHA256": "64 lowercase hex characters for the extracted package",
  "archiveSHA256": "64 lowercase hex characters for the downloaded zip",
  "releaseNotesURL": "https://example.com/timer-status/releases/1.0.0",
  "websiteURL": "https://example.com/timer-status",
  "supportURL": "mailto:[email protected]",
  "status": "available"
}

developers is optional and supports up to two creators. Keep developerName for compatibility with older DynamicLake versions; when two creators are present, set it to both names joined with & . Each creator profile is optional.

The catalog version controls updates. When the catalog version is newer than the installed version for the same identifier, DynamicLake shows an Update action.

Submit For Review

Submit plugins from DynamicLake Market:

https://market.dynamiclake.com

The submission form asks for:

After submission, DynamicLake creates a private review issue and sends a status email to the developer. Status emails can be:

When a submission is rejected, the review team should include a short public reply note so the developer knows what to fix.

Review Checklist

Before a plugin goes live:

Testing Plugin Changes

Run the package tests when changing the JSON wire protocol or public plugin schema types.

swift test

The tests cover:

When adding a plugin schema feature, add at least one success case and one rejection case. For new JSON component fields, add both a valid decode test and a malformed payload test.

Local Install vs Market Install

Local install is for development and testing. DynamicLake still validates package structure and size, but local installs are not reviewed.

Market install is for users. DynamicLake uses the signed catalog, package URL, package hash, and archive hash before installing or updating a plugin.

For plugin message schema details, see JSONPluginAPI. For shared UI rules, see DesignGuidelines.