polymath-society 0.2.7 → 0.2.9

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/dist/web/app.js CHANGED
@@ -7279,7 +7279,7 @@ var require_jsx_runtime = __commonJS({
7279
7279
  });
7280
7280
 
7281
7281
  // web/entry.tsx
7282
- var import_react11 = __toESM(require_react(), 1);
7282
+ var import_react9 = __toESM(require_react(), 1);
7283
7283
  var import_client = __toESM(require_client(), 1);
7284
7284
 
7285
7285
  // ../../components/CodeAnalysisView.tsx
@@ -8167,6 +8167,7 @@ function TypingDots() {
8167
8167
 
8168
8168
  // ../../components/ReportChatSidebar.tsx
8169
8169
  var import_jsx_runtime4 = __toESM(require_jsx_runtime());
8170
+ var DISMISSED = "polymath:ask-drawer-dismissed";
8170
8171
  var STARTERS = [
8171
8172
  "Why did I score where I did on taste?",
8172
8173
  "What's my strongest signal, and what's the evidence?",
@@ -8184,11 +8185,26 @@ function ReportChatSidebar({ endpoint = "/api/coding/chat" } = {}) {
8184
8185
  if (!isLocal) return null;
8185
8186
  const [open, setOpen] = (0, import_react3.useState)(() => {
8186
8187
  try {
8188
+ if (localStorage.getItem(DISMISSED) === "1") return false;
8187
8189
  return window.matchMedia("(min-width: 640px)").matches;
8188
8190
  } catch {
8189
8191
  return false;
8190
8192
  }
8191
8193
  });
8194
+ const closeByUser = () => {
8195
+ setOpen(false);
8196
+ try {
8197
+ localStorage.setItem(DISMISSED, "1");
8198
+ } catch {
8199
+ }
8200
+ };
8201
+ const openByUser = () => {
8202
+ setOpen(true);
8203
+ try {
8204
+ localStorage.removeItem(DISMISSED);
8205
+ } catch {
8206
+ }
8207
+ };
8192
8208
  const [msgs, setMsgs] = (0, import_react3.useState)([]);
8193
8209
  const [input, setInput] = (0, import_react3.useState)("");
8194
8210
  const [busy, setBusy] = (0, import_react3.useState)(false);
@@ -8201,7 +8217,7 @@ function ReportChatSidebar({ endpoint = "/api/coding/chat" } = {}) {
8201
8217
  }, [open]);
8202
8218
  (0, import_react3.useEffect)(() => {
8203
8219
  const onKey = (e) => {
8204
- if (e.key === "Escape") setOpen(false);
8220
+ if (e.key === "Escape") closeByUser();
8205
8221
  };
8206
8222
  window.addEventListener("keydown", onKey);
8207
8223
  return () => window.removeEventListener("keydown", onKey);
@@ -8235,7 +8251,7 @@ function ReportChatSidebar({ endpoint = "/api/coding/chat" } = {}) {
8235
8251
  !open && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
8236
8252
  "button",
8237
8253
  {
8238
- onClick: () => setOpen(true),
8254
+ onClick: openByUser,
8239
8255
  className: "fixed bottom-5 right-5 z-40 flex items-center gap-2 rounded-full bg-accent px-4 py-3 text-[13px] font-medium text-white shadow-lg shadow-accent/25 transition-transform hover:scale-[1.03]",
8240
8256
  "aria-label": "Ask about your report",
8241
8257
  children: [
@@ -8247,7 +8263,7 @@ function ReportChatSidebar({ endpoint = "/api/coding/chat" } = {}) {
8247
8263
  ]
8248
8264
  }
8249
8265
  ),
8250
- open && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { onClick: () => setOpen(false), className: "fixed inset-0 z-40 bg-black/20 sm:hidden", "aria-hidden": true }),
8266
+ open && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { onClick: closeByUser, className: "fixed inset-0 z-40 bg-black/20 sm:hidden", "aria-hidden": true }),
8251
8267
  /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
8252
8268
  "aside",
8253
8269
  {
@@ -8262,7 +8278,7 @@ function ReportChatSidebar({ endpoint = "/api/coding/chat" } = {}) {
8262
8278
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
8263
8279
  "button",
8264
8280
  {
8265
- onClick: () => setOpen(false),
8281
+ onClick: closeByUser,
8266
8282
  className: "-mr-1 shrink-0 rounded-lg p-1.5 text-faint transition-colors hover:bg-canvas hover:text-ink",
8267
8283
  "aria-label": "Close",
8268
8284
  children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M18 6 6 18M6 6l12 12", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }) })
@@ -10430,7 +10446,7 @@ function pctForScore(s, doc) {
10430
10446
  if (i === 5) return "median";
10431
10447
  return (doc ?? void 0)?.scoreBands.find((b) => b.score === i)?.label ?? "median";
10432
10448
  }
10433
- function ScoreDistribution({ marks, className }) {
10449
+ function ScoreDistribution({ marks, className, compact = false }) {
10434
10450
  const doc = useCalibration();
10435
10451
  const NORM = norm(doc);
10436
10452
  const label = (s) => doc.scoreBands.find((b) => b.score === s)?.label ?? "";
@@ -10452,7 +10468,7 @@ function ScoreDistribution({ marks, className }) {
10452
10468
  }
10453
10469
  const area = `M${X0} ${BASE} ${curve.replace(/^M/, "L")}L${X1} ${BASE} Z`;
10454
10470
  const yours = (marks ?? []).filter((m) => m.score11 != null);
10455
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: `rounded-2xl border border-line bg-paper p-5 shadow-[0_1px_2px_rgba(0,0,0,0.02)] ${className ?? ""}`, children: [
10471
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: `rounded-2xl border border-line bg-paper ${compact ? "p-4" : "p-5"} shadow-[0_1px_2px_rgba(0,0,0,0.02)] ${className ?? ""}`, children: [
10456
10472
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "text-[13.5px] font-medium text-ink", children: "What the percentiles really mean" }),
10457
10473
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("p", { className: "mb-1 text-[12.5px] leading-relaxed text-faint", children: [
10458
10474
  "Most people land 4\u20136. Each step into the right tail is far rarer: a 7 is ~",
@@ -10470,7 +10486,7 @@ function ScoreDistribution({ marks, className }) {
10470
10486
  ".",
10471
10487
  yours.length ? " The white dots are you." : ""
10472
10488
  ] }),
10473
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("svg", { viewBox: "0 0 700 252", className: "w-full", role: "img", "aria-label": "Bell curve showing how scores 1 to 11 map to population percentiles; high scores cluster in the rare right tail", children: [
10489
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("svg", { viewBox: "0 0 700 252", className: compact ? "mx-auto block w-full max-w-[860px]" : "w-full", role: "img", "aria-label": "Bell curve showing how scores 1 to 11 map to population percentiles; high scores cluster in the rare right tail", children: [
10474
10490
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: area, className: "text-accent", fill: "currentColor", fillOpacity: 0.07 }),
10475
10491
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: curve, className: "text-accent", fill: "none", stroke: "currentColor", strokeWidth: 2 }),
10476
10492
  /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: X0, y1: BASE, x2: X1, y2: BASE, className: "text-line", stroke: "currentColor", strokeWidth: 1 }),
@@ -11255,6 +11271,85 @@ function OceanSection({ entries, demos, facetLines, slipLines, fb, onOpen }) {
11255
11271
  entries.map((e) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CollapsibleFacet, { entry: e, demos, facetLines, slipLines, fb, onOpen }, e.key))
11256
11272
  ] });
11257
11273
  }
11274
+ function OpenShareButton() {
11275
+ const openShare = () => {
11276
+ const claimed = !window.dispatchEvent(new CustomEvent("polymath:open-share", { cancelable: true }));
11277
+ if (!claimed) window.location.href = "/report";
11278
+ };
11279
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { onClick: openShare, className: "inline-flex items-center gap-1.5 rounded-xl bg-ink px-4 py-2 text-[13px] font-medium text-paper hover:opacity-90", children: "Edit your public report \u2192" });
11280
+ }
11281
+ function RemainingExports() {
11282
+ const [missing, setMissing] = (0, import_react6.useState)([]);
11283
+ const [connected, setConnected] = (0, import_react6.useState)([]);
11284
+ (0, import_react6.useEffect)(() => {
11285
+ fetch("/api/exports-manifest").then((r) => r.ok ? r.json() : null).then((j) => {
11286
+ if (!j?.links) return;
11287
+ const have = new Set(j.connectedKinds ?? []);
11288
+ setMissing(j.links.filter((l) => l.requestUrl && !have.has(l.kind)));
11289
+ setConnected(j.links.filter((l) => l.requestUrl && have.has(l.kind)));
11290
+ }).catch(() => {
11291
+ });
11292
+ }, []);
11293
+ if (!missing.length && !connected.length) return null;
11294
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mb-9 rounded-2xl border border-line bg-paper p-5", children: [
11295
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "font-serif text-[17px] text-ink", children: "Add what's missing" }),
11296
+ missing.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { className: "mt-1 max-w-[68ch] text-[13px] leading-relaxed text-muted", children: [
11297
+ "This read is built from what you've connected so far. Each export below adds history it hasn't seen yet. Request one, then run ",
11298
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("code", { className: "rounded bg-canvas px-1.5 py-0.5 text-[12px]", children: "polymath-society" }),
11299
+ " again \u2014 it finds the downloaded zip on its own."
11300
+ ] }),
11301
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "mt-3 space-y-2", children: missing.map((l) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
11302
+ "a",
11303
+ {
11304
+ href: l.requestUrl,
11305
+ target: "_blank",
11306
+ rel: "noreferrer",
11307
+ className: "flex items-center justify-between gap-3 rounded-xl border border-line bg-canvas px-4 py-3 transition-colors hover:border-accent",
11308
+ children: [
11309
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "min-w-0", children: [
11310
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "text-[13px] font-semibold text-ink", children: [
11311
+ "Request my ",
11312
+ l.label,
11313
+ " export"
11314
+ ] }),
11315
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mt-0.5 text-[11.5px] text-faint", children: [
11316
+ l.buttonPath,
11317
+ " \xB7 ready in ",
11318
+ l.eta
11319
+ ] })
11320
+ ] }),
11321
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "shrink-0 text-[12px] font-medium text-accent", children: "Open \u2192" })
11322
+ ]
11323
+ },
11324
+ l.kind
11325
+ )) }),
11326
+ connected.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: missing.length ? "mt-4 border-t border-line pt-3" : "mt-3", children: [
11327
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "text-[13px] font-semibold text-ink", children: "Other accounts?" }),
11328
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { className: "mt-0.5 max-w-[68ch] text-[12.5px] leading-relaxed text-muted", children: [
11329
+ "What you connected covers one account. If you also use ",
11330
+ connected.map((l) => l.label).join(" or "),
11331
+ " under a second account (work, school, an old login), request an export there too and run ",
11332
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("code", { className: "rounded bg-canvas px-1 py-0.5 text-[11.5px]", children: "polymath-society" }),
11333
+ " again."
11334
+ ] }),
11335
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "mt-2 flex flex-wrap gap-2", children: connected.map((l) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
11336
+ "a",
11337
+ {
11338
+ href: l.requestUrl,
11339
+ target: "_blank",
11340
+ rel: "noreferrer",
11341
+ className: "inline-flex items-center gap-1.5 rounded-lg border border-line bg-canvas px-3 py-1.5 text-[12px] font-medium text-ink transition-colors hover:border-accent",
11342
+ children: [
11343
+ l.label,
11344
+ " export ",
11345
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-accent", children: "\u2192" })
11346
+ ]
11347
+ },
11348
+ l.kind
11349
+ )) })
11350
+ ] })
11351
+ ] });
11352
+ }
11258
11353
  function DetailedDataView() {
11259
11354
  const [dims, setDims] = (0, import_react6.useState)(null);
11260
11355
  const [headline, setHeadline] = (0, import_react6.useState)(null);
@@ -11323,7 +11418,7 @@ function DetailedDataView() {
11323
11418
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h2", { className: "font-serif text-[26px] text-ink", children: "Now, your stats" }),
11324
11419
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "h-px flex-1 bg-line" })
11325
11420
  ] }),
