@polishd/next 0.2.1 → 0.2.2-dev.1

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.
Files changed (59) hide show
  1. package/CHANGELOG.md +57 -0
  2. package/DATABASE.md +8 -1
  3. package/README.md +52 -0
  4. package/dist/ai/actions.d.ts +10 -1
  5. package/dist/ai/actions.d.ts.map +1 -1
  6. package/dist/ai/actions.js +21 -0
  7. package/dist/ai/actions.js.map +1 -1
  8. package/dist/ai/ignored.d.ts +26 -0
  9. package/dist/ai/ignored.d.ts.map +1 -0
  10. package/dist/ai/ignored.js +134 -0
  11. package/dist/ai/ignored.js.map +1 -0
  12. package/dist/ai/summary.d.ts +8 -1
  13. package/dist/ai/summary.d.ts.map +1 -1
  14. package/dist/ai/summary.js +59 -22
  15. package/dist/ai/summary.js.map +1 -1
  16. package/dist/ai/types.d.ts +31 -0
  17. package/dist/ai/types.d.ts.map +1 -1
  18. package/dist/client/dom.d.ts +23 -0
  19. package/dist/client/dom.d.ts.map +1 -0
  20. package/dist/client/dom.js +71 -0
  21. package/dist/client/dom.js.map +1 -0
  22. package/dist/client/init.d.ts.map +1 -1
  23. package/dist/client/init.js +3 -62
  24. package/dist/client/init.js.map +1 -1
  25. package/dist/dashboard/index.d.ts.map +1 -1
  26. package/dist/dashboard/index.js +16 -10
  27. package/dist/dashboard/index.js.map +1 -1
  28. package/dist/dashboard/summary.d.ts.map +1 -1
  29. package/dist/dashboard/summary.js +64 -4
  30. package/dist/dashboard/summary.js.map +1 -1
  31. package/dist/dashboard/telemetry-consent.d.ts +3 -0
  32. package/dist/dashboard/telemetry-consent.d.ts.map +1 -0
  33. package/dist/dashboard/telemetry-consent.js +20 -0
  34. package/dist/dashboard/telemetry-consent.js.map +1 -0
  35. package/dist/dashboard/telemetry.d.ts +21 -0
  36. package/dist/dashboard/telemetry.d.ts.map +1 -0
  37. package/dist/dashboard/telemetry.js +212 -0
  38. package/dist/dashboard/telemetry.js.map +1 -0
  39. package/dist/dashboard.css +52 -0
  40. package/dist/server/ingest.d.ts +20 -0
  41. package/dist/server/ingest.d.ts.map +1 -1
  42. package/dist/server/ingest.js +49 -0
  43. package/dist/server/ingest.js.map +1 -1
  44. package/dist/server/store.d.ts +6 -2
  45. package/dist/server/store.d.ts.map +1 -1
  46. package/dist/server/store.js +34 -13
  47. package/dist/server/store.js.map +1 -1
  48. package/dist/server/telemetry.d.ts +28 -0
  49. package/dist/server/telemetry.d.ts.map +1 -0
  50. package/dist/server/telemetry.js +83 -0
  51. package/dist/server/telemetry.js.map +1 -0
  52. package/dist/shared/types.d.ts +16 -0
  53. package/dist/shared/types.d.ts.map +1 -1
  54. package/dist/shared/types.js.map +1 -1
  55. package/dist/telemetry.d.ts +43 -0
  56. package/dist/telemetry.d.ts.map +1 -0
  57. package/dist/telemetry.js +81 -0
  58. package/dist/telemetry.js.map +1 -0
  59. package/package.json +5 -1
@@ -14,7 +14,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
14
14
  * the server-side cadence refresh.
15
15
  */
16
16
  import { useState, useTransition } from "react";
17
- import { createIssueFromLossAction, generateSummaryAction } from "../ai/actions";
17
+ import { createIssueFromLossAction, generateSummaryAction, ignoreLossAction, unignoreLossAction, } from "../ai/actions";
18
18
  import { TabLink } from "./chrome";
19
19
  import { GearIcon, RefreshIcon, border, card, iconBtn, labelCls, primaryBtn, relTime } from "./ui";
