polymath-society 0.2.4 → 0.2.6

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_react10 = __toESM(require_react(), 1);
7282
+ var import_react11 = __toESM(require_react(), 1);
7283
7283
  var import_client = __toESM(require_client(), 1);
7284
7284
 
7285
7285
  // ../../components/CodeAnalysisView.tsx
@@ -7855,8 +7855,30 @@ function FeedbackSection({
7855
7855
  const api = (0, import_react2.useContext)(FeedbackCtx);
7856
7856
  const ref = (0, import_react2.useRef)(null);
7857
7857
  const [text, setText] = (0, import_react2.useState)("");
7858
+ const [quick, setQuick] = (0, import_react2.useState)("idle");
7858
7859
  const status = api?.statusOf(sectionKey);
7859
7860
  if (!isLocalRuntime()) return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children });
7861
+ const sendNow = async () => {
7862
+ const t = text.trim();
7863
+ if (!t || quick === "sending") return;
7864
+ setQuick("sending");
7865
+ try {
7866
+ const r = await fetch("/api/feedback/submit", {
7867
+ method: "POST",
7868
+ headers: { "Content-Type": "application/json" },
7869
+ body: JSON.stringify({ reportKind, sectionKey, sectionLabel: label, feedback: t, context: "", evidence: {} })
7870
+ });
7871
+ if (!r.ok) {
7872
+ setQuick("error");
7873
+ return;
7874
+ }
7875
+ setQuick("sent");
7876
+ setText("");
7877
+ setTimeout(() => setQuick("idle"), 4e3);
7878
+ } catch {
7879
+ setQuick("error");
7880
+ }
7881
+ };
7860
7882
  const startGather = () => {
7861
7883
  if (!api) return;
7862
7884
  api.gather({
@@ -7922,13 +7944,22 @@ function FeedbackSection({
7922
7944
  {
7923
7945
  value: text,
7924
7946
  onChange: (e) => setText(e.target.value),
7925
- placeholder: "What's wrong, harsh, missed, or right about this read? Say it however you want \u2014 nothing is sent until you preview and approve it.",
7947
+ onKeyDown: (e) => {
7948
+ if (e.key === "Enter" && !e.shiftKey) {
7949
+ e.preventDefault();
7950
+ void sendNow();
7951
+ }
7952
+ },
7953
+ placeholder: "What's wrong, harsh, missed, or right about this read? Say it however you want \u2014 Enter sends your words right away.",
7926
7954
  className: "min-h-[52px] w-full resize-y rounded-lg border border-line bg-paper px-3 py-2 text-[13px] leading-relaxed text-ink placeholder:text-faint focus:border-accent focus:outline-none"
7927
7955
  }
7928
7956
  ),
7929
- text.trim() && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "mt-2 flex items-center gap-2.5", children: [
7930
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { onClick: startGather, className: "rounded-lg bg-accent px-3 py-1.5 text-[12px] font-semibold text-white", children: "Gather evidence" }),
7931
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-[11px] text-faint", children: "stays on this machine \u2014 review & send later, all at once" })
7957
+ quick === "sent" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "mt-1.5 text-[12px] font-medium text-emerald-600", children: "\u2713 Sent \u2014 thank you. Got more? Just keep writing." }),
7958
+ quick === "error" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "mt-1.5 text-[12px] text-red-600", children: "Couldn't send \u2014 check you're signed in (top right) and try again." }),
7959
+ text.trim() && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "mt-2 flex flex-wrap items-center gap-2.5", children: [
7960
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { onClick: () => void sendNow(), disabled: quick === "sending", className: "rounded-lg bg-accent px-3.5 py-1.5 text-[12px] font-semibold text-white disabled:opacity-50", children: quick === "sending" ? "Sending\u2026" : "Send" }),
7961
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-[11px] text-faint", children: "sends your words + this section's name, instantly" }),
7962
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { onClick: startGather, className: "rounded-lg border border-line px-3 py-1.5 text-[11.5px] text-muted transition-colors hover:text-ink", title: "Runs a local audit of what the analysis missed for this section \u2014 takes minutes, previewed before anything extra is sent", children: "Deep audit first" })
7932
7963
  ] })
7933
7964
  ] })
7934
7965
  ] })
@@ -8175,6 +8206,11 @@ function ReportChatSidebar({ endpoint = "/api/coding/chat" } = {}) {
8175
8206
  window.addEventListener("keydown", onKey);
8176
8207
  return () => window.removeEventListener("keydown", onKey);
8177
8208
  }, []);
