plugin-template/AGENTS.md

95 lines
4.3 KiB
Markdown
Raw Normal View History

# Quartz Community Plugin Template
Provider-agnostic instruction file for AI coding assistants developing Quartz community plugins.
## Project Overview
This repository is a template for building, testing, and publishing Quartz community plugins. It uses a factory-function API where plugins are created by functions returning objects with a `name` and lifecycle hooks.
## Plugin Type Decision Tree
Plugins are not mutually exclusive. A single plugin can implement multiple types.
- **Transformer**: Modifies content during the build (remark/rehype). Use if you need to change how Markdown is parsed or rendered.
- **Filter**: Decides which files to include in the final site. Use for drafts, private notes, or path-based exclusions.
- **Emitter**: Generates new files (JSON, RSS, CNAME, etc.). Use for site-wide manifests or integration files.
- **Page Type**: Defines custom routes and page generation logic. Use for virtual pages or non-Markdown content.
- **Component**: Provides UI elements for Quartz layouts. Use for navigation, sidebars, or custom widgets.
- **Bases View**: Registers custom views in the `@quartz-community/bases-page` system.
## Files to Modify
- `src/`: All plugin logic, components, and styles.
- `package.json`: Plugin manifest (`quartz` field), dependencies, and metadata.
- `src/i18n/`: Translations for multi-language support.
## Leave Alone
- `dist/`: Build output. Committed to repo for pre-built distribution. Regenerated by `npm run build`.
- `.github/`: CI/CD workflows (unless customizing publishing).
- `tsup.config.ts`: Build configuration. Defines SINGLETON_EXTERNALS and bundling strategy. Only modify to add native dep exclusions.
## Plugin Creation Workflow
1. **Define Options**: Create an interface for plugin configuration in `src/types.ts`.
2. **Implement Logic**: Create the plugin factory in a new file (e.g., `src/my-plugin.ts`).
3. **Export**: Add the plugin to `src/index.ts`.
4. **Manifest**: Update the `quartz` field in `package.json` with category and default options.
5. **Test**: Add a test case in `src/tests/` and run `npm test`.
6. **Build and commit**: Run `npm run build` and commit the `dist/` output.
## Package.json Quartz Manifest
The `quartz` field is required for discovery and configuration:
```json
{
"quartz": {
"name": "my-plugin",
"category": ["transformer", "component"],
"defaultOptions": { "enabled": true },
"optionSchema": { "enabled": { "type": "boolean" } },
"components": { "MyComponent": { "defaultPosition": "right" } }
}
}
```
## Import Patterns
- **Types**: Import from `@quartz-community/types`.
- **Utils**: Import from `@quartz-community/utils`.
- **Runtime**: Use `vfile` for content manipulation in transformers.
## i18n Setup
1. Add keys to `src/i18n/locales/en-US.ts`.
2. Create other locales in `src/i18n/locales/`.
3. Use the `i18n` helper in your plugin or component.
## Common Mistakes
- **Missing Exports**: Forgetting to export the plugin factory from `src/index.ts`.
- **Wrong Category**: Not matching the `category` in `package.json` with the implemented hooks.
- **Peer Dependencies**: Adding `preact` or `vfile` as `dependencies` instead of `peerDependencies`.
- **Gitignoring dist/**: The `dist/` directory must be committed for pre-built distribution.
- **Bundling native deps**: Plugins using `sharp`, `@napi-rs/*`, or other NAPI packages must exclude them from `noExternal`.
## Testing Patterns
Use `vitest`. Mock the `BuildCtx` and `ProcessedContent` when testing transformers or emitters.
## Checklist Before Submission
- [ ] `npm run build` completes without errors.
- [ ] `npm test` passes all cases.
- [ ] `dist/` is committed and up to date (CI verifies this).
- [ ] `package.json` manifest is complete and accurate.
- [ ] `README.md` documents all options.
## Build System Quirks
- **SINGLETON_EXTERNALS**: `SINGLETON_EXTERNALS` in `tsup.config.ts` defines packages that must NOT be bundled — they must be the same instance across all plugins (`preact`, `vfile`, `unified`, `@jackyzha0/quartz`). Everything else is bundled into `dist/`.
- **.inline.ts**: Files ending in `.inline.ts` are bundled as raw strings for client-side injection.
- **.scss**: Styles are compiled to CSS strings and attached to components via `Component.css`.
- **Branded Types**: Use `FullSlug` and `FilePath` from `@quartz-community/types` for path safety.