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.
@@ -142,6 +142,25 @@ import { spawn } from "child_process";
142
142
  import { promises as fs2 } from "fs";
143
143
  import path2 from "path";
144
144
 
145
+ // ../coding-core/dist/env.js
146
+ var AUTH_VARS = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
147
+ var warned = false;
148
+ function claudeCliEnv(base = process.env) {
149
+ if (process.env.POLYMATH_USE_API_KEY === "1")
150
+ return base;
151
+ const present = AUTH_VARS.filter((k) => base[k]);
152
+ if (!present.length)
153
+ return base;
154
+ if (!warned) {
155
+ warned = true;
156
+ 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.`);
157
+ }
158
+ const scrubbed = { ...base };
159
+ for (const k of AUTH_VARS)
160
+ delete scrubbed[k];
161
+ return scrubbed;
162
+ }
163
+
145
164
  // ../../lib/agents/shared/adapter.ts
146
165
  function extractJson(text2) {
147
166
  const fences = [...text2.matchAll(/```json\s*([\s\S]*?)```/gi)];
@@ -246,7 +265,9 @@ var cliAdapter = {
246
265
  await new Promise((resolve2, reject) => {
247
266
  const child = spawn(CLAUDE_BIN, args, {
248
267
  cwd: inv.cwd ?? inv.addDir,
249
- env: process.env,
268
+ // scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
269
+ // claude CLI away from their claude.ai login (coding-core/env.ts)
270
+ env: claudeCliEnv(),
250
271
  stdio: ["ignore", "pipe", "pipe"],
251
272
  // Own process group, so a timeout can kill the WHOLE tree (claude spawns
252
273
  // its own children that otherwise orphan and pile up — the root cause of
@@ -265,6 +265,25 @@ import { spawn } from "child_process";
265
265
  import { promises as fs4 } from "fs";
266
266
  import path5 from "path";
267
267
 
268
+ // ../coding-core/dist/env.js
269
+ var AUTH_VARS = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
270
+ var warned = false;
271
+ function claudeCliEnv(base = process.env) {
272
+ if (process.env.POLYMATH_USE_API_KEY === "1")
273
+ return base;
274
+ const present = AUTH_VARS.filter((k) => base[k]);
275
+ if (!present.length)
276
+ return base;
277
+ if (!warned) {
278
+ warned = true;
279
+ 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.`);
280
+ }
281
+ const scrubbed = { ...base };
282
+ for (const k of AUTH_VARS)
283
+ delete scrubbed[k];
284
+ return scrubbed;
285
+ }
286
+
268
287
  // ../../lib/agents/shared/adapter.ts
269
288
  function extractJson(text2) {
270
289
  const fences = [...text2.matchAll(/```json\s*([\s\S]*?)```/gi)];
@@ -369,7 +388,9 @@ var cliAdapter = {
369
388
  await new Promise((resolve2, reject) => {
370
389
  const child = spawn(CLAUDE_BIN, args, {
371
390
  cwd: inv.cwd ?? inv.addDir,
372
- env: process.env,
391
+ // scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
392
+ // claude CLI away from their claude.ai login (coding-core/env.ts)
393
+ env: claudeCliEnv(),
373
394
  stdio: ["ignore", "pipe", "pipe"],
374
395
  // Own process group, so a timeout can kill the WHOLE tree (claude spawns
375
396
  // its own children that otherwise orphan and pile up — the root cause of
@@ -242,6 +242,25 @@ import { spawn } from "child_process";
242
242
  import { promises as fs3 } from "fs";
243
243
  import path4 from "path";
244
244
 
245
+ // ../coding-core/dist/env.js
246
+ var AUTH_VARS = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
247
+ var warned = false;
248
+ function claudeCliEnv(base = process.env) {
249
+ if (process.env.POLYMATH_USE_API_KEY === "1")
250
+ return base;
251
+ const present = AUTH_VARS.filter((k) => base[k]);
252
+ if (!present.length)
253
+ return base;
254
+ if (!warned) {
255
+ warned = true;
256
+ 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.`);
257
+ }
258
+ const scrubbed = { ...base };
259
+ for (const k of AUTH_VARS)
260
+ delete scrubbed[k];
261
+ return scrubbed;
262
+ }
263
+
245
264
  // ../../lib/agents/shared/adapter.ts
246
265
  function extractJson(text2) {
247
266
  const fences = [...text2.matchAll(/```json\s*([\s\S]*?)```/gi)];
@@ -346,7 +365,9 @@ var cliAdapter = {
346
365
  await new Promise((resolve2, reject) => {
347
366
  const child = spawn(CLAUDE_BIN, args, {
348
367
  cwd: inv.cwd ?? inv.addDir,
349
- env: process.env,
368
+ // scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
369
+ // claude CLI away from their claude.ai login (coding-core/env.ts)
370
+ env: claudeCliEnv(),
350
371
  stdio: ["ignore", "pipe", "pipe"],
351
372
  // Own process group, so a timeout can kill the WHOLE tree (claude spawns
352
373
  // its own children that otherwise orphan and pile up — the root cause of
package/dist/index.js CHANGED
@@ -1794,6 +1794,25 @@ import path3 from "path";
1794
1794
  // src/grade/cliAdapter.ts
1795
1795
  import { spawn } from "child_process";
1796
1796
 
1797
+ // ../coding-core/dist/env.js
1798
+ var AUTH_VARS = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
1799
+ var warned = false;
1800
+ function claudeCliEnv(base2 = process.env) {
1801
+ if (process.env.POLYMATH_USE_API_KEY === "1")
1802
+ return base2;
1803
+ const present = AUTH_VARS.filter((k) => base2[k]);
1804
+ if (!present.length)
1805
+ return base2;
1806
+ if (!warned) {
1807
+ warned = true;
1808
+ 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.`);
1809
+ }
1810
+ const scrubbed = { ...base2 };
1811
+ for (const k of AUTH_VARS)
1812
+ delete scrubbed[k];
1813
+ return scrubbed;
1814
+ }
1815
+
1797
1816
  // src/grade/adapter.ts
1798
1817
  function extractJson(text2) {
1799
1818
  const fences = [...text2.matchAll(/```json\s*([\s\S]*?)```/gi)];
@@ -1945,7 +1964,9 @@ var cliAdapter = {
1945
1964
  await new Promise((resolve2, reject) => {
1946
1965
  const child = spawn(bin, args, {
1947
1966
  cwd: inv.cwd ?? inv.addDir,
1948
- env: process.env,
1967
+ // scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
1968
+ // claude CLI away from their claude.ai login (coding-core/env.ts)
1969
+ env: claudeCliEnv(),
1949
1970
  stdio: ["ignore", "pipe", "pipe"],
1950
1971
  // Own process group, so a timeout can kill the WHOLE tree (claude spawns
1951
1972
  // children that otherwise orphan and pile up).
@@ -3263,7 +3284,9 @@ var cliAdapter2 = {
3263
3284
  await new Promise((resolve2, reject) => {
3264
3285
  const child = spawn3(CLAUDE_BIN, args, {
3265
3286
  cwd: inv.cwd ?? inv.addDir,
3266
- env: process.env,
3287
+ // scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
3288
+ // claude CLI away from their claude.ai login (coding-core/env.ts)
3289
+ env: claudeCliEnv(),
3267
3290
  stdio: ["ignore", "pipe", "pipe"],
3268
3291
  // Own process group, so a timeout can kill the WHOLE tree (claude spawns
3269
3292
  // its own children that otherwise orphan and pile up — the root cause of
@@ -23367,8 +23390,9 @@ function startServer(opts) {
23367
23390
  if (req.method === "GET" && route === "/auth/callback") {
23368
23391
  try {
23369
23392
  const id = await completeLogin(dataDir, new URL(url, serverUrl).searchParams);
23393
+ const back = host === "127.0.0.1" ? serverUrl.replace("//127.0.0.1:", "//localhost:") : serverUrl;
23370
23394
  res.writeHead(200, { "content-type": MIME[".html"] });
23371
- 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>`);
23395
+ 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>`);
23372
23396
  } catch (e) {
23373
23397
  res.writeHead(400, { "content-type": MIME[".html"] });
23374
23398
  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>`);
@@ -23532,7 +23556,12 @@ function startServer(opts) {
23532
23556
  }).catch(() => {
23533
23557
  });
23534
23558
  resolve2({
23535
- url: serverUrl,
23559
+ // The DISPLAYED/opened URL says localhost — friendlier than 127.0.0.1
23560
+ // (owner call 2026-07-15); same server, same loopback. serverUrl itself
23561
+ // stays on the bound host because the Google sign-in redirect is
23562
+ // allow-listed for http://127.0.0.1:*/** in Supabase — auth flows
23563
+ // through 127.0.0.1 no matter which name the person's tab uses.
23564
+ url: host === "127.0.0.1" ? `http://localhost:${port}` : serverUrl,
23536
23565
  port,
23537
23566
  close: () => new Promise((r) => server.close(() => r())),
23538
23567
  setProfile: (p) => {
@@ -151,6 +151,25 @@ import { spawn } from "child_process";
151
151
  import { promises as fs2 } from "fs";
152
152
  import path2 from "path";
153
153
 
154
+ // ../coding-core/dist/env.js
155
+ var AUTH_VARS = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
156
+ var warned = false;
157
+ function claudeCliEnv(base = process.env) {
158
+ if (process.env.POLYMATH_USE_API_KEY === "1")
159
+ return base;
160
+ const present = AUTH_VARS.filter((k) => base[k]);
161
+ if (!present.length)
162
+ return base;
163
+ if (!warned) {
164
+ warned = true;
165
+ 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.`);
166
+ }
167
+ const scrubbed = { ...base };
168
+ for (const k of AUTH_VARS)
169
+ delete scrubbed[k];
170
+ return scrubbed;
171
+ }
172
+
154
173
  // ../../lib/agents/shared/adapter.ts
155
174
  function extractJson(text2) {
156
175
  const fences = [...text2.matchAll(/```json\s*([\s\S]*?)```/gi)];
@@ -255,7 +274,9 @@ var cliAdapter = {
255
274
  await new Promise((resolve2, reject) => {
256
275
  const child = spawn(CLAUDE_BIN, args, {
257
276
  cwd: inv.cwd ?? inv.addDir,
258
- env: process.env,
277
+ // scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
278
+ // claude CLI away from their claude.ai login (coding-core/env.ts)
279
+ env: claudeCliEnv(),
259
280
  stdio: ["ignore", "pipe", "pipe"],
260
281
  // Own process group, so a timeout can kill the WHOLE tree (claude spawns
261
282
  // its own children that otherwise orphan and pile up — the root cause of
@@ -145,6 +145,25 @@ import { spawn } from "child_process";
145
145
  import { promises as fs2 } from "fs";
146
146
  import path2 from "path";
147
147
 
148
+ // ../coding-core/dist/env.js
149
+ var AUTH_VARS = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
150
+ var warned = false;
151
+ function claudeCliEnv(base = process.env) {
152
+ if (process.env.POLYMATH_USE_API_KEY === "1")
153
+ return base;
154
+ const present = AUTH_VARS.filter((k) => base[k]);
155
+ if (!present.length)
156
+ return base;
157
+ if (!warned) {
158
+ warned = true;
159
+ 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.`);
160
+ }
161
+ const scrubbed = { ...base };
162
+ for (const k of AUTH_VARS)
163
+ delete scrubbed[k];
164
+ return scrubbed;
165
+ }
166
+
148
167
  // ../../lib/agents/shared/adapter.ts
149
168
  function extractJson(text2) {
150
169
  const fences = [...text2.matchAll(/```json\s*([\s\S]*?)```/gi)];
@@ -249,7 +268,9 @@ var cliAdapter = {
249
268
  await new Promise((resolve2, reject) => {
250
269
  const child = spawn(CLAUDE_BIN, args, {
251
270
  cwd: inv.cwd ?? inv.addDir,
252
- env: process.env,
271
+ // scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
272
+ // claude CLI away from their claude.ai login (coding-core/env.ts)
273
+ env: claudeCliEnv(),
253
274
  stdio: ["ignore", "pipe", "pipe"],
254
275
  // Own process group, so a timeout can kill the WHOLE tree (claude spawns
255
276
  // its own children that otherwise orphan and pile up — the root cause of
@@ -151,6 +151,25 @@ import { spawn } from "child_process";
151
151
  import { promises as fs2 } from "fs";
152
152
  import path2 from "path";
153
153
 
154
+ // ../coding-core/dist/env.js
155
+ var AUTH_VARS = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
156
+ var warned = false;
157
+ function claudeCliEnv(base = process.env) {
158
+ if (process.env.POLYMATH_USE_API_KEY === "1")
159
+ return base;
160
+ const present = AUTH_VARS.filter((k) => base[k]);
161
+ if (!present.length)
162
+ return base;
163
+ if (!warned) {
164
+ warned = true;
165
+ 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.`);
166
+ }
167
+ const scrubbed = { ...base };
168
+ for (const k of AUTH_VARS)
169
+ delete scrubbed[k];
170
+ return scrubbed;
171
+ }
172
+
154
173
  // ../../lib/agents/shared/adapter.ts
155
174
  function extractJson(text2) {
156
175
  const fences = [...text2.matchAll(/```json\s*([\s\S]*?)```/gi)];
@@ -255,7 +274,9 @@ var cliAdapter = {
255
274
  await new Promise((resolve2, reject) => {
256
275
  const child = spawn(CLAUDE_BIN, args, {
257
276
  cwd: inv.cwd ?? inv.addDir,
258
- env: process.env,
277
+ // scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
278
+ // claude CLI away from their claude.ai login (coding-core/env.ts)
279
+ env: claudeCliEnv(),
259
280
  stdio: ["ignore", "pipe", "pipe"],
260
281
  // Own process group, so a timeout can kill the WHOLE tree (claude spawns
261
282
  // its own children that otherwise orphan and pile up — the root cause of
@@ -151,6 +151,25 @@ import { spawn } from "child_process";
151
151
  import { promises as fs2 } from "fs";
152
152
  import path2 from "path";
153
153
 
154
+ // ../coding-core/dist/env.js
155
+ var AUTH_VARS = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
156
+ var warned = false;
157
+ function claudeCliEnv(base = process.env) {
158
+ if (process.env.POLYMATH_USE_API_KEY === "1")
159
+ return base;
160
+ const present = AUTH_VARS.filter((k) => base[k]);
161
+ if (!present.length)
162
+ return base;
163
+ if (!warned) {
164
+ warned = true;
165
+ 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.`);
166
+ }
167
+ const scrubbed = { ...base };
168
+ for (const k of AUTH_VARS)
169
+ delete scrubbed[k];
170
+ return scrubbed;
171
+ }
172
+
154
173
  // ../../lib/agents/shared/adapter.ts
155
174
  function extractJson(text2) {
156
175
  const fences = [...text2.matchAll(/```json\s*([\s\S]*?)```/gi)];
@@ -255,7 +274,9 @@ var cliAdapter = {
255
274
  await new Promise((resolve2, reject) => {
256
275
  const child = spawn(CLAUDE_BIN, args, {
257
276
  cwd: inv.cwd ?? inv.addDir,
258
- env: process.env,
277
+ // scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
278
+ // claude CLI away from their claude.ai login (coding-core/env.ts)
279
+ env: claudeCliEnv(),
259
280
  stdio: ["ignore", "pipe", "pipe"],
260
281
  // Own process group, so a timeout can kill the WHOLE tree (claude spawns
261
282
  // its own children that otherwise orphan and pile up — the root cause of
@@ -147,6 +147,25 @@ import { spawn } from "child_process";
147
147
  import { promises as fs2 } from "fs";
148
148
  import path2 from "path";
149
149
 
150
+ // ../coding-core/dist/env.js
151
+ var AUTH_VARS = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
152
+ var warned = false;
153
+ function claudeCliEnv(base = process.env) {
154
+ if (process.env.POLYMATH_USE_API_KEY === "1")
155
+ return base;
156
+ const present = AUTH_VARS.filter((k) => base[k]);
157
+ if (!present.length)
158
+ return base;
159
+ if (!warned) {
160
+ warned = true;
161
+ 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.`);
162
+ }
163
+ const scrubbed = { ...base };
164
+ for (const k of AUTH_VARS)
165
+ delete scrubbed[k];
166
+ return scrubbed;
167
+ }
168
+
150
169
  // ../../lib/agents/shared/adapter.ts
151
170
  function extractJson(text2) {
152
171
  const fences = [...text2.matchAll(/```json\s*([\s\S]*?)```/gi)];
@@ -251,7 +270,9 @@ var cliAdapter = {
251
270
  await new Promise((resolve2, reject) => {
252
271
  const child = spawn(CLAUDE_BIN, args, {
253
272
  cwd: inv.cwd ?? inv.addDir,
254
- env: process.env,
273
+ // scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
274
+ // claude CLI away from their claude.ai login (coding-core/env.ts)
275
+ env: claudeCliEnv(),
255
276
  stdio: ["ignore", "pipe", "pipe"],
256
277
  // Own process group, so a timeout can kill the WHOLE tree (claude spawns
257
278
  // its own children that otherwise orphan and pile up — the root cause of
@@ -135,6 +135,19 @@ var require_secure_json_parse = __commonJS({
135
135
 
136
136
  // ../../scripts/coding-focus.mts
137
137
  import { promises as fs6 } from "fs";
138
+
139
+ // ../../lib/agents/coding/promptCache.ts
140
+ import { createHash } from "crypto";
141
+ function promptSha(parts) {
142
+ const h = createHash("sha256");
143
+ for (const p of parts) {
144
+ h.update(p ?? "");
145
+ h.update("\0");
146
+ }
147
+ return h.digest("hex").slice(0, 16);
148
+ }
149
+
150
+ // ../../scripts/coding-focus.mts
138
151
  import path10 from "path";
139
152
 
140
153
  // ../../lib/agents/shared/agent.ts
@@ -146,6 +159,25 @@ import { spawn } from "child_process";
146
159
  import { promises as fs2 } from "fs";
147
160
  import path2 from "path";
148
161
 
162
+ // ../coding-core/dist/env.js
163
+ var AUTH_VARS = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
164
+ var warned = false;
165
+ function claudeCliEnv(base = process.env) {
166
+ if (process.env.POLYMATH_USE_API_KEY === "1")
167
+ return base;
168
+ const present = AUTH_VARS.filter((k) => base[k]);
169
+ if (!present.length)
170
+ return base;
171
+ if (!warned) {
172
+ warned = true;
173
+ 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.`);
174
+ }
175
+ const scrubbed = { ...base };
176
+ for (const k of AUTH_VARS)
177
+ delete scrubbed[k];
178
+ return scrubbed;
179
+ }
180
+
149
181
  // ../../lib/agents/shared/adapter.ts
150
182
  function extractJson(text2) {
151
183
  const fences = [...text2.matchAll(/```json\s*([\s\S]*?)```/gi)];
@@ -250,7 +282,9 @@ var cliAdapter = {
250
282
  await new Promise((resolve2, reject) => {
251
283
  const child = spawn(CLAUDE_BIN, args, {
252
284
  cwd: inv.cwd ?? inv.addDir,
253
- env: process.env,
285
+ // scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
286
+ // claude CLI away from their claude.ai login (coding-core/env.ts)
287
+ env: claudeCliEnv(),
254
288
  stdio: ["ignore", "pipe", "pipe"],
255
289
  // Own process group, so a timeout can kill the WHOLE tree (claude spawns
256
290
  // its own children that otherwise orphan and pile up — the root cause of
@@ -16170,7 +16204,13 @@ async function run2() {
16170
16204
 
16171
16205
  SESSIONS:
16172
16206
  ${JSON.stringify(listing, null, 1)}`;
16173
- try {
16207
+ const clusterSha = promptSha([cprompt]);
16208
+ if (prev?.features?.length && prev?.featuresPromptSha === clusterSha && !process.env.FOCUS_REFRESH) {
16209
+ out.features = prev.features;
16210
+ out.featuresDaysUnit = prev.featuresDaysUnit ?? "min";
16211
+ out.featuresPromptSha = clusterSha;
16212
+ console.log("focus: cluster inputs unchanged \u2014 reusing features (FOCUS_REFRESH=1 to redo)");
16213
+ } else try {
16174
16214
  const cr = await invokeAgent({ prompt: cprompt, systemPrompt: "You produce strict JSON only.", maxTurns: 3, timeoutMs: 48e4, model: "sonnet" });
16175
16215
  let cj = cr.json ?? null;
16176
16216
  if (!cj) cj = parseModelJson(cr.raw);
@@ -16205,6 +16245,7 @@ ${JSON.stringify(listing, null, 1)}`;
16205
16245
  }
16206
16246
  out.features = feats.sort((a, b) => Object.keys(b.days).length - Object.keys(a.days).length);
16207
16247
  out.featuresDaysUnit = "min";
16248
+ out.featuresPromptSha = clusterSha;
16208
16249
  console.log(`focus: ${out.features.length} semantic features from ${recentSess.length} sessions (${stray.length} unmapped \u2192 Everything else)`);
16209
16250
  } else console.error(`focus: feature clustering returned no usable JSON (raw ${String(cr.raw || "").length} chars)`);
16210
16251
  } catch (e) {
@@ -16229,7 +16270,11 @@ ${examples}
16229
16270
  ${summary}
16230
16271
 
16231
16272
  Return the Part 5 JSON only.`;
16232
- try {
16273
+ const judgeSha = promptSha([prompt, process.env.FOCUS_JUDGE_MODEL || "opus"]);
16274
+ if (prev?.llm?.promptSha === judgeSha && !process.env.FOCUS_REFRESH) {
16275
+ out.llm = prev.llm;
16276
+ console.log("focus: judgment inputs unchanged \u2014 reusing llm block (FOCUS_REFRESH=1 to redo)");
16277
+ } else try {
16233
16278
  const judgeModel = process.env.FOCUS_JUDGE_MODEL || "opus";
16234
16279
  const run22 = await invokeAgent({ prompt, systemPrompt: "You produce strict JSON per the rubric's output contract. No prose outside the JSON.", maxTurns: 3, timeoutMs: 48e4, model: judgeModel });
16235
16280
  let parsed = run22.json ?? null;
@@ -16242,7 +16287,7 @@ Return the Part 5 JSON only.`;
16242
16287
  The block to append in step 1:
16243
16288
  ${parsed.claudeMdSnippet}`;
16244
16289
  }
16245
- if (parsed && (parsed.causalFindings?.length || parsed.flowKinds)) out.llm = { ...parsed, model: judgeModel, generatedAt: (/* @__PURE__ */ new Date()).toISOString() };
16290
+ if (parsed && (parsed.causalFindings?.length || parsed.flowKinds)) out.llm = { ...parsed, model: judgeModel, generatedAt: (/* @__PURE__ */ new Date()).toISOString(), promptSha: judgeSha };
16246
16291
  else console.error(`focus: LLM pass returned no usable JSON (raw ${String(run22.raw || "").length} chars) \u2014 deterministic data written, causal block empty`);
16247
16292
  } catch (e) {
16248
16293
  console.error("focus: LLM pass failed \u2014", e.message);
@@ -145,6 +145,25 @@ import { spawn } from "child_process";
145
145
  import { promises as fs2 } from "fs";
146
146
  import path2 from "path";
147
147
 
148
+ // ../coding-core/dist/env.js
149
+ var AUTH_VARS = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
150
+ var warned = false;
151
+ function claudeCliEnv(base = process.env) {
152
+ if (process.env.POLYMATH_USE_API_KEY === "1")
153
+ return base;
154
+ const present = AUTH_VARS.filter((k) => base[k]);
155
+ if (!present.length)
156
+ return base;
157
+ if (!warned) {
158
+ warned = true;
159
+ 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.`);
160
+ }
161
+ const scrubbed = { ...base };
162
+ for (const k of AUTH_VARS)
163
+ delete scrubbed[k];
164
+ return scrubbed;
165
+ }
166
+
148
167
  // ../../lib/agents/shared/adapter.ts
149
168
  function extractJson(text2) {
150
169
  const fences = [...text2.matchAll(/```json\s*([\s\S]*?)```/gi)];
@@ -249,7 +268,9 @@ var cliAdapter = {
249
268
  await new Promise((resolve2, reject) => {
250
269
  const child = spawn(CLAUDE_BIN, args, {
251
270
  cwd: inv.cwd ?? inv.addDir,
252
- env: process.env,
271
+ // scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
272
+ // claude CLI away from their claude.ai login (coding-core/env.ts)
273
+ env: claudeCliEnv(),
253
274
  stdio: ["ignore", "pipe", "pipe"],
254
275
  // Own process group, so a timeout can kill the WHOLE tree (claude spawns
255
276
  // its own children that otherwise orphan and pile up — the root cause of
@@ -146,6 +146,25 @@ import { spawn } from "child_process";
146
146
  import { promises as fs2 } from "fs";
147
147
  import path2 from "path";
148
148
 
149
+ // ../coding-core/dist/env.js
150
+ var AUTH_VARS = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
151
+ var warned = false;
152
+ function claudeCliEnv(base = process.env) {
153
+ if (process.env.POLYMATH_USE_API_KEY === "1")
154
+ return base;
155
+ const present = AUTH_VARS.filter((k) => base[k]);
156
+ if (!present.length)
157
+ return base;
158
+ if (!warned) {
159
+ warned = true;
160
+ 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.`);
161
+ }
162
+ const scrubbed = { ...base };
163
+ for (const k of AUTH_VARS)
164
+ delete scrubbed[k];
165
+ return scrubbed;
166
+ }
167
+
149
168
  // ../../lib/agents/shared/adapter.ts
150
169
  function extractJson(text2) {
151
170
  const fences = [...text2.matchAll(/```json\s*([\s\S]*?)```/gi)];
@@ -250,7 +269,9 @@ var cliAdapter = {
250
269
  await new Promise((resolve2, reject) => {
251
270
  const child = spawn(CLAUDE_BIN, args, {
252
271
  cwd: inv.cwd ?? inv.addDir,
253
- env: process.env,
272
+ // scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
273
+ // claude CLI away from their claude.ai login (coding-core/env.ts)
274
+ env: claudeCliEnv(),
254
275
  stdio: ["ignore", "pipe", "pipe"],
255
276
  // Own process group, so a timeout can kill the WHOLE tree (claude spawns
256
277
  // its own children that otherwise orphan and pile up — the root cause of
@@ -151,6 +151,25 @@ import { spawn } from "child_process";
151
151
  import { promises as fs2 } from "fs";
152
152
  import path2 from "path";
153
153
 
154
+ // ../coding-core/dist/env.js
155
+ var AUTH_VARS = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
156
+ var warned = false;
157
+ function claudeCliEnv(base = process.env) {
158
+ if (process.env.POLYMATH_USE_API_KEY === "1")
159
+ return base;
160
+ const present = AUTH_VARS.filter((k) => base[k]);
161
+ if (!present.length)
162
+ return base;
163
+ if (!warned) {
164
+ warned = true;
165
+ 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.`);
166
+ }
167
+ const scrubbed = { ...base };
168
+ for (const k of AUTH_VARS)
169
+ delete scrubbed[k];
170
+ return scrubbed;
171
+ }
172
+
154
173
  // ../../lib/agents/shared/adapter.ts
155
174
  function extractJson(text2) {
156
175
  const fences = [...text2.matchAll(/```json\s*([\s\S]*?)```/gi)];
@@ -255,7 +274,9 @@ var cliAdapter = {
255
274
  await new Promise((resolve2, reject) => {
256
275
  const child = spawn(CLAUDE_BIN, args, {
257
276
  cwd: inv.cwd ?? inv.addDir,
258
- env: process.env,
277
+ // scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
278
+ // claude CLI away from their claude.ai login (coding-core/env.ts)
279
+ env: claudeCliEnv(),
259
280
  stdio: ["ignore", "pipe", "pipe"],
260
281
  // Own process group, so a timeout can kill the WHOLE tree (claude spawns
261
282
  // its own children that otherwise orphan and pile up — the root cause of
@@ -16162,6 +16183,19 @@ function aiWindowCutoff(sessions, opts = {}) {
16162
16183
  const floorStart = gradableStarts[floor - 1];
16163
16184
  return floorStart < windowCutoff ? floorStart : windowCutoff;
16164
16185
  }
16186
+ var MAX_GRADED_DEFAULT = 150;
16187
+ function maxGraded() {
16188
+ const n = Number(process.env.POLYMATH_MAX_GRADED);
16189
+ return Number.isFinite(n) && n >= 0 ? n : MAX_GRADED_DEFAULT;
16190
+ }
16191
+ function substanceRank(a, b) {
16192
+ return b.humanChars * Math.log1p(b.humanTurns) - a.humanChars * Math.log1p(a.humanTurns);
16193
+ }
16194
+ function capGradable(gradable) {
16195
+ const sorted = gradable.slice().sort(substanceRank);
16196
+ const cap = maxGraded();
16197
+ return cap > 0 && sorted.length > cap ? sorted.slice(0, cap) : sorted;
16198
+ }
16165
16199
 
16166
16200
  // ../../lib/agents/coding/profile.ts
16167
16201
  import path10 from "path";
@@ -16362,9 +16396,10 @@ async function main() {
16362
16396
  const { gradable: allGradable, thin, trivial } = partition(live);
16363
16397
  const cutoff = aiWindowCutoff(live);
16364
16398
  const gradable = cutoff ? allGradable.filter((s) => (s.start ?? "") >= cutoff) : allGradable;
16365
- const ranked = gradable.slice().sort((a, b) => b.humanChars * Math.log1p(b.humanTurns) - a.humanChars * Math.log1p(a.humanTurns));
16399
+ const ranked = capGradable(gradable);
16366
16400
  console.log(`[coding-grade] ${sessions.length} sessions \u2192 ${allGradable.length} gradable \xB7 ${thin.length} thin \xB7 ${trivial.length} trivial (skipped)`);
16367
16401
  if (cutoff) console.log(`[coding-grade] AI window: grading sessions since ${cutoff.slice(0, 10)} \u2014 ${gradable.length} of ${allGradable.length} gradable (POLYMATH_AI_WINDOW_DAYS=0 for full history)`);
16402
+ if (ranked.length < gradable.length) console.log(`[coding-grade] cap: grading the ${ranked.length} richest of ${gradable.length} gradable sessions (POLYMATH_MAX_GRADED=${maxGraded()}; 0 = uncapped) \u2014 the rest still feed every deterministic number`);
16368
16403
  await fs6.mkdir(LOGS, { recursive: true });
16369
16404
  const limit = ALL ? ranked.length : N;
16370
16405
  const picked = [];
@@ -147,6 +147,25 @@ import { spawn } from "child_process";
147
147
  import { promises as fs2 } from "fs";
148
148
  import path2 from "path";
149
149
 
150
+ // ../coding-core/dist/env.js
151
+ var AUTH_VARS = ["ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN"];
152
+ var warned = false;
153
+ function claudeCliEnv(base = process.env) {
154
+ if (process.env.POLYMATH_USE_API_KEY === "1")
155
+ return base;
156
+ const present = AUTH_VARS.filter((k) => base[k]);
157
+ if (!present.length)
158
+ return base;
159
+ if (!warned) {
160
+ warned = true;
161
+ 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.`);
162
+ }
163
+ const scrubbed = { ...base };
164
+ for (const k of AUTH_VARS)
165
+ delete scrubbed[k];
166
+ return scrubbed;
167
+ }
168
+
150
169
  // ../../lib/agents/shared/adapter.ts
151
170
  function extractJson(text2) {
152
171
  const fences = [...text2.matchAll(/```json\s*([\s\S]*?)```/gi)];
@@ -251,7 +270,9 @@ var cliAdapter = {
251
270
  await new Promise((resolve2, reject) => {
252
271
  const child = spawn(CLAUDE_BIN, args, {
253
272
  cwd: inv.cwd ?? inv.addDir,
254
- env: process.env,
273
+ // scrubbed: a stray ANTHROPIC_API_KEY in the user's shell hijacks the
274
+ // claude CLI away from their claude.ai login (coding-core/env.ts)
275
+ env: claudeCliEnv(),
255
276
  stdio: ["ignore", "pipe", "pipe"],
256
277
  // Own process group, so a timeout can kill the WHOLE tree (claude spawns
257
278
  // its own children that otherwise orphan and pile up — the root cause of