8209
+ (0, import_react3.useEffect)(() => {
8210
+ const close = () => setOpen(false);
8211
+ window.addEventListener("polymath:close-ask-drawer", close);
8212
+ return () => window.removeEventListener("polymath:close-ask-drawer", close);
8213
+ }, []);
8178
8214
  const send = async (text) => {
8179
8215
  const t = text.trim();
8180
8216
  if (!t || busy) return;
@@ -8279,7 +8315,7 @@ function ReportChatSidebar({ endpoint = "/api/coding/chat" } = {}) {
8279
8315
 
8280
8316
  // ../../lib/calibration/index.ts
8281
8317
  var DEFAULT_CALIBRATION = {
8282
- version: "2026-07-12.2",
8318
+ version: "2026-07-14.2",
8283
8319
  // = RUBRIC_FINGERPRINT of the shipped npm rubric (packages/coding-analyzer/
8284
8320
  // src/grade/criteria.ts). A unit test fails loud when the rubric changes
8285
8321
  // without this being updated (and re-pushed to the server).
@@ -8368,7 +8404,7 @@ var DEFAULT_CALIBRATION = {
8368
8404
  }
8369
8405
  ],
8370
8406
  codingTiers: {
8371
- push: { median: 300, sigma: 1.121, tag: "estimated \u2014 log-normal fit", source: "Anthropic 2026 Claude Code study (400k sessions): median engaged user ~8 prompts/day at ~35 words \u2014 ~300 directed words/day; tail shape from its actions-per-prompt distribution. AVERAGE over substantial days, cumulative not spiky." },
8407
+ push: { median: 300, sigma: 0.91, tag: "estimated \u2014 log-normal fit", source: "Anthropic 2026 Claude Code study (400k sessions): median engaged user ~8 prompts/day at ~35 words \u2014 ~300 directed words/day; tail: a 1-in-1,000 user AVERAGES ~5k directed words/day (near-daily heavy dictation, clearly below the ~10k single-day record). AVERAGE over substantial days, cumulative not spiky." },
8372
8408
  focus: { median: 0.08, sigma: 0.559, tag: "estimated \u2014 proxy-anchored", source: "median: Anthropic 20h/week engaged-user figure implies ~1h/day of true rapid exchange against an 8h working day; ceiling anchored to the ~4h/day deep-work limit (45% share = 1-in-1,000). AVERAGE share, cumulative not spiky." },
8373
8409
  orchestration: { tag: "estimated \u2014 behavior bands", source: "no published concurrency distribution exists; ceiling anchored to the Claude Code lead's documented 10-15 parallel sessions" }
8374
8410
  },
@@ -8401,12 +8437,18 @@ var DEFAULT_CALIBRATION = {
8401
8437
  line: "the Claude Code lead runs 10\u201315 sessions at once; his #1 tip is 3\u20135 git worktrees in parallel"
8402
8438
  },
8403
8439
  throughput: {
8404
- // Top-0.1% words/day reference lines, anchored to the throughput ladder
8405
- // (THROUGHPUT_LADDER in throughput.ts): score 10 "world-class sustained" =
8406
- // 9k/day, score 11 "superhuman ceiling" = 12k/day. Calibrated to the person's
8407
- // own anchors, not a wild guess but still a target, not a measured population.
8408
- topAvgWordsPerDay: 9e3,
8409
- topPeakWordsPerDay: 12e3,
8440
+ // Two DIFFERENT kinds of line (2026-07-14.2): topAvg is a PERCENTILE
8441
+ // claim — what a 1-in-1,000 user AVERAGES over substantial days (5k/day:
8442
+ // near-daily heavy dictation; a measured top dictating power user
8443
+ // averages ~3.9k). topPeak is NOT a percentileit is the CEILING
8444
+ // reference, the wildest single days on record (~10k: a 14-16h
8445
+ // launch-day marathon), rendered as "wildest single days", never
8446
+ // "top X% peak". An avg-percentile and a peak-percentile can't both be
8447
+ // shown at a same-ish value (avg≈peak reads broken — user call), and a
8448
+ // peak PERCENTILE line is unknowable anyway; the record framing is
8449
+ // honest and keeps the visual gap.
8450
+ topAvgWordsPerDay: 5e3,
8451
+ topPeakWordsPerDay: 1e4,
8410
8452
  benchLabel: "top 0.1%",
8411
8453
  // No published "words typed/day" for heavy users — the real story is OUTPUT.
8412
8454
  loopsHeadline: ">1,000,000 lines of Rust at 99.8% tests passing",
@@ -9482,14 +9524,6 @@ var DO_THIS = {
9482
9524
  context: "`/init` to generate or refresh CLAUDE.md; send the `anthropic-beta: context-1m-2025-08-07` header (Sonnet) to unlock the 1M-token window.",
9483
9525
  headless: '`claude -p "<task>" --allowedTools "Bash,Read,Edit"` to run unattended; `/install-github-app` so a `@claude` mention on a PR/issue auto-fixes it.'
9484
9526
  };
9485
- var FOR_YOU = {
9486
- worktrees: "You run everything in `main` with parallel sessions, so git branching isn't your pain \u2014 fair. Worktrees only help when two concurrent sessions edit the SAME files and clobber each other (or one runs a migration/install while another reads). If your parallel sessions stay on separate areas, skip this. If they ever collide, the one flag above is the entire fix.",
9487
- subagents: "You're already fanning out \u2014 Claude spun up subagents on its own in 19 of your sessions, so the ad-hoc version is automatic; you don't need to \u201Cset up a multi-agent system.\u201D The thing you're NOT doing: saving your OWN reusable specialists. Your per-criterion graders (OCEAN, Growth, interpersonal, agency) should each be a named `.claude/agents/*.md` agent you invoke by name, instead of re-prompting the rubric every run.",
9488
- loops: "Your overnight \u201CSet up EC2 instance\u201D and nightly grading re-runs are unattended grinds you currently babysit and re-run by hand \u2014 the exact shape a self-correcting loop finishes overnight against your test suite.",
9489
- browser: "You already drive Claude-in-Chrome by hand (8 sessions). Same job \u2014 but the agent navigates, screenshots, reads the console, and fixes its own regression in one turn, instead of you relaying what you saw.",
9490
- context: "This repo already ships a CLAUDE.md, so you have half of it. The lever you're not using is the 1M window \u2014 hold the whole engine + coding pipeline in one pass for big cross-cutting changes instead of hitting mid-task compaction.",
9491
- headless: "You manually \u201CContinue interrupted HITL server task\u201D to resume stalled runs \u2014 a `claude -p` job (or a GitHub Action) could re-run and self-heal those with no one watching."
9492
- };
9493
9527
  function FrontierPanel({ f, detail, coaching, gap, parallelism }) {
9494
9528
  const AUTO = /* @__PURE__ */ new Set(["queue-ahead", "deferred-tools", "subagent-fanout", "task-orchestration", "visualize", "web-research"]);
9495
9529
  const deliberate = f.capabilities.filter((c) => !AUTO.has(c.key)).sort((a, b) => b.sessions - a.sessions);
@@ -9567,10 +9601,6 @@ function FrontierPanel({ f, detail, coaching, gap, parallelism }) {
9567
9601
  DO_THIS[m.key] && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "mt-1.5 rounded-lg bg-accentSoft/40 px-2.5 py-1.5 text-[12.5px] leading-relaxed text-ink", children: [
9568
9602
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "font-semibold text-accent", children: "Do this \u2014 " }),
9569
9603
  DO_THIS[m.key]
9570
- ] }),
9571
- FOR_YOU[m.key] && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "mt-1.5 border-l-2 border-line pl-2.5 text-[12px] leading-relaxed text-muted", children: [
9572
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "font-semibold text-ink", children: "For you \u2014 " }),
9573
- FOR_YOU[m.key]
9574
9604
  ] })
