polymath-society 0.2.10 → 0.2.12

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 CHANGED
@@ -841,7 +841,19 @@ function aiWindowCutoff(sessions, opts = {}) {
841
841
  const floorStart = gradableStarts[floor - 1];
842
842
  return floorStart < windowCutoff ? floorStart : windowCutoff;
843
843
  }
844
- var GATE, AI_WINDOW;
844
+ function maxGraded() {
845
+ const n = Number(process.env.POLYMATH_MAX_GRADED);
846
+ return Number.isFinite(n) && n >= 0 ? n : MAX_GRADED_DEFAULT;
847
+ }
848
+ function substanceRank(a, b) {
849
+ return b.humanChars * Math.log1p(b.humanTurns) - a.humanChars * Math.log1p(a.humanTurns);
850
+ }
851
+ function capGradable(gradable) {
852
+ const sorted = gradable.slice().sort(substanceRank);
853
+ const cap = maxGraded();
854
+ return cap > 0 && sorted.length > cap ? sorted.slice(0, cap) : sorted;
855
+ }
856
+ var GATE, AI_WINDOW, MAX_GRADED_DEFAULT;
845
857
  var init_gate = __esm({
846
858
  "../coding-core/dist/gate.js"() {
847
859
  "use strict";
@@ -860,6 +872,7 @@ var init_gate = __esm({
860
872
  minSessions: 40
861
873
  // extend the window back until this many gradable sessions
862
874
  };
875
+ MAX_GRADED_DEFAULT = 150;
863
876
  }
864
877
  });
865
878
 
@@ -868,10 +881,14 @@ var gate_exports = {};
868
881
  __export(gate_exports, {
869
882
  AI_WINDOW: () => AI_WINDOW,
870
883
  GATE: () => GATE,
884
+ MAX_GRADED_DEFAULT: () => MAX_GRADED_DEFAULT,
871
885
  aiWindowCutoff: () => aiWindowCutoff,
886
+ capGradable: () => capGradable,
872
887
  isGradable: () => isGradable,
873
888
  isTrivial: () => isTrivial,
874
- partition: () => partition
889
+ maxGraded: () => maxGraded,
890
+ partition: () => partition,
891
+ substanceRank: () => substanceRank
875
892
  });
876
893
  var init_gate2 = __esm({
877
894
  "src/gate.ts"() {
@@ -880,6 +897,31 @@ var init_gate2 = __esm({
880
897
  }
881
898
  });
882
899
 
900
+ // ../coding-core/dist/env.js
901
+ function claudeCliEnv(base2 = process.env) {
902
+ if (process.env.POLYMATH_USE_API_KEY === "1")
903
+ return base2;
904
+ const present = AUTH_VARS.filter((k) => base2[k]);
905
+ if (!present.length)
906
+ return base2;
907
+ if (!warned) {
908
+ warned = true;
909
+ console.error(`[polymath-society] ${present.join(" + ")} is set in your shell \u2014 ignoring it so the analysis runs on your claude.ai login (the key would take over auth and either fail or bill your API account). Set POLYMATH_USE_API_KEY=1 if you really want the API key used.`);
910
+ }
911
+ const scrubbed = { ...base2 };
912
+ for (const k of AUTH_VARS)
913
+ delete scrubbed[k];
914
+ return scrubbed;
915
+ }
916
+ var AUTH_VARS, warned;
917
+ var init_env = __esm({
918
+ "../coding-core/dist/env.js"() {
919
+ "use strict";
920
+ AUTH_VARS = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
921
+ warned = false;
922
+ }
923
+ });
924
+
883
925
  // src/grade/adapter.ts
884
926
  function extractJson(text2) {
885
927
  const fences = [...text2.matchAll(/```json\s*([\s\S]*?)```/gi)];
@@ -1013,6 +1055,7 @@ var cliAdapter;
1013
1055
  var init_cliAdapter = __esm({
1014
1056
  "src/grade/cliAdapter.ts"() {
1015
1057
  "use strict";
1058
+ init_env();
1016
1059
  init_adapter();
1017
1060
  init_backends();
1018
1061
  cliAdapter = {
@@ -1049,7 +1092,9 @@ var init_cliAdapter = __esm({
1049
1092
  await new Promise((resolve2, reject) => {
1050
1093
  const child = spawn(bin, args, {
1051
1094
  cwd: inv.cwd ?? inv.addDir,
1052
- env: process.env,
1095
+ // scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
1096
+ // claude CLI away from their claude.ai login (coding-core/env.ts)
1097
+ env: claudeCliEnv(),
1053
1098
  stdio: ["ignore", "pipe", "pipe"],
1054
1099
  // Own process group, so a timeout can kill the WHOLE tree (claude spawns
1055
1100
  // children that otherwise orphan and pile up).
@@ -2458,19 +2503,19 @@ function makeMultiBar(out = process.stderr) {
2458
2503
  const lanes = /* @__PURE__ */ new Map();
2459
2504
  let link = "";
2460
2505
  let paintedRows = 0;
2461
- const laneText = (name17, l) => {
2462
- const w = l.within ? ` ${l.within.done}/${l.within.total}` : "";
2463
- return `${name17} ${l.i}/${l.total} ${l.label.slice(0, 26)}${w}`;
2464
- };
2465
2506
  const rows = () => {
2466
- const frac = (l) => l.total ? (l.i - 1 + (l.within && l.within.total ? l.within.done / l.within.total : 0)) / l.total : 0;
2467
- const parts = [...lanes.entries()].map(([n, l]) => laneText(n, l));
2468
- const avg2 = lanes.size ? [...lanes.values()].reduce((a, l) => a + frac(l), 0) / lanes.size : 0;
2469
- const width = 14;
2470
- const fill = Math.max(0, Math.min(width, Math.round(avg2 * width)));
2507
+ const width = 16;
2471
2508
  const elapsedMin = Math.round((Date.now() - t0) / 6e4);
2472
- const bar = `[${"\u2588".repeat(fill)}${"\u2591".repeat(width - fill)}] ${parts.join(" \xB7 ")} \xB7 ${elapsedMin}m`;
2473
- return link ? [bar, `\u21B3 report (live, fills in as stages finish) \u2192 ${link}`] : [bar];
2509
+ const laneRow = ([name17, l]) => {
2510
+ const frac = l.total ? (l.i - 1 + (l.within && l.within.total ? l.within.done / l.within.total : 0)) / l.total : 0;
2511
+ const clamped = Math.max(0, Math.min(1, frac));
2512
+ const fill = Math.round(clamped * width);
2513
+ return ` ${name17.padEnd(6)} [${"\u2588".repeat(fill)}${"\u2591".repeat(width - fill)}] ${String(Math.round(clamped * 100)).padStart(3)}%`;
2514
+ };
2515
+ const out2 = [];
2516
+ if (link) out2.push(`\u21B3 your reports (live, fill in as stages finish) \u2192 ${link} \xB7 ${elapsedMin}m`);
2517
+ out2.push(...[...lanes.entries()].map(laneRow));
2518
+ return out2.length ? out2 : [`(starting\u2026 ${elapsedMin}m)`];
2474
2519
  };
2475
2520
  const clearPinned = () => {
2476
2521
  if (!paintedRows) return;
@@ -4360,6 +4405,7 @@ import { readFileSync } from "fs";
4360
4405
  import path13 from "path";
4361
4406
 
4362
4407
  // ../../lib/agents/shared/cliAdapter.ts
4408
+ init_env();
4363
4409
  import { spawn as spawn3 } from "child_process";
4364
4410
  import { promises as fs7 } from "fs";
4365
4411
  import path7 from "path";
@@ -4468,7 +4514,9 @@ var cliAdapter2 = {
4468
4514
  await new Promise((resolve2, reject) => {
4469
4515
  const child = spawn3(CLAUDE_BIN, args, {
4470
4516
  cwd: inv.cwd ?? inv.addDir,
4471
- env: process.env,
4517
+ // scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
4518
+ // claude CLI away from their claude.ai login (coding-core/env.ts)
4519
+ env: claudeCliEnv(),
4472
4520
  stdio: ["ignore", "pipe", "pipe"],
4473
4521
  // Own process group, so a timeout can kill the WHOLE tree (claude spawns
4474
4522
  // its own children that otherwise orphan and pile up — the root cause of
@@ -24494,8 +24542,9 @@ function startServer(opts) {
24494
24542
  if (req.method === "GET" && route === "/auth/callback") {
24495
24543
  try {
24496
24544
  const id = await completeLogin(dataDir, new URL(url, serverUrl).searchParams);
24545
+ const back = host === "127.0.0.1" ? serverUrl.replace("//127.0.0.1:", "//localhost:") : serverUrl;
24497
24546
  res.writeHead(200, { "content-type": MIME[".html"] });
24498
- res.end(`<!doctype html><meta charset="utf-8"><title>Signed in</title><body style="font-family:system-ui;padding:40px"><p>Signed in as <b>${id.email.replace(/</g, "&lt;")}</b>.</p><p><a href="/">Back to your report</a> (or just close this tab \u2014 the report page picks it up on its own).</p></body>`);
24547
+ res.end(`<!doctype html><meta charset="utf-8"><title>Signed in</title><body style="font-family:system-ui;padding:40px"><p>Signed in as <b>${id.email.replace(/</g, "&lt;")}</b>.</p><p><a href="${back}/">Back to your report</a> (or just close this tab \u2014 the report page picks it up on its own).</p></body>`);
24499
24548
  } catch (e) {
24500
24549
  res.writeHead(400, { "content-type": MIME[".html"] });
24501
24550
  res.end(`<!doctype html><meta charset="utf-8"><title>Sign-in failed</title><body style="font-family:system-ui;padding:40px"><p><b>Sign-in failed.</b></p><p>${String(e.message).replace(/</g, "&lt;")}</p><p><a href="/auth/login">Try again</a></p></body>`);
@@ -24659,7 +24708,12 @@ function startServer(opts) {
24659
24708
  }).catch(() => {
24660
24709
  });
24661
24710
  resolve2({
24662
- url: serverUrl,
24711
+ // The DISPLAYED/opened URL says localhost — friendlier than 127.0.0.1
24712
+ // (owner call 2026-07-15); same server, same loopback. serverUrl itself
24713
+ // stays on the bound host because the Google sign-in redirect is
24714
+ // allow-listed for http://127.0.0.1:*/** in Supabase — auth flows
24715
+ // through 127.0.0.1 no matter which name the person's tab uses.
24716
+ url: host === "127.0.0.1" ? `http://localhost:${port}` : serverUrl,
24663
24717
  port,
24664
24718
  close: () => new Promise((r) => server.close(() => r())),
24665
24719
  setProfile: (p) => {
@@ -24863,7 +24917,7 @@ function apportionHeavy(budget) {
24863
24917
  const grade = Math.max(2, Math.floor(budget * 0.45));
24864
24918
  const digest = Math.max(1, Math.floor(budget * 0.17));
24865
24919
  const walkthrough = Math.max(1, Math.floor(budget * 0.17));
24866
- const delegation = Math.max(1, budget - grade - digest - walkthrough - 1);
24920
+ const delegation = Math.max(1, budget - grade - digest - walkthrough - 2);
24867
24921
  return { grade, digest, walkthrough, delegation };
24868
24922
  }
24869
24923
  function stages(o) {
@@ -24896,6 +24950,14 @@ function stages(o) {
24896
24950
  { script: "coding-walkthrough.mts", label: "Per-session walkthroughs", llm: true, args: ["--model", model, "--conc", String(h.walkthrough)], batch: "heavy" },
24897
24951
  { script: "coding-frontier-detail.mts", label: "What you're doing at the frontier", llm: true, args: [], out: "coding/frontier-detail.json", batch: "heavy" },
24898
24952
  { script: "coding-delegation.mts", label: "Delegation patterns", llm: true, args: ["--model", model, "--conc", String(h.delegation)], out: "coding/delegation-rollup.json", batch: "heavy" },
24953
+ // The FULL focus stage: flow-rule judgment + the paste-into-CLAUDE.md block.
24954
+ // The deterministic --skip-llm run above keeps the numbers current every
24955
+ // run; this one produces the AI block — it was MISSING from the graded tier
24956
+ // entirely (688d788 added focus for the numbers-only tier and no one added
24957
+ // the companion), so overnight full runs shipped a report with no flow
24958
+ // rules and nothing failed loud (found 2026-07-15). Both LLM passes are
24959
+ // prompt-hash gated, so an unchanged corpus re-run costs zero calls.
24960
+ { script: "coding-focus.mts", label: "Flow rules + focus judgment", llm: true, args: [], out: "coding/focus.json", batch: "heavy" },
24899
24961
  // ---- corpus aggregate (reads grades; deterministic rollup) ----
24900
24962
  { script: "coding-aggregate.mts", label: "Corpus aggregate \u2014 ability ceiling + flow", llm: false, args: [], out: "coding/aggregate.json" },
24901
24963
  // ---- grade readers (grades/* is complete once aggregate ran) ----
@@ -24962,11 +25024,12 @@ function upToDateSkip(i) {
24962
25024
  }
24963
25025
  async function evalUpToDate(codingDir, threshold, regrade) {
24964
25026
  try {
24965
- const { partition: partition2, aiWindowCutoff: aiWindowCutoff2 } = await Promise.resolve().then(() => (init_gate2(), gate_exports));
25027
+ const { partition: partition2, aiWindowCutoff: aiWindowCutoff2, capGradable: capGradable2 } = await Promise.resolve().then(() => (init_gate2(), gate_exports));
24966
25028
  const sessions = JSON.parse(await fs31.readFile(path36.join(codingDir, "sessions.json"), "utf8"));
24967
25029
  const live = sessions.filter((s) => s.klass === "interactive" && !s.duplicateOf);
24968
25030
  const cutoff = aiWindowCutoff2(live);
24969
- const { gradable } = partition2(cutoff ? live.filter((s) => (s.start ?? "") >= cutoff) : live);
25031
+ const { gradable: uncapped } = partition2(cutoff ? live.filter((s) => (s.start ?? "") >= cutoff) : live);
25032
+ const gradable = capGradable2(uncapped);
24970
25033
  const graded = new Set(
24971
25034
  (await fs31.readdir(path36.join(codingDir, "grades")).catch(() => [])).filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -5))
24972
25035
  );
@@ -25253,7 +25316,19 @@ async function runChatPipeline(o) {
25253
25316
  }
25254
25317
  log.event("ingest-export", { ok, ms: Date.now() - stStart, source: f.kind });
25255
25318
  }
25319
+ const minNewDocs = Number(process.env.POLYMATH_MIN_NEW_DOCS ?? 10);
25320
+ const signalDocs = async () => {
25321
+ const t = await fs32.readFile(path37.join(dataRoot, "signals", "index.jsonl"), "utf8").catch(() => "");
25322
+ return t ? t.split("\n").filter(Boolean).length : 0;
25323
+ };
25324
+ const docsBeforeTagger = await signalDocs();
25325
+ let upToDate = false;
25256
25326
  for (const st of chatEngineStages()) {
25327
+ if (upToDate && st.llm) {
25328
+ o.onStage?.(++idx, total, `${st.label} \u2014 up to date, skipped`, st.llm);
25329
+ log.event(st.script.replace(/\.mts$/, ""), { ok: true, ms: 0, skipped: true });
25330
+ continue;
25331
+ }
25257
25332
  o.onStage?.(++idx, total, st.label, st.llm);
25258
25333
  const stStart = Date.now();
25259
25334
  let ok = true;
@@ -25267,6 +25342,14 @@ async function runChatPipeline(o) {
25267
25342
  }
25268
25343
  const sha = st.out ? await fileSha(path37.join(dataRoot, st.out)) : null;
25269
25344
  log.event(st.script.replace(/\.mts$/, ""), { ok, ms: Date.now() - stStart, ...sha ? { sha } : {} });
25345
+ if (st.script === "run-tagger.mts" && ok && minNewDocs > 0) {
25346
+ const newDocs = await signalDocs() - docsBeforeTagger;
25347
+ const report = await fs32.readFile(path37.join(dataRoot, "engine-pilot", "public-report.json"), "utf8").then((s) => JSON.parse(s)).catch(() => null);
25348
+ if (report?.headline && (report.spikes?.length ?? 0) > 0 && newDocs < minNewDocs) {
25349
+ upToDate = true;
25350
+ o.onLine?.(`\u2713 chat report is up to date \u2014 ${newDocs} new doc(s) since the last full run (below the ${minNewDocs}-doc threshold), so the AI stages are skipped and the existing report is served as-is. POLYMATH_MIN_NEW_DOCS=0 forces a full run.`);
25351
+ }
25352
+ }
25270
25353
  }
25271
25354
  log.event("pipeline_completed", { ok: failed.length === 0, failedStages: failed.length, ms: Date.now() - t0 });
25272
25355
  await log.finish();
@@ -1356,6 +1356,25 @@ import { spawn } from "child_process";
1356
1356
  import { promises as fs2 } from "fs";
1357
1357
  import path2 from "path";
1358
1358
 
1359
+ // ../coding-core/dist/env.js
1360
+ var AUTH_VARS = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
1361
+ var warned = false;
1362
+ function claudeCliEnv(base = process.env) {
1363
+ if (process.env.POLYMATH_USE_API_KEY === "1")
1364
+ return base;
1365
+ const present = AUTH_VARS.filter((k) => base[k]);
1366
+ if (!present.length)
1367
+ return base;
1368
+ if (!warned) {
1369
+ warned = true;
1370
+ console.error(`[polymath-society] ${present.join(" + ")} is set in your shell \u2014 ignoring it so the analysis runs on your claude.ai login (the key would take over auth and either fail or bill your API account). Set POLYMATH_USE_API_KEY=1 if you really want the API key used.`);
1371
+ }
1372
+ const scrubbed = { ...base };
1373
+ for (const k of AUTH_VARS)
1374
+ delete scrubbed[k];
1375
+ return scrubbed;
1376
+ }
1377
+
1359
1378
  // ../../lib/agents/shared/adapter.ts
1360
1379
  function extractJson(text2) {
1361
1380
  const fences = [...text2.matchAll(/```json\s*([\s\S]*?)```/gi)];
@@ -1460,7 +1479,9 @@ var cliAdapter = {
1460
1479
  await new Promise((resolve2, reject) => {
1461
1480
  const child = spawn(CLAUDE_BIN, args, {
1462
1481
  cwd: inv.cwd ?? inv.addDir,
1463
- env: process.env,
1482
+ // scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
1483
+ // claude CLI away from their claude.ai login (coding-core/env.ts)
1484
+ env: claudeCliEnv(),
1464
1485
  stdio: ["ignore", "pipe", "pipe"],
1465
1486
  // Own process group, so a timeout can kill the WHOLE tree (claude spawns
1466
1487
  // its own children that otherwise orphan and pile up — the root cause of
@@ -16902,6 +16923,14 @@ async function run2() {
16902
16923
  }
16903
16924
  }
16904
16925
  if (!sigs.length) throw new Error("loops: empty signals index \u2014 refusing to write");
16926
+ const fingerprint = `${sigs.length}:${sigs.reduce((a, s) => s.date > a ? s.date : a, "")}`;
16927
+ if (!process.env.LOOPS_REFRESH) {
16928
+ const prev2 = await fs6.readFile(OUT2, "utf8").then(JSON.parse).catch(() => null);
16929
+ if (prev2?.inputFingerprint === fingerprint && prev2?.loops?.loops?.length) {
16930
+ console.log(`loops: inputs unchanged (${sigs.length} signals) \u2014 keeping ${prev2.generatedAt} (LOOPS_REFRESH=1 to redo)`);
16931
+ return;
16932
+ }
16933
+ }
16905
16934
  const artifacts = importArtifactDates(sigs);
16906
16935
  const dated = sigs.filter((s) => !artifacts.has(s.date));
16907
16936
  const chats = dated.filter((s) => s.source === "chatgpt" || s.source === "claude");
@@ -16988,6 +17017,8 @@ ${sample.join("\n")}`;
16988
17017
  rules.sort((a, b) => a.date.localeCompare(b.date));
16989
17018
  const out = {
16990
17019
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
17020
+ inputFingerprint: fingerprint,
17021
+ // the skip gate above compares against this
16991
17022
  totals: { signals: sigs.length, dated: dated.length, chats: chats.length, ruleDeclarations: rules.length, importDatesExcluded: [...artifacts] },
16992
17023
  chatsByMonth: monthCounts(chats.map((c) => c.date)),
16993
17024
  rules,
@@ -153,6 +153,25 @@ import { spawn } from "child_process";
153
153
  import { promises as fs2 } from "fs";
154
154
  import path3 from "path";
155
155
 
156
+ // ../coding-core/dist/env.js
157
+ var AUTH_VARS = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
158
+ var warned = false;
159
+ function claudeCliEnv(base = process.env) {
160
+ if (process.env.POLYMATH_USE_API_KEY === "1")
161
+ return base;
162
+ const present = AUTH_VARS.filter((k) => base[k]);
163
+ if (!present.length)
164
+ return base;
165
+ if (!warned) {
166
+ warned = true;
167
+ console.error(`[polymath-society] ${present.join(" + ")} is set in your shell \u2014 ignoring it so the analysis runs on your claude.ai login (the key would take over auth and either fail or bill your API account). Set POLYMATH_USE_API_KEY=1 if you really want the API key used.`);
168
+ }
169
+ const scrubbed = { ...base };
170
+ for (const k of AUTH_VARS)
171
+ delete scrubbed[k];
172
+ return scrubbed;
173
+ }
174
+
156
175
  // ../../lib/agents/shared/adapter.ts
157
176
  function extractJson(text2) {
158
177
  const fences = [...text2.matchAll(/```json\s*([\s\S]*?)```/gi)];
@@ -257,7 +276,9 @@ var cliAdapter = {
257
276
  await new Promise((resolve2, reject) => {
258
277
  const child = spawn(CLAUDE_BIN, args, {
259
278
  cwd: inv.cwd ?? inv.addDir,
260
- env: process.env,
279
+ // scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
280
+ // claude CLI away from their claude.ai login (coding-core/env.ts)
281
+ env: claudeCliEnv(),
261
282
  stdio: ["ignore", "pipe", "pipe"],
262
283
  // Own process group, so a timeout can kill the WHOLE tree (claude spawns
263
284
  // its own children that otherwise orphan and pile up — the root cause of
@@ -153,6 +153,25 @@ import { spawn } from "child_process";
153
153
  import { promises as fs2 } from "fs";
154
154
  import path3 from "path";
155
155
 
156
+ // ../coding-core/dist/env.js
157
+ var AUTH_VARS = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
158
+ var warned = false;
159
+ function claudeCliEnv(base = process.env) {
160
+ if (process.env.POLYMATH_USE_API_KEY === "1")
161
+ return base;
162
+ const present = AUTH_VARS.filter((k) => base[k]);
163
+ if (!present.length)
164
+ return base;
165
+ if (!warned) {
166
+ warned = true;
167
+ console.error(`[polymath-society] ${present.join(" + ")} is set in your shell \u2014 ignoring it so the analysis runs on your claude.ai login (the key would take over auth and either fail or bill your API account). Set POLYMATH_USE_API_KEY=1 if you really want the API key used.`);
168
+ }
169
+ const scrubbed = { ...base };
170
+ for (const k of AUTH_VARS)
171
+ delete scrubbed[k];
172
+ return scrubbed;
173
+ }
174
+
156
175
  // ../../lib/agents/shared/adapter.ts
157
176
  function extractJson(text2) {
158
177
  const fences = [...text2.matchAll(/```json\s*([\s\S]*?)```/gi)];
@@ -257,7 +276,9 @@ var cliAdapter = {
257
276
  await new Promise((resolve2, reject) => {
258
277
  const child = spawn(CLAUDE_BIN, args, {
259
278
  cwd: inv.cwd ?? inv.addDir,
260
- env: process.env,
279
+ // scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
280
+ // claude CLI away from their claude.ai login (coding-core/env.ts)
281
+ env: claudeCliEnv(),
261
282
  stdio: ["ignore", "pipe", "pipe"],
262
283
  // Own process group, so a timeout can kill the WHOLE tree (claude spawns
263
284
  // its own children that otherwise orphan and pile up — the root cause of
@@ -148,6 +148,25 @@ import { spawn } from "child_process";
148
148
  import { promises as fs2 } from "fs";
149
149
  import path2 from "path";
150
150
 
151
+ // ../coding-core/dist/env.js
152
+ var AUTH_VARS = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
153
+ var warned = false;
154
+ function claudeCliEnv(base = process.env) {
155
+ if (process.env.POLYMATH_USE_API_KEY === "1")
156
+ return base;
157
+ const present = AUTH_VARS.filter((k) => base[k]);
158
+ if (!present.length)
159
+ return base;
160
+ if (!warned) {
161
+ warned = true;
162
+ console.error(`[polymath-society] ${present.join(" + ")} is set in your shell \u2014 ignoring it so the analysis runs on your claude.ai login (the key would take over auth and either fail or bill your API account). Set POLYMATH_USE_API_KEY=1 if you really want the API key used.`);
163
+ }
164
+ const scrubbed = { ...base };
165
+ for (const k of AUTH_VARS)
166
+ delete scrubbed[k];
167
+ return scrubbed;
168
+ }
169
+
151
170
  // ../../lib/agents/shared/adapter.ts
152
171
  function extractJson(text2) {
153
172
  const fences = [...text2.matchAll(/```json\s*([\s\S]*?)```/gi)];
@@ -252,7 +271,9 @@ var cliAdapter = {
252
271
  await new Promise((resolve2, reject) => {
253
272
  const child = spawn(CLAUDE_BIN, args, {
254
273
  cwd: inv.cwd ?? inv.addDir,
255
- env: process.env,
274
+ // scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
275
+ // claude CLI away from their claude.ai login (coding-core/env.ts)
276
+ env: claudeCliEnv(),
256
277
  stdio: ["ignore", "pipe", "pipe"],
257
278
  // Own process group, so a timeout can kill the WHOLE tree (claude spawns
258
279
  // its own children that otherwise orphan and pile up — the root cause of
@@ -1144,6 +1144,25 @@ import { spawn } from "child_process";
1144
1144
  import { promises as fs3 } from "fs";
1145
1145
  import path4 from "path";
1146
1146
 
1147
+ // ../coding-core/dist/env.js
1148
+ var AUTH_VARS = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
1149
+ var warned = false;
1150
+ function claudeCliEnv(base = process.env) {
1151
+ if (process.env.POLYMATH_USE_API_KEY === "1")
1152
+ return base;
1153
+ const present = AUTH_VARS.filter((k) => base[k]);
1154
+ if (!present.length)
1155
+ return base;
1156
+ if (!warned) {
1157
+ warned = true;
1158
+ console.error(`[polymath-society] ${present.join(" + ")} is set in your shell \u2014 ignoring it so the analysis runs on your claude.ai login (the key would take over auth and either fail or bill your API account). Set POLYMATH_USE_API_KEY=1 if you really want the API key used.`);
1159
+ }
1160
+ const scrubbed = { ...base };
1161
+ for (const k of AUTH_VARS)
1162
+ delete scrubbed[k];
1163
+ return scrubbed;
1164
+ }
1165
+
1147
1166
  // ../../lib/agents/shared/adapter.ts
1148
1167
  function extractJson(text2) {
1149
1168
  const fences = [...text2.matchAll(/```json\s*([\s\S]*?)```/gi)];
@@ -1248,7 +1267,9 @@ var cliAdapter = {
1248
1267
  await new Promise((resolve2, reject) => {
1249
1268
  const child = spawn(CLAUDE_BIN, args, {
1250
1269
  cwd: inv.cwd ?? inv.addDir,
1251
- env: process.env,
1270
+ // scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
1271
+ // claude CLI away from their claude.ai login (coding-core/env.ts)
1272
+ env: claudeCliEnv(),
1252
1273
  stdio: ["ignore", "pipe", "pipe"],
1253
1274
  // Own process group, so a timeout can kill the WHOLE tree (claude spawns
1254
1275
  // its own children that otherwise orphan and pile up — the root cause of
@@ -1144,6 +1144,25 @@ import { spawn } from "child_process";
1144
1144
  import { promises as fs3 } from "fs";
1145
1145
  import path4 from "path";
1146
1146
 
1147
+ // ../coding-core/dist/env.js
1148
+ var AUTH_VARS = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
1149
+ var warned = false;
1150
+ function claudeCliEnv(base = process.env) {
1151
+ if (process.env.POLYMATH_USE_API_KEY === "1")
1152
+ return base;
1153
+ const present = AUTH_VARS.filter((k) => base[k]);
1154
+ if (!present.length)
1155
+ return base;
1156
+ if (!warned) {
1157
+ warned = true;
1158
+ console.error(`[polymath-society] ${present.join(" + ")} is set in your shell \u2014 ignoring it so the analysis runs on your claude.ai login (the key would take over auth and either fail or bill your API account). Set POLYMATH_USE_API_KEY=1 if you really want the API key used.`);
1159
+ }
1160
+ const scrubbed = { ...base };
1161
+ for (const k of AUTH_VARS)
1162
+ delete scrubbed[k];
1163
+ return scrubbed;
1164
+ }
1165
+
1147
1166
  // ../../lib/agents/shared/adapter.ts
1148
1167
  function extractJson(text2) {
1149
1168
  const fences = [...text2.matchAll(/```json\s*([\s\S]*?)```/gi)];
@@ -1248,7 +1267,9 @@ var cliAdapter = {
1248
1267
  await new Promise((resolve2, reject) => {
1249
1268
  const child = spawn(CLAUDE_BIN, args, {
1250
1269
  cwd: inv.cwd ?? inv.addDir,
1251
- env: process.env,
1270
+ // scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
1271
+ // claude CLI away from their claude.ai login (coding-core/env.ts)
1272
+ env: claudeCliEnv(),
1252
1273
  stdio: ["ignore", "pipe", "pipe"],
1253
1274
  // Own process group, so a timeout can kill the WHOLE tree (claude spawns
1254
1275
  // its own children that otherwise orphan and pile up — the root cause of
@@ -1144,6 +1144,25 @@ import { spawn } from "child_process";
1144
1144
  import { promises as fs3 } from "fs";
1145
1145
  import path4 from "path";
1146
1146
 
1147
+ // ../coding-core/dist/env.js
1148
+ var AUTH_VARS = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
1149
+ var warned = false;
1150
+ function claudeCliEnv(base = process.env) {
1151
+ if (process.env.POLYMATH_USE_API_KEY === "1")
1152
+ return base;
1153
+ const present = AUTH_VARS.filter((k) => base[k]);
1154
+ if (!present.length)
1155
+ return base;
1156
+ if (!warned) {
1157
+ warned = true;
1158
+ console.error(`[polymath-society] ${present.join(" + ")} is set in your shell \u2014 ignoring it so the analysis runs on your claude.ai login (the key would take over auth and either fail or bill your API account). Set POLYMATH_USE_API_KEY=1 if you really want the API key used.`);
1159
+ }
1160
+ const scrubbed = { ...base };
1161
+ for (const k of AUTH_VARS)
1162
+ delete scrubbed[k];
1163
+ return scrubbed;
1164
+ }
1165
+
1147
1166
  // ../../lib/agents/shared/adapter.ts
1148
1167
  function extractJson(text2) {
1149
1168
  const fences = [...text2.matchAll(/```json\s*([\s\S]*?)```/gi)];
@@ -1248,7 +1267,9 @@ var cliAdapter = {
1248
1267
  await new Promise((resolve2, reject) => {
1249
1268
  const child = spawn(CLAUDE_BIN, args, {
1250
1269
  cwd: inv.cwd ?? inv.addDir,
1251
- env: process.env,
1270
+ // scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
1271
+ // claude CLI away from their claude.ai login (coding-core/env.ts)
1272
+ env: claudeCliEnv(),
1252
1273
  stdio: ["ignore", "pipe", "pipe"],
1253
1274
  // Own process group, so a timeout can kill the WHOLE tree (claude spawns
1254
1275
  // its own children that otherwise orphan and pile up — the root cause of
@@ -1144,6 +1144,25 @@ import { spawn } from "child_process";
1144
1144
  import { promises as fs3 } from "fs";
1145
1145
  import path4 from "path";
1146
1146
 
1147
+ // ../coding-core/dist/env.js
1148
+ var AUTH_VARS = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
1149
+ var warned = false;
1150
+ function claudeCliEnv(base = process.env) {
1151
+ if (process.env.POLYMATH_USE_API_KEY === "1")
1152
+ return base;
1153
+ const present = AUTH_VARS.filter((k) => base[k]);
1154
+ if (!present.length)
1155
+ return base;
1156
+ if (!warned) {
1157
+ warned = true;
1158
+ console.error(`[polymath-society] ${present.join(" + ")} is set in your shell \u2014 ignoring it so the analysis runs on your claude.ai login (the key would take over auth and either fail or bill your API account). Set POLYMATH_USE_API_KEY=1 if you really want the API key used.`);
1159
+ }
1160
+ const scrubbed = { ...base };
1161
+ for (const k of AUTH_VARS)
1162
+ delete scrubbed[k];
1163
+ return scrubbed;
1164
+ }
1165
+
1147
1166
  // ../../lib/agents/shared/adapter.ts
1148
1167
  function extractJson(text2) {
1149
1168
  const fences = [...text2.matchAll(/```json\s*([\s\S]*?)```/gi)];
@@ -1248,7 +1267,9 @@ var cliAdapter = {
1248
1267
  await new Promise((resolve2, reject) => {
1249
1268
  const child = spawn(CLAUDE_BIN, args, {
1250
1269
  cwd: inv.cwd ?? inv.addDir,
1251
- env: process.env,
1270
+ // scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
1271
+ // claude CLI away from their claude.ai login (coding-core/env.ts)
1272
+ env: claudeCliEnv(),
1252
1273
  stdio: ["ignore", "pipe", "pipe"],
1253
1274
  // Own process group, so a timeout can kill the WHOLE tree (claude spawns
1254
1275
  // its own children that otherwise orphan and pile up — the root cause of
@@ -1144,6 +1144,25 @@ import { spawn } from "child_process";
1144
1144
  import { promises as fs3 } from "fs";
1145
1145
  import path4 from "path";
1146
1146
 
1147
+ // ../coding-core/dist/env.js
1148
+ var AUTH_VARS = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
1149
+ var warned = false;
1150
+ function claudeCliEnv(base = process.env) {
1151
+ if (process.env.POLYMATH_USE_API_KEY === "1")
1152
+ return base;
1153
+ const present = AUTH_VARS.filter((k) => base[k]);
1154
+ if (!present.length)
1155
+ return base;
1156
+ if (!warned) {
1157
+ warned = true;
1158
+ console.error(`[polymath-society] ${present.join(" + ")} is set in your shell \u2014 ignoring it so the analysis runs on your claude.ai login (the key would take over auth and either fail or bill your API account). Set POLYMATH_USE_API_KEY=1 if you really want the API key used.`);
1159
+ }
1160
+ const scrubbed = { ...base };
1161
+ for (const k of AUTH_VARS)
1162
+ delete scrubbed[k];
1163
+ return scrubbed;
1164
+ }
1165
+
1147
1166
  // ../../lib/agents/shared/adapter.ts
1148
1167
  function extractJson(text2) {
1149
1168
  const fences = [...text2.matchAll(/```json\s*([\s\S]*?)```/gi)];
@@ -1248,7 +1267,9 @@ var cliAdapter = {
1248
1267
  await new Promise((resolve2, reject) => {
1249
1268
  const child = spawn(CLAUDE_BIN, args, {
1250
1269
  cwd: inv.cwd ?? inv.addDir,
1251
- env: process.env,
1270
+ // scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
1271
+ // claude CLI away from their claude.ai login (coding-core/env.ts)
1272
+ env: claudeCliEnv(),
1252
1273
  stdio: ["ignore", "pipe", "pipe"],
1253
1274
  // Own process group, so a timeout can kill the WHOLE tree (claude spawns
1254
1275
  // its own children that otherwise orphan and pile up — the root cause of
@@ -1096,6 +1096,25 @@ import { spawn } from "child_process";
1096
1096
  import { promises as fs4 } from "fs";
1097
1097
  import path5 from "path";
1098
1098
 
1099
+ // ../coding-core/dist/env.js
1100
+ var AUTH_VARS = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
1101
+ var warned = false;
1102
+ function claudeCliEnv(base = process.env) {
1103
+ if (process.env.POLYMATH_USE_API_KEY === "1")
1104
+ return base;
1105
+ const present = AUTH_VARS.filter((k) => base[k]);
1106
+ if (!present.length)
1107
+ return base;
1108
+ if (!warned) {
1109
+ warned = true;
1110
+ console.error(`[polymath-society] ${present.join(" + ")} is set in your shell \u2014 ignoring it so the analysis runs on your claude.ai login (the key would take over auth and either fail or bill your API account). Set POLYMATH_USE_API_KEY=1 if you really want the API key used.`);
1111
+ }
1112
+ const scrubbed = { ...base };
1113
+ for (const k of AUTH_VARS)
1114
+ delete scrubbed[k];
1115
+ return scrubbed;
1116
+ }
1117
+
1099
1118
  // ../../lib/agents/shared/adapter.ts
1100
1119
  function extractJson(text2) {
1101
1120
  const fences = [...text2.matchAll(/```json\s*([\s\S]*?)```/gi)];
@@ -1200,7 +1219,9 @@ var cliAdapter = {
1200
1219
  await new Promise((resolve2, reject) => {
1201
1220
  const child = spawn(CLAUDE_BIN, args, {
1202
1221
  cwd: inv.cwd ?? inv.addDir,
1203
- env: process.env,
1222
+ // scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
1223
+ // claude CLI away from their claude.ai login (coding-core/env.ts)
1224
+ env: claudeCliEnv(),
1204
1225
  stdio: ["ignore", "pipe", "pipe"],
1205
1226
  // Own process group, so a timeout can kill the WHOLE tree (claude spawns
1206
1227
  // its own children that otherwise orphan and pile up — the root cause of