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/cli.js +3132 -1694
- package/dist/engine/ingest-export.js +14 -8
- package/dist/engine/public-report.js +14 -8
- package/dist/index.js +1506 -57
- package/dist/pipeline/coding-agglomerate.js +439 -26
- package/dist/pipeline/coding-aggregate.js +313 -9
- package/dist/pipeline/coding-build.js +361 -8
- package/dist/pipeline/coding-coaching.js +274 -22
- package/dist/pipeline/coding-day-digest.js +351 -33
- package/dist/pipeline/coding-delegation.js +369 -22
- package/dist/pipeline/coding-expertise.js +456 -49
- package/dist/pipeline/coding-flow.js +308 -4
- package/dist/pipeline/coding-focus.js +16306 -0
- package/dist/pipeline/coding-frontier-detail.js +444 -26
- package/dist/pipeline/coding-frontier.js +356 -1
- package/dist/pipeline/coding-gap-dist.js +308 -4
- package/dist/pipeline/coding-gap.js +141 -40
- package/dist/pipeline/coding-grade.js +216 -26
- package/dist/pipeline/coding-nutshell.js +347 -17
- package/dist/pipeline/coding-projects.js +387 -7
- package/dist/pipeline/coding-walkthrough.js +324 -19
- package/dist/web/app.js +539 -113
- package/dist/web/styles.css +1 -1
- package/package.json +2 -2
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
|
|
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
|
-
|
|
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
|
-
|
|
7930
|
-
|
|
7931
|
-
|
|
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-
|
|
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:
|
|
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
|
-
//
|
|
8405
|
-
//
|
|
8406
|
-
//
|
|
8407
|
-
//
|
|
8408
|
-
|
|
8409
|
-
|
|
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 percentile — it 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:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
12183
|
+
var import_jsx_runtime12 = __toESM(require_jsx_runtime(), 1);
|
|
11832
12184
|
function PublicReportTab() {
|
|
11833
|
-
const [loaded, setLoaded] = (0,
|
|
11834
|
-
const [footprint, setFootprint] = (0,
|
|
11835
|
-
const [report, setReport] = (0,
|
|
11836
|
-
const [editing, setEditing] = (0,
|
|
11837
|
-
(0,
|
|
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,
|
|
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,
|
|
11847
|
-
/* @__PURE__ */ (0,
|
|
11848
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
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,
|
|
11858
|
-
/* @__PURE__ */ (0,
|
|
11859
|
-
/* @__PURE__ */ (0,
|
|
11860
|
-
/* @__PURE__ */ (0,
|
|
11861
|
-
editing && /* @__PURE__ */ (0,
|
|
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,
|
|
11872
|
-
const [tab, setTab] = (0,
|
|
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 [
|
|
11884
|
-
|
|
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,
|
|
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,
|
|
11932
|
-
/* @__PURE__ */ (0,
|
|
11933
|
-
/* @__PURE__ */ (0,
|
|
11934
|
-
/* @__PURE__ */ (0,
|
|
11935
|
-
/* @__PURE__ */ (0,
|
|
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,
|
|
11938
|
-
identity ? /* @__PURE__ */ (0,
|
|
11939
|
-
/* @__PURE__ */ (0,
|
|
11940
|
-
/* @__PURE__ */ (0,
|
|
11941
|
-
] }) : canAuth ? /* @__PURE__ */ (0,
|
|
11942
|
-
|
|
11943
|
-
|
|
11944
|
-
|
|
11945
|
-
|
|
11946
|
-
|
|
11947
|
-
|
|
11948
|
-
|
|
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,
|
|
11954
|
-
|
|
11955
|
-
|
|
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,
|
|
11973
|
-
tab === "chat" && /* @__PURE__ */ (0,
|
|
11974
|
-
tab === "public" && /* @__PURE__ */ (0,
|
|
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,
|
|
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:
|