11326
- filter === "all" && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ScoreDistribution, { marks: distributionMarks(dims), className: "mb-5" }),
11421
+ filter === "all" && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ScoreDistribution, { marks: distributionMarks(dims), compact: true, className: "mb-5" }),
11327
11422
  /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mb-6 flex flex-wrap items-center gap-2", children: [
11328
11423
  ["all", ...dims.map((d) => d.key)].map((k) => {
11329
11424
  const label = k === "all" ? "Overview" : dims.find((d) => d.key === k)?.label || k;
@@ -11364,10 +11459,11 @@ function DetailedDataView() {
11364
11459
  close.trajectory && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "mt-3 text-[15.5px] leading-relaxed text-ink", children: close.trajectory }),
11365
11460
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "mt-3 text-[15.5px] leading-relaxed text-ink", children: "We would love to help you show this to the rest of the world. If you edit and approve a public report, we can start showing it to people to get you opportunities and intros you may like." })
11366
11461
  ] }),
11367
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mb-9 flex flex-wrap items-center gap-x-3 gap-y-1", children: [
11368
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("a", { href: "/report", className: "inline-flex items-center gap-1.5 rounded-xl bg-ink px-4 py-2 text-[13px] font-medium text-paper hover:opacity-90", children: "Edit your public report \u2192" }),
11462
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mb-4 flex flex-wrap items-center gap-x-3 gap-y-1", children: [
11463
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(OpenShareButton, {}),
11369
11464
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-[12px] text-faint", children: "Optional. You choose what to share." })
11370
- ] })
11465
+ ] }),
11466
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(RemainingExports, {})
11371
11467
  ] }) : shown.map((dim) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(DimensionCard, { dim, onOpen: openGrade, fb, demos, facetLines, slipLines, summary: dimSummary[dim.key] }, dim.key)),
11372
11468
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Drawer, { state: drawer, onClose: () => setDrawer({ kind: "closed" }), onTranscript: openTranscript })
11373
11469
  ] }),
@@ -11636,232 +11732,8 @@ function PublicReportView({ r, footprint, dims }) {
11636
11732
  ] });
11637
11733
  }
11638
11734
 
11639
- // ../../components/PublicReportEditor.tsx
11640
- var import_react8 = __toESM(require_react());
11735
+ // ../../components/CodingPageView.tsx
11641
11736
  var import_jsx_runtime9 = __toESM(require_jsx_runtime());
11642
- var STARTERS2 = [
11643
- "Show more on my contrarian takes",
11644
- "Hide the failure modes",
11645
- "Make the headline punchier",
11646
- "Cut anything that names a private person"
11647
- ];
11648
- function PublicReportEditor({ onUpdate }) {
11649
- const [msgs, setMsgs] = (0, import_react8.useState)([]);
11650
- const [input, setInput] = (0, import_react8.useState)("");
11651
- const [busy, setBusy] = (0, import_react8.useState)(false);
11652
- const scrollRef = (0, import_react8.useRef)(null);
11653
- const send = async (text) => {
11654
- const t = text.trim();
11655
- if (!t || busy) return;
11656
- const base = [...msgs, { role: "user", content: t }];
11657
- setMsgs([...base, { role: "assistant", content: "" }]);
11658
- setInput("");
11659
- setBusy(true);
11660
- const setLast = (content) => setMsgs((m) => {
11661
- const c = [...m];
11662
- c[c.length - 1] = { role: "assistant", content };
11663
- return c;
11664
- });
11665
- try {
11666
- const r = await fetch("/api/public-report", {
11667
- method: "POST",
11668
- headers: { "Content-Type": "application/json" },
11669
- body: JSON.stringify({ messages: base })
11670
- });
11671
- const data = await r.json().catch(() => ({}));
11672
- if (!r.ok) {
11673
- setLast(r.status === 401 ? "Please sign in to edit your report." : data.error || "Couldn't apply that \u2014 try again.");
11674
- } else {
11675
- if (data.report) onUpdate(data.report);
11676
- setLast(data.reply || "Done.");
11677
- }
11678
- requestAnimationFrame(() => scrollRef.current?.scrollTo({ top: scrollRef.current.scrollHeight }));
11679
- } catch {
11680
- setLast("Something went wrong \u2014 try again.");
11681
- } finally {
11682
- setBusy(false);
11683
- }
11684
- };
11685
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex h-full flex-col rounded-2xl border border-line bg-paper p-4 shadow-[0_1px_2px_rgba(0,0,0,0.02)]", children: [
11686
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "mb-2", children: [
11687
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("h3", { className: "font-serif text-[16px] text-ink", children: "Edit your public report" }),
11688
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "mt-0.5 text-[12.5px] leading-relaxed text-muted", children: "Tell it what to show or hide \u2014 it pulls from your full analysis and updates the report live." })
11689
- ] }),
11690
- msgs.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "flex flex-wrap gap-1.5 py-1", children: STARTERS2.map((s) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
11691
- "button",
11692
- {
11693
- onClick: () => send(s),
11694
- disabled: busy,
11695
- className: "rounded-full border border-line bg-canvas px-3 py-1 text-[12px] text-muted transition-colors hover:border-accent hover:text-accent disabled:opacity-40",
11696
- children: s
11697
- },
11698
- s
11699
- )) }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { ref: scrollRef, className: "min-h-0 flex-1 space-y-2 overflow-y-auto py-1", children: msgs.map((m, i) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: m.role === "user" ? "flex justify-end" : "flex justify-start", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
11700
- "div",
11701
- {
11702
- className: `max-w-[88%] rounded-2xl px-3 py-1.5 text-[13px] leading-relaxed ${m.role === "user" ? "bg-accent text-white" : "bg-canvas text-ink"}`,
11703
- children: m.content || (busy ? "\u2026" : "")
11704
- }
11705
- ) }, i)) }),
11706
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "mt-2 flex items-end gap-2", children: [
11707
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
11708
- "textarea",
11709
- {
11710
- value: input,
11711
- onChange: (e) => setInput(e.target.value),
11712
- onKeyDown: (e) => {
11713
- if (e.key === "Enter" && !e.shiftKey) {
11714
- e.preventDefault();
11715
- send(input);
11716
- }
11717
- },
11718
- rows: 2,
11719
- placeholder: "e.g. don't show the failure modes",
11720
- className: "min-h-[40px] flex-1 resize-none rounded-xl border border-line bg-canvas px-3 py-2 text-[13px] text-ink outline-none focus:border-accent focus:ring-1 focus:ring-accent"
11721
- }
11722
- ),
11723
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
11724
- "button",
11725
- {
11726
- onClick: () => send(input),
11727
- disabled: busy || !input.trim(),
11728
- className: "rounded-xl bg-accent px-4 py-2 text-[13px] font-medium text-white transition-opacity hover:opacity-90 disabled:opacity-40",
11729
- children: busy ? "\u2026" : "Send"
11730
- }
11731
- )
11732
- ] })
11733
- ] });
11734
- }
11735
-
11736
- // ../../components/SharePublic.tsx
11737
- var import_react9 = __toESM(require_react());
11738
- var import_jsx_runtime10 = __toESM(require_jsx_runtime());
11739
- function publicBase() {
11740
- const env = "https://polymathsociety.us";
11741
- if (env) return env.replace(/\/$/, "");
11742
- if (typeof window !== "undefined") return window.location.origin;
11743
- return "https://polymathsociety.us";
11744
- }
11745
- function SharePublic({ editing, onToggleEdit } = {}) {
11746
- const [loading, setLoading] = (0, import_react9.useState)(true);
11747
- const [busy, setBusy] = (0, import_react9.useState)(false);
11748
- const [isPublic, setIsPublic] = (0, import_react9.useState)(false);
11749
- const [slug, setSlug] = (0, import_react9.useState)(null);
11750
- const [copied, setCopied] = (0, import_react9.useState)(false);
11751
- (0, import_react9.useEffect)(() => {
11752
- let alive = true;
11753
- fetch("/api/profile/visibility").then((r) => r.json()).then((d) => {
11754
- if (!alive) return;
11755
- setIsPublic(!!d.isPublic);
11756
- setSlug(d.slug ?? null);
11757
- }).catch(() => {
11758
- }).finally(() => alive && setLoading(false));
11759
- return () => {
11760
- alive = false;
11761
- };
11762
- }, []);
11763
- async function toggle(next) {
11764
- setBusy(true);
11765
- setCopied(false);
11766
- try {
11767
- const r = await fetch("/api/profile/visibility", {
11768
- method: "POST",
11769
- headers: { "Content-Type": "application/json" },
11770
- body: JSON.stringify({ isPublic: next })
11771
- });
11772
- const d = await r.json();
11773
- if (r.ok) {
11774
- setIsPublic(!!d.isPublic);
11775
- setSlug(d.slug ?? null);
11776
- }
11777
- } finally {
11778
- setBusy(false);
11779
- }
11780
- }
11781
- const url = slug ? `${publicBase()}/${slug}` : "";
11782
- async function copy() {
11783
- if (!url) return;
11784
- try {
11785
- await navigator.clipboard.writeText(url);
11786
- setCopied(true);
11787
- setTimeout(() => setCopied(false), 1800);
11788
- } catch {
11789
- }
11790
- }
11791
- if (loading) return null;
11792
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "mb-6 rounded-2xl border border-line bg-paper p-4", children: [
11793
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center justify-between gap-3", children: [
11794
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { children: [
11795
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "text-[13px] font-semibold text-ink", children: isPublic ? "Your report is public" : "Share your report" }),
11796
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "mt-0.5 text-[12px] text-faint", children: isPublic ? "Anyone with the link can view this report under your name." : "Publish a private link to this report. Off by default \u2014 nothing is shared until you flip it on." })
11797
- ] }),
11798
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex shrink-0 items-center gap-2", children: [
11799
- onToggleEdit && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
11800
- "button",
11801
- {
11802
- onClick: onToggleEdit,
11803
- "aria-pressed": !!editing,
11804
- title: editing ? "Close editor" : "Edit your public report",
11805
- className: `inline-flex items-center gap-1.5 rounded-xl border px-3 py-2 text-[13px] font-medium transition-colors ${editing ? "border-accent bg-accent text-white" : "border-line bg-canvas text-ink hover:border-accent hover:text-accent"}`,
11806
- children: [
11807
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: [
11808
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M12 20h9" }),
11809
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", { d: "M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4 12.5-12.5z" })
11810
- ] }),
11811
- editing ? "Editing" : "Edit"
11812
- ]
11813
- }
11814
- ),
11815
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
11816
- "button",
11817
- {
11818
- onClick: () => toggle(!isPublic),
11819
- disabled: busy,
11820
- className: `inline-flex items-center gap-2 rounded-xl px-4 py-2 text-[13px] font-medium transition-opacity disabled:opacity-60 ${isPublic ? "border border-line bg-canvas text-ink hover:bg-paper" : "bg-ink text-paper hover:opacity-90"}`,
11821
- children: [
11822
- busy && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Spinner, { className: isPublic ? "" : "text-paper" }),
11823
- isPublic ? "Make private" : "Make public"
11824
- ]
11825
- }
11826
- )
11827
- ] })
11828
- ] }),
11829
- isPublic && url && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "mt-3 flex items-center gap-2 border-t border-line pt-3", children: [
11830
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
11831
- "input",
11832
- {
11833
- readOnly: true,
11834
- value: url,
11835
- onFocus: (e) => e.currentTarget.select(),
11836
- className: "min-w-0 flex-1 truncate rounded-lg border border-line bg-canvas px-3 py-2 font-mono text-[12.5px] text-muted outline-none"
11837
- }
11838
- ),
11839
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
11840
- "button",
11841
- {
11842
- onClick: copy,
11843
- className: "shrink-0 rounded-lg border border-line px-3 py-2 text-[12.5px] font-medium text-ink transition-colors hover:bg-canvas",
11844
- children: copied ? "Copied" : "Copy"
11845
- }
11846
- ),
11847
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
11848
- "a",
11849
- {
11850
- href: url,
11851
- target: "_blank",
11852
- rel: "noreferrer",
11853
- className: "shrink-0 rounded-lg border border-line px-3 py-2 text-[12.5px] font-medium text-ink transition-colors hover:bg-canvas",
11854
- children: "Open"
11855
- }
11856
- )
11857
- ] })
11858
- ] });
11859
- }
11860
-
11861
- // ../../components/PublicCodingPageShare.tsx
11862
- var import_react10 = __toESM(require_react());
11863
- var import_jsx_runtime11 = __toESM(require_jsx_runtime());
11864
- var THINKING = "__polymath_public_page_thinking__";
11865
11737
  var rarity = (topPct2) => Math.min(11.2, 5 + 2 * Math.log10(50 / Math.max(0.01, topPct2)));