20
20
  export default function SummaryCard({ initialSummary, initialSettings, initialStale, initialProfile, initialGaps, sourceAvailable, }) {
@@ -38,7 +38,7 @@ export default function SummaryCard({ initialSummary, initialSettings, initialSt
38
38
  };
39
39
  const hasSummary = summary !== null;
40
40
  const cadence = settings.refreshCadence ?? "manual";
41
- return (_jsxs("section", { className: `mb-8 ${card} overflow-hidden`, children: [_jsxs("div", { className: `flex items-center justify-between gap-3 border-b ${border} px-4 py-3 sm:px-5`, children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: labelCls, children: "All you need to know" }), settings.hasApiKey && (_jsxs("span", { className: "hidden rounded-full bg-[#1a1a1a] px-2 py-0.5 text-[10px] font-medium text-[#888] sm:inline", children: [settings.provider, " \u00B7 ", settings.model] }))] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("button", { type: "button", onClick: () => generate(hasSummary), disabled: pending || !settings.hasApiKey, title: settings.hasApiKey ? "Regenerate the summary now" : "Connect a model first", "aria-label": "Refresh summary", className: iconBtn, children: _jsx(RefreshIcon, { spinning: pending }) }), _jsx(TabLink, { tab: "settings", title: "Model, site context and GitHub settings", "aria-label": "Open settings", className: iconBtn, children: _jsx(GearIcon, {}) })] })] }), _jsxs("div", { className: "px-4 py-4 sm:px-5 sm:py-5", children: [error && (_jsx("div", { className: "mb-3 rounded-md border border-red-900/50 bg-red-950/30 px-3 py-2 text-[12px] text-red-400", children: error })), hasSummary ? (_jsxs(_Fragment, { children: [_jsx("p", { className: "text-[14px] leading-relaxed text-[#e4e4e4]", children: summary.text }), _jsx(WinsLosses, { wins: summary.wins, losses: summary.losses, githubConnected: settings.hasGithubToken && !!settings.githubRepo }), _jsxs("div", { className: "mt-3 flex flex-wrap items-center gap-x-3 gap-y-1 text-[11px] text-[#555]", children: [_jsxs("span", { children: ["Generated ", relTime(summary.generatedAt), " \u00B7 ", summary.provider, "/", summary.model, cadence !== "manual" && ` · refreshes ${cadence}`] }), stale && (_jsx("span", { className: "rounded-full bg-amber-950/50 px-2 py-0.5 text-amber-400", children: "New data since this summary \u2014 refresh to update" }))] })] })) : (_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [_jsx("p", { className: "text-[13px] leading-relaxed text-[#888]", children: settings.hasApiKey
41
+ return (_jsxs("section", { className: `mb-8 ${card} overflow-hidden`, children: [_jsxs("div", { className: `flex items-center justify-between gap-3 border-b ${border} px-4 py-3 sm:px-5`, children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: labelCls, children: "All you need to know" }), settings.hasApiKey && (_jsxs("span", { className: "hidden rounded-full bg-[#1a1a1a] px-2 py-0.5 text-[10px] font-medium text-[#888] sm:inline", children: [settings.provider, " \u00B7 ", settings.model] }))] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("button", { type: "button", onClick: () => generate(hasSummary), disabled: pending || !settings.hasApiKey, title: settings.hasApiKey ? "Regenerate the summary now" : "Connect a model first", "aria-label": "Refresh summary", className: iconBtn, children: _jsx(RefreshIcon, { spinning: pending }) }), _jsx(TabLink, { tab: "settings", title: "Model, site context and GitHub settings", "aria-label": "Open settings", className: iconBtn, children: _jsx(GearIcon, {}) })] })] }), _jsxs("div", { className: "px-4 py-4 sm:px-5 sm:py-5", children: [error && (_jsx("div", { className: "mb-3 rounded-md border border-red-900/50 bg-red-950/30 px-3 py-2 text-[12px] text-red-400", children: error })), hasSummary ? (_jsxs(_Fragment, { children: [_jsx("p", { className: "text-[14px] leading-relaxed text-[#e4e4e4]", children: summary.text }), _jsx(WinsLosses, { wins: summary.wins, losses: summary.losses, githubConnected: settings.hasGithubToken && !!settings.githubRepo }), _jsxs("div", { className: "mt-3 flex flex-wrap items-center gap-x-3 gap-y-1 text-[11px] text-[#555]", children: [_jsxs("span", { children: ["Generated ", relTime(summary.generatedAt), " \u00B7 ", summary.provider, "/", summary.model, cadence !== "manual" && ` · refreshes ${cadence}`] }), stale && (_jsx("span", { className: "rounded-full bg-amber-950/50 px-2 py-0.5 text-amber-400", children: "Something's changed since this summary \u2014 refresh to update" }))] })] })) : (_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [_jsx("p", { className: "text-[13px] leading-relaxed text-[#888]", children: settings.hasApiKey
42
42
  ? "No summary yet — generate the story of how visitors are using this site from the signals below."
43
43
  : "No model connected yet. Add a key in Settings and Polishd will read these numbers back to you in plain English." }), settings.hasApiKey ? (_jsx("button", { type: "button", onClick: () => generate(false), disabled: pending, className: primaryBtn, children: pending ? "Thinking…" : "Generate summary" })) : (_jsx(TabLink, { tab: "settings", className: primaryBtn, children: "Connect a model" }))] }))] }), _jsx(ProfileNudge, { profile: initialProfile, gaps: initialGaps, sourceAvailable: sourceAvailable })] }));
44
44
  }
@@ -61,6 +61,9 @@ function ProfileNudge({ profile, gaps, sourceAvailable, }) {
61
61
  return (_jsxs("div", { className: `flex flex-wrap items-center justify-between gap-2 border-t ${border} bg-[#080808] px-4 py-2.5 sm:px-5`, children: [_jsx("span", { className: "text-[11px] text-[#666]", children: message }), _jsxs(TabLink, { tab: "settings", className: "text-[11px] text-[#888] underline decoration-[#444] underline-offset-2 hover:text-white", children: [profile ? "Re-scan in Settings" : "Scan in Settings", " \u2192"] })] }));
62
62
  }
63
63
  // ── Wins & losses ────────────────────────────────────────────────────────────
