@mhosaic/feedback 0.15.3 → 0.15.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,100 @@
1
+ # @mhosaic/feedback
2
+
3
+ Embeddable feedback + bug-report widget. Preact + Shadow DOM (renders inside any host app without leaking styles), opt-in modules for session replay, Web Vitals, and automatic error capture.
4
+
5
+ The fastest way to integrate is the guided Claude Code skill — it walks you through both halves (operator provisioning + consumer install), framework-aware, with a live smoke test that confirms a report lands in admin before declaring done.
6
+
7
+ ## The 30-second install (guided)
8
+
9
+ ```bash
10
+ # 1. One-time: drop the skill into ~/.claude/skills/
11
+ npx @mhosaic/feedback-cli@latest install-skill
12
+
13
+ # 2. In any project where you want the widget:
14
+ cd ~/path/to/your-app
15
+ claude
16
+ ```
17
+
18
+ Inside Claude Code:
19
+
20
+ ```
21
+ /integrate-feedback
22
+ ```
23
+
24
+ The skill asks one question (operator / consumer / both) and drives the rest: framework detection, env files, provider wiring, `identify()` recipe for your auth provider, smoke test in Chrome. Full docs: [`docs/INTEGRATING.md`](https://github.com/mhosaic-technologies/feedback-tool-mhosaic/blob/main/docs/INTEGRATING.md) in the source repo.
25
+
26
+ ## Manual install
27
+
28
+ ```bash
29
+ npm install @mhosaic/feedback
30
+ ```
31
+
32
+ ```typescript
33
+ import { createFeedback } from '@mhosaic/feedback'
34
+ import { withErrorTracking } from '@mhosaic/feedback/error-tracking'
35
+ import { withReplay } from '@mhosaic/feedback/replay'
36
+ import { withWebVitals } from '@mhosaic/feedback/webvitals'
37
+
38
+ const fb = withErrorTracking(
39
+ withReplay(
40
+ withWebVitals(createFeedback({
41
+ apiKey: 'pk_proj_…',
42
+ endpoint: 'https://your-feedback-backend.example.com',
43
+ env: 'prod',
44
+ }))
45
+ )
46
+ )
47
+
48
+ // Call identify() once auth resolves; FAB stays hidden until then.
49
+ fb.identify({ id: 'user-id', email: 'user@example.com', name: 'User' })
50
+ ```
51
+
52
+ Or via CDN with pinned SRI:
53
+
54
+ ```html
55
+ <script
56
+ src="https://cdn.jsdelivr.net/npm/@mhosaic/feedback@0.15.4/dist/embed.min.js"
57
+ integrity="sha384-…"
58
+ crossorigin="anonymous"
59
+ data-key="pk_proj_…"
60
+ data-endpoint="https://your-feedback-backend.example.com"
61
+ data-env="prod"
62
+ defer
63
+ ></script>
64
+ ```
65
+
66
+ Pin the exact version + integrity hash — `@latest` breaks SRI. Hash is published in each GitHub Release.
67
+
68
+ ## React provider
69
+
70
+ For React hosts, `@mhosaic/feedback/react` exposes `<FeedbackProvider>` + `useFeedback()`:
71
+
72
+ ```tsx
73
+ import { FeedbackProvider } from '@mhosaic/feedback/react'
74
+
75
+ <FeedbackProvider apiKey={…} endpoint={…} env="prod">
76
+ <App />
77
+ </FeedbackProvider>
78
+ ```
79
+
80
+ The CLI auto-wires this for Vite + React apps on `init`. For Next/Remix/Vue/SvelteKit/Astro/Nuxt, see the framework-specific reference docs at `packages/cli/skills/integrate-feedback/references/` (or `~/.claude/skills/integrate-feedback/references/` after `install-skill`).
81
+
82
+ ## Opt-in modules
83
+
84
+ | Subpath | What it does | Approx gzip |
85
+ |---|---|---|
86
+ | `@mhosaic/feedback/replay` | rrweb session replay (last N seconds) | ~15 KiB |
87
+ | `@mhosaic/feedback/webvitals` | Core Web Vitals capture | ~3 KiB |
88
+ | `@mhosaic/feedback/error-tracking` | Auto-files synthetic reports on `window.error` + `unhandledrejection` | ~2 KiB |
89
+
90
+ All three are middleware wrappers — chain them around `createFeedback()`. See the install snippet above.
91
+
92
+ ## Backend
93
+
94
+ The widget POSTs to your `mhosaic-feedback` Django backend at `/api/feedback/v1/reports/`. The backend is multi-tenant (Company → Project → Report) and authenticates the widget by `pk_proj_…` Bearer key + origin allow-list. Source + deployment: <https://github.com/mhosaic-technologies/feedback-tool-mhosaic>.
95
+
96
+ ## Links
97
+
98
+ - **Source code + issues:** <https://github.com/mhosaic-technologies/feedback-tool-mhosaic>
99
+ - **Design spec:** [`docs/superpowers/specs/2026-04-21-feedback-plugin-design.md`](https://github.com/mhosaic-technologies/feedback-tool-mhosaic/blob/main/docs/superpowers/specs/2026-04-21-feedback-plugin-design.md)
100
+ - **CLI:** [`@mhosaic/feedback-cli`](https://www.npmjs.com/package/@mhosaic/feedback-cli)
@@ -4731,8 +4731,8 @@ function createFeedback(config) {
4731
4731
  capture_method: captureMethod,
4732
4732
  technical_context
4733
4733
  };
4734
- if ("0.15.3") {
4735
- payload.widget_version = "0.15.3";
4734
+ if ("0.15.5") {
4735
+ payload.widget_version = "0.15.5";
4736
4736
  }
4737
4737
  if (manualScreenshot) payload.screenshot = manualScreenshot;
4738
4738
  if (values.synthetic) payload.synthetic = true;
@@ -4818,4 +4818,4 @@ function createFeedback(config) {
4818
4818
  export {
4819
4819
  createFeedback
4820
4820
  };
4821
- //# sourceMappingURL=chunk-SRAA5JQN.mjs.map
4821
+ //# sourceMappingURL=chunk-TEQF35XT.mjs.map
package/dist/embed.min.js CHANGED
@@ -1679,5 +1679,5 @@
1679
1679
  @media (prefers-reduced-motion: reduce) {
1680
1680
  .skeleton-line { animation: none; }
1681
1681
  }
1682
- `;function $t(e){let t=e.host.attachShadow({mode:"open"}),r=document.createElement("style");r.textContent=It,t.appendChild(r);let n=document.createElement("div");t.appendChild(n);let a={open:!1,status:"idle",tab:"send"},i=null;function s(c){a=c,Ae(Be(f,{state:c}),n)}function l(c){let{selectedReportId:b,...d}=c;return d}function f({state:c}){var w;let b=_t(async h=>{s({...a,status:"submitting"});try{await e.onSubmit(h),s({...a,status:"success"}),i!==null&&clearTimeout(i),i=setTimeout(()=>{i=null,s({...a,open:!1,status:"idle",tab:e.api?"mine":"send"})},1200)}catch(m){typeof console!="undefined"&&console.warn("[mhosaic] submit:",m),s({...a,status:"error",error:e.strings["form.error"]})}},[]),d=(w=e.getExternalId)==null?void 0:w.call(e),y=e.showFAB&&(e.getExternalId===void 0?!0:!!d),v=!!(e.api&&d);return o(N,{children:[y&&o(Et,{label:e.strings["fab.label"],onClick:()=>s({...a,open:!0})}),c.open&&o(At,{onDismiss:()=>s(l({...a,open:!1,status:"idle"})),closeLabel:e.strings["form.close"],expanded:c.tab==="board",children:[v&&o("div",{class:"tab-strip",role:"tablist",children:[o("button",{type:"button",role:"tab","aria-selected":c.tab==="send",class:`tab-button ${c.tab==="send"?"is-active":""}`,onClick:()=>s(l({...a,tab:"send"})),children:e.strings["tab.send"]}),o("button",{type:"button",role:"tab","aria-selected":c.tab==="mine",class:`tab-button ${c.tab==="mine"?"is-active":""}`,onClick:()=>s(l({...a,tab:"mine"})),children:e.strings["tab.mine"]}),o("button",{type:"button",role:"tab","aria-selected":c.tab==="changelog",class:`tab-button ${c.tab==="changelog"?"is-active":""}`,onClick:()=>s(l({...a,tab:"changelog"})),children:e.strings["tab.changelog"]}),o("button",{type:"button",role:"tab","aria-selected":c.tab==="board",class:`tab-button tab-button--board ${c.tab==="board"?"is-active":""}`,onClick:()=>s(l({...a,tab:"board"})),children:e.strings["tab.board"]})]}),c.tab==="send"&&o(zt,{strings:e.strings,onSubmit:b,onCancel:()=>s({...a,open:!1,status:"idle"}),status:c.status,...c.error!==void 0&&{errorMessage:c.error}}),c.tab==="mine"&&e.api&&d&&!c.selectedReportId&&o(Ft,{api:e.api,externalId:d,strings:e.strings,onSelect:h=>s({...a,selectedReportId:h.id})}),(c.tab==="mine"||c.tab==="changelog")&&e.api&&d&&c.selectedReportId&&o(ve,{api:e.api,externalId:d,reportId:c.selectedReportId,strings:e.strings,onBack:()=>s(l({...a}))}),c.tab==="changelog"&&e.api&&d&&!c.selectedReportId&&o(Rt,{api:e.api,externalId:d,strings:e.strings,onSelect:h=>s({...a,selectedReportId:h.id})}),c.tab==="board"&&e.api&&d&&o(Ct,{api:e.api,externalId:d,strings:e.strings})]})]})}return s(a),{open(){s({...a,open:!0})},close(){s({...a,open:!1,status:"idle"})},dispose(){i!==null&&(clearTimeout(i),i=null),Ae(null,n),e.host.innerHTML=""},notifyIdentityChanged(){s({...a})}}}function He(e){var v,w,h,m,p;let t=(v=e.env)!=null?v:"prod",r=(w=e.locale)!=null?w:typeof navigator!="undefined"?navigator.language:void 0,n=Ze((h=e.translations)!=null?h:{},r!==void 0?{locale:r}:{}),a=Xe({...e.sanitizeUrl!==void 0&&{sanitizeUrl:e.sanitizeUrl}}),i=e.user,s=(m=e.metadata)!=null?m:{},l=Ne({apiKey:e.apiKey,endpoint:e.endpoint,...e.fetchImpl!==void 0&&{fetch:e.fetchImpl},...e.beforeSend!==void 0&&{beforeSend:e.beforeSend},getSignedIdentity:()=>!i||!i.userHash||!i.exp||!i.email?null:{userHash:i.userHash,exp:i.exp,email:i.email}}),f=[],c=document.createElement("div");if(c.className="mhosaic-feedback",e.attachTo){let u=typeof e.attachTo=="string"?document.querySelector(e.attachTo):e.attachTo;u==null||u.appendChild(c)}else document.body.appendChild(c);async function b(u){var F,B,W,z,j;let _=u.synthetic?void 0:u.screenshot,S=a.snapshot();if(i){let{userHash:D,exp:G,...ne}=i;S.user=ne}s&&Object.keys(s).length>0&&(S.metadata={...s});let R=_?(F=u.capture_method)!=null?F:"manual":"none",L={description:u.description,feedback_type:(B=u.feedback_type)!=null?B:"bug",severity:(W=u.severity)!=null?W:"medium",env:t,page_url:window.location.href,user_agent:navigator.userAgent,capture_method:R,technical_context:S};L.widget_version="0.15.3",_&&(L.screenshot=_),u.synthetic&&(L.synthetic=!0),(i==null?void 0:i.id)!==void 0&&i.id!==null&&i.id!==""&&(L.user={id:String(i.id),...i.email!==void 0&&{email:i.email},...i.name!==void 0&&{name:i.name}});let T=L;for(let D of f)T=await D(T);try{let D=await l.submitReport(T);return(z=e.onSubmitSuccess)==null||z.call(e,D),a.clear(),D}catch(D){let G=D instanceof Error?D:new Error(String(D));throw(j=e.onError)==null||j.call(e,G),G}}let d=$t({host:c,strings:n,showFAB:(p=e.showFAB)!=null?p:!0,onSubmit:async u=>{await b(u)},api:l,getExternalId:()=>(i==null?void 0:i.id)!==void 0&&i.id!==null&&i.id!==""?String(i.id):void 0}),y={show(){d.open()},hide(){d.close()},open(u){d.open()},async submit(u){return b({description:u.description,...u.feedback_type!==void 0&&{feedback_type:u.feedback_type},...u.severity!==void 0&&{severity:u.severity},...u.synthetic!==void 0&&{synthetic:u.synthetic},...u.screenshot!==void 0&&{screenshot:u.screenshot}})},identify(u){i=u,d.notifyIdentityChanged()},setMetadata(u){s={...s,...u}},shutdown(){d.dispose(),a.dispose(),c.remove();let u=window;u.mhosaicFeedback===y&&delete u.mhosaicFeedback},_registerTransformer(u){f.push(u)}};return window.mhosaicFeedback=y,y}var Ht=window;function po(){let e=document.currentScript;if(!e)return null;let t=e.dataset.key,r=e.dataset.endpoint;if(!t||!r)return null;let n=e.dataset.env;return{apiKey:t,endpoint:r,...n!==void 0&&{env:n}}}var J=null,Wt,Kt,xe=(Kt=(Wt=Ht.Feedback)==null?void 0:Wt.q)!=null?Kt:[];function Nt(e){let[t,r]=e;if(t==="init"){if(J)return;J=He(r);return}if(!J){xe.push(e);return}t==="identify"?J.identify(r):t==="setMetadata"?J.setMetadata(r):t==="open"&&J.open(r)}var Dt=po();Dt&&(J=He(Dt));for(;xe.length>0;)Nt(xe.shift());var uo=Object.assign(function(t,r){Nt([t,r])},{q:xe});Ht.Feedback=uo;})();
1682
+ `;function $t(e){let t=e.host.attachShadow({mode:"open"}),r=document.createElement("style");r.textContent=It,t.appendChild(r);let n=document.createElement("div");t.appendChild(n);let a={open:!1,status:"idle",tab:"send"},i=null;function s(c){a=c,Ae(Be(f,{state:c}),n)}function l(c){let{selectedReportId:b,...d}=c;return d}function f({state:c}){var w;let b=_t(async h=>{s({...a,status:"submitting"});try{await e.onSubmit(h),s({...a,status:"success"}),i!==null&&clearTimeout(i),i=setTimeout(()=>{i=null,s({...a,open:!1,status:"idle",tab:e.api?"mine":"send"})},1200)}catch(m){typeof console!="undefined"&&console.warn("[mhosaic] submit:",m),s({...a,status:"error",error:e.strings["form.error"]})}},[]),d=(w=e.getExternalId)==null?void 0:w.call(e),y=e.showFAB&&(e.getExternalId===void 0?!0:!!d),v=!!(e.api&&d);return o(N,{children:[y&&o(Et,{label:e.strings["fab.label"],onClick:()=>s({...a,open:!0})}),c.open&&o(At,{onDismiss:()=>s(l({...a,open:!1,status:"idle"})),closeLabel:e.strings["form.close"],expanded:c.tab==="board",children:[v&&o("div",{class:"tab-strip",role:"tablist",children:[o("button",{type:"button",role:"tab","aria-selected":c.tab==="send",class:`tab-button ${c.tab==="send"?"is-active":""}`,onClick:()=>s(l({...a,tab:"send"})),children:e.strings["tab.send"]}),o("button",{type:"button",role:"tab","aria-selected":c.tab==="mine",class:`tab-button ${c.tab==="mine"?"is-active":""}`,onClick:()=>s(l({...a,tab:"mine"})),children:e.strings["tab.mine"]}),o("button",{type:"button",role:"tab","aria-selected":c.tab==="changelog",class:`tab-button ${c.tab==="changelog"?"is-active":""}`,onClick:()=>s(l({...a,tab:"changelog"})),children:e.strings["tab.changelog"]}),o("button",{type:"button",role:"tab","aria-selected":c.tab==="board",class:`tab-button tab-button--board ${c.tab==="board"?"is-active":""}`,onClick:()=>s(l({...a,tab:"board"})),children:e.strings["tab.board"]})]}),c.tab==="send"&&o(zt,{strings:e.strings,onSubmit:b,onCancel:()=>s({...a,open:!1,status:"idle"}),status:c.status,...c.error!==void 0&&{errorMessage:c.error}}),c.tab==="mine"&&e.api&&d&&!c.selectedReportId&&o(Ft,{api:e.api,externalId:d,strings:e.strings,onSelect:h=>s({...a,selectedReportId:h.id})}),(c.tab==="mine"||c.tab==="changelog")&&e.api&&d&&c.selectedReportId&&o(ve,{api:e.api,externalId:d,reportId:c.selectedReportId,strings:e.strings,onBack:()=>s(l({...a}))}),c.tab==="changelog"&&e.api&&d&&!c.selectedReportId&&o(Rt,{api:e.api,externalId:d,strings:e.strings,onSelect:h=>s({...a,selectedReportId:h.id})}),c.tab==="board"&&e.api&&d&&o(Ct,{api:e.api,externalId:d,strings:e.strings})]})]})}return s(a),{open(){s({...a,open:!0})},close(){s({...a,open:!1,status:"idle"})},dispose(){i!==null&&(clearTimeout(i),i=null),Ae(null,n),e.host.innerHTML=""},notifyIdentityChanged(){s({...a})}}}function He(e){var v,w,h,m,p;let t=(v=e.env)!=null?v:"prod",r=(w=e.locale)!=null?w:typeof navigator!="undefined"?navigator.language:void 0,n=Ze((h=e.translations)!=null?h:{},r!==void 0?{locale:r}:{}),a=Xe({...e.sanitizeUrl!==void 0&&{sanitizeUrl:e.sanitizeUrl}}),i=e.user,s=(m=e.metadata)!=null?m:{},l=Ne({apiKey:e.apiKey,endpoint:e.endpoint,...e.fetchImpl!==void 0&&{fetch:e.fetchImpl},...e.beforeSend!==void 0&&{beforeSend:e.beforeSend},getSignedIdentity:()=>!i||!i.userHash||!i.exp||!i.email?null:{userHash:i.userHash,exp:i.exp,email:i.email}}),f=[],c=document.createElement("div");if(c.className="mhosaic-feedback",e.attachTo){let u=typeof e.attachTo=="string"?document.querySelector(e.attachTo):e.attachTo;u==null||u.appendChild(c)}else document.body.appendChild(c);async function b(u){var F,B,W,z,j;let _=u.synthetic?void 0:u.screenshot,S=a.snapshot();if(i){let{userHash:D,exp:G,...ne}=i;S.user=ne}s&&Object.keys(s).length>0&&(S.metadata={...s});let R=_?(F=u.capture_method)!=null?F:"manual":"none",L={description:u.description,feedback_type:(B=u.feedback_type)!=null?B:"bug",severity:(W=u.severity)!=null?W:"medium",env:t,page_url:window.location.href,user_agent:navigator.userAgent,capture_method:R,technical_context:S};L.widget_version="0.15.5",_&&(L.screenshot=_),u.synthetic&&(L.synthetic=!0),(i==null?void 0:i.id)!==void 0&&i.id!==null&&i.id!==""&&(L.user={id:String(i.id),...i.email!==void 0&&{email:i.email},...i.name!==void 0&&{name:i.name}});let T=L;for(let D of f)T=await D(T);try{let D=await l.submitReport(T);return(z=e.onSubmitSuccess)==null||z.call(e,D),a.clear(),D}catch(D){let G=D instanceof Error?D:new Error(String(D));throw(j=e.onError)==null||j.call(e,G),G}}let d=$t({host:c,strings:n,showFAB:(p=e.showFAB)!=null?p:!0,onSubmit:async u=>{await b(u)},api:l,getExternalId:()=>(i==null?void 0:i.id)!==void 0&&i.id!==null&&i.id!==""?String(i.id):void 0}),y={show(){d.open()},hide(){d.close()},open(u){d.open()},async submit(u){return b({description:u.description,...u.feedback_type!==void 0&&{feedback_type:u.feedback_type},...u.severity!==void 0&&{severity:u.severity},...u.synthetic!==void 0&&{synthetic:u.synthetic},...u.screenshot!==void 0&&{screenshot:u.screenshot}})},identify(u){i=u,d.notifyIdentityChanged()},setMetadata(u){s={...s,...u}},shutdown(){d.dispose(),a.dispose(),c.remove();let u=window;u.mhosaicFeedback===y&&delete u.mhosaicFeedback},_registerTransformer(u){f.push(u)}};return window.mhosaicFeedback=y,y}var Ht=window;function po(){let e=document.currentScript;if(!e)return null;let t=e.dataset.key,r=e.dataset.endpoint;if(!t||!r)return null;let n=e.dataset.env;return{apiKey:t,endpoint:r,...n!==void 0&&{env:n}}}var J=null,Wt,Kt,xe=(Kt=(Wt=Ht.Feedback)==null?void 0:Wt.q)!=null?Kt:[];function Nt(e){let[t,r]=e;if(t==="init"){if(J)return;J=He(r);return}if(!J){xe.push(e);return}t==="identify"?J.identify(r):t==="setMetadata"?J.setMetadata(r):t==="open"&&J.open(r)}var Dt=po();Dt&&(J=He(Dt));for(;xe.length>0;)Nt(xe.shift());var uo=Object.assign(function(t,r){Nt([t,r])},{q:xe});Ht.Feedback=uo;})();
1683
1683
  //# sourceMappingURL=embed.min.js.map
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createFeedback
3
- } from "./chunk-SRAA5JQN.mjs";
3
+ } from "./chunk-TEQF35XT.mjs";
4
4
  import "./chunk-FGA63IEZ.mjs";
5
5
  export {
6
6
  createFeedback
package/dist/react.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createFeedback
3
- } from "./chunk-SRAA5JQN.mjs";
3
+ } from "./chunk-TEQF35XT.mjs";
4
4
  import "./chunk-FGA63IEZ.mjs";
5
5
 
6
6
  // src/react/FeedbackProvider.tsx
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mhosaic/feedback",
3
- "version": "0.15.3",
3
+ "version": "0.15.5",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "exports": {