11866
11738
  function Radar2({ axes }) {
11867
11739
  const withPct = axes.filter((a) => a.topPct != null);
@@ -11874,24 +11746,24 @@ function Radar2({ axes }) {
11874
11746
  const n = withPct.length;
11875
11747
  const ring = (f) => withPct.map((_, i) => pt(i, R * f, n).join(",")).join(" ");
11876
11748
  const poly = withPct.map((a, i) => pt(i, R * 0.96 * rarity(a.topPct) / 11.2, n).join(",")).join(" ");
11877
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("svg", { viewBox: "-75 -14 490 330", width: "100%", style: { maxWidth: 490 }, "aria-label": "ability radar", children: [
11878
- [0.33, 0.66, 1].map((f) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("polygon", { points: ring(f), fill: "none", stroke: "var(--line, #e7e2d9)" }, f)),
11749
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("svg", { viewBox: "-75 -14 490 330", width: "100%", style: { maxWidth: 490 }, "aria-label": "ability radar", children: [
11750
+ [0.33, 0.66, 1].map((f) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("polygon", { points: ring(f), fill: "none", stroke: "var(--line, #e7e2d9)" }, f)),
11879
11751
  withPct.map((_, i) => {
11880
11752
  const [x, y] = pt(i, R, n);
11881
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("line", { x1: cx, y1: cy, x2: x, y2: y, stroke: "var(--line, #e7e2d9)" }, i);
11753
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("line", { x1: cx, y1: cy, x2: x, y2: y, stroke: "var(--line, #e7e2d9)" }, i);
11882
11754
  }),
11883
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("polygon", { points: poly, fill: "rgba(180,95,63,.14)", stroke: "#b45f3f", strokeWidth: 2 }),
11755
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("polygon", { points: poly, fill: "rgba(180,95,63,.14)", stroke: "#b45f3f", strokeWidth: 2 }),
11884
11756
  withPct.map((a, i) => {
11885
11757
  const [x, y] = pt(i, R * 0.96 * rarity(a.topPct) / 11.2, n);
11886
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("circle", { cx: x, cy: y, r: 3, fill: "#b45f3f" }, i);
11758
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("circle", { cx: x, cy: y, r: 3, fill: "#b45f3f" }, i);
11887
11759
  }),
11888
11760
  withPct.map((a, i) => {
11889
11761
  const [x, y] = pt(i, R + 24, n);
11890
11762
  const anchor = Math.abs(x - cx) < 10 ? "middle" : x > cx ? "start" : "end";
11891
11763
  const above = y < cy;
11892
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("text", { x, y: above ? y - 8 : y + 4, textAnchor: anchor, fontSize: 11, fill: "#6b6257", children: [
11893
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("tspan", { x, children: a.label }),
11894
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("tspan", { x, dy: 14, fontWeight: 700, fill: "#1a1714", children: [
11764
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("text", { x, y: above ? y - 8 : y + 4, textAnchor: anchor, fontSize: 11, fill: "#6b6257", children: [
11765
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("tspan", { x, children: a.label }),
11766
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("tspan", { x, dy: 14, fontWeight: 700, fill: "#1a1714", children: [
11895
11767
  "Top ",
11896
11768
  a.topPct,
11897
11769
  "%"
@@ -11900,70 +11772,104 @@ function Radar2({ axes }) {
11900
11772
  })
11901
11773
  ] });
11902
11774
  }
11903
- function buildChips(page) {
11904
- const specific = [];
11905
- for (const ax of page.axes) {
11906
- for (const m of ax.moments) {
11907
- const snippet = m.what.length > 46 ? `${m.what.slice(0, 46).trim()}\u2026` : m.what;
11908
- if (m.quote) specific.push(`Remove the "${snippet}" example in ${ax.label} (${m.date})`);
11909
- else specific.push(`Find different evidence than "${snippet}" for ${ax.label} (${m.date})`);
11910
- }
11911
- }
11912
- const general = [
11913
- "Hide the swear words in any quote",
11914
- "Don't show the specific project names",
11915
- "Get more evidence for the Taste claim"
11916
- ];
11917
- return [...specific.slice(0, 2), ...general].slice(0, 3);
11918
- }
11919
11775
  function AxisCard({ axis, hidden, onToggle }) {
11920
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: `rounded-xl border border-line p-3 transition-opacity ${hidden ? "bg-canvas opacity-45" : "bg-paper"}`, children: [
11921
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
11922
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "text-[12.5px] font-semibold text-ink", children: [
11776
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: `rounded-xl border border-line p-3 transition-opacity ${hidden ? "bg-canvas opacity-45" : "bg-paper"}`, children: [
11777
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
11778
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "text-[12.5px] font-semibold text-ink", children: [
11923
11779
  axis.label,
11924
11780
  " ",
11925
- axis.topPct != null && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "text-accent", children: [
11781
+ axis.topPct != null && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "text-accent", children: [
11926
11782
  "Top ",
11927
11783
  axis.topPct,
11928
11784
  "%"
11929
11785
  ] })
11930
11786
  ] }),
11931
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { onClick: onToggle, className: "rounded-full border border-line px-2.5 py-0.5 text-[10.5px] text-muted transition-colors hover:text-ink", children: hidden ? "Include" : "Hide" })
11787
+ onToggle && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { onClick: onToggle, className: "rounded-full border border-line px-2.5 py-0.5 text-[10.5px] text-muted transition-colors hover:text-ink", children: hidden ? "Include" : "Hide" })
11932
11788
  ] }),
11933
- !hidden && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
11934
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "mt-1.5 text-[13px] font-semibold text-ink", children: axis.claim }),
11935
- axis.read && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "mt-1 text-[12px] leading-relaxed text-muted", children: axis.read }),
11936
- axis.numbers.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "mt-2 flex flex-wrap gap-4", children: axis.numbers.map((n, i) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { children: [
11937
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "font-serif text-[18px] text-ink", children: n.big }),
11938
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "text-[10.5px] text-muted", children: n.lab })
11789
+ !hidden && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
11790
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "mt-1.5 text-[13px] font-semibold text-ink", children: axis.claim }),
11791
+ axis.read && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "mt-1 text-[12px] leading-relaxed text-muted", children: axis.read }),
11792
+ axis.numbers.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "mt-2 flex flex-wrap gap-4", children: axis.numbers.map((n, i) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { children: [
11793
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "font-serif text-[18px] text-ink", children: n.big }),
11794
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "text-[10.5px] text-muted", children: n.lab })
11939
11795
  ] }, i)) }),