64
+ /** The two verdicts on a loss sit side by side, and share their button style. */
65
+ const microBtn = "rounded border border-[#2e2e2e] px-1.5 py-0.5 text-[10px] text-[#888] transition-colors hover:border-[#555] hover:text-white disabled:cursor-not-allowed disabled:opacity-40";
66
+ const microLink = "text-[10px] text-[#666] underline decoration-[#333] underline-offset-2 transition-colors hover:text-[#ccc] disabled:cursor-not-allowed disabled:opacity-40";
64
67
  /**
65
68
  * One-click "loss → GitHub issue". The server action verifies the report
66
69
  * against the repository's source first: confirmed reports become issues with
@@ -91,13 +94,70 @@ function FileBugButton({ loss }) {
91
94
  else
92
95
  setFailed({ notABug: res.error === "not-a-bug", message: res.message });
93
96
  });
94
- return (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", onClick: file, disabled: pending, title: "Verify this problem against the source code, then create a GitHub issue with the technical details", className: "rounded border border-[#2e2e2e] px-1.5 py-0.5 text-[10px] text-[#888] transition-colors hover:border-[#555] hover:text-white disabled:cursor-not-allowed disabled:opacity-40", children: pending ? "Verifying…" : "File bug" }), failed && _jsx("span", { className: "text-[10px] text-red-400", children: failed.message })] }));
97
+ return (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", onClick: file, disabled: pending, title: "Verify this problem against the source code, then create a GitHub issue with the technical details", className: microBtn, children: pending ? "Verifying…" : "File bug" }), failed && _jsx("span", { className: "text-[10px] text-red-400", children: failed.message })] }));
98
+ }
99
+ /**
100
+ * One loss, and the two things you can do with it: file it as a bug, or ignore
101
+ * it. Ignoring takes one click and no explanation — a reason is offered
102
+ * afterwards, because the fast path is "this isn't a problem, stop showing me
103
+ * it" and typing shouldn't be the toll for that. A reason is worth giving
104
+ * though: it's replayed to the model on every later summary, so "the second CTA
105
+ * is deliberate" stops the same finding coming back in different words.
106
+ *
107
+ * The dismissal is stored server-side immediately; the row stays put, struck
108
+ * through with an undo, and only disappears on the next render. Ignored losses
109
+ * never reappear — not from the cached summary, and not from a regenerate.
110
+ */
111
+ function LossRow({ loss, githubConnected }) {
112
+ const [ignored, setIgnored] = useState(null);
113
+ const [editing, setEditing] = useState(false);
114
+ const [draft, setDraft] = useState("");
115
+ const [error, setError] = useState(null);
116
+ const [pending, startIgnore] = useTransition();
117
+ const ignore = (reason) => startIgnore(async () => {
118
+ setError(null);
119
+ const res = await ignoreLossAction({ issue: loss.issue, evidence: loss.evidence }, reason);
120
+ if (res.ok) {
121
+ setIgnored(res.ignored);
122
+ setEditing(false);
123
+ }
124
+ else
125
+ setError(res.message);
126
+ });
127
+ const undo = () => startIgnore(async () => {
128
+ setError(null);
129
+ const res = await unignoreLossAction(loss.evidence);
130
+ if (res.ok) {
131
+ setIgnored(null);
132
+ setEditing(false);
133
+ setDraft("");
134
+ }
135
+ else
136
+ setError(res.message);
137
+ });
138
+ if (ignored) {
139
+ return (_jsxs("li", { className: "flex gap-2 text-[13px] leading-snug text-[#666]", children: [_jsx("span", { className: "mt-px shrink-0 text-[#444]", children: "\u2715" }), _jsxs("span", { children: [_jsx("span", { className: "line-through decoration-[#3a3a3a]", children: loss.issue }), _jsxs("span", { className: "mt-0.5 flex flex-wrap items-center gap-1.5", children: [_jsxs("span", { className: "rounded bg-[#1a1a1a] px-1.5 py-0.5 text-[10px] text-[#777]", children: ["Ignored", ignored.reason ? ` — ${ignored.reason}` : ""] }), editing ? (_jsx(ReasonForm, { draft: draft, setDraft: setDraft, pending: pending, onSubmit: () => ignore(draft.trim() || undefined), onCancel: () => setEditing(false) })) : (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", onClick: () => {
140
+ setDraft(ignored.reason ?? "");
141
+ setEditing(true);
142
+ }, disabled: pending, title: "Tell the model why this isn't a problem \u2014 it reads this on every later summary", className: microLink, children: ignored.reason ? "Edit reason" : "Add a reason" }), _jsx("button", { type: "button", onClick: undo, disabled: pending, title: "Put this back \u2014 the model can report it again", className: microLink, children: pending ? "Undoing…" : "Undo" })] })), error && _jsx("span", { className: "text-[10px] text-red-400", children: error })] })] })] }));
143
+ }
144
+ return (_jsxs("li", { className: "flex gap-2 text-[13px] leading-snug text-[#bbb]", children: [_jsx("span", { className: "mt-px shrink-0 text-red-400", children: "\u2715" }), _jsxs("span", { children: [loss.issue, _jsxs("span", { className: "mt-0.5 flex flex-wrap items-center gap-1.5", children: [_jsx("code", { className: "rounded bg-[#1a1a1a] px-1.5 py-0.5 font-mono text-[10px] text-[#888]", children: loss.evidence }), loss.location ? (_jsx("code", { className: "rounded bg-[#101c14] px-1.5 py-0.5 font-mono text-[10px] text-emerald-500", children: loss.location })) : (_jsx("span", { className: "rounded bg-[#1a1a1a] px-1.5 py-0.5 text-[10px] text-[#666]", title: "The citation is real analytics data, but no matching file was found on disk (dynamic content, or source not available here).", children: "not matched to source" })), (githubConnected || !!loss.issueUrl) && _jsx(FileBugButton, { loss: loss }), _jsx("button", { type: "button", onClick: () => ignore(), disabled: pending, title: "Not a problem \u2014 drop it from this summary and stop the model reporting it again", className: microBtn, children: pending ? "Ignoring…" : "Ignore" }), error && _jsx("span", { className: "text-[10px] text-red-400", children: error })] })] })] }));
145
+ }
146
+ /** The optional half of ignoring: why it isn't a problem, in the owner's words. */
147
+ function ReasonForm({ draft, setDraft, pending, onSubmit, onCancel, }) {
148
+ return (_jsxs("form", { onSubmit: (e) => {
149
+ e.preventDefault();
150
+ onSubmit();
151
+ }, className: "flex flex-wrap items-center gap-1.5", children: [_jsx("input", { autoFocus: true, value: draft, onChange: (e) => setDraft(e.target.value), onKeyDown: (e) => {
152
+ if (e.key === "Escape")
153
+ onCancel();
154
+ }, maxLength: 240, placeholder: "Why isn't this a problem?", "aria-label": "Reason for ignoring this loss", className: "w-56 rounded border border-[#2e2e2e] bg-[#0d0d0d] px-1.5 py-0.5 text-[10px] text-[#ddd] placeholder:text-[#555] focus:border-[#555] focus:outline-none" }), _jsx("button", { type: "submit", disabled: pending, className: microBtn, children: pending ? "Saving…" : "Save" }), _jsx("button", { type: "button", onClick: onCancel, disabled: pending, className: microLink, children: "Cancel" })] }));
95
155
  }
96
156
  function WinsLosses({ wins, losses, githubConnected, }) {
97
157
  const hasWins = !!wins?.length;
98
158
  const hasLosses = !!losses?.length;
99
159
  if (!hasWins && !hasLosses)
100
160
  return null;
101
- return (_jsxs("div", { className: "mt-4 grid gap-4 sm:grid-cols-2", children: [hasWins && (_jsxs("div", { children: [_jsx("div", { className: `${labelCls} mb-2 text-emerald-500`, children: "Wins" }), _jsx("ul", { className: "space-y-1.5", children: wins.map((w, i) => (_jsxs("li", { className: "flex gap-2 text-[13px] leading-snug text-[#bbb]", children: [_jsx("span", { className: "mt-px shrink-0 text-emerald-500", children: "\u2713" }), _jsx("span", { children: w })] }, i))) })] })), hasLosses && (_jsxs("div", { children: [_jsx("div", { className: `${labelCls} mb-2 text-red-400`, children: "Losses" }), _jsx("ul", { className: "space-y-2.5", children: losses.map((l, i) => (_jsxs("li", { className: "flex gap-2 text-[13px] leading-snug text-[#bbb]", children: [_jsx("span", { className: "mt-px shrink-0 text-red-400", children: "\u2715" }), _jsxs("span", { children: [l.issue, _jsxs("span", { className: "mt-0.5 flex flex-wrap items-center gap-1.5", children: [_jsx("code", { className: "rounded bg-[#1a1a1a] px-1.5 py-0.5 font-mono text-[10px] text-[#888]", children: l.evidence }), l.location ? (_jsx("code", { className: "rounded bg-[#101c14] px-1.5 py-0.5 font-mono text-[10px] text-emerald-500", children: l.location })) : (_jsx("span", { className: "rounded bg-[#1a1a1a] px-1.5 py-0.5 text-[10px] text-[#666]", title: "The citation is real analytics data, but no matching file was found on disk (dynamic content, or source not available here).", children: "not matched to source" })), (githubConnected || !!l.issueUrl) && _jsx(FileBugButton, { loss: l })] })] })] }, i))) })] }))] }));
161
+ return (_jsxs("div", { className: "mt-4 grid gap-4 sm:grid-cols-2", children: [hasWins && (_jsxs("div", { children: [_jsx("div", { className: `${labelCls} mb-2 text-emerald-500`, children: "Wins" }), _jsx("ul", { className: "space-y-1.5", children: wins.map((w, i) => (_jsxs("li", { className: "flex gap-2 text-[13px] leading-snug text-[#bbb]", children: [_jsx("span", { className: "mt-px shrink-0 text-emerald-500", children: "\u2713" }), _jsx("span", { children: w })] }, i))) })] })), hasLosses && (_jsxs("div", { children: [_jsx("div", { className: `${labelCls} mb-2 text-red-400`, children: "Losses" }), _jsx("ul", { className: "space-y-2.5", children: losses.map((l, i) => (_jsx(LossRow, { loss: l, githubConnected: githubConnected }, l.evidence || i))) })] }))] }));
102
162
  }
