minco-plugin-feedback
Official Minco plugin for a short, structured client-feedback loop.
It provides:
- a configurable floating action button with no frontend-framework dependency;
- browser-authorized screen capture plus screenshot and file attachments;
- browser voice recording with optional OpenAI-compatible or local-command transcription;
- client/developer threaded discussion and explicit workflow states;
- memory, PostgreSQL, SQLite, and application-provided persistence adapters;
- provider-neutral object storage, notifications, audit, and event/outbox integration;
- a protected developer inbox API and typed HTTP client;
- deterministic JSON and Markdown context for AI-assisted implementation;
- explicit upload limits, privacy controls, authorization, and optimistic concurrency.
Embed the widget
The element can also be configured programmatically or with attributes. Supported
positions are top-left, top-right, bottom-left, and bottom-right.
The widget is isolated in a Shadow DOM and requires no React, Vue, or other
frontend runtime.
The browser Screen Capture and MediaRecorder APIs always retain their normal user consent surfaces. Minco does not capture a screen or microphone without the browser and user granting access. Query strings are excluded from captured page context by default and configured secret-like parameter names are redacted when query capture is enabled.
Client access tokens are bearer credentials. The default widget stores them in
sessionStorage; applications with a different threat model can configure local
storage or provide their own client. A same-origin script compromise can read
browser storage, so Content Security Policy, dependency hygiene, retention, and
data classification remain part of the application security review.
Anonymous submission is disabled by default. Production deployments should grant
authenticated principals feedback.create. project_key is browser-visible and
provides only a basic abuse-control boundary. Enabling allow_anonymous therefore
also requires ingress rate limits, upload-cost monitoring, and a deliberate data-
retention policy.
Voice transcription can invoke a paid provider or a local process, so it is
available only to authenticated principals with feedback.create. A deployment
cannot combine transcription_enabled with project_key or allow_anonymous.
Ingress rate limits and provider spend alerts remain required defense in depth
for authenticated callers.
Compose the plugin
The plugin declares its dependencies explicitly. They must be registered, but Minco automatically enables them when Feedback is selected unless an operator explicitly disables one.
use Router;
use ;
use ;
use AuditPlugin;
use EventsPlugin;
use ;
use HealthPlugin;
use IdentityPlugin;
use NotificationsPlugin;
use ObjectStoragePlugin;
let mut manager = default;
manager.register?;
manager.register?;
manager.register?;
manager.register?;
manager.register?;
manager.register?;
manager.register?;
let feedback = new?;
let mut selection = default;
selection.enabled.insert;
selection.set_configuration?;
let application = manager.compose?;
let router = compose_plugin_http?;
# let _ = router;
# Ok::
compose_plugin_http is important: it merges the statically contributed routes
and raises the global body ceiling to the plugin's configured aggregate upload
limit. Route handlers still enforce attachment count, media class, and per-file
limits. Set max_attachments to zero for a text-only profile: the bundled widget
hides screenshot, file, and voice controls, and the server rejects multipart
attachment fields.
Production applications should replace memory implementations with durable
adapters. developer_token is an operator fallback for local or narrowly
controlled environments and must come from a secret provider. A normal production
application should instead inject a verified minco_http::Principal containing
the feedback.manage permission.
Persistence and delivery semantics
The PostgreSQL and SQLite features persist feedback threads and hashed client
tokens. Object bytes are stored through ObjectStoreService; the feedback table
contains metadata and stable object keys rather than large blobs.
Feedback persistence is authoritative. Notification, audit, and event-delivery failures are returned as warnings after the feedback mutation has committed, so a temporary downstream outage does not discard client input. Client responses contain stable warning codes and public-safe summaries; provider diagnostics stay in access-controlled server logs. The bundled event integration writes to the configured outbox service, but it cannot make the feedback-store transaction and an independently configured outbox transaction atomic. Applications requiring that guarantee must provide a transaction-integrated feedback store/outbox adapter. Minco does not hide a scheduled polling worker.
Transcription
Two official adapters are feature-gated:
openai-transcription: multipart audio transcription through a configured API;command-transcription: a direct-process adapter suitable forwhisper.cpp,faster-whisper, or another audited local transcription command.
The command adapter invokes an executable directly, never through a shell. Use
{input} in an argument to place the temporary audio path, or omit the placeholder
to append it as the final argument.
The core trait remains provider-neutral, so teams can implement an on-premises, regional, or privacy-specific transcriber without modifying the plugin.
Contract and developer workflow
The plugin contract is committed at
openapi/feedback.openapi.yaml. The developer
CLI supports:
cargo minco feedback inbox
cargo minco feedback show <id>
cargo minco feedback reply <id> --body "Could you clarify the expected result?"
cargo minco feedback status <id> needs_clarification
cargo minco feedback pull <id> --output tasks/feedback/<id>.md
cargo minco feedback attachment <feedback-id> <attachment-id> --output screenshot.png
feedback pull produces deterministic, repository-friendly context for a coding
agent. Status transitions keep the clarification loop explicit rather than
turning every raw comment immediately into implementation work.