11940
- axis.moments.map((m, i) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "mt-2 border-t border-dashed border-line pt-2 text-[12px] leading-relaxed", children: [
11941
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "mr-1.5 text-[10.5px] text-faint", children: m.date }),
11796
+ axis.moments.map((m, i) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "mt-2 border-t border-dashed border-line pt-2 text-[12px] leading-relaxed", children: [
11797
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "mr-1.5 text-[10.5px] text-faint", children: m.date }),
11942
11798
  m.what,
11943
- m.quote && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "mt-0.5 italic text-muted", children: [
11799
+ m.quote && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "mt-0.5 italic text-muted", children: [
11944
11800
  "\u201C",
11945
11801
  m.quote,
11946
11802
  "\u201D"
11947
11803
  ] })
11948
11804
  ] }, i)),
11949
- axis.edge && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "mt-2 border-t border-dashed border-line pt-2 text-[11.5px] text-muted", children: [
11950
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("b", { className: "text-ink", children: "Honest edge: " }),
11805
+ axis.edge && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "mt-2 border-t border-dashed border-line pt-2 text-[11.5px] text-muted", children: [
11806
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("b", { className: "text-ink", children: "Honest edge: " }),
11951
11807
  axis.edge
11952
11808
  ] })
11953
11809
  ] })
11954
11810
  ] });
11955
11811
  }
11812
+ function NumbersCard({ sec }) {
11813
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "rounded-xl border border-line bg-paper p-3", children: [
11814
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "text-[12.5px] font-semibold text-ink", children: sec.section }),
11815
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "mt-1.5 grid grid-cols-2 gap-x-4 gap-y-1 text-[12px]", children: sec.stats.map((s, j) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-baseline justify-between gap-2", children: [
11816
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "text-faint", children: s.lab }),
11817
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "font-medium text-ink", children: s.big })
11818
+ ] }, j)) })
11819
+ ] });
11820
+ }
11821
+ function CodingPageView({
11822
+ page,
11823
+ hiddenAxes,
11824
+ onToggleAxis
11825
+ }) {
11826
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "space-y-3", children: [
11827
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "rounded-xl border border-line bg-paper p-3.5 font-serif text-[15px] leading-relaxed text-ink", children: page.verdict }),
11828
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "flex justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Radar2, { axes: page.axes }) }),
11829
+ page.axes.map((a) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
11830
+ AxisCard,
11831
+ {
11832
+ axis: a,
11833
+ hidden: hiddenAxes?.has(a.key),
11834
+ onToggle: onToggleAxis ? () => onToggleAxis(a.key) : void 0
11835
+ },
11836
+ a.key
11837
+ )),
11838
+ page.moreNumbers.map((sec, i) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(NumbersCard, { sec }, i))
11839
+ ] });
11840
+ }
11841
+
11842
+ // ../../components/PublicCodingPageShare.tsx
11843
+ var import_react8 = __toESM(require_react());
11844
+ var import_jsx_runtime10 = __toESM(require_jsx_runtime());
11845
+ var THINKING = "__polymath_public_page_thinking__";
11846
+ function buildChips(page) {
11847
+ const specific = [];
11848
+ for (const ax of page.axes) {
11849
+ for (const m of ax.moments) {
11850
+ const snippet = m.what.length > 46 ? `${m.what.slice(0, 46).trim()}\u2026` : m.what;
11851
+ if (m.quote) specific.push(`Remove the "${snippet}" example in ${ax.label} (${m.date})`);
11852
+ else specific.push(`Find different evidence than "${snippet}" for ${ax.label} (${m.date})`);
11853
+ }
11854
+ }
11855
+ const general = [
11856
+ "Hide the swear words in any quote",
11857
+ "Don't show the specific project names",
11858
+ "Get more evidence for the Taste claim"
11859
+ ];
11860
+ return [...specific.slice(0, 2), ...general].slice(0, 3);
11861
+ }
11956
11862
  function PublicCodingPageShare({ identity, canAuth }) {
11957
- const [open, setOpen] = (0, import_react10.useState)(false);
11958
- const [page, setPage] = (0, import_react10.useState)(null);
11959
- const [loading, setLoading] = (0, import_react10.useState)("idle");
11960
- const [error, setError] = (0, import_react10.useState)(null);
11961
- const [hiddenAxes, setHiddenAxes] = (0, import_react10.useState)(/* @__PURE__ */ new Set());
11962
- const [msgs, setMsgs] = (0, import_react10.useState)([]);
11963
- const [busy, setBusy] = (0, import_react10.useState)(false);
11964
- const [sent, setSent] = (0, import_react10.useState)(false);
11965
- const [chatReport, setChatReport] = (0, import_react10.useState)(null);
11966
- const [includeChat, setIncludeChat] = (0, import_react10.useState)(true);
11863
+ const [open, setOpen] = (0, import_react8.useState)(false);
11864
+ const [page, setPage] = (0, import_react8.useState)(null);
11865
+ const [loading, setLoading] = (0, import_react8.useState)("idle");
11866
+ const [error, setError] = (0, import_react8.useState)(null);
11867
+ const [hiddenAxes, setHiddenAxes] = (0, import_react8.useState)(/* @__PURE__ */ new Set());
11868
+ const [msgs, setMsgs] = (0, import_react8.useState)([]);
11869
+ const [busy, setBusy] = (0, import_react8.useState)(false);
11870
+ const [sent, setSent] = (0, import_react8.useState)(false);
11871
+ const [chatReport, setChatReport] = (0, import_react8.useState)(null);
11872
+ const [includeChat, setIncludeChat] = (0, import_react8.useState)(true);
11967
11873
  const openModal = async () => {
11968
11874
  setOpen(true);
11969
11875
  setError(null);
@@ -11982,6 +11888,16 @@ function PublicCodingPageShare({ identity, canAuth }) {
11982
11888
  }
11983
11889
  setLoading("idle");
11984
11890
  };
11891
+ const openRef = (0, import_react8.useRef)(openModal);
11892
+ openRef.current = openModal;
11893
+ (0, import_react8.useEffect)(() => {
11894
+ const onAsk = (e) => {
11895
+ e.preventDefault();
11896
+ void openRef.current();
11897
+ };
11898
+ window.addEventListener("polymath:open-share", onAsk);
11899
+ return () => window.removeEventListener("polymath:open-share", onAsk);
11900
+ }, []);
11985
11901
  const generate = async () => {
11986
11902
  setLoading("generating");
11987
11903
  setError(null);
@@ -12007,6 +11923,7 @@ function PublicCodingPageShare({ identity, canAuth }) {
12007
11923
  body: JSON.stringify({ page, messages: base })
12008
11924
  }).then((r2) => r2.json());
12009
11925
  if (r.page) setPage(r.page);
11926
+ if (r.chatReport) setChatReport(r.chatReport);
12010
11927
  setMsgs((m) => {
12011
11928
  const c = [...m];
12012
11929
  c[c.length - 1] = { role: "assistant", content: r.reply || r.error || "Done." };
@@ -12039,79 +11956,81 @@ function PublicCodingPageShare({ identity, canAuth }) {
12039
11956
  }
12040
11957
  setLoading("idle");
12041
11958
  };
12042
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
12043
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { onClick: openModal, className: "rounded-full bg-ink px-3.5 py-1.5 text-[12px] font-medium text-paper transition-opacity hover:opacity-85", children: "Share report" }),
12044
- open && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "fixed inset-0 z-[60] flex items-center justify-center bg-black/30 p-4", onClick: () => setOpen(false), children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex max-h-[88vh] w-full max-w-[900px] flex-col rounded-2xl border border-line bg-canvas p-5 shadow-xl", onClick: (e) => e.stopPropagation(), children: [
12045
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h2", { className: "font-serif text-[23px] leading-snug text-ink", children: "We'll get you intros and opportunities based on how good you are." }),
12046
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "mt-1.5 text-[14px] font-semibold text-ink", children: [
11959
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
11960
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { onClick: openModal, className: "rounded-full bg-ink px-3.5 py-1.5 text-[12px] font-medium text-paper transition-opacity hover:opacity-85", children: "Share report" }),
11961
+ open && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "fixed inset-0 z-[60] flex items-center justify-center bg-black/30 p-4", onClick: () => setOpen(false), children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex max-h-[88vh] w-full max-w-[900px] flex-col rounded-2xl border border-line bg-canvas p-5 shadow-xl", onClick: (e) => e.stopPropagation(), children: [
11962
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h2", { className: "font-serif text-[23px] leading-snug text-ink", children: "We'll get you intros and opportunities based on how good you are." }),
11963
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "mt-1.5 text-[14px] font-semibold text-ink", children: [
12047
11964
  "Your ",
12048
11965
  chatReport ? "coding + chat profile" : "coding profile",
12049
11966
  " \u2014 review before sharing"
12050
11967
  ] }),