103
163
  //# sourceMappingURL=summary.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"summary.js","sourceRoot":"","sources":["../../src/dashboard/summary.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"summary.js","sourceRoot":"","sources":["../../src/dashboard/summary.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare function grantPolishdTelemetry(): Promise<void>;
2
+ export declare function denyPolishdTelemetry(): Promise<void>;
3
+ //# sourceMappingURL=telemetry-consent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry-consent.d.ts","sourceRoot":"","sources":["../../src/dashboard/telemetry-consent.ts"],"names":[],"mappings":"AAYA,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAG3D;AAED,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAG1D"}
@@ -0,0 +1,20 @@
1
+ "use server";
2
+ /**
3
+ * Polishd — telemetry consent actions.
4
+ *
5
+ * The consent prompt's two buttons land here. Guarded like every other action
6
+ * in the package: server actions are independently addressable POST endpoints,
7
+ * so without the auth check anyone who found the action id could flip a
8
+ * dashboard's telemetry on. See ai/guard.ts.
9
+ */
10
+ import { requirePolishdAuth } from "../ai/guard";
11
+ import { saveTelemetryConsent } from "../server/telemetry";
12
+ export async function grantPolishdTelemetry() {
13
+ await requirePolishdAuth();
14
+ await saveTelemetryConsent(true);
15
+ }
16
+ export async function denyPolishdTelemetry() {
17
+ await requirePolishdAuth();
18
+ await saveTelemetryConsent(false);
19
+ }
20
+ //# sourceMappingURL=telemetry-consent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry-consent.js","sourceRoot":"","sources":["../../src/dashboard/telemetry-consent.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AACb;;;;;;;GAOG;AACH,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAE3D,MAAM,CAAC,KAAK,UAAU,qBAAqB;IACzC,MAAM,kBAAkB,EAAE,CAAC;IAC3B,MAAM,oBAAoB,CAAC,IAAI,CAAC,CAAC;AACnC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB;IACxC,MAAM,kBAAkB,EAAE,CAAC;IAC3B,MAAM,oBAAoB,CAAC,KAAK,CAAC,CAAC;AACpC,CAAC"}
@@ -0,0 +1,21 @@
1
+ declare global {
2
+ interface Window {
3
+ __polishdTelemetryStarted?: boolean;
4
+ }
5
+ }
6
+ /**
7
+ * Mounted by the dashboard page only when consent is granted. Renders nothing;
8
+ * starts the capture singleton once per page load (the listeners are global
9
+ * and deliberately never torn down — capture suspends off-dashboard instead).
10
+ */
11
+ export declare function PolishdTelemetryEmitter({ endpoint, installId, }: {
12
+ endpoint: string;
13
+ installId: string;
14
+ }): null;
15
+ /**
16
+ * The one-time opt-in prompt, shown while consent is "unset". Both buttons
17
+ * persist the decision through a guarded server action; "Share" refreshes the
18
+ * server render so the emitter mounts immediately rather than on next visit.
19
+ */
20
+ export declare function PolishdTelemetryConsent(): import("react").JSX.Element | null;
21
+ //# sourceMappingURL=telemetry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry.d.ts","sourceRoot":"","sources":["../../src/dashboard/telemetry.tsx"],"names":[],"mappings":"AAsDA,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,yBAAyB,CAAC,EAAE,OAAO,CAAC;KACrC;CACF;AAuID;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,QAAQ,EACR,SAAS,GACV,EAAE;IACD,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB,QAQA;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,uCAuDtC"}
@@ -0,0 +1,212 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ /**
4
+ * Polishd — the dashboard's own telemetry: emitter + consent prompt.
5
+ *
6
+ * The dashboard is polishd's product surface, and it is exactly the traffic
7
+ * the package refuses to record for its hosts (the dashboard-path drop in
8
+ * ingest). This emitter is the separate, opt-in channel that records it —
9
+ * dashboard interactions only — and reports it to the polishd project's own
10
+ * `@polishd/next/telemetry` endpoint, so the dashboard is improved by the same
11
+ * signals it preaches.
12
+ *
13
+ * Everything about the transport differs from the host-site capture layer
14
+ * because the POST crosses origins:
15
+ *
16
+ * • Identity travels in the body — an anonymous session id minted here (the
17
+ * httpOnly session cookie never leaves its origin) plus the stable
18
+ * anonymous install id the server resolved from `polishd_meta`.
19
+ * • Batches are sent as `text/plain`, which keeps the request inside CORS's
20
+ * "simple" class — no preflight — and is the only shape `sendBeacon` can
21
+ * deliver cross-origin anyway. The receiving route parses the body as
22
+ * JSON regardless of the header.
23
+ * • Paths are namespaced under `/~polishd/<tab>` so the receiving database
24
+ * can never confuse dashboard telemetry with the receiving site's own
25
+ * first-party pages.
26
+ *
27
+ * What is captured: page views (tab switches), clicks (with the same
28
+ * rage/dead classification as the host capture layer, via the shared DOM
29
+ * helpers), one viewport sample per session, and session end. Nothing else —
30
+ * no scroll depth, no errors, no design scans, and never anything from the
31
+ * host site's own pages: capture suspends the moment the URL leaves the
32
+ * dashboard's mount path.
33
+ */
34
+ import { useRouter } from "next/navigation";
35
+ import { useEffect, useState, useTransition } from "react";
36
+ import { componentOf, deviceCategory, hasTextSelection, isInteractive, labelOf, selectorOf, } from "../client/dom";
37
+ import { denyPolishdTelemetry, grantPolishdTelemetry } from "./telemetry-consent";
38
+ const PATH_PREFIX = "/~polishd";
39
+ const SESSION_KEY = "polishd_telemetry_session";
40
+ const FLUSH_INTERVAL_MS = 15_000;
41
+ const MAX_BATCH = 50;
42
+ const RAGE_COUNT = 3;
43
+ const RAGE_WINDOW_MS = 500;
44
+ /** The telemetry path for the tab currently in the URL. */
45
+ function telemetryPath() {
46
+ const tab = new URLSearchParams(location.search).get("tab");
47
+ return `${PATH_PREFIX}/${tab || "analytics"}`;
48
+ }
49
+ /** A session id that survives soft navigation but not the browser session. */
50
+ function sessionId() {
51
+ try {
52
+ const existing = sessionStorage.getItem(SESSION_KEY);
53
+ if (existing)
54
+ return existing;
55
+ const minted = crypto.randomUUID();
56
+ sessionStorage.setItem(SESSION_KEY, minted);
57
+ return minted;
58
+ }
59
+ catch {
60
+ // Storage blocked — a per-page-load id is the honest fallback.
61
+ return crypto.randomUUID();
62
+ }
63
+ }
64
+ function start(endpoint, installId) {
65
+ const sid = sessionId();
66
+ // The route the dashboard is mounted at, learned from where we woke up.
67
+ // Capture is suspended whenever the URL wanders off it — the listeners
68
+ // below outlive the dashboard page, and host-site interactions must never
69
+ // leak into telemetry.
70
+ const mountPath = location.pathname;
71
+ const onDashboard = () => location.pathname === mountPath;
72
+ const queue = [];
73
+ let currentPath = telemetryPath();
74
+ const flush = (useBeacon = false) => {
75
+ if (queue.length === 0)
76
+ return;
77
+ const batch = queue.splice(0, queue.length);
78
+ const body = JSON.stringify({ installId, sessionId: sid, events: batch });
79
+ if (useBeacon && navigator.sendBeacon) {
80
+ const ok = navigator.sendBeacon(endpoint, new Blob([body], { type: "text/plain" }));
81
+ if (!ok)
82
+ queue.unshift(...batch);
83
+ return;
84
+ }
85
+ fetch(endpoint, {
86
+ method: "POST",
87
+ headers: { "Content-Type": "text/plain" },
88
+ body,
89
+ keepalive: true,
90
+ }).catch(() => {
91
+ queue.unshift(...batch);
92
+ });
93
+ };
94
+ const push = (e) => {
95
+ if (!onDashboard())
96
+ return;
97
+ queue.push({ ts: Date.now(), path: currentPath, ...e });
98
+ if (queue.length >= MAX_BATCH)
99
+ flush();
100
+ };
101
+ // ---- clicks (same classification as the host capture layer) --------------
102
+ let lastClick = { selector: "", time: 0, count: 0 };
103
+ document.addEventListener("click", (ev) => {
104
+ const target = ev.target;
105
+ if (!target || !onDashboard())
106
+ return;
107
+ const selector = selectorOf(target);
108
+ const component = componentOf(target);
109
+ const text = labelOf(target);
110
+ const now = Date.now();
111
+ if (selector === lastClick.selector && now - lastClick.time < RAGE_WINDOW_MS) {
112
+ lastClick.count++;
113
+ lastClick.time = now;
114
+ if (lastClick.count === RAGE_COUNT) {
115
+ push({ type: "rage_click", selector, component, text });
116
+ }
117
+ }
118
+ else {
119
+ lastClick = { selector: selector ?? "", time: now, count: 1 };
120
+ }
121
+ if (!isInteractive(target)) {
122
+ if (hasTextSelection())
123
+ return;
124
+ push({ type: "dead_click", selector, component, text });
125
+ }
126
+ else {
127
+ push({ type: "click", selector, component, text });
128
+ }
129
+ }, { capture: true, passive: true });
130
+ // ---- page views (tab switches ride on the History API) -------------------
131
+ const onNavigate = () => {
132
+ if (!onDashboard())
133
+ return;
134
+ const next = telemetryPath();
135
+ if (next === currentPath)
136
+ return;
137
+ currentPath = next;
138
+ push({ type: "page_view", path: currentPath });
139
+ };
140
+ const wrapHistory = (method) => {
141
+ const original = history[method];
142
+ history[method] = function (...args) {
143
+ const ret = original.apply(this, args);
144
+ onNavigate();
145
+ return ret;
146
+ };
147
+ };
148
+ wrapHistory("pushState");
149
+ wrapHistory("replaceState");
150
+ addEventListener("popstate", onNavigate);
151
+ // ---- lifecycle -----------------------------------------------------------
152
+ addEventListener("pagehide", () => {
153
+ push({ type: "session_end" });
154
+ flush(true);
155
+ });
156
+ addEventListener("visibilitychange", () => {
157
+ if (document.visibilityState === "hidden")
158
+ flush(true);
159
+ });
160
+ setInterval(() => flush(false), FLUSH_INTERVAL_MS);
161
+ const w = window.innerWidth || document.documentElement.clientWidth || 0;
162
+ if (w > 0) {
163
+ push({ type: "viewport", value: w, text: deviceCategory(w) });
164
+ }
165
+ push({ type: "page_view", path: currentPath });
166
+ }
167
+ /**
168
+ * Mounted by the dashboard page only when consent is granted. Renders nothing;
169
+ * starts the capture singleton once per page load (the listeners are global
170
+ * and deliberately never torn down — capture suspends off-dashboard instead).
171
+ */
172
+ export function PolishdTelemetryEmitter({ endpoint, installId, }) {
173
+ useEffect(() => {
174
+ if (window.__polishdTelemetryStarted)
175
+ return;
176
+ if (navigator.doNotTrack === "1")
177
+ return;
178
+ window.__polishdTelemetryStarted = true;
179
+ start(endpoint, installId);
180
+ }, [endpoint, installId]);
181
+ return null;
182
+ }
183
+ /**
184
+ * The one-time opt-in prompt, shown while consent is "unset". Both buttons
185
+ * persist the decision through a guarded server action; "Share" refreshes the
186
+ * server render so the emitter mounts immediately rather than on next visit.
187
+ */
188
+ export function PolishdTelemetryConsent() {
189
+ const router = useRouter();
190
+ const [dismissed, setDismissed] = useState(false);
191
+ const [pending, startTransition] = useTransition();
192
+ if (dismissed)
193
+ return null;
194
+ const decide = (granted) => startTransition(async () => {
195
+ try {
196
+ if (granted) {
197
+ await grantPolishdTelemetry();
198
+ router.refresh();
199
+ }
200
+ else {
201
+ await denyPolishdTelemetry();
202
+ }
203
+ }
204
+ catch {
205
+ // Denied or store unavailable — the banner will be back next render;
206
+ // hiding it now keeps this visit usable either way.
207
+ }
208
+ setDismissed(true);
209
+ });
210
+ return (_jsxs("div", { role: "dialog", "aria-label": "Polishd telemetry consent", className: "fixed bottom-4 right-4 z-50 w-[340px] max-w-[calc(100vw-2rem)] rounded-xl border border-[#2e2e2e] bg-[#111] p-4 shadow-2xl", children: [_jsx("p", { className: "text-[13px] font-medium text-white", children: "Help improve polishd?" }), _jsxs("p", { className: "mt-1.5 text-[12px] leading-relaxed text-[#888]", children: ["Share anonymous usage of ", _jsx("span", { className: "text-[#aaa]", children: "this dashboard" }), " \u2014 clicks and tab views inside it, tied to a random install id. Never your site's analytics, never your visitors' data. Opt out any time with", " ", _jsx("code", { className: "font-mono text-[11px] text-[#aaa]", children: "POLISHD_TELEMETRY=off" }), "."] }), _jsxs("div", { className: "mt-3 flex gap-2", children: [_jsx("button", { type: "button", disabled: pending, onClick: () => decide(true), className: "rounded-lg bg-white px-3 py-1.5 text-[12px] font-medium text-black transition-opacity hover:opacity-90 disabled:opacity-50", children: "Share" }), _jsx("button", { type: "button", disabled: pending, onClick: () => decide(false), className: "rounded-lg border border-[#2e2e2e] px-3 py-1.5 text-[12px] text-[#888] transition-colors hover:text-white disabled:opacity-50", children: "No thanks" })] })] }));
211
+ }
212
+ //# sourceMappingURL=telemetry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../../src/dashboard/telemetry.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAG3D,OAAO,EACL,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,OAAO,EACP,UAAU,GACX,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAElF,MAAM,WAAW,GAAG,WAAW,CAAC;AAChC,MAAM,WAAW,GAAG,2BAA2B,CAAC;AAChD,MAAM,iBAAiB,GAAG,MAAM,CAAC;AACjC,MAAM,SAAS,GAAG,EAAE,CAAC;AACrB,MAAM,UAAU,GAAG,CAAC,CAAC;AACrB,MAAM,cAAc,GAAG,GAAG,CAAC;AAQ3B,2DAA2D;AAC3D,SAAS,aAAa;IACpB,MAAM,GAAG,GAAG,IAAI,eAAe,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC5D,OAAO,GAAG,WAAW,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC;AAChD,CAAC;AAED,8EAA8E;AAC9E,SAAS,SAAS;IAChB,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,cAAc,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QACrD,IAAI,QAAQ;YAAE,OAAO,QAAQ,CAAC;QAC9B,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;QACnC,cAAc,CAAC,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QAC5C,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,MAAM,CAAC;QACP,+DAA+D;QAC/D,OAAO,MAAM,CAAC,UAAU,EAAE,CAAC;IAC7B,CAAC;AACH,CAAC;AAED,SAAS,KAAK,CAAC,QAAgB,EAAE,SAAiB;IAChD,MAAM,GAAG,GAAG,SAAS,EAAE,CAAC;IACxB,wEAAwE;IACxE,uEAAuE;IACvE,0EAA0E;IAC1E,uBAAuB;IACvB,MAAM,SAAS,GAAG,QAAQ,CAAC,QAAQ,CAAC;IACpC,MAAM,WAAW,GAAG,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,KAAK,SAAS,CAAC;IAE1D,MAAM,KAAK,GAAmB,EAAE,CAAC;IACjC,IAAI,WAAW,GAAG,aAAa,EAAE,CAAC;IAElC,MAAM,KAAK,GAAG,CAAC,SAAS,GAAG,KAAK,EAAE,EAAE;QAClC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAC/B,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1E,IAAI,SAAS,IAAI,SAAS,CAAC,UAAU,EAAE,CAAC;YACtC,MAAM,EAAE,GAAG,SAAS,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC;YACpF,IAAI,CAAC,EAAE;gBAAE,KAAK,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC;YACjC,OAAO;QACT,CAAC;QACD,KAAK,CAAC,QAAQ,EAAE;YACd,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE;YACzC,IAAI;YACJ,SAAS,EAAE,IAAI;SAChB,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;YACZ,KAAK,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,MAAM,IAAI,GAAG,CACX,CAAiF,EACjF,EAAE;QACF,IAAI,CAAC,WAAW,EAAE;YAAE,OAAO;QAC3B,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,CAAC,EAAkB,CAAC,CAAC;QACxE,IAAI,KAAK,CAAC,MAAM,IAAI,SAAS;YAAE,KAAK,EAAE,CAAC;IACzC,CAAC,CAAC;IAEF,6EAA6E;IAE7E,IAAI,SAAS,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;IAEpD,QAAQ,CAAC,gBAAgB,CACvB,OAAO,EACP,CAAC,EAAE,EAAE,EAAE;QACL,MAAM,MAAM,GAAG,EAAE,CAAC,MAAwB,CAAC;QAC3C,IAAI,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE;YAAE,OAAO;QACtC,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;QACpC,MAAM,SAAS,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;QACtC,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;QAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEvB,IAAI,QAAQ,KAAK,SAAS,CAAC,QAAQ,IAAI,GAAG,GAAG,SAAS,CAAC,IAAI,GAAG,cAAc,EAAE,CAAC;YAC7E,SAAS,CAAC,KAAK,EAAE,CAAC;YAClB,SAAS,CAAC,IAAI,GAAG,GAAG,CAAC;YACrB,IAAI,SAAS,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;gBACnC,IAAI,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC1D,CAAC;QACH,CAAC;aAAM,CAAC;YACN,SAAS,GAAG,EAAE,QAAQ,EAAE,QAAQ,IAAI,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QAChE,CAAC;QAED,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3B,IAAI,gBAAgB,EAAE;gBAAE,OAAO;YAC/B,IAAI,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACrD,CAAC;IACH,CAAC,EACD,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CACjC,CAAC;IAEF,6EAA6E;IAE7E,MAAM,UAAU,GAAG,GAAG,EAAE;QACtB,IAAI,CAAC,WAAW,EAAE;YAAE,OAAO;QAC3B,MAAM,IAAI,GAAG,aAAa,EAAE,CAAC;QAC7B,IAAI,IAAI,KAAK,WAAW;YAAE,OAAO;QACjC,WAAW,GAAG,IAAI,CAAC;QACnB,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;IACjD,CAAC,CAAC;IAEF,MAAM,WAAW,GAAG,CAAC,MAAoC,EAAE,EAAE;QAC3D,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;QACjC,OAAO,CAAC,MAAM,CAAC,GAAG,UAAyB,GAAG,IAAsC;YAClF,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YACvC,UAAU,EAAE,CAAC;YACb,OAAO,GAAG,CAAC;QACb,CAAC,CAAC;IACJ,CAAC,CAAC;IACF,WAAW,CAAC,WAAW,CAAC,CAAC;IACzB,WAAW,CAAC,cAAc,CAAC,CAAC;IAC5B,gBAAgB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IAEzC,6EAA6E;IAE7E,gBAAgB,CAAC,UAAU,EAAE,GAAG,EAAE;QAChC,IAAI,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC;QAC9B,KAAK,CAAC,IAAI,CAAC,CAAC;IACd,CAAC,CAAC,CAAC;IACH,gBAAgB,CAAC,kBAAkB,EAAE,GAAG,EAAE;QACxC,IAAI,QAAQ,CAAC,eAAe,KAAK,QAAQ;YAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IACH,WAAW,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,iBAAiB,CAAC,CAAC;IAEnD,MAAM,CAAC,GAAG,MAAM,CAAC,UAAU,IAAI,QAAQ,CAAC,eAAe,CAAC,WAAW,IAAI,CAAC,CAAC;IACzE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACV,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAChE,CAAC;IACD,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;AACjD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,EACtC,QAAQ,EACR,SAAS,GAIV;IACC,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,MAAM,CAAC,yBAAyB;YAAE,OAAO;QAC7C,IAAI,SAAS,CAAC,UAAU,KAAK,GAAG;YAAE,OAAO;QACzC,MAAM,CAAC,yBAAyB,GAAG,IAAI,CAAC;QACxC,KAAK,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IAC7B,CAAC,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC;IAC1B,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,uBAAuB;IACrC,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAClD,MAAM,CAAC,OAAO,EAAE,eAAe,CAAC,GAAG,aAAa,EAAE,CAAC;IACnD,IAAI,SAAS;QAAE,OAAO,IAAI,CAAC;IAE3B,MAAM,MAAM,GAAG,CAAC,OAAgB,EAAE,EAAE,CAClC,eAAe,CAAC,KAAK,IAAI,EAAE;QACzB,IAAI,CAAC;YACH,IAAI,OAAO,EAAE,CAAC;gBACZ,MAAM,qBAAqB,EAAE,CAAC;gBAC9B,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,CAAC;iBAAM,CAAC;gBACN,MAAM,oBAAoB,EAAE,CAAC;YAC/B,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,qEAAqE;YACrE,oDAAoD;QACtD,CAAC;QACD,YAAY,CAAC,IAAI,CAAC,CAAC;IACrB,CAAC,CAAC,CAAC;IAEL,OAAO,CACL,eACE,IAAI,EAAC,QAAQ,gBACF,2BAA2B,EACtC,SAAS,EAAC,4HAA4H,aAEtI,YAAG,SAAS,EAAC,oCAAoC,sCAA0B,EAC3E,aAAG,SAAS,EAAC,gDAAgD,0CAClC,eAAM,SAAS,EAAC,aAAa,+BAAsB,wJAE5B,GAAG,EACnD,eAAM,SAAS,EAAC,mCAAmC,sCAA6B,SAC9E,EACJ,eAAK,SAAS,EAAC,iBAAiB,aAC9B,iBACE,IAAI,EAAC,QAAQ,EACb,QAAQ,EAAE,OAAO,EACjB,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAC3B,SAAS,EAAC,4HAA4H,sBAG/H,EACT,iBACE,IAAI,EAAC,QAAQ,EACb,QAAQ,EAAE,OAAO,EACjB,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAC5B,SAAS,EAAC,+HAA+H,0BAGlI,IACL,IACF,CACP,CAAC;AACJ,CAAC"}
@@ -298,10 +298,18 @@
298
298
  right: 0;