9575
9605
  ] }, m.key)) }) })
9576
9606
  ] });
@@ -9876,9 +9906,9 @@ function ThroughputScatterPanel({ data, coaching, minDate }) {
9876
9906
  ] })
9877
9907
  ] }),
9878
9908
  /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "mt-0.5 text-[12px] text-faint", children: [
9879
- "words per day \u2014 a proxy for focus & hard work \xB7 your days in orange (your avg = orange dashed line) \xB7 grey dashed = ",
9909
+ "words per day \u2014 a proxy for focus & hard work \xB7 your days in orange (your avg = orange dashed line) \xB7 grey dashed = the ",
9880
9910
  BEST2.throughput.benchLabel,
9881
- " \xB7 hover a dot for detail"
9911
+ " average and the wildest single days on record \xB7 hover a dot for detail"
9882
9912
  ] }),
9883
9913
  /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { ref: wrapRef, className: "relative mt-3", children: [
9884
9914
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "overflow-x-auto", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("svg", { viewBox: `0 0 ${W} ${H}`, className: "w-full min-w-[560px]", role: "img", "aria-label": "throughput by day", children: [
@@ -9888,7 +9918,7 @@ function ThroughputScatterPanel({ data, coaching, minDate }) {
9888
9918
  ] }, i)),
9889
9919
  [
9890
9920
  { v: BEST2.throughput.topAvgWordsPerDay, label: `${BEST2.throughput.benchLabel} avg` },
9891
- { v: BEST2.throughput.topPeakWordsPerDay, label: `${BEST2.throughput.benchLabel} peak` }
9921
+ { v: BEST2.throughput.topPeakWordsPerDay, label: "wildest days on record" }
9892
9922
  ].map((ref, i) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("g", { children: [
9893
9923
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("line", { x1: L, x2: W - R, y1: y(ref.v), y2: y(ref.v), className: "stroke-ink/40", strokeWidth: 1, strokeDasharray: "4 3" }),
9894
9924
  /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("text", { x: W - R, y: y(ref.v) - 4, textAnchor: "end", className: "fill-muted", fontSize: 9, children: [
@@ -9982,6 +10012,7 @@ function IntensityWeekRows({ data }) {
9982
10012
  const effWeeks = nDays / 7;
9983
10013
  const avgSpan = Math.round(inStretch.reduce((a, d) => a + d.span, 0) / effWeeks * 10) / 10;
9984
10014
  const avgBrk = Math.round(inStretch.reduce((a, d) => a + d.brk, 0) / effWeeks * 10) / 10;
10015
+ const breaksMeasured = (data.focus?.days ?? []).some((d) => d.ranges);
9985
10016
  const row = (label, value, sub) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-baseline justify-between rounded-xl border border-line bg-canvas px-4 py-3", children: [
9986
10017
  /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
9987
10018
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "text-[13px] font-semibold text-ink", children: label }),
@@ -10067,8 +10098,8 @@ function IntensityWeekRows({ data }) {
10067
10098
  ] })
10068
10099
  ] }),
10069
10100
  nDays === 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "mt-2 rounded-lg border border-line bg-canvas px-3 py-2 text-[12.5px] text-muted", children: "No solid coding stretch in this window (a stretch needs days with 2h+ of work at most 4 days apart) \u2014 widen the range or hit Reset to all." }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "mt-2 space-y-2", children: [
10070
- row("Hours / week, including breaks", `${avgSpan}h`, "your working day with meals and breaks; overnight and 4h+ absences excluded"),
10071
- row("Break hours / week", `${avgBrk}h`, "daytime gaps of 30 min to 4h inside your workday; meals, errands, drift")
10101
+ row("Hours / week, including breaks", `${avgSpan}h`, breaksMeasured ? "your working day with meals and breaks; overnight and 4h+ absences excluded" : "first \u2192 last activity per day"),
10102
+ breaksMeasured && row("Break hours / week", `${avgBrk}h`, "daytime gaps of 30 min to 4h inside your workday; meals, errands, drift")
10072
10103
  ] })