12051
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "mt-0.5 mb-3 text-[11.5px] text-faint", children: "Not a public page. Sending it goes privately to Polymath for opportunity-matching \u2014 nothing gets a public link." }),
12052
- loading === "checking" && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "py-10 text-center text-[13px] text-muted", children: "Loading\u2026" }),
12053
- error && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "mb-2 rounded-xl bg-amber-50 px-3 py-2 text-[12px] text-amber-800", children: error }),
12054
- !page && loading !== "checking" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "rounded-xl border border-dashed border-line p-8 text-center", children: [
12055
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "text-[13px] text-muted", children: "You haven't generated your coding profile yet." }),
12056
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { onClick: generate, disabled: loading === "generating", className: "mt-3 rounded-full bg-ink px-4 py-1.5 text-[12px] font-medium text-paper disabled:opacity-50", children: loading === "generating" ? "Generating\u2026 (this reads your sessions, ~1-2 min)" : "Generate my report" })
11968
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "mt-0.5 mb-3 text-[11.5px] text-faint", children: "Not a public page. Sending it goes privately to Polymath for opportunity-matching \u2014 nothing gets a public link." }),
11969
+ loading === "checking" && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "py-10 text-center text-[13px] text-muted", children: "Loading\u2026" }),
11970
+ error && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "mb-2 rounded-xl bg-amber-50 px-3 py-2 text-[12px] text-amber-800", children: error }),
11971
+ !page && loading !== "checking" && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "rounded-xl border border-dashed border-line p-8 text-center", children: [
11972
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "text-[13px] text-muted", children: "You haven't generated your coding profile yet." }),
11973
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { onClick: generate, disabled: loading === "generating", className: "mt-3 rounded-full bg-ink px-4 py-1.5 text-[12px] font-medium text-paper disabled:opacity-50", children: loading === "generating" ? "Generating\u2026 (this reads your sessions, ~1-2 min)" : "Generate my report" })
12057
11974
  ] }),
12058
- page && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "grid min-h-0 flex-1 gap-4 md:grid-cols-[1fr_300px]", children: [
12059
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "min-h-0 space-y-3 overflow-y-auto pr-1", children: [
12060
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "text-[11px] font-semibold uppercase tracking-[0.1em] text-faint", children: "Coding profile" }),
12061
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "rounded-xl border border-line bg-paper p-3.5 font-serif text-[15px] leading-relaxed text-ink", children: page.verdict }),
12062
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "flex justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Radar2, { axes: page.axes }) }),
12063
- page.axes.map((a) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(AxisCard, { axis: a, hidden: hiddenAxes.has(a.key), onToggle: () => setHiddenAxes((s) => {
12064
- const n = new Set(s);
12065
- n.has(a.key) ? n.delete(a.key) : n.add(a.key);
12066
- return n;
12067
- }) }, a.key)),
12068
- page.moreNumbers.map((sec, i) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "rounded-xl border border-line bg-paper p-3", children: [
12069
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "text-[12.5px] font-semibold text-ink", children: sec.section }),
12070
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "mt-1.5 grid grid-cols-2 gap-x-4 gap-y-1 text-[12px]", children: sec.stats.map((s, j) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-baseline justify-between gap-2", children: [
12071
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-faint", children: s.lab }),
12072
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-medium text-ink", children: s.big })
12073
- ] }, j)) })
12074
- ] }, i)),
12075
- chatReport && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
12076
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center justify-between gap-2 pt-2", children: [
12077
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h3", { className: "font-serif text-[19px] text-ink", children: "Your chat profile" }),
12078
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { onClick: () => setIncludeChat((v) => !v), className: "rounded-full border border-line px-2.5 py-0.5 text-[10.5px] text-muted transition-colors hover:text-ink", children: includeChat ? "Exclude from send" : "Include in send" })
11975
+ page && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "grid min-h-0 flex-1 gap-4 md:grid-cols-[1fr_300px]", children: [
11976
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "min-h-0 space-y-3 overflow-y-auto pr-1", children: [
11977
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "text-[11px] font-semibold uppercase tracking-[0.1em] text-faint", children: "Coding profile" }),
11978
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
11979
+ CodingPageView,
11980
+ {
11981
+ page,
11982
+ hiddenAxes,
11983
+ onToggleAxis: (key) => setHiddenAxes((s) => {
11984
+ const n = new Set(s);
11985
+ n.has(key) ? n.delete(key) : n.add(key);
11986
+ return n;
11987
+ })
11988
+ }
11989
+ ),
11990
+ chatReport && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
11991
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center justify-between gap-2 pt-2", children: [
11992
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h3", { className: "font-serif text-[19px] text-ink", children: "Your chat profile" }),
11993
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { onClick: () => setIncludeChat((v) => !v), className: "rounded-full border border-line px-2.5 py-0.5 text-[10.5px] text-muted transition-colors hover:text-ink", children: includeChat ? "Exclude from send" : "Include in send" })
12079
11994
  ] }),
12080
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "text-[10.5px] text-faint", children: "Sent with the coding profile. This is exactly the version from the Public report tab \u2014 edit it there." }),
12081
- includeChat ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "rounded-xl border border-line bg-paper p-3", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PublicReportView, { r: chatReport }) }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "rounded-xl border border-dashed border-line bg-canvas p-3 text-[12px] text-muted", children: "Excluded \u2014 only the coding profile will be sent." })
11995
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "text-[10.5px] text-faint", children: "Sent with the coding profile. Say \u201Cin the chat report\u2026\u201D to redact anything in it." }),
11996
+ includeChat ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "rounded-xl border border-line bg-paper p-3", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PublicReportView, { r: chatReport }) }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "rounded-xl border border-dashed border-line bg-canvas p-3 text-[12px] text-muted", children: "Excluded \u2014 only the coding profile will be sent." })
12082
11997
  ] })
12083
11998
  ] }),
12084
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex min-h-0 flex-col rounded-xl border border-line bg-paper p-3", children: [
12085
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "text-[12.5px] font-semibold text-ink", children: "Change it by talking to it" }),
12086
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "mt-0.5 text-[10.5px] text-faint", children: "Redact anything, or ask it to find different evidence. It can't invent achievements or change any number." }),
12087
- msgs.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "mt-2 flex flex-col gap-1.5", children: buildChips(page).map((c, i) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { onClick: () => send(c), disabled: busy, className: "text-left rounded-lg border border-line bg-canvas px-2.5 py-1.5 text-[10.5px] leading-snug text-muted transition-colors hover:text-ink disabled:opacity-40", children: c }, i)) }),
12088
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "mt-2 min-h-0 flex-1 space-y-1.5 overflow-y-auto", children: msgs.map((m, i) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: m.role === "user" ? "flex justify-end" : "flex justify-start", children: m.content === THINKING ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ThinkingBubble, {}) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: `max-w-[90%] rounded-xl px-2.5 py-1 text-[11.5px] leading-relaxed ${m.role === "user" ? "bg-ink text-paper" : "bg-canvas text-ink"}`, children: m.content }) }, i)) }),
12089
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ChatInput, { busy, onSend: send })
11999
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex min-h-0 flex-col rounded-xl border border-line bg-paper p-3", children: [
12000
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "text-[12.5px] font-semibold text-ink", children: "Change it by talking to it" }),
12001
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "mt-0.5 text-[10.5px] text-faint", children: [
12002
+ "Redact anything, or ask it to find different evidence. ",
12003
+ chatReport ? "Say \u201Cin the coding report\u2026\u201D or \u201Cin the chat report\u2026\u201D to aim it. " : "",
12004
+ "It can't invent achievements or change any number."
12005
+ ] }),
12006
+ msgs.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "mt-2 flex flex-col gap-1.5", children: buildChips(page).map((c, i) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { onClick: () => send(c), disabled: busy, className: "text-left rounded-lg border border-line bg-canvas px-2.5 py-1.5 text-[10.5px] leading-snug text-muted transition-colors hover:text-ink disabled:opacity-40", children: c }, i)) }),
12007
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "mt-2 min-h-0 flex-1 space-y-1.5 overflow-y-auto", children: msgs.map((m, i) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: m.role === "user" ? "flex justify-end" : "flex justify-start", children: m.content === THINKING ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ThinkingBubble, {}) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: `max-w-[90%] rounded-xl px-2.5 py-1 text-[11.5px] leading-relaxed ${m.role === "user" ? "bg-ink text-paper" : "bg-canvas text-ink"}`, children: m.content }) }, i)) }),
12008
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ChatInput, { busy, onSend: send })
12090
12009
  ] })
12091
12010
  ] }),
12092
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "mt-3 flex items-center justify-end gap-2 border-t border-line pt-3", children: sent ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "text-[12.5px] font-medium text-emerald-600", children: [
12011
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "mt-3 flex items-center justify-end gap-2 border-t border-line pt-3", children: sent ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "text-[12.5px] font-medium text-emerald-600", children: [
12093
12012
  "\u2713 Sent to Polymath \u2014 ",
12094
12013
  sent === "both" ? "coding + chat profile, " : "",
12095
12014
  "private, not a public page."
12096
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
12097
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { onClick: () => setOpen(false), className: "rounded-full px-3.5 py-1.5 text-[12px] text-muted transition-colors hover:text-ink", children: "Cancel" }),
12098
- identity ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { onClick: shareWithPolymath, disabled: !page || loading === "sending", className: "rounded-full bg-ink px-4 py-1.5 text-[12px] font-medium text-paper transition-opacity hover:opacity-85 disabled:opacity-50", children: loading === "sending" ? "Sending\u2026" : "Share with Polymath for opportunities" }) : canAuth ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("a", { href: "/auth/login", target: "_blank", rel: "noreferrer", className: "rounded-full bg-ink px-4 py-1.5 text-[12px] font-medium text-paper", children: "Sign in with Google to share" }) : null
12015
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
12016
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { onClick: () => setOpen(false), className: "rounded-full px-3.5 py-1.5 text-[12px] text-muted transition-colors hover:text-ink", children: "Cancel" }),
12017
+ identity ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { onClick: shareWithPolymath, disabled: !page || loading === "sending", className: "rounded-full bg-ink px-4 py-1.5 text-[12px] font-medium text-paper transition-opacity hover:opacity-85 disabled:opacity-50", children: loading === "sending" ? "Sending\u2026" : "Share with Polymath for opportunities" }) : canAuth ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("a", { href: "/auth/login", target: "_blank", rel: "noreferrer", className: "rounded-full bg-ink px-4 py-1.5 text-[12px] font-medium text-paper", children: "Sign in with Google to share" }) : null
12099
12018
  ] }) })
