This guide is designed to instruct AI Agents on how to develop and write custom plugins for Seer, the Windows Quick Look tool.
- Official Plugin Development Docs: https://1218.io/docs/seer/create-plugin.html
- Existing Plugins List (for reference): https://github.com/stars/ccseer/lists/plugins
- Seer SDK Repository: https://github.com/ccseer/Seer-sdk
- Control Plugins Repository: https://github.com/ccseer/Seer-Controls
- Property Plugins Repository: https://github.com/ccseer/Seer-Properties
Seer supports two types of plugins to extend file preview capabilities: Convert Plugins and DLL Plugins.
Convert plugins run an external executable or script via command line. The plugin parses the source file, converts it to one of the formats Seer natively supports (such as HTML, JSON, TXT, PNG/JPG), and Seer loads and renders the output.
- Match: The user selects a file and presses the Spacebar. Seer matches the file extension against the configured plugins.
- Execute: Seer launches the plugin executable or script.
- Convert: The plugin reads/parses
${input_file}, writes the converted content to${output_file}.<format>(e.g.${output_file}.html), and exits. - Render: Once the plugin exits, Seer reads and displays
${output_file}.<format>.
Important
Script Execution and Runtimes:
- Seer only adapts
.ps1files to run automatically via PowerShell (powershell.exe -NoProfile -ExecutionPolicy Bypass -File <script>). - For any other script formats (such as
.py,.js,.bat,.cmd), Seer does not select or wrap a system interpreter based on the file extension. The configured entry is launched directly viaQProcess::start(exe, args). - Therefore, use a directly executable entry: package the converter as a standalone
.exe(for example, with PyInstaller for Python), include a compiled launcher, or bundle the required runtime executable in the plugin directory and use it asentrywhile passing the script file throughargs.
${input_file}: The absolute path of the source file to preview.${output_file}: The target output file path (omit suffix in the placeholder; append the suffix in the arguments array, e.g.${output_file}.html).${no_cache}: Disables reuse/caching of the output file for subsequent previews of the same file, and stores the output in the auto-delete temp directory. The generated file is deleted after all preview windows (including the main window and any separated windows) are completely closed. Note that${no_cache}is intercepted by Seer and not passed to the executable.
Native C++/Qt dynamic link libraries (.dll) loaded directly by Seer using QPluginLoader.
- Language Standard: C++17
- Framework: Qt 6.8 (Do not use Qt 6.9+ APIs)
- Compiler: MSVC 2022 (x64)
- Build System: CMake 3.22+
- Minimum App Version: DLL plugins compiled with SDK v3 must declare
appMinVersionas"4.2.9".
ViewerBase: The base class for the widget performing the preview. The plugin's viewer class must inherit fromViewerBase.ViewerPluginInterface: The interface that Seer uses to instantiate the plugin.class ViewerPluginInterface { public: virtual ~ViewerPluginInterface() = default; virtual ViewerBase *createViewer(QWidget *parent = nullptr) = 0; };
ViewerPluginInterface_iid: The interface identifier string defined as"seer.plugin.interface.preview/3".- Qt Macros: The plugin class implementing
ViewerPluginInterfacemust declare:Q_OBJECTQ_INTERFACES(ViewerPluginInterface)Q_PLUGIN_METADATA(IID ViewerPluginInterface_iid)
Every Seer plugin must contain a plugin.json file in its root directory. Seer parses this file using strict JSON parsing (QJsonDocument::fromJson).
Warning
Strict JSON Compliance:
The plugin.json must be strictly valid JSON. No comments (// or /* */) or trailing commas are allowed. If there is any formatting error, Seer's installation task will fail.
| Field Name | Type | Presence | Description |
|---|---|---|---|
name |
String | Required | The user-facing name of the plugin. Cannot be empty. |
version |
String | Required | Version string (e.g., "1.0.0"). Cannot be empty. |
type |
String | Required | Must be "convert" or "dll". |
roles |
Array | Required | Array of strings representing roles. Must contain "viewer". Cannot be empty. |
entry |
String | Required | File name of the entry point (e.g., "MyConverter.exe", "MyScript.ps1", or "MyPlugin.dll"). Must point to a file that actually exists inside the plugin directory. |
formats |
Array | Required | Supported file extensions. Must be lowercase and without a leading dot (e.g., ["ipynb"], NOT [".ipynb"]). Cannot be empty. |
appMinVersion |
String | Required | Must be a version string of at least "3.9.10" (e.g., "4.1.3" for Convert; "4.2.9" for SDK v3 DLL plugins). If missing or below "3.9.10", Seer routes the manifest through the incompatible legacy parser. |
args |
Array | Convert-Specific | Command line arguments array. Mandatory for "convert" plugins (must not be empty). For "dll" plugins, it is optional and acts as plugin configuration (passed to the DLL via ViewOptionsKeys::kKeyPluginCmd). |
author |
String | Optional | Developer's name. |
releaseDate |
String | Optional | Release date in YYYY-MM-DD format. |
{
"name": "ipynb",
"version": "1.2.0",
"type": "convert",
"roles": [
"viewer"
],
"entry": "ipynb.ps1",
"args": [
"-i",
"${input_file}",
"-o",
"${output_file}.html"
],
"formats": [
"ipynb"
],
"appMinVersion": "4.1.3",
"author": "yourname",
"releaseDate": "2026-07-14"
}{
"name": "JsonTreeViewer",
"version": "1.0.0",
"type": "dll",
"roles": [
"viewer"
],
"entry": "JsonTreeViewer.dll",
"args": [
"--expand-depth",
"2"
],
"formats": [
"json"
],
"appMinVersion": "4.2.9",
"author": "yourname",
"releaseDate": "2026-07-14"
}When implementing a plugin from a user request, the AI Agent must:
-
Confirm the Requirement:
- Do not start if the request is missing, still contains placeholder text, or lacks enough detail to identify the target format and desired preview behavior.
- Ask one clarifying question and wait instead of inventing the missing requirement.
-
Choose the Architecture:
- Select Convert or DLL based on the format, preview behavior, performance needs, and available toolchain.
- State the choice and a brief technical reason before implementation.
-
Deliver the Complete Plugin:
- Create the plugin in a new, appropriately named directory without modifying Seer itself.
- Include every required source file,
plugin.json, asset, representative sample, plugin-levelREADME.md, and build configuration. - Do not stop at a plan, scaffold, or isolated code snippets.
-
Verify the Result:
- Run every applicable check in the following validation checklist and report the exact commands and results.
- When a compatible Seer installation is available, install the plugin and complete an in-app preview smoke test with the representative sample.
- If Seer is unavailable, do not claim runtime verification. State explicitly that the in-app load and preview test remains outstanding.
-
Document Delivery Requirements:
- Document local installation, catalog packaging when applicable, external runtime requirements, and dependencies that users must install separately.
- Distinguish verified behavior from unverified assumptions in the final report.
Before releasing or loading the plugin, the AI Agent must verify the following items:
- Parse the
plugin.jsonthrough a strict JSON parser (e.g., python'sjson.loadsor a JSON validator) to ensure no comments or trailing commas exist. - Ensure the
entryfile name matches the actual compiled binary or script file name exactly. - Confirm all entries in the
formatsarray are lowercase and do not contain leading dots.
Test the script or program locally in PowerShell using the exact argument format:
# For PowerShell script plugins:
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\ipynb.ps1 -i "test_input.ipynb" -o "output_path.html"
# For executable plugins:
.\MyConverter.exe -i "test_input.xyz" -o "output_path.html"Ensure the program exits with code 0 and generates the expected output format.
Seer installer behavior differs depending on installation method:
- Local Installation: Extract the plugin files locally. Open Seer Settings -> Plugins, click Add from local, and select the extracted
plugin.jsonfile. - Online/Remote Catalog Installation (ZIP): The online package installer expects extraction to create a top-level directory named after the ZIP archive itself. Thus, the ZIP layout must be:
<archive-name>/<plugin.json, entry, assets, ...>Do NOT placeplugin.jsondirectly at the archive root for online catalog packaging.
- If the plugin relies on external runtimes (such as Python or Node.js), clearly state the requirements in a
README.md. - Prefer bundling the runtimes or compiling to a single-file executable (EXE) so the end user does not need to install external development stacks.
- If your plugin converts content into
HTMLfor rendering, you must escape or sanitize any untrusted input data extracted from the source files before embedding it into the HTML template to prevent potential script injection vulnerabilities.