Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Snapr Plugin Example

A dependency-free reference plugin for Snapr's local post-capture plugin system. It accepts image and video captures, creates a Markdown metadata report, and returns the report to Snapr as a file artifact.

This repository is both a working sample and the first-version plugin development guide. Fork it when starting a plugin of your own.

What it demonstrates

  • A cross-platform snapr.plugin.json manifest
  • Repository-relative Python runners for macOS and Windows
  • One JSON request from Snapr over stdin
  • Status, progress, result, and error events over stdout as line-delimited JSON
  • A file artifact written inside Snapr's per-run output directory
  • A dependency-free unittest suite

Requirements

  • Snapr with local plugin support
  • A trusted Python 3 installation, used only to create this repository's virtual environment

Snapr does not search the system PATH when it runs a plugin. Each platform runner must point to an executable inside the plugin repository. The example uses .venv/bin/python on macOS and .venv\Scripts\python.exe on Windows.

Quick start

Clone this repository, then create its local Python environment.

macOS

python3 -m venv .venv

Windows

py -3 -m venv .venv

No packages need to be installed. Next:

  1. Open Snapr Settings → Plugins.
  2. Choose Register Plugin and select this repository directory.
  3. Capture an image or video.
  4. In the floating preview, choose More → Post Process, or press Cmd/Ctrl+P.
  5. Run Create Example Report.
  6. Choose Reveal to locate the generated report.md file.

Snapr registers the repository in place. You can edit or update the clone and use Reload in Settings without registering it again.

Repository structure

snapr-plugin-example/
├── snapr.plugin.json   # Plugin metadata, runners, and actions
├── plugin.py           # stdin/stdout protocol implementation
└── tests/
    └── test_plugin.py  # Dependency-free protocol test

Manifest

Snapr reads snapr.plugin.json from the repository root.

{
  "manifestVersion": 1,
  "id": "dev.snapr.example",
  "name": "Snapr Plugin Example",
  "version": "0.1.0",
  "description": "Creates a Markdown metadata report to test the Snapr plugin lifecycle.",
  "runners": {
    "darwin": { "command": ".venv/bin/python", "args": ["plugin.py"] },
    "win32": { "command": ".venv/Scripts/python.exe", "args": ["plugin.py"] }
  },
  "actions": [
    {
      "id": "create-example-report",
      "name": "Create Example Report",
      "description": "Generate a Markdown report and sample artifacts.",
      "accepts": ["image", "video"]
    }
  ]
}

Runner commands and arguments must be repository-relative paths. Absolute paths and .. traversal are rejected. Snapr currently supports darwin and win32, and action input kinds image and video.

Runtime protocol

Snapr starts the configured runner with the repository as its working directory. It writes exactly one JSON object followed by a newline to stdin.

{
  "protocolVersion": 1,
  "runId": "unique-run-id",
  "pluginId": "dev.snapr.example",
  "actionId": "create-example-report",
  "input": {
    "kind": "image",
    "path": "/absolute/path/to/capture.png"
  },
  "outputDirectory": "/absolute/path/to/snapr-managed-output",
  "config": {}
}

The runner writes line-delimited JSON events to stdout and flushes after every event. Do not write logs or other text to stdout; use stderr for diagnostics.

Status

{ "type": "status", "message": "Reading capture metadata" }

Progress

{ "type": "progress", "current": 2, "total": 3, "message": "Writing Markdown" }

current, total, and message are optional, but current and total should be emitted together when showing determinate progress.

Result

{
  "type": "result",
  "artifacts": [
    {
      "kind": "file",
      "path": "report.md",
      "title": "Example Markdown report",
      "mediaType": "text/markdown"
    },
    {
      "kind": "notification",
      "title": "Complete",
      "message": "Example plugin completed"
    }
  ]
}

File and image artifact paths must be relative to outputDirectory. Snapr rejects missing files, directories, absolute paths, path traversal, and symlinks that escape the output directory.

Supported artifact kinds:

Kind Required field Host actions
file path Copy Path, Reveal
image path Open, Copy Image, Reveal
text text Copy
url url (http or https) Open Link, Copy Link
notification message Displayed with completion status

Error

{ "type": "error", "message": "Input file not found", "code": "example_failed" }

Catch runner errors and emit a final error event. A plugin run should emit either one final result event or one final error event.

Creating your own plugin

  1. Fork or copy this repository.
  2. Change the manifest id, name, version, description, and actions.
  3. Keep every runner executable and script inside the repository.
  4. Read one request line from stdin.
  5. Write generated files only inside outputDirectory.
  6. Emit protocol events as line-delimited JSON on stdout.
  7. Add tests for every action before registering the repository in Snapr.

Plugin IDs and action IDs may contain lowercase letters, digits, ., _, and -, and must start with a letter or digit. Action IDs must be unique within a manifest.

Security model

Snapr plugins are local programs with the same user permissions as Snapr. Register and run only repositories you trust, inspect runner changes before pulling updates, and keep dependencies pinned when your plugin uses third-party packages.

Snapr validates manifests and returned artifacts, but it does not sandbox plugin processes.

Test

macOS

.venv/bin/python -m unittest discover -s tests -v

Windows

.venv\Scripts\python.exe -m unittest discover -s tests -v

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages