mirror of
https://github.com/got-feedBack/feedBack.git
synced 2026-09-12 23:28:30 +00:00
chore: update PR 332 tooling for capability model
This commit is contained in:
@@ -7,7 +7,7 @@ model: sonnet
|
||||
|
||||
# slopsmith-reviewer
|
||||
|
||||
Plugin-aware reviewer for Slopsmith. Use when reviewing a plugin's code or manifest. Does **not** duplicate the built-in `peer-review` skill — focus is narrow: the plugin contract surface defined in [`docs/PLUGIN_AUTHORING.md`](../../docs/PLUGIN_AUTHORING.md) and enforced by [`schema/plugin.schema.json`](../../schema/plugin.schema.json) and `tests/test_plugin_schema.py`.
|
||||
Plugin-aware reviewer for Slopsmith. Use when reviewing a plugin's code or manifest. Does **not** duplicate the built-in `peer-review` skill — focus is narrow: the plugin contract surface defined in [`docs/PLUGIN_AUTHORING.md`](../../docs/PLUGIN_AUTHORING.md) and enforced by [`schema/plugin.schema.json`](../../schema/plugin.schema.json), including `capability-pipelines.v1` metadata, and `tests/test_plugin_schema.py`.
|
||||
|
||||
## When to invoke
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ These rules apply only when editing files under `plugins/**`. They encode the co
|
||||
## Manifest
|
||||
|
||||
- **`plugin.json` is required** and must validate against [`schema/plugin.schema.json`](../../schema/plugin.schema.json). Required fields: `id`, `name`. The `id` must match the parent directory name (the loader keys discovery by directory; drift breaks plugin lookup).
|
||||
- **Capability-aware plugins declare intent** with `standards: ["capability-pipelines.v1"]` and redaction-safe `capabilities` / `ui` metadata. Legacy fields still work, but don't strip or reject native metadata when editing manifests.
|
||||
- **License must come from the curated allowlist** if the plugin is intended for the curated list. See [`CONTRIBUTING.md`](../../CONTRIBUTING.md) "Plugin licensing".
|
||||
- **`type: "visualization"`** requires a `script` field exporting `window.slopsmithViz_<id>`. See [`docs/plugin-visualization-contracts.md`](../../docs/plugin-visualization-contracts.md).
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"hooks": {},
|
||||
|
||||
"_commented_example_hooks": {
|
||||
"_comment": "Copy the block below into the empty `hooks` object above if you want plugin.json edits to be auto-validated against schema/plugin.schema.json on save. Per-user opt-in; not enabled by default because hooks run in every Claude Code session that loads this repo.",
|
||||
"_comment": "Copy the block below into the empty `hooks` object above if you want plugin.json edits to be auto-validated against schema/plugin.schema.json, including capability metadata, on save. Per-user opt-in; not enabled by default because hooks run in every Claude Code session that loads this repo.",
|
||||
"PostToolUse": [
|
||||
{
|
||||
"matcher": "Write|Edit",
|
||||
|
||||
@@ -30,25 +30,31 @@ If the plugin slug or type is missing, ask once.
|
||||
|
||||
**Common to all types:**
|
||||
|
||||
- `plugins/<id>/plugin.json` — minimum schema-valid manifest. Set `id`, `name`, `version: "0.1.0"`, and `license: "AGPL-3.0-only"` by default (ask if a different license is desired).
|
||||
- `plugins/<id>/plugin.json` — schema-valid manifest. Set `id`, `name`, `version: "0.1.0"`, `license: "AGPL-3.0-only"`, and `standards: ["capability-pipelines.v1", "plugin-runtime-idempotent.v1"]` by default (ask if a different license is desired).
|
||||
|
||||
**`type=visualization`** — adds:
|
||||
- `"type": "visualization"` and `"script": "screen.js"` to manifest
|
||||
- `"capabilities": { "visualization": { "roles": ["provider"], "operations": ["renderer.create", "renderer.destroy", "renderer.inspect"], "mode": "active", "compatibility": "shim-allowed", "ownership": "multi-provider", "safety": "safe", "version": 1 } }`
|
||||
- `screen.js` exporting `window.slopsmithViz_<id> = function () { return { contextType: '2d', init(canvas, bundle) { this.ctx = canvas.getContext('2d'); }, draw(bundle) { /* TODO */ }, destroy() {} }; };` plus a static `matchesArrangement` example commented out
|
||||
- `tests/browser/<id>.spec.ts` — Playwright stub that loads the app and asserts the plugin's factory is registered
|
||||
|
||||
**`type=overlay`** — adds:
|
||||
- `"script": "screen.js"` to manifest (no `type` declared — overlays don't use the picker)
|
||||
- `"capabilities": { "ui.player-overlays": { "roles": ["provider"], "mode": "active", "compatibility": "shim-allowed", "ownership": "multi-provider", "safety": "safe", "version": 1 } }`
|
||||
- a matching `"ui"` contribution with a stable overlay id and redaction-safe label
|
||||
- `screen.js` scaffolding a navbar toggle, an own-canvas + own-rAF loop reading `highway.getNotes()` / `getChords()` / `getTime()`, and respecting `highway.isDefaultRenderer()` if using `highway.project` / `fretX`
|
||||
- `tests/browser/<id>.spec.ts` — toggle on / off test
|
||||
|
||||
**`type=settings-only`** — adds:
|
||||
- `"settings": { "html": "settings.html" }` to manifest
|
||||
- `"settings_schema"` with a schema version and an empty `packable_keys` list
|
||||
- a `"ui"` settings contribution with a stable id
|
||||
- `settings.html` — empty form skeleton with explanatory comments
|
||||
- `screen.js` reading/writing `localStorage` keys prefixed with `<id>_`
|
||||
|
||||
**`type=routes-only`** — adds:
|
||||
- `"routes": "routes.py"` to manifest
|
||||
- a conservative `"capabilities"` declaration only when the route participates in a known domain such as `library`, `jobs`, or `privileged-capabilities`; otherwise leave capability participation out and ask what workflow the route owns
|
||||
- `routes.py` with `def setup(app, context):` that registers one example route and uses `context["log"].info("plugin ready")` (never `print()`)
|
||||
- `tests/test_<id>_routes.py` — FastAPI TestClient stub
|
||||
|
||||
@@ -64,7 +70,7 @@ Then point the user at [`docs/PLUGIN_AUTHORING.md`](../../../docs/PLUGIN_AUTHORI
|
||||
|
||||
## Don'ts
|
||||
|
||||
- Don't add fields to the manifest that aren't in the schema. If the user wants something custom, ask whether it should become a real field — that's a `schema/plugin.schema.json` change, not a plugin-local convention.
|
||||
- Don't invent plugin-local manifest conventions. If the user wants something custom, either express it through existing `capability-pipelines.v1` metadata or ask whether it should become a real schema field.
|
||||
- Don't scaffold a `requirements.txt` without confirming the deps. The plugin loader installs them on first load; an accidental dep slows everyone's startup.
|
||||
- Don't pre-fill `localStorage` keys without a prefix. Collisions across plugins are real.
|
||||
- Don't generate hidden side effects at import time (`screen.js` top level or `routes.py` top level). Keep all wiring inside the IIFE / `setup()`.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: plugin-validate
|
||||
description: Validate a Slopsmith plugin's plugin.json against the schema and run structural checks. USE WHEN the user asks to validate a plugin, check the manifest, plugin.json errors, lint plugin, verify plugin structure, plugin license check, or audit plugin contract. Runs JSON Schema validation, file-existence checks for declared script/routes/settings.html/tour paths, and license-allowlist check.
|
||||
description: Validate a Slopsmith plugin's plugin.json against the schema and run structural checks. USE WHEN the user asks to validate a plugin, check the manifest, plugin.json errors, lint plugin, verify plugin structure, plugin license check, or audit plugin contract. Runs JSON Schema validation, capability metadata checks, file-existence checks for declared script/routes/settings.html/tour paths, and license-allowlist check.
|
||||
---
|
||||
|
||||
# plugin-validate
|
||||
@@ -32,7 +32,7 @@ for path in sorted(glob.glob('plugins/*/plugin.json')):
|
||||
plugin_id = plugin_dir.name
|
||||
m = json.load(open(path))
|
||||
plugin_ok = True # per-iteration flag so we don't print OK after a later FAIL
|
||||
# 1. Schema
|
||||
# 1. Schema, including capability-pipelines.v1 metadata
|
||||
try:
|
||||
jsonschema.validate(m, schema)
|
||||
except jsonschema.ValidationError as e:
|
||||
|
||||
Reference in New Issue
Block a user