12100
12019
  ] }) })
12101
12020
  ] });
12102
12021
  }
12103
12022
  function ThinkingBubble() {
12104
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "polymath-edit-thinking max-w-[92%] rounded-2xl border border-line bg-canvas px-3 py-2 text-[11px] text-muted shadow-sm", children: [
12105
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "polymath-edit-thinking__bar", "aria-hidden": "true" }),
12106
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "relative inline-flex items-center gap-2", children: [
12107
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-medium text-ink", children: "Checking evidence" }),
12108
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "inline-flex items-center gap-1", "aria-label": "editing", children: [
12109
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", {}),
12110
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", {}),
12111
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", {})
12023
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "polymath-edit-thinking max-w-[92%] rounded-2xl border border-line bg-canvas px-3 py-2 text-[11px] text-muted shadow-sm", children: [
12024
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "polymath-edit-thinking__bar", "aria-hidden": "true" }),
12025
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "relative inline-flex items-center gap-2", children: [
12026
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "font-medium text-ink", children: "Checking evidence" }),
12027
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "inline-flex items-center gap-1", "aria-label": "editing", children: [
12028
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", {}),
12029
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", {}),
12030
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", {})
12112
12031
  ] })
12113
12032
  ] }),
12114
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("style", { children: `
12033
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("style", { children: `
12115
12034
  .polymath-edit-thinking {
12116
12035
  position: relative;
12117
12036
  overflow: hidden;
@@ -12151,15 +12070,15 @@ function ThinkingBubble() {
12151
12070
  ] });
12152
12071
  }
12153
12072
  function ChatInput({ busy, onSend }) {
12154
- const [text, setText] = (0, import_react10.useState)("");
12073
+ const [text, setText] = (0, import_react8.useState)("");
12155
12074
  const go = () => {
12156
12075
  if (text.trim()) {
12157
12076
  onSend(text);
12158
12077
  setText("");
12159
12078
  }
12160
12079
  };
12161
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "mt-2 flex items-end gap-1.5", children: [
12162
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
12080
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "mt-2 flex items-end gap-1.5", children: [
12081
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
12163
12082
  "textarea",
12164
12083
  {
12165
12084
  value: text,
@@ -12175,42 +12094,48 @@ function ChatInput({ busy, onSend }) {
12175
12094
  className: "min-h-[36px] flex-1 resize-none rounded-lg border border-line bg-canvas px-2.5 py-1.5 text-[11px] text-ink outline-none focus:border-ink/40"
12176
12095
  }
12177
12096
  ),
12178
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { onClick: go, disabled: busy || !text.trim(), className: "rounded-lg bg-ink px-3 py-1.5 text-[11px] font-medium text-paper disabled:opacity-40", children: busy ? "..." : "Send" })
12097
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { onClick: go, disabled: busy || !text.trim(), className: "rounded-lg bg-ink px-3 py-1.5 text-[11px] font-medium text-paper disabled:opacity-40", children: busy ? "..." : "Send" })
12179
12098
  ] });
12180
12099
  }
12181
12100
 
12182
12101
  // web/entry.tsx
12183
- var import_jsx_runtime12 = __toESM(require_jsx_runtime(), 1);
12102
+ var import_jsx_runtime11 = __toESM(require_jsx_runtime(), 1);
12184
12103
  function PublicReportTab() {
12185
- const [loaded, setLoaded] = (0, import_react11.useState)(false);
12186
- const [footprint, setFootprint] = (0, import_react11.useState)(null);
12187
- const [report, setReport] = (0, import_react11.useState)(null);
12188
- const [editing, setEditing] = (0, import_react11.useState)(false);
12189
- (0, import_react11.useEffect)(() => {
12190
- fetch("/api/public-report").then((r) => r.ok ? r.json() : null).then((d) => {
12191
- setReport(d?.report ?? null);
12192
- setFootprint(d?.footprint ?? null);
12193
- }).catch(() => {
12104
+ const [loaded, setLoaded] = (0, import_react9.useState)(false);
12105
+ const [shared, setShared] = (0, import_react9.useState)(null);
12106
+ (0, import_react9.useEffect)(() => {
12107
+ fetch("/api/shared-report").then((r) => r.ok ? r.json() : null).then((d) => setShared(d?.shared ?? null)).catch(() => {
12194
12108
  }).finally(() => setLoaded(true));
12195
12109
  }, []);
12196
- if (!loaded) return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "py-16 text-center text-[13px] text-faint", children: "Loading your public report\u2026" });
12197
- if (!report) {
12198
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rounded-2xl border border-dashed border-line bg-paper/60 px-6 py-16 text-center", children: [
12199
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("h2", { className: "font-serif text-[20px] text-ink", children: "No public report yet" }),
12200
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("p", { className: "mx-auto mt-2 max-w-[460px] text-[13.5px] leading-relaxed text-muted", children: [
12201
- "Your shareable report is distilled from the full analysis. Run",
12202
- " ",
12203
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("code", { className: "rounded bg-canvas px-1.5 py-0.5 text-[12px]", children: "polymath-analyzer serve --grade" }),
12204
- " ",
12205
- "(or pick a full-analysis depth in the wizard) and it will appear here."
12110
+ if (!loaded) return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "py-16 text-center text-[13px] text-faint", children: "Checking what you've shared\u2026" });
12111
+ if (!shared || !shared.page && !shared.chatReport) {
12112
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "rounded-xl border border-line bg-paper px-4 py-3", children: [
12113
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "font-serif text-[17px] text-ink", children: "You haven't shared anything yet" }),
12114
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("p", { className: "mt-1 max-w-[72ch] text-[13px] leading-relaxed text-muted", children: [
12115
+ "Nothing of yours has been sent to Polymath. Click ",
12116
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-medium text-ink", children: "Share report" }),
12117
+ " in the header to review your profile and choose what to send. Whatever you send shows up here."
12206
12118
  ] })
12207
12119
  ] });
12208
12120
  }
12209
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
12210
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SharePublic, { editing, onToggleEdit: () => setEditing((e) => !e) }),
12211
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: editing ? "grid grid-cols-1 gap-5 lg:grid-cols-[1fr_360px]" : "", children: [
12212
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "min-w-0", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(PublicReportView, { r: report, footprint }) }),
12213
- editing && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "lg:sticky lg:top-6 lg:h-[calc(100vh-3rem)]", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(PublicReportEditor, { onUpdate: setReport }) })
12121
+ const when = shared.sharedAt ? new Date(shared.sharedAt).toLocaleDateString(void 0, { month: "long", day: "numeric", year: "numeric" }) : null;
12122
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
12123
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "mb-4 rounded-xl border border-line bg-paper px-4 py-3", children: [
12124
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "font-serif text-[17px] text-ink", children: "What you shared with Polymath" }),
12125
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("p", { className: "mt-1 max-w-[72ch] text-[13px] leading-relaxed text-muted", children: [
12126
+ when ? `Sent ${when}. ` : "",
12127
+ "This is the exact copy Polymath holds, for opportunity-matching. It is not a public page and has no link. To change it, use ",
12128
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-medium text-ink", children: "Share report" }),
12129
+ " and send again."
12130
+ ] })
12131
+ ] }),
12132
+ shared.page && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "mb-5", children: [
12133
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "mb-2 text-[11px] font-semibold uppercase tracking-[0.1em] text-faint", children: "Coding profile" }),
12134
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(CodingPageView, { page: shared.page })
12135
+ ] }),
12136
+ shared.chatReport && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { children: [
12137
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "mb-2 text-[11px] font-semibold uppercase tracking-[0.1em] text-faint", children: "Chat profile" }),
12138
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PublicReportView, { r: shared.chatReport })
12214
12139
  ] })
12215
12140
  ] });
12216
12141
  }
@@ -12224,20 +12149,20 @@ function LaneRow({ name, l }) {
12224
12149
  if (l.skipped) return null;
12225
12150
  const pct = Math.round(laneFrac(l) * 100);
12226
12151
  const detail = l.done ? l.failed ? `${l.failed} stage${l.failed === 1 ? "" : "s"} failed. A rerun resumes them.` : "done \u2713" : `${l.label}${l.within ? ` \xB7 ${l.within.done}/${l.within.total}` : ""}${l.overnight ? " \xB7 heavy grading runs at 2:00 am tonight" : ""}`;
12227
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex min-w-0 flex-1 basis-full items-center gap-2 sm:basis-auto", children: [
12228
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "w-12 shrink-0 text-[11.5px] font-medium text-ink", children: name }),
12229
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "h-1.5 w-24 shrink-0 overflow-hidden rounded-full bg-canvas", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "h-full rounded-full bg-ink transition-all duration-700", style: { width: `${pct}%` } }) }),
12230
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "w-9 shrink-0 text-[12px] font-semibold tabular-nums text-ink", children: [
12152
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex min-w-0 flex-1 basis-full items-center gap-2 sm:basis-auto", children: [
12153
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "w-12 shrink-0 text-[11.5px] font-medium text-ink", children: name }),
12154
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "h-1.5 w-24 shrink-0 overflow-hidden rounded-full bg-canvas", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "h-full rounded-full bg-ink transition-all duration-700", style: { width: `${pct}%` } }) }),
12155
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "w-9 shrink-0 text-[12px] font-semibold tabular-nums text-ink", children: [
12231
12156
  pct,
12232
12157
  "%"
12233
12158
  ] }),
