MediaUse Docs
Plugin Development
A step-by-step tutorial on creating and maintaining MediaUse plugins.
Introduction
MediaUse plugins are best developed using AI assistance (Copilot/Codex) combined with the `mediause plugin create` skill. This guide explains both the AI-driven and manual workflows.
Step 1: Scaffolding (AI-First)
The recommended way to start is to use an agent with Vision capability to explore the site and generate the initial scaffold.
# Example Agent Request @codex Create a site plugin for 'https://www.example.com'. 1. Visit the site and analyze search/detail pages. 2. Generate manifest.yaml with search capability. 3. Create workflows for listing results. 4. Use 'mediause plugin create' skill to output the structure.
Step 2: Defining the Manifest (The Contract)
The `manifest.yaml` file defines how the user speaks to your plugin. Here is a concrete example for a movie site:
# crates/platforms/plugins/dytt/manifest.yaml name: "dytt" version: "1.0.0" commands: search: list: workflow: workflows/search.yaml operation: list description: "Search movies by keyword" params: - name: keyword type: string required: true - name: page type: number default: 1
Step 3: Implementing Workflows
Workflows use browser actions to drive the page. Use `waitforfunction` to ensure stability. Note that workflows support both native browser actions (click, fill, navigate) and custom JavaScript evaluation via `evaluate`.
# workflows/search.yaml list: steps: - action: navigate url: "https://www.example.com/search?q={{keyword}}" - action: waitforfunction expression: "!!document.querySelector(".movie-item")" - action: evaluate script: | (function() { const items = Array.from(document.querySelectorAll(".movie-item")).map(el => ({ title: el.querySelector("h3").innerText, url: el.querySelector("a").href })); return { success: true, data: items }; })()
Key Browser Actions
While MediaUse supports 50+ actions, these are the primary ones used in almost all site plugins. Native actions are preferred over raw JavaScript for stability.
| Action | Description | Required Params |
|---|---|---|
| navigate | Go to a specific URL. | url |
| waitforfunction | Wait until a JS expression is true. (Recommended wait method) | expression |
| fill | Input text into a field. | selector, value |
| click | Click an element. | selector |
| upload | Inject files into an upload input. | selector, files |
| evaluate | Execute JavaScript and return data. | script |
| snapshot | Take a DOM snapshot for AI analysis. | ref (optional) |
Action Examples & Syntax
Each step in a workflow is a JSON object with an `action` key and its corresponding parameters.
# Navigation with wait condition - action: navigate url: "https://example.com" waitUntil: "networkidle" # Filling and submitting a form - action: fill selector: "input[name='q']" value: "MediaUse" - action: press key: "Enter" # Dynamic waiting (Recommended) - action: waitforfunction expression: "!!document.querySelector('.results')" timeoutMs: 15000 # File Upload (Standardized) - action: upload selector: "input[type='file']" files: ["{{filePath}}"] # JavaScript Execution - action: evaluate script: "() => ({ width: window.innerWidth, height: window.innerHeight })"
Step 4: Standard Return Structure
Every command *must* return a structured JSON object. For account-related commands, the structure is strictly enforced:
# Standard Account Health Return { "success": true, "data": { "healthy": true, "account": { "id": "user_123", "nick": "JohnDoe", "login": true } } }
Step 5: Testing and Deployment
Always verify your plugin against live sites before submitting.
# 1. Run low-level Rust tests cargo test -p platforms dytt -- --nocapture # 2. Run real command via CLI mediause dytt search list --keyword "Inception" --json
Development Checklist
Review this checklist to ensure your plugin meets production standards:
- Always use English for `description` fields in manifest.
- Redirect all DOM extraction to `scripts/*.js` or `evaluate` steps.
- Use Vision to confirm selectors actually exist on the live page.