299
299
  }
300
300
 
301
+ .polishd-root.polishd-root .right-4 {
302
+ right: calc(var(--spacing) * 4);
303
+ }
304
+
301
305
  .polishd-root.polishd-root .bottom-0 {
302
306
  bottom: 0;
303
307
  }
304
308
 
309
+ .polishd-root.polishd-root .bottom-4 {
310
+ bottom: calc(var(--spacing) * 4);
311
+ }
312
+
305
313
  .polishd-root.polishd-root .bottom-full {
306
314
  bottom: 100%;
307
315
  }
@@ -712,6 +720,10 @@
712
720
  width: calc(var(--spacing) * 40);
713
721
  }
714
722
 
723
+ .polishd-root.polishd-root .w-56 {
724
+ width: calc(var(--spacing) * 56);
725
+ }
726
+
715
727
  .polishd-root.polishd-root .w-64 {
716
728
  width: calc(var(--spacing) * 64);
717
729
  }
@@ -744,6 +756,10 @@
744
756
  width: 92%;
745
757
  }
746
758
 
759
+ .polishd-root.polishd-root .w-\[340px\] {
760
+ width: 340px;
761
+ }
762
+
747
763
  .polishd-root.polishd-root .w-full {
748
764
  width: 100%;
749
765
  }