12234
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "min-w-0 text-[11.5px] text-muted", children: detail })
12159
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "min-w-0 text-[11.5px] text-muted", children: detail })
12235
12160
  ] });
12236
12161
  }
12237
- function PipelineProgressBanner() {
12238
- const [p, setP] = (0, import_react11.useState)(null);
12239
- const [landedSinceLoad, setLandedSinceLoad] = (0, import_react11.useState)(false);
12240
- (0, import_react11.useEffect)(() => {
12162
+ function usePipelineProgress() {
12163
+ const [p, setP] = (0, import_react9.useState)(null);
12164
+ const [landedSinceLoad, setLandedSinceLoad] = (0, import_react9.useState)(false);
12165
+ (0, import_react9.useEffect)(() => {
12241
12166
  let alive = true;
12242
12167
  let baseRev = null;
12243
12168
  const poll = () => fetch("/api/progress").then((r) => r.ok ? r.json() : null).then((j) => {
@@ -12256,48 +12181,81 @@ function PipelineProgressBanner() {
12256
12181
  window.clearInterval(t);
12257
12182
  };
12258
12183
  }, []);
12184
+ return { p, landedSinceLoad };
12185
+ }
12186
+ function PipelineProgressBanner({ p, landedSinceLoad }) {
12259
12187
  const visible = [["coding", p?.coding], ["chat", p?.chat]].filter(([, l]) => l && !l.skipped);
12260
12188
  const anyRunning = visible.some(([, l]) => !l.done);
12261
12189
  const anyOvernight = visible.some(([, l]) => !l.done && l.overnight);
12262
12190
  if (!visible.length || !anyRunning && !landedSinceLoad) return null;
12263
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "mb-4 rounded-xl border border-line bg-paper px-4 py-3 text-[12.5px] text-muted", children: [
12264
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "mb-1.5 flex items-center gap-2", children: [
12265
- anyRunning && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "inline-block h-2 w-2 animate-pulse rounded-full bg-amber-500", "aria-hidden": true }),
12266
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "font-medium text-ink", children: !anyRunning ? "New results just landed." : anyOvernight ? "Part of your analysis is scheduled for 2:00 am tonight. This page fills in as stages finish." : "Your analysis is still running. This page fills in as stages finish." }),
12267
- landedSinceLoad && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { onClick: () => window.location.reload(), className: "ml-auto rounded-full bg-ink px-3 py-1 text-[11.5px] font-medium text-paper transition-opacity hover:opacity-85", children: "Load the new results" })
12191
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "mb-4 rounded-xl border border-line bg-paper px-4 py-3 text-[12.5px] text-muted", children: [
12192
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "mb-1.5 flex items-center gap-2", children: [
12193
+ anyRunning && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "inline-block h-2 w-2 animate-pulse rounded-full bg-amber-500", "aria-hidden": true }),
12194
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-medium text-ink", children: !anyRunning ? "New results just landed." : anyOvernight ? "Part of your analysis is scheduled for 2:00 am tonight. This page fills in as stages finish." : "Your analysis is still running. This page fills in as stages finish." }),
12195
+ landedSinceLoad && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { onClick: () => window.location.reload(), className: "ml-auto rounded-full bg-ink px-3 py-1 text-[11.5px] font-medium text-paper transition-opacity hover:opacity-85", children: "Load the new results" })
12268
12196
  ] }),
12269
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "flex flex-wrap items-center gap-x-6 gap-y-1.5", children: visible.map(([name, l]) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(LaneRow, { name, l }, name)) }),
12270
- anyOvernight && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "mt-2 rounded-lg bg-canvas px-3 py-2 text-[12px] text-ink", children: [
12271
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "font-medium", children: "For the overnight part to finish:" }),
12272
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "ml-2", children: "1. Keep the laptop plugged in." }),
12273
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "ml-3", children: "2. Keep the lid open. A closed lid means sleep, and the run stalls until morning." })
12197
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "flex flex-wrap items-center gap-x-6 gap-y-1.5", children: visible.map(([name, l]) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(LaneRow, { name, l }, name)) }),
12198
+ anyOvernight && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "mt-2 rounded-lg bg-canvas px-3 py-2 text-[12px] text-ink", children: [
12199
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-medium", children: "For the overnight part to finish:" }),
12200
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "ml-2", children: "1. Keep the laptop plugged in." }),
12201
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "ml-3", children: "2. Keep the lid open. A closed lid means sleep, and the run stalls until morning." })
12274
12202
  ] })
12275
12203
  ] });
12276
12204
  }
12205
+ function LaneStatusCard({ name, lane }) {
12206
+ if (!lane || lane.done || lane.skipped) return null;
12207
+ const pct = Math.round(laneFrac(lane) * 100);
12208
+ const isOvernight = !!lane.overnight;
12209
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "mb-5 rounded-2xl border border-line bg-paper p-5", children: [
12210
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-wrap items-center justify-between gap-3", children: [
12211
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { children: [
12212
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "text-[11px] font-semibold uppercase tracking-[0.1em] text-faint", children: [
12213
+ name,
12214
+ " analysis"
12215
+ ] }),
12216
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "mt-1 font-serif text-[20px] leading-snug text-ink", children: isOvernight ? "Will run at 2:00 am tonight" : "Analysis is still running" })
12217
+ ] }),
12218
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "text-right", children: [
12219
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "font-serif text-[26px] text-ink", children: [
12220
+ pct,
12221
+ "%"
12222
+ ] }),
12223
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "text-[11.5px] text-faint", children: "complete" })
12224
+ ] })
12225
+ ] }),
12226
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "mt-4 h-2 overflow-hidden rounded-full bg-canvas", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "h-full rounded-full bg-accent transition-all duration-700", style: { width: `${pct}%` } }) }),
12227
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("p", { className: "mt-3 text-[13px] leading-relaxed text-muted", children: [
12228
+ lane.label ? `${lane.label}${lane.within ? `, ${lane.within.done}/${lane.within.total}` : ""}. ` : "",
12229
+ isOvernight ? "The deterministic prep can run now, but the AI grading and synthesis are waiting for the overnight window." : "This tab will fill in as stages finish."
12230
+ ] }),
12231
+ isOvernight && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "mt-2 rounded-lg bg-canvas px-3 py-2 text-[12px] text-ink", children: "Keep the laptop plugged in and the lid open. Closing the lid can put the machine to sleep and stall the run." })
12232
+ ] });
12233
+ }
12277
12234
  var TABS = [
12278
12235
  { key: "coding", label: "Code analysis" },
12279
12236
  { key: "chat", label: "Chat analysis" },
12280
- { key: "public", label: "Public report" }
12237
+ { key: "public", label: "Shared report" }
12281
12238
  ];
12282
- function ChatTab() {
12283
- const [state, setState] = (0, import_react11.useState)("loading");
12284
- const [links, setLinks] = (0, import_react11.useState)([]);
12285
- (0, import_react11.useEffect)(() => {
12239
+ function ChatTab({ progress }) {
12240
+ const [state, setState] = (0, import_react9.useState)("loading");
12241
+ const [links, setLinks] = (0, import_react9.useState)([]);
12242
+ (0, import_react9.useEffect)(() => {
12286
12243
  fetch("/api/exports-manifest").then((r) => r.ok ? r.json() : null).then((j) => {
12287
12244
  setLinks(j?.links ?? []);
12288
12245
  setState(j?.connectedKinds?.length ? "connected" : "empty");
12289
12246
  }).catch(() => setState("connected"));
12290
12247
  }, []);
12291
12248
  if (state === "loading") return null;
12292
- if (state === "connected") return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(DetailedDataView, {});
12293
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rounded-2xl border border-line bg-paper p-6", children: [
12294
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "font-serif text-[19px] text-ink", children: "No chat exports connected yet" }),
12295
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("p", { className: "mt-1.5 max-w-[62ch] text-[13px] leading-relaxed text-muted", children: [
12249
+ if (state === "connected" && progress && !progress.done && !progress.skipped) return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(LaneStatusCard, { name: "chat", lane: progress });
12250
+ if (state === "connected") return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(DetailedDataView, {});
12251
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "rounded-2xl border border-line bg-paper p-6", children: [
12252
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "font-serif text-[19px] text-ink", children: "No chat exports connected yet" }),
12253
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("p", { className: "mt-1.5 max-w-[62ch] text-[13px] leading-relaxed text-muted", children: [
12296
12254
  "This tab analyzes your ChatGPT, claude.ai, or Notion history the same way the Code tab analyzes your Claude Code sessions. Request an export below, then run ",
12297
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("code", { className: "rounded bg-canvas px-1.5 py-0.5 text-[12px]", children: "polymath-society" }),
12255
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("code", { className: "rounded bg-canvas px-1.5 py-0.5 text-[12px]", children: "polymath-society" }),
12298
12256
  " again in your terminal \u2014 it finds the downloaded zip automatically and adds it to your report."
12299
12257
  ] }),
12300
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "mt-4 space-y-2.5", children: links.filter((l) => l.requestUrl).map((l) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
12258
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "mt-4 space-y-2.5", children: links.filter((l) => l.requestUrl).map((l) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
12301
12259
  "a",
12302
12260
  {
12303
12261
  href: l.requestUrl,
@@ -12305,19 +12263,19 @@ function ChatTab() {
12305
12263
  rel: "noreferrer",
12306
12264
  className: "flex items-center justify-between gap-3 rounded-xl border border-line bg-canvas px-4 py-3 transition-colors hover:border-accent",
12307
12265
  children: [
12308
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { children: [
12309
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "text-[13px] font-semibold text-ink", children: [
12266
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { children: [
12267
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "text-[13px] font-semibold text-ink", children: [
12310
12268
  "Request my ",
12311
12269
  l.label,
12312
12270
  " export"
12313
12271
  ] }),
12314
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "mt-0.5 text-[11.5px] text-faint", children: [
12272
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "mt-0.5 text-[11.5px] text-faint", children: [
12315
12273
  l.buttonPath,
12316
12274
  " \xB7 ready in ",
12317
12275
  l.eta
12318
12276
  ] })
12319
12277
  ] }),
12320
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "shrink-0 text-[12px] font-medium text-accent", children: "Open \u2192" })
12278
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "shrink-0 text-[12px] font-medium text-accent", children: "Open \u2192" })
12321
12279
  ]
12322
12280
  },
12323
12281
  l.kind
@@ -12325,8 +12283,9 @@ function ChatTab() {
12325
12283
  ] });
