This document outlines the formal contract that all plugins for oshea must adhere to. It serves as a guide for plugin developers, ensuring that plugins are reliable, predictable, and integrate smoothly with the core application.
The contract is enforced at runtime by a validation system (src/plugins/plugin-validator.js) that uses JSON Schemas. Every plugin's configuration is checked against a base schema, and optionally against its own specific schema.
A plugin must follow a specific file structure to be considered valid. This structure separates the core functional files from supporting documentation and validation assets, creating an intuitive layout for developers.
plugins/my-plugin/
├── default.yaml # REQUIRED: The plugin's manifest and primary metadata.
├── index.js # REQUIRED: The handler script.
├── README.md # REQUIRED: The primary human-readable documentation.
├── example.md # REQUIRED: A self-activating example file.
├── style.css # OPTIONAL: Core CSS, as defined in config.
│
└── .contract/ # OPTIONAL: Houses machine-readable/validation assets.
├── schema.json # OPTIONAL: The structural contract for the config.
└── test/ # OPTIONAL: Co-located tests.
└── e2e.test.js
The default.yaml file is the heart of the plugin. It is the single source of truth for the plugin's identity and its default configuration.
These properties must be present in every plugin's configuration file.
- Type:
string - Purpose: The official, unique name of the plugin. This value must match the plugin's directory name.
- Example:
"cv"
- Type:
string - Purpose: The version of the plugin, preferably following SemVer.
- Example:
"1.0.0"
- Type:
string - Purpose: The version of the oshea plugin contract this plugin adheres to. For this version, it must be
"v1". - Example:
"v1"
- Type:
string - Purpose: A brief, user-facing description of what the plugin does. This is used in help text and other UI elements to inform the user.
- Example:
"A plugin for creating a professional two-column CV."
- Type:
string - Purpose: The path to the Node.js module that serves as the plugin's entry point. This path is relative to the location of the plugin's configuration file.
- Example:
"index.js"
These are standard properties that plugins can use to hook into oshea's functionality.
- Type:
object - Purpose: Defines default PDF generation options for this plugin, following the Puppeteer
pdfOptionsformat. These values can be overridden by the user's global, project, or local configurations. - Example:
pdf_options: format: 'Letter' printBackground: true margin: top: '0.5in' bottom: '0.5in'
- Type:
arrayofstrings - Purpose: A list of CSS files to be applied to the document. Paths are resolved relative to the plugin's configuration file.
- Example:
css_files: ["style.css"]
- Type:
object - Purpose: Configures KaTeX math rendering options for the plugin.
- Example:
math: enabled: true
- Type:
object - Purpose: Configures the Table of Contents generation for the plugin.
- Example:
toc_options: enabled: false
- Type:
arrayofobjects - Purpose: Defines additional files or directories for oshea to monitor in
--watchmode. This is useful for plugins that depend on external assets not directly referenced in the Markdown or CSS. - Example:
watch_sources: - path: "./assets" type: "directory" - path: "./data.json" type: "file"
- Type: Markdown front matter object
- Purpose: Placeholder replacement uses document front matter values at render time (for example
{{ author }}or{{ .contact.email }}). - Example:
--- title: "My Document" author: "Your Name" contact: email: "[email protected]" ---
Plugins can extend the base contract by providing their own schema file, located at .contract/schema.json. This allows plugins to define their own custom properties and enforce specific constraints.
When a plugin-specific schema is present, it is merged with the base schema. See plugins/cv/.contract/schema.json for an example.