{"_id":"@bamr87/fleet-feedback","_rev":"2-453c8865606dfd24b7d51a3946a74d42","name":"@bamr87/fleet-feedback","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.0":{"name":"@bamr87/fleet-feedback","version":"0.1.0","keywords":["feedback","github-issues","web-component","fleet"],"author":{"name":"bamr87"},"license":"MIT","_id":"@bamr87/fleet-feedback@0.1.0","maintainers":[{"name":"bamrman","email":"Amr.abdel@gmail.com"}],"homepage":"https://github.com/bamr87/bamr87/tree/main/templates/feedback","bugs":{"url":"https://github.com/bamr87/bamr87/issues"},"dist":{"shasum":"06913aa3936b031b26f49688e929b6a03e964076","tarball":"https://registry.npmjs.org/@bamr87/fleet-feedback/-/fleet-feedback-0.1.0.tgz","fileCount":9,"integrity":"sha512-Ry66fMnDoPQtVFsMpxAIhUpuEq7NlmG4/p0VKSxrN1QpyMKdjBhAoIQwlL10uoATShkAUB5AyudE4uLH5H4ZpA==","signatures":[{"sig":"MEQCIEtDGysNxaqEl0yjb9ULC5lukXAEHzYIL1sORgN0VMveAiB/3GqEIfO/ouF0/+vSvw8jFvnwftRVD9Hc+pt7ecujnw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bamr87%2ffleet-feedback@0.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":40850},"main":"fleet-feedback.js","browser":"fleet-feedback.js","exports":{".":"./fleet-feedback.js","./react":"./adapters/FeedbackButton.tsx","./types":"./feedback_types.yml","./issue-template":"./page_feedback.yml"},"gitHead":"61e58e4db17856e8557ff7501ecbd4bc7302fd10","_npmUser":{"name":"bamrman","email":"Amr.abdel@gmail.com"},"repository":{"url":"git+https://github.com/bamr87/bamr87.git","type":"git","directory":"templates/feedback"},"_npmVersion":"10.8.2","description":"Universal 'Improve this page' widget: a zero-dependency <fleet-feedback> web component that files a prefilled GitHub issue with page context, environment, and captured console errors. Spec: bamr87/bamr87 specs/FEEDBACK.md.","directories":{},"sideEffects":true,"_nodeVersion":"20.20.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/fleet-feedback_0.1.0_1788312218502_0.6796597186795612","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@bamr87/fleet-feedback","version":"0.2.0","description":"Universal 'Improve this page' widget: a zero-dependency <fleet-feedback> web component that files a prefilled GitHub issue with page context, environment, and captured console errors. Spec: bamr87/bamr87 specs/FEEDBACK.md.","license":"MIT","author":{"name":"bamr87"},"repository":{"type":"git","url":"git+https://github.com/bamr87/bamr87.git","directory":"templates/feedback"},"homepage":"https://github.com/bamr87/bamr87/tree/main/templates/feedback","keywords":["feedback","github-issues","web-component","fleet"],"main":"fleet-feedback.js","browser":"fleet-feedback.js","exports":{".":"./fleet-feedback.js","./capture":"./capture.js","./react":"./adapters/FeedbackButton.tsx","./nextjs":"./adapters/nextjs.tsx","./types":"./feedback_types.yml","./issue-template":"./page_feedback.yml"},"sideEffects":true,"publishConfig":{"access":"public"},"scripts":{"test":"node --test tests/contract.test.mjs"},"_id":"@bamr87/fleet-feedback@0.2.0","gitHead":"355e76f4f6a9772d96c72a10e54c947c5332ecfb","bugs":{"url":"https://github.com/bamr87/bamr87/issues"},"_nodeVersion":"20.20.2","_npmVersion":"10.8.2","dist":{"integrity":"sha512-jrCUWIehKmj+Z6oQMUV8cCf1b3lgcnqj8fEAUbYJVSsXEhb9wVzk43hkOF6DDi0WdFR1yu/gLtSKmwhNmQr5+g==","shasum":"851d17e725cd125c5c650903b99933f61024860c","tarball":"https://registry.npmjs.org/@bamr87/fleet-feedback/-/fleet-feedback-0.2.0.tgz","fileCount":11,"unpackedSize":75943,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bamr87%2ffleet-feedback@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIBA8ALUbxBw6dYH/8/I6IyMdFqC7BCt8EApvnRA9dOviAiB6xeLQULXb3o2jWig9VHyg4i/Gg1EIl7oxkYJ0RQdGHA=="}]},"_npmUser":{"name":"bamrman","email":"Amr.abdel@gmail.com"},"directories":{},"maintainers":[{"name":"bamrman","email":"Amr.abdel@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/fleet-feedback_0.2.0_1788804198712_0.6587145458045716"},"_hasShrinkwrap":false}},"time":{"created":"2026-09-02T01:23:38.237Z","modified":"2026-09-07T18:03:19.247Z","0.1.0":"2026-09-02T01:23:38.630Z","0.2.0":"2026-09-07T18:03:18.900Z"},"bugs":{"url":"https://github.com/bamr87/bamr87/issues"},"author":{"name":"bamr87"},"license":"MIT","homepage":"https://github.com/bamr87/bamr87/tree/main/templates/feedback","keywords":["feedback","github-issues","web-component","fleet"],"repository":{"type":"git","url":"git+https://github.com/bamr87/bamr87.git","directory":"templates/feedback"},"description":"Universal 'Improve this page' widget: a zero-dependency <fleet-feedback> web component that files a prefilled GitHub issue with page context, environment, and captured console errors. Spec: bamr87/bamr87 specs/FEEDBACK.md.","maintainers":[{"name":"bamrman","email":"Amr.abdel@gmail.com"}],"readme":"# templates/feedback — the universal feedback widget kit\n\n> `<fleet-feedback>`: one component that gives any page, in any stack, an \"Improve this page\" button which files a prefilled GitHub issue carrying page context, environment, and the console errors that led up to the report. Spec: [`specs/FEEDBACK.md`](../../specs/FEEDBACK.md) (UPS-FB).\n\n| File | Purpose |\n| --- | --- |\n| `fleet-feedback.js` | The component, in three layers: the capture buffer, `FleetFeedbackCore` (the issue contract as pure functions), and `<fleet-feedback>` (the default dialog). Zero dependencies, shadow DOM, native `<dialog>`, token-aware (`--fleet-*` with `--zer0-*`/`--bs-*` fallbacks). |\n| `capture.js` | The buffer alone, for `<head>`. Byte-identical to the block inside `fleet-feedback.js`. |\n| `feedback_types.yml` | The request-type taxonomy (also embedded in the JS as the fallback). Type labels map onto the fleet issue-pipeline label set. |\n| `page_feedback.yml` | The no-JS twin: a GitHub issue form the inline anchor points at, with the same sections. Copy to `.github/ISSUE_TEMPLATE/`. |\n| `adapters/jekyll.html` | Include for Jekyll sites not on the zer0-mistakes theme (and MkDocs overrides). |\n| `adapters/FeedbackButton.tsx` | React/Next wrapper, plus `openFeedback()` and `breadcrumb()` for the error boundary, 404 route, and fetch wrapper. |\n| `adapters/nextjs.tsx` | `FeedbackCapture` — installs the buffer `beforeInteractive` from the App Router root layout. |\n| `adapters/django.html` | Django template snippet (translate 1:1 to ERB for Rails). |\n| `tests/contract.test.mjs` | 25 contract tests. `npm test` — `node:test`, no dependencies. |\n| `VERSION` · `archive/` | Kit provenance, changelog, and the shapes `--upgrade` recognises as machine-seeded. |\n\n## Install\n\nThe fan-out does all of this for a fleet repo:\n\n```bash\ntools/fanout.sh --kit feedback --target <name> --apply\n```\n\nBy hand, in any stack:\n\n1. Vendor `capture.js` and `fleet-feedback.js` into the repo's static assets (`assets/js/`, `public/`, `static/js/`). Never hot-link the hub.\n2. Load `capture.js` **first, in `<head>`**, and `fleet-feedback.js` before `</body>`. The split is the point: a buffer installed after hydration reports a clean console for exactly the failures worth reporting.\n3. Mount the element once in the shell with at least `repo=\"owner/name\"`. Use the adapter for your stack.\n4. Create the labels — `page-feedback`, `bug`, `feature`, `docs`, `question`, `area:a11y`, `area:perf` (`gh label create …`). **GitHub silently drops unknown labels** from a prefilled URL: no error, no warning, the label is simply gone.\n5. Copy `page_feedback.yml` to `.github/ISSUE_TEMPLATE/` so the no-JS anchor works.\n6. Wire the integrations: 404 page → `FleetFeedback.open({type:'fix-page', extra:'Missing URL: …'})`; error boundary → `open({type:'fix-page', extra: stack})`; \"Suggest an edit\" → `data-fleet-feedback-open data-type=\"improve-page\"`.\n\n## Contract (what an issue looks like)\n\nTitle `[<type label>] <page title>`. Body, in this order, each under a `##` heading: **Description** · **Page context** table · **Environment** table · **Console & error logs** (`<details>`) · **Agent directive** (agent types only) · footer with `<!-- fleet-feedback v1 type=<id> -->`. Labels = marker + type labels; assignee = `copilot` for agent types. URL budget 7000 chars, trimming logs → directive → environment, with the full body copied to the clipboard whenever anything was trimmed or the pop-up was blocked. Nothing is ever silently lost.\n\nThat hidden marker is the load-bearing part: the issue pipeline's intake tier reads it and treats the report as already structured instead of re-templating it.\n\n## Two UIs, one contract\n\n`FleetFeedbackCore` is pure — explicit input object in, strings out, no DOM and no globals — so it runs under Node in the tests, and so a host with its own dialog can produce a byte-identical issue by calling it. The zer0-mistakes theme does exactly that: it vendors this file for the buffer and the core, keeps its Bootstrap modal and its AI triage step, and never writes the `<fleet-feedback>` tag. Change the contract here and both widgets move together.\n\n```js\nFleetFeedbackCore.buildIssue({ type, description, extra, page, environment, logs, config })\n  // -> { title, body, sections, labels, assignees, marker, type }\nFleetFeedbackCore.buildUrl(issue, { repo })\n  // -> { url, trimmed, overBudget, fullBody }\n```\n\n## Attributes\n\n`repo` (required) · `branch` · `source` · `route` · `page-title` · `labels` (csv markers) · `assignee` (`''` disables) · `mode` (`url` | `proxy` | `postmessage`) · `endpoint` · `capture-logs` · `log-limit` · `fab` · `label` · `env` · `app-version` · `types` (URL of a JSON array; or an inline `<script type=\"application/json\">` child).\n\n`url` mode needs no token — the reader submits the prefilled form under their own account. `proxy` mode POSTs `{title, body, labels, assignees, type}` to an endpoint that holds the token server-side, falling back to the URL path rather than losing the report. `postmessage` mode hands the issue to a sandboxed host (a VS Code extension) that has no `window.open` of its own.\n\n## JS API\n\n```js\nFleetFeedback.open({ type: 'fix-page', extra: `Missing route: ${pathname}` });\nFleetFeedback.breadcrumb('net', `POST /api/analysis → 502 (1243ms) req=${id}`);\nwindow.__fleetFeedback.snapshot();   // the buffer, newest last\n```\n\nAny element with `[data-fleet-feedback-open]` (plus optional `data-type`) opens the dialog. Make it a real `issues/new` link and it keeps working when the script does not.\n\n## Privacy\n\nNo cookies, no analytics, no request of any kind until the reader submits. The environment section carries no identity, IP, or form contents. Every captured line is redacted before it enters the ring buffer — bearer tokens, API keys, JWTs, GitHub tokens, email addresses — and the reader previews the logs and can untick them before filing.\n\n## Theming\n\nReads `--fleet-color-{ink,bg-elevated,ink-muted,border,primary}`, `--fleet-radius-lg`, `--fleet-shadow-{lg,focus}`, `--fleet-layer-{fab-feedback,feedback-modal}`, `--fleet-space-fab-{offset,size,gap}`, `--fleet-font-sans`, `--fleet-motion-base`; each falls back to the zer0-mistakes / Bootstrap variable, then to a literal. Respects `prefers-reduced-motion`.\n\n## Changing the kit\n\n- The capture block lives in `capture.js` and is spliced into `fleet-feedback.js`. Edit it in **one** place; the parity test fails when the copies diverge.\n- Snapshot the outgoing `fleet-feedback.js` into `archive/` **before** editing it, or every deployed copy reads as hand-modified and `--upgrade` silently stops reaching the fleet.\n- `npm test` before committing. The contract these tests lock is what ~25 repositories file issues against.\n","readmeFilename":"README.md"}