@@ -860,6 +876,10 @@
860
876
  flex: none;
861
877
  }
862
878
 
879
+ .polishd-root.polishd-root .shrink {
880
+ flex-shrink: 1;
881
+ }
882
+
863
883
  .polishd-root.polishd-root .shrink-0 {
864
884
  flex-shrink: 0;
865
885
  }
@@ -1149,6 +1169,10 @@
1149
1169
  border-radius: var(--radius-sm);
1150
1170
  }
1151
1171
 
1172
+ .polishd-root.polishd-root .rounded-xl {
1173
+ border-radius: var(--radius-xl);
1174
+ }
1175
+
1152
1176
  .polishd-root.polishd-root .rounded-t-xl {
1153
1177
  border-top-left-radius: var(--radius-xl);
1154
1178
  border-top-right-radius: var(--radius-xl);
@@ -1255,6 +1279,10 @@
1255
1279
  background-color: oklab(21.479% -.0106614 -.037564 / .6);
1256
1280
  }
1257
1281
 
1282
+ .polishd-root.polishd-root .bg-\[\#0d0d0d\] {
1283
+ background-color: #0d0d0d;
1284
+ }
1285
+
1258
1286
  .polishd-root.polishd-root .bg-\[\#1a1a1a\] {
1259
1287
  background-color: #1a1a1a;
1260
1288
  }
@@ -2019,6 +2047,10 @@
2019
2047
  color: #ccc;
2020
2048
  }
2021
2049
 
2050
+ .polishd-root.polishd-root .text-\[\#ddd\] {
2051
+ color: #ddd;
2052
+ }
2053
+
2022
2054
  .polishd-root.polishd-root .text-\[\#e4e4e4\] {
2023
2055
  color: #e4e4e4;
2024
2056
  }
@@ -2120,10 +2152,22 @@
2120
2152
  font-variant-numeric: var(--tw-ordinal, ) var(--tw-slashed-zero, ) var(--tw-numeric-figure, ) var(--tw-numeric-spacing, ) var(--tw-numeric-fraction, );
2121
2153
  }
2122
2154
 
2155
+ .polishd-root.polishd-root .line-through {
2156
+ text-decoration-line: line-through;
2157
+ }
2158
+
2123
2159
  .polishd-root.polishd-root .underline {
2124
2160
  text-decoration-line: underline;
2125
2161
  }
2126
2162
 
2163
+ .polishd-root.polishd-root .decoration-\[\#3a3a3a\] {
2164
+ text-decoration-color: #3a3a3a;
2165
+ }
2166
+
2167
+ .polishd-root.polishd-root .decoration-\[\#333\] {
2168
+ text-decoration-color: #333;
2169
+ }
2170
+
2127
2171
  .polishd-root.polishd-root .decoration-\[\#444\] {
2128
2172
  text-decoration-color: #444;
2129
2173
  }
@@ -2275,6 +2319,10 @@
2275
2319
  color: #888;
2276
2320
  }
2277
2321
 
2322
+ .polishd-root.polishd-root .hover\:text-\[\#ccc\]:hover {
2323
+ color: #ccc;
2324
+ }
2325
+
2278
2326
  .polishd-root.polishd-root .hover\:text-emerald-400:hover {
2279
2327
  color: var(--color-emerald-400);
2280
2328
  }
@@ -2309,6 +2357,10 @@
2309
2357
  opacity: .4;
2310
2358
  }
2311
2359
 
2360
+ .polishd-root.polishd-root .disabled\:opacity-50:disabled {
2361
+ opacity: .5;
2362
+ }
2363
+
2312
2364
  @media not all and (min-width: 40rem) {
2313
2365
  .polishd-root.polishd-root .max-sm\:hidden {
2314
2366
  display: none;
@@ -42,4 +42,24 @@ export declare function sessionIdFromCookie(cookieValue: string | undefined): st
42
42
  * they do in the browser. It falls back to the defaults when omitted.
43
43
  */
44
44
  export declare function ingest(body: unknown, cookieValue: string | undefined, config?: Partial<PolishdConfig>): Promise<IngestResult>;
45
+ /**
46
+ * Ingest a telemetry batch from a *remote* polishd installation.
47
+ *
48
+ * This differs from first-party {@link ingest} in exactly three ways, each a
49
+ * consequence of the request crossing origins:
50
+ *
51
+ * 1. Identity travels in the body. The session cookie is httpOnly and
52
+ * first-party, so it never arrives here; the emitter mints an anonymous
53
+ * session id itself and sends it alongside a stable `installId`. Both are
54
+ * validated by shape only — there is nothing to verify them against, and
55
+ * the worst a forger achieves is polluting telemetry, same as any public
56
+ * ingest endpoint.
57
+ * 2. Every stored row is tagged with the `installId`, so one shared database
58
+ * can tell installations apart.
59
+ * 3. Dashboard paths are NOT dropped. Recording how the dashboard itself is
60
+ * used is the entire point of this channel; the emitter is expected to
61
+ * namespace its paths so they can't collide with the receiving site's own
62
+ * first-party events.
63
+ */
64
+ export declare function ingestTelemetry(body: unknown, config?: Partial<PolishdConfig>): Promise<IngestResult>;
45
65
  //# sourceMappingURL=ingest.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ingest.d.ts","sourceRoot":"","sources":["../../src/server/ingest.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAIL,KAAK,aAAa,EACnB,MAAM,WAAW,CAAC;AAenB;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB,uBAAuB,CAAC;AAExD,sDAAsD;AACtD,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AA+BD,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAElF;AAkCD;;;;;;GAMG;AACH,wBAAsB,MAAM,CAC1B,IAAI,EAAE,OAAO,EACb,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,MAAM,GAAE,OAAO,CAAC,aAAa,CAAM,GAClC,OAAO,CAAC,YAAY,CAAC,CA4BvB"}
1
+ {"version":3,"file":"ingest.d.ts","sourceRoot":"","sources":["../../src/server/ingest.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAIL,KAAK,aAAa,EACnB,MAAM,WAAW,CAAC;AAenB;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB,uBAAuB,CAAC;AAExD,sDAAsD;AACtD,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AA+BD,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAElF;AAkCD;;;;;;GAMG;AACH,wBAAsB,MAAM,CAC1B,IAAI,EAAE,OAAO,EACb,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,MAAM,GAAE,OAAO,CAAC,aAAa,CAAM,GAClC,OAAO,CAAC,YAAY,CAAC,CA4BvB;AAWD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,OAAO,EACb,MAAM,GAAE,OAAO,CAAC,aAAa,CAAM,GAClC,OAAO,CAAC,YAAY,CAAC,CAyBvB"}