12326
12284
  }
12327
12285
  function Shell() {
12328
- const [meta, setMeta] = (0, import_react11.useState)(null);
12329
- const [tab, setTab] = (0, import_react11.useState)(() => {
12286
+ const [meta, setMeta] = (0, import_react9.useState)(null);
12287
+ const { p: progress, landedSinceLoad } = usePipelineProgress();
12288
+ const [tab, setTab] = (0, import_react9.useState)(() => {
12330
12289
  const h = (typeof window !== "undefined" ? window.location.hash : "").replace("#", "");
12331
12290
  return h === "chat" || h === "public" ? h : "coding";
12332
12291
  });
@@ -12337,8 +12296,8 @@ function Shell() {
12337
12296
  } catch {
12338
12297
  }
12339
12298
  };
12340
- const [rubricNudge, setRubricNudge] = (0, import_react11.useState)(null);
12341
- (0, import_react11.useEffect)(() => {
12299
+ const [rubricNudge, setRubricNudge] = (0, import_react9.useState)(null);
12300
+ (0, import_react9.useEffect)(() => {
12342
12301
  fetch("/api/config/calibration").then((r) => r.ok ? r.json() : null).then((cal) => {
12343
12302
  if (cal?.source === "central" && cal.localRubricVersion && cal.doc?.rubricVersion && cal.localRubricVersion !== cal.doc.rubricVersion) {
12344
12303
  setRubricNudge(`A newer grading rubric is published (${cal.doc.rubricVersion} \u2014 this install has ${cal.localRubricVersion}). Update polymath-analyzer and re-grade to stay comparable.`);
@@ -12347,7 +12306,7 @@ function Shell() {
12347
12306
  });
12348
12307
  }, []);
12349
12308
  const refreshMeta = () => fetch("/meta.json").then((r) => r.ok ? r.json() : null).then(setMeta).catch(() => setMeta(null));
12350
- (0, import_react11.useEffect)(() => {
12309
+ (0, import_react9.useEffect)(() => {
12351
12310
  refreshMeta();
12352
12311
  const onFocus = () => refreshMeta();
12353
12312
  window.addEventListener("focus", onFocus);
@@ -12360,31 +12319,31 @@ function Shell() {
12360
12319
  };
12361
12320
  const identity = meta?.identity;
12362
12321
  const canAuth = meta?.capabilities?.auth !== false;
12363
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
12364
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "mb-6 flex flex-wrap items-center justify-between gap-3 border-b border-line pb-4", children: [
12365
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { children: [
12366
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "text-[15px] font-semibold text-ink", children: "Your coding analysis" }),
12367
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "text-[11.5px] text-faint", children: "computed on this machine \xB7 nothing leaves it without your say-so" })
12322
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
12323
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "mb-6 flex flex-wrap items-center justify-between gap-3 border-b border-line pb-4", children: [
12324
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { children: [
12325
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "text-[15px] font-semibold text-ink", children: "Your coding analysis" }),
12326
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "text-[11.5px] text-faint", children: "computed on this machine \xB7 nothing leaves it without your say-so" })
12368
12327
  ] }),
12369
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex items-center gap-2", children: [
12370
- identity ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
12371
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rounded-full bg-paper px-3 py-1 text-[12px] text-muted", title: identity.email, children: identity.name || identity.email }),
12372
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { onClick: signOut, className: "rounded-full px-2 py-1 text-[11.5px] text-faint transition-colors hover:text-ink", children: "Sign out" })
12373
- ] }) : canAuth ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("a", { href: "/auth/login", target: "_blank", rel: "noreferrer", className: "inline-flex items-center gap-2 rounded-full border border-line bg-paper px-3.5 py-1.5 text-[12px] font-medium text-ink transition-colors hover:bg-canvas", children: [
12374
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 48 48", "aria-hidden": "true", children: [
12375
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { fill: "#EA4335", d: "M24 9.5c3.54 0 6.71 1.22 9.21 3.6l6.85-6.85C35.9 2.38 30.47 0 24 0 14.62 0 6.51 5.38 2.56 13.22l7.98 6.19C12.43 13.72 17.74 9.5 24 9.5z" }),
12376
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { fill: "#4285F4", d: "M46.98 24.55c0-1.57-.15-3.09-.38-4.55H24v9.02h12.94c-.58 2.96-2.26 5.48-4.78 7.18l7.73 6c4.51-4.18 7.09-10.36 7.09-17.65z" }),
12377
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { fill: "#FBBC05", d: "M10.53 28.59c-.48-1.45-.76-2.99-.76-4.59s.27-3.14.76-4.59l-7.98-6.19C.92 16.46 0 20.12 0 24c0 3.88.92 7.54 2.56 10.78l7.97-6.19z" }),
12378
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { fill: "#34A853", d: "M24 48c6.48 0 11.93-2.13 15.89-5.81l-7.73-6c-2.15 1.45-4.92 2.3-8.16 2.3-6.26 0-11.57-4.22-13.47-9.91l-7.98 6.19C6.51 42.62 14.62 48 24 48z" })
12328
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-2", children: [
12329
+ identity ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
12330
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "rounded-full bg-paper px-3 py-1 text-[12px] text-muted", title: identity.email, children: identity.name || identity.email }),
12331
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { onClick: signOut, className: "rounded-full px-2 py-1 text-[11.5px] text-faint transition-colors hover:text-ink", children: "Sign out" })
12332
+ ] }) : canAuth ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("a", { href: "/auth/login", target: "_blank", rel: "noreferrer", className: "inline-flex items-center gap-2 rounded-full border border-line bg-paper px-3.5 py-1.5 text-[12px] font-medium text-ink transition-colors hover:bg-canvas", children: [
12333
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 48 48", "aria-hidden": "true", children: [
12334
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { fill: "#EA4335", d: "M24 9.5c3.54 0 6.71 1.22 9.21 3.6l6.85-6.85C35.9 2.38 30.47 0 24 0 14.62 0 6.51 5.38 2.56 13.22l7.98 6.19C12.43 13.72 17.74 9.5 24 9.5z" }),
12335
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { fill: "#4285F4", d: "M46.98 24.55c0-1.57-.15-3.09-.38-4.55H24v9.02h12.94c-.58 2.96-2.26 5.48-4.78 7.18l7.73 6c4.51-4.18 7.09-10.36 7.09-17.65z" }),
12336
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { fill: "#FBBC05", d: "M10.53 28.59c-.48-1.45-.76-2.99-.76-4.59s.27-3.14.76-4.59l-7.98-6.19C.92 16.46 0 20.12 0 24c0 3.88.92 7.54 2.56 10.78l7.97-6.19z" }),
12337
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { fill: "#34A853", d: "M24 48c6.48 0 11.93-2.13 15.89-5.81l-7.73-6c-2.15 1.45-4.92 2.3-8.16 2.3-6.26 0-11.57-4.22-13.47-9.91l-7.98 6.19C6.51 42.62 14.62 48 24 48z" })
12379
12338
  ] }),
12380
12339
  "Sign in with Google"
12381
12340
  ] }) : null,
12382
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(PublicCodingPageShare, { identity: identity ?? null, canAuth })
12341
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PublicCodingPageShare, { identity: identity ?? null, canAuth })
12383
12342
  ] })
12384
12343
  ] }),
12385
- rubricNudge && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "mb-4 rounded-xl bg-amber-50 px-4 py-2.5 text-[12.5px] text-amber-800", children: rubricNudge }),
12386
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(PipelineProgressBanner, {}),
12387
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "mb-6 flex items-center gap-1 rounded-full border border-line bg-paper p-1", role: "tablist", "aria-label": "Report sections", children: TABS.map((t) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
12344
+ rubricNudge && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "mb-4 rounded-xl bg-amber-50 px-4 py-2.5 text-[12.5px] text-amber-800", children: rubricNudge }),
12345
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PipelineProgressBanner, { p: progress, landedSinceLoad }),
12346
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "mb-6 flex items-center gap-1 rounded-full border border-line bg-paper p-1", role: "tablist", "aria-label": "Report sections", children: TABS.map((t) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
12388
12347
  "button",
12389
12348
  {
12390
12349
  role: "tab",
@@ -12395,13 +12354,16 @@ function Shell() {
12395
12354
  },
12396
12355
  t.key
12397
12356
  )) }),
12398
- tab === "coding" && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(CodeAnalysisView, {}),
12399
- tab === "chat" && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ChatTab, {}),
12400
- tab === "public" && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(PublicReportTab, {})
12357
+ tab === "coding" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
12358
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(LaneStatusCard, { name: "coding", lane: progress?.coding }),
12359
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(CodeAnalysisView, {})
12360
+ ] }),
12361
+ tab === "chat" && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ChatTab, { progress: progress?.chat }),
12362
+ tab === "public" && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PublicReportTab, {})
12401
12363
  ] });
12402
12364
  }
12403
12365
  var el = document.getElementById("root");
12404
- if (el) (0, import_client.createRoot)(el).render(/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Shell, {}));
12366
+ if (el) (0, import_client.createRoot)(el).render(/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Shell, {}));
12405
12367
  /*! Bundled license information:
12406
12368
 
12407
12369
  react/cjs/react.production.min.js: