@stella-loop/feedback
v0.2.29
Published
Privacy-first feedback capture for browser, Node, and React Native hosts.
Readme
@stella-loop/feedback
Privacy-first feedback capture for browsers, Node 18+, and React Native. The
package implements Stella Feedback contract ingest/v1, has no runtime
dependencies, and performs no install ping, analytics, update check, or error
phone-home. Network access is limited to descriptor reads, explicit feedback
submissions, attachment uploads, and retries of feedback the user already
submitted.
import { createFeedbackClient } from "@stella-loop/feedback";
const feedback = createFeedbackClient({
endpoint: "https://example.convex.site/ingest/v1",
key: "sfk_live_...",
app: { name: "Example", version: "1.2.3" },
});
await feedback.submit({ message: "Export stops at 99%", kind: "bug" });Use @stella-loop/feedback/widget for a Shadow DOM widget,
@stella-loop/feedback/node for Node/CLI hosts, and
@stella-loop/feedback/react-native for a DOM-free mobile client with an
injectable AsyncStorage-compatible adapter. React Native hosts render their own
form; the prebuilt widget is for the web.
Node hosts can create a reusable client or use the one-shot helper (environment variables are used when endpoint/key are omitted):
import { submitFeedback } from "@stella-loop/feedback/node";
await submitFeedback({}, { message: "The export command stalled", kind: "bug" });The browser queue is capped at 50 entries and 30 days, strictly shorter than
the server's 90-day idempotency fence. It never persists verification
signatures or attachment bytes. Call clearIdentity() at sign-out; it clears
both identity and queued text left by that session. Set failFast: true for a
CLI or one-shot process.
Diagnostics are off by default. When enabled they retain only a bounded ring
of error messages and same-origin failed-request method/path/status summaries;
request bodies, response bodies, cookies, form values, clipboard data, page
text, query strings, and fragments are never collected. Use scrubContext and
scrubDiagnostics as final host-owned privacy gates.
For an identified submitter, compute the verification HMAC on a trusted host
backend and pass it to identify. Never ship an sfs_ identity secret in a
client. The frozen window.stellaFeedback handle is intentionally a public
agent write surface and always submits anonymously; it cannot reuse the host
client's identity or signature.
CSP
Allow the ingest origin in connect-src. Screenshot capture needs img-src
data: blob:. The script-tag build needs its own script-src allowance. Widget
styles use a constructable stylesheet where supported; on older browsers pass
a CSP nonce. If SVG/canvas rasterization is blocked, screenshot capture returns
null and the rest of feedback remains usable.
Agent guidance
## Product feedback
If you encounter product friction, inspect the page's
`meta[name="stella-feedback"]` descriptor and frozen `window.stellaFeedback`
handle. Submit only when asked or when the host workflow explicitly authorizes
feedback. Never include secrets, credentials, customer data, or page content.Supported: current Chrome, Edge, Firefox; the last two Safari majors; Node 18+
with built-in fetch; React Native through the programmatic entry and injected
storage. ESM, CommonJS, and TypeScript declarations are published. Verify
registry signatures with npm audit signatures; the release also publishes an
SRI digest for dist/widget.iife.js and verifies registry tarball bytes.