10073
10104
  ] });
10074
10105
  }
@@ -10327,15 +10358,15 @@ function CodeAnalysisView({ data: dataProp } = {}) {
10327
10358
  data.frontierArsenal && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(FrontierPanel, { f: data.frontierArsenal, detail: data.frontierDetail, coaching: data.coaching?.coaching?.frontier, gap: data.gap, parallelism: data.parallelism }),
10328
10359
  data.delegationRollup && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(DelegationPanel, { r: data.delegationRollup, takes: data.criteria?.find((c) => c.key === "delegation")?.takes })
10329
10360
  ] }), ["delegation", "frontier"]),
10330
- fs("coding:expertise", "Expertise", /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
10361
+ data.expertiseMap && fs("coding:expertise", "Expertise", /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
10331
10362
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SectionDivider, { label: "Expertise" }),
10332
- data.expertiseMap && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ExpertiseMapPanel, { x: data.expertiseMap, coaching: data.coaching?.coaching?.expertise })
10363
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ExpertiseMapPanel, { x: data.expertiseMap, coaching: data.coaching?.coaching?.expertise })
10333
10364
  ] }), ["expertise"]),
10334
- fs("coding:qualitatives", "The qualitatives", /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
10365
+ (data.gradedSessions ?? 0) > 0 && data.aggregate?.ability && fs("coding:qualitatives", "The qualitatives", /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
10335
10366
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SectionDivider, { label: "The qualitatives", note: "Our best estimate, with the specific chats behind each read. These are hard to tell from your Claude Code logs alone \u2014 you may well be much better than what shows up here." }),
10336
- data.aggregate?.ability && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AbilityPanel, { a: data.aggregate.ability, feelSeen: data.coaching?.feelSeen, agencyScore: (data.stackUp ?? []).find((r) => r.label === "Agency")?.score ?? null })
10367
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AbilityPanel, { a: data.aggregate.ability, feelSeen: data.coaching?.feelSeen, agencyScore: (data.stackUp ?? []).find((r) => r.label === "Agency")?.score ?? null })
10337
10368
  ] }), []),
10338
- fs("coding:conclusion", "In conclusion", /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
10369
+ (data.gradedSessions ?? 0) > 0 && fs("coding:conclusion", "In conclusion", /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
10339
10370
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SectionDivider, { label: "In conclusion" }),
10340
10371
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(FeelSeenConclusionPanel, { data }),
10341
10372
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(BetterThanYouPanel, { data })
@@ -11827,38 +11858,419 @@ function SharePublic({ editing, onToggleEdit } = {}) {
11827
11858
  ] });
11828
11859
  }
11829
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
+ var rarity = (topPct2) => Math.min(11.2, 5 + 2 * Math.log10(50 / Math.max(0.01, topPct2)));
11866
+ function Radar2({ axes }) {
11867
+ const withPct = axes.filter((a) => a.topPct != null);
11868
+ if (!withPct.length) return null;
11869
+ const cx = 170, cy = 150, R = 104;
11870
+ const pt = (i, r, n2) => {
11871
+ const a = Math.PI * 2 * i / n2 - Math.PI / 2;
11872
+ return [cx + r * Math.cos(a), cy + r * Math.sin(a)];
11873
+ };
11874
+ const n = withPct.length;
11875
+ const ring = (f) => withPct.map((_, i) => pt(i, R * f, n).join(",")).join(" ");
11876
+ 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)),
11879
+ withPct.map((_, i) => {
11880
+ 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);
11882
+ }),
11883
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("polygon", { points: poly, fill: "rgba(180,95,63,.14)", stroke: "#b45f3f", strokeWidth: 2 }),
11884
+ withPct.map((a, i) => {
11885
+ 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);
11887
+ }),
11888
+ withPct.map((a, i) => {
11889
+ const [x, y] = pt(i, R + 24, n);
11890
+ const anchor = Math.abs(x - cx) < 10 ? "middle" : x > cx ? "start" : "end";
11891
+ 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: [
11895
+ "Top ",
11896
+ a.topPct,
11897
+ "%"
11898
+ ] })
11899
+ ] }, i);
11900
+ })
11901
+ ] });
11902
+ }
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
+ 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: [
11923
+ axis.label,
11924
+ " ",
11925
+ axis.topPct != null && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "text-accent", children: [
11926
+ "Top ",
11927
+ axis.topPct,
11928
+ "%"
11929
+ ] })
11930
+ ] }),
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" })
11932
+ ] }),
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 })
11939
+ ] }, 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 }),
11942
+ m.what,
11943
+ m.quote && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "mt-0.5 italic text-muted", children: [
11944
+ "\u201C",
11945
+ m.quote,
11946
+ "\u201D"
11947
+ ] })
11948
+ ] }, 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: " }),
11951
+ axis.edge
11952
+ ] })
11953
+ ] })
11954
+ ] });
11955
+ }
11956
+ 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);
11967
+ const openModal = async () => {
11968
+ setOpen(true);
11969
+ setError(null);
11970
+ setSent(false);
11971
+ setLoading("checking");
11972
+ try {
11973
+ window.dispatchEvent(new Event("polymath:close-ask-drawer"));
11974
+ } catch {
11975
+ }
11976
+ try {
11977
+ const r = await fetch("/api/public-coding-page").then((r2) => r2.json());
11978
+ setPage(r.page ?? null);
11979
+ setChatReport(r.chatReport ?? null);
11980
+ } catch {
11981
+ setError("couldn't load your report");
11982
+ }
11983
+ setLoading("idle");
11984
+ };
11985
+ const generate = async () => {
11986
+ setLoading("generating");
11987
+ setError(null);
11988
+ try {
11989
+ const r = await fetch("/api/public-coding-page/generate", { method: "POST" }).then((r2) => r2.json());
11990
+ if (r.page) setPage(r.page);
11991
+ else setError(r.error || "generation failed");
11992
+ } catch {
11993
+ setError("generation failed \u2014 try again");
11994
+ }
11995
+ setLoading("idle");
11996
+ };
11997
+ const send = async (text) => {
11998
+ const t = text.trim();
11999
+ if (!t || busy || !page) return;
12000
+ const base = [...msgs, { role: "user", content: t }];
12001
+ setMsgs([...base, { role: "assistant", content: THINKING }]);
12002
+ setBusy(true);
12003
+ try {
12004
+ const r = await fetch("/api/public-coding-page/edit", {
12005
+ method: "POST",
12006
+ headers: { "content-type": "application/json" },
12007
+ body: JSON.stringify({ page, messages: base })
12008
+ }).then((r2) => r2.json());
12009
+ if (r.page) setPage(r.page);
12010
+ setMsgs((m) => {
12011
+ const c = [...m];
12012
+ c[c.length - 1] = { role: "assistant", content: r.reply || r.error || "Done." };
12013
+ return c;
12014
+ });
12015
+ } catch {
12016
+ setMsgs((m) => {
12017
+ const c = [...m];
12018
+ c[c.length - 1] = { role: "assistant", content: "Something went wrong \u2014 try again." };
12019
+ return c;
12020
+ });
12021
+ }
12022
+ setBusy(false);
12023
+ };
12024
+ const shareWithPolymath = async () => {
12025
+ if (!page) return;
12026
+ setLoading("sending");
12027
+ setError(null);
12028
+ const toSend = { ...page, axes: page.axes.filter((a) => !hiddenAxes.has(a.key)) };
12029
+ try {
12030
+ const r = await fetch("/api/public-coding-page/share", {
12031
+ method: "POST",
12032
+ headers: { "content-type": "application/json" },
12033
+ body: JSON.stringify({ page: toSend, includeChat: includeChat && !!chatReport })
12034
+ }).then((r2) => r2.json());
12035
+ if (r.ok) setSent(r.includedChat ? "both" : "coding");
12036
+ else setError(r.error || "couldn't send");
12037
+ } catch {
12038
+ setError("couldn't send \u2014 try again");
12039
+ }
12040
+ setLoading("idle");
12041
+ };
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: [
12047
+ "Your ",
12048
+ chatReport ? "coding + chat profile" : "coding profile",
12049
+ " \u2014 review before sharing"
12050
+ ] }),
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" })
12057
+ ] }),
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" })
12079
+ ] }),
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." })
12082
+ ] })
12083
+ ] }),
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 })
12090
+ ] })
12091
+ ] }),
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: [
12093
+ "\u2713 Sent to Polymath \u2014 ",
12094
+ sent === "both" ? "coding + chat profile, " : "",
12095
+ "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
12099
+ ] }) })
12100
+ ] }) })
12101
+ ] });
12102
+ }
12103
+ 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", {})
12112
+ ] })
12113
+ ] }),
12114
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("style", { children: `
12115
+ .polymath-edit-thinking {
12116
+ position: relative;
12117
+ overflow: hidden;
12118
+ }
12119
+ .polymath-edit-thinking__bar {
12120
+ position: absolute;
12121
+ inset: 0;
12122
+ background: linear-gradient(90deg, transparent, rgba(180, 95, 63, 0.10), transparent);
12123
+ transform: translateX(-110%);
12124
+ animation: polymath-edit-scan 1.45s ease-in-out infinite;
12125
+ }
12126
+ .polymath-edit-thinking span[aria-label="editing"] span {
12127
+ width: 4px;
12128
+ height: 4px;
12129
+ border-radius: 999px;
12130
+ background: currentColor;
12131
+ opacity: .35;
12132
+ animation: polymath-edit-dot 1.05s ease-in-out infinite;
12133
+ }
12134
+ .polymath-edit-thinking span[aria-label="editing"] span:nth-child(2) { animation-delay: .15s; }
12135
+ .polymath-edit-thinking span[aria-label="editing"] span:nth-child(3) { animation-delay: .30s; }
12136
+ @keyframes polymath-edit-scan {
12137
+ 0% { transform: translateX(-110%); }
12138
+ 55%, 100% { transform: translateX(110%); }
12139
+ }
12140
+ @keyframes polymath-edit-dot {
12141
+ 0%, 80%, 100% { opacity: .30; transform: translateY(0); }
12142
+ 40% { opacity: .95; transform: translateY(-2px); }
12143
+ }
12144
+ @media (prefers-reduced-motion: reduce) {
12145
+ .polymath-edit-thinking__bar,
12146
+ .polymath-edit-thinking span[aria-label="editing"] span {
12147
+ animation: none;
12148
+ }
12149
+ }
12150
+ ` })
12151
+ ] });
12152
+ }
12153
+ function ChatInput({ busy, onSend }) {
12154
+ const [text, setText] = (0, import_react10.useState)("");
12155
+ const go = () => {
12156
+ if (text.trim()) {
12157
+ onSend(text);
12158
+ setText("");
12159
+ }
12160
+ };
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)(
12163
+ "textarea",
12164
+ {
12165
+ value: text,
12166
+ onChange: (e) => setText(e.target.value),
12167
+ onKeyDown: (e) => {
12168
+ if (e.key === "Enter" && !e.shiftKey) {
12169
+ e.preventDefault();
12170
+ go();
12171
+ }
12172
+ },
12173
+ rows: 2,
12174
+ placeholder: "or say it your own way\u2026",
12175
+ 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
+ }
12177
+ ),
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" })
12179
+ ] });
12180
+ }
12181
+
11830
12182
  // web/entry.tsx
11831
- var import_jsx_runtime11 = __toESM(require_jsx_runtime(), 1);
12183
+ var import_jsx_runtime12 = __toESM(require_jsx_runtime(), 1);
11832
12184
  function PublicReportTab() {
11833
- const [loaded, setLoaded] = (0, import_react10.useState)(false);
11834
- const [footprint, setFootprint] = (0, import_react10.useState)(null);
11835
- const [report, setReport] = (0, import_react10.useState)(null);
11836
- const [editing, setEditing] = (0, import_react10.useState)(false);
11837
- (0, import_react10.useEffect)(() => {
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)(() => {
11838
12190
  fetch("/api/public-report").then((r) => r.ok ? r.json() : null).then((d) => {
11839
12191
  setReport(d?.report ?? null);
11840
12192
  setFootprint(d?.footprint ?? null);
11841
12193
  }).catch(() => {
11842
12194
  }).finally(() => setLoaded(true));
11843
12195
  }, []);
11844
- if (!loaded) return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "py-16 text-center text-[13px] text-faint", children: "Loading your public report\u2026" });
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" });
11845
12197
  if (!report) {
11846
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "rounded-2xl border border-dashed border-line bg-paper/60 px-6 py-16 text-center", children: [
11847
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h2", { className: "font-serif text-[20px] text-ink", children: "No public report yet" }),
11848
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("p", { className: "mx-auto mt-2 max-w-[460px] text-[13.5px] leading-relaxed text-muted", children: [
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: [
11849
12201
  "Your shareable report is distilled from the full analysis. Run",
11850
12202
  " ",
11851
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("code", { className: "rounded bg-canvas px-1.5 py-0.5 text-[12px]", children: "polymath-analyzer serve --grade" }),
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" }),
11852
12204
  " ",
11853
12205
  "(or pick a full-analysis depth in the wizard) and it will appear here."
11854
12206
  ] })
11855
12207
  ] });
11856
12208
  }
11857
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
11858
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SharePublic, { editing, onToggleEdit: () => setEditing((e) => !e) }),
11859
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: editing ? "grid grid-cols-1 gap-5 lg:grid-cols-[1fr_360px]" : "", children: [
11860
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "min-w-0", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PublicReportView, { r: report, footprint }) }),
11861
- editing && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "lg:sticky lg:top-6 lg:h-[calc(100vh-3rem)]", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PublicReportEditor, { onUpdate: setReport }) })
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 }) })
12214
+ ] })
12215
+ ] });
12216
+ }
12217
+ function laneFrac(l) {
12218
+ if (l.done) return 1;
12219
+ if (!l.total) return 0;
12220
+ const w = l.within && l.within.total ? l.within.done / l.within.total : 0;
12221
+ return Math.min(1, Math.max(0, (l.i - 1 + w) / l.total));
12222
+ }
12223
+ function LaneRow({ name, l }) {
12224
+ if (l.skipped) return null;
12225
+ const pct = Math.round(laneFrac(l) * 100);
12226
+ 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: [
12231
+ pct,
12232
+ "%"
12233
+ ] }),
12234
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "min-w-0 text-[11.5px] text-muted", children: detail })
12235
+ ] });
12236
+ }
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)(() => {
12241
+ let alive = true;
12242
+ let baseRev = null;
12243
+ const poll = () => fetch("/api/progress").then((r) => r.ok ? r.json() : null).then((j) => {
12244
+ if (!alive || !j) return;
12245
+ if (typeof j.profileRev === "number") {
12246
+ if (baseRev == null) baseRev = j.profileRev;
12247
+ else if (j.profileRev > baseRev) setLandedSinceLoad(true);
12248
+ }
12249
+ setP(j);
12250
+ }).catch(() => {
12251
+ });
12252
+ poll();
12253
+ const t = window.setInterval(poll, 5e3);
12254
+ return () => {
12255
+ alive = false;
12256
+ window.clearInterval(t);
12257
+ };
12258
+ }, []);
12259
+ const visible = [["coding", p?.coding], ["chat", p?.chat]].filter(([, l]) => l && !l.skipped);
12260
+ const anyRunning = visible.some(([, l]) => !l.done);
12261
+ const anyOvernight = visible.some(([, l]) => !l.done && l.overnight);
12262
+ 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" })
12268
+ ] }),
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." })
11862
12274
  ] })
11863
12275
  ] });
11864
12276
  }
@@ -11867,9 +12279,54 @@ var TABS = [
11867
12279
  { key: "chat", label: "Chat analysis" },
11868
12280
  { key: "public", label: "Public report" }
11869
12281
  ];
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)(() => {
12286
+ fetch("/api/exports-manifest").then((r) => r.ok ? r.json() : null).then((j) => {
12287
+ setLinks(j?.links ?? []);
12288
+ setState(j?.connectedKinds?.length ? "connected" : "empty");
12289
+ }).catch(() => setState("connected"));
12290
+ }, []);
12291
+ 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: [
12296
+ "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" }),
12298
+ " again in your terminal \u2014 it finds the downloaded zip automatically and adds it to your report."
12299
+ ] }),
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)(
12301
+ "a",
12302
+ {
12303
+ href: l.requestUrl,
12304
+ target: "_blank",
12305
+ rel: "noreferrer",
12306
+ 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
+ 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: [
12310
+ "Request my ",
12311
+ l.label,
12312
+ " export"
12313
+ ] }),
12314
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "mt-0.5 text-[11.5px] text-faint", children: [
12315
+ l.buttonPath,
12316
+ " \xB7 ready in ",
12317
+ l.eta
12318
+ ] })
12319
+ ] }),
12320
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "shrink-0 text-[12px] font-medium text-accent", children: "Open \u2192" })
12321
+ ]
12322
+ },
12323
+ l.kind
12324
+ )) })
12325
+ ] });
12326
+ }
11870
12327
  function Shell() {
11871
- const [meta, setMeta] = (0, import_react10.useState)(null);
11872
- const [tab, setTab] = (0, import_react10.useState)(() => {
12328
+ const [meta, setMeta] = (0, import_react11.useState)(null);
12329
+ const [tab, setTab] = (0, import_react11.useState)(() => {
11873
12330
  const h = (typeof window !== "undefined" ? window.location.hash : "").replace("#", "");
11874
12331
  return h === "chat" || h === "public" ? h : "coding";
11875
12332
  });
@@ -11880,10 +12337,8 @@ function Shell() {
11880
12337
  } catch {
11881
12338
  }
11882
12339
  };
11883
- const [shareState, setShareState] = (0, import_react10.useState)("idle");
11884
- const [shareMsg, setShareMsg] = (0, import_react10.useState)("");
11885
- const [rubricNudge, setRubricNudge] = (0, import_react10.useState)(null);
11886
- (0, import_react10.useEffect)(() => {
12340
+ const [rubricNudge, setRubricNudge] = (0, import_react11.useState)(null);
12341
+ (0, import_react11.useEffect)(() => {
11887
12342
  fetch("/api/config/calibration").then((r) => r.ok ? r.json() : null).then((cal) => {
11888
12343
  if (cal?.source === "central" && cal.localRubricVersion && cal.doc?.rubricVersion && cal.localRubricVersion !== cal.doc.rubricVersion) {
11889
12344
  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.`);
@@ -11892,7 +12347,7 @@ function Shell() {
11892
12347
  });
11893
12348
  }, []);
11894
12349
  const refreshMeta = () => fetch("/meta.json").then((r) => r.ok ? r.json() : null).then(setMeta).catch(() => setMeta(null));
11895
- (0, import_react10.useEffect)(() => {
12350
+ (0, import_react11.useEffect)(() => {
11896
12351
  refreshMeta();
11897
12352
  const onFocus = () => refreshMeta();
11898
12353
  window.addEventListener("focus", onFocus);
@@ -11903,62 +12358,33 @@ function Shell() {
11903
12358
  });
11904
12359
  refreshMeta();
11905
12360
  };
11906
- const share = async () => {
11907
- if (shareState === "sharing") return;
11908
- setShareState("sharing");
11909
- setShareMsg("");
11910
- try {
11911
- const r = await fetch("/share", {
11912
- method: "POST",
11913
- headers: { "content-type": "application/json" },
11914
- body: JSON.stringify({ all: true, name: meta?.identity?.name || void 0 })
11915
- });
11916
- const j = await r.json().catch(() => ({}));
11917
- if (r.ok && j.ok) {
11918
- setShareState("shared");
11919
- setShareMsg(`Shared ${Array.isArray(j.shared) ? j.shared.length : ""} sections`);
11920
- } else {
11921
- setShareState("error");
11922
- setShareMsg(j.error || `sharing failed (${r.status})`);
11923
- }
11924
- } catch (e) {
11925
- setShareState("error");
11926
- setShareMsg(e.message || "sharing failed");
11927
- }
11928
- };
11929
12361
  const identity = meta?.identity;
11930
12362
  const canAuth = meta?.capabilities?.auth !== false;
11931
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
11932
- /* @__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: [
11933
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { children: [
11934
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "text-[15px] font-semibold text-ink", children: "Your coding analysis" }),
11935
- /* @__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" })
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" })
11936
12368
  ] }),
11937
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-center gap-2", children: [
11938
- identity ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
11939
- /* @__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 }),
11940
- /* @__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" })
11941
- ] }) : canAuth ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("a", { href: "/auth/login", target: "_blank", rel: "noreferrer", className: "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: "Sign in with Google" }) : null,
11942
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
11943
- "button",
11944
- {
11945
- onClick: share,
11946
- disabled: shareState === "sharing",
11947
- className: "rounded-full bg-ink px-3.5 py-1.5 text-[12px] font-medium text-paper transition-opacity hover:opacity-85 disabled:opacity-50",
11948
- children: shareState === "sharing" ? "Sharing\u2026" : shareState === "shared" ? "Shared \u2713" : "Share report"
11949
- }
11950
- )
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" })
12379
+ ] }),
12380
+ "Sign in with Google"
12381
+ ] }) : null,
12382
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(PublicCodingPageShare, { identity: identity ?? null, canAuth })
11951
12383
  ] })
11952
12384
  ] }),
11953
- 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 }),
11954
- shareMsg && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: `mb-4 rounded-xl px-4 py-2.5 text-[12.5px] ${shareState === "error" ? "bg-amber-50 text-amber-800" : "bg-paper text-muted"}`, children: [
11955
- shareMsg,
11956
- shareState === "error" && /sign in/i.test(shareMsg) && !identity && canAuth ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
11957
- " ",
11958
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("a", { href: "/auth/login", target: "_blank", rel: "noreferrer", className: "font-medium underline", children: "Sign in" })
11959
- ] }) : null
11960
- ] }),
11961
- /* @__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)(
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)(
11962
12388
  "button",
11963
12389
  {
11964
12390
  role: "tab",
@@ -11969,13 +12395,13 @@ function Shell() {
11969
12395
  },
11970
12396
  t.key
11971
12397
  )) }),
11972
- tab === "coding" && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(CodeAnalysisView, {}),
11973
- tab === "chat" && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(DetailedDataView, {}),
11974
- tab === "public" && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PublicReportTab, {})
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, {})
11975
12401
  ] });
11976
12402
  }
11977
12403
  var el = document.getElementById("root");
11978
- if (el) (0, import_client.createRoot)(el).render(/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Shell, {}));
12404
+ if (el) (0, import_client.createRoot)(el).render(/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Shell, {}));
11979
12405
  /*! Bundled license information:
11980
12406
 
11981
12407
  react/cjs/react.production.min.js: