polymath-society 0.2.19 → 0.2.21
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 +24620 -22073
- package/dist/engine/chat-loops.js +8 -1
- package/dist/engine/exp-allfacets.js +8 -1
- package/dist/engine/exp-person.js +8 -1
- package/dist/engine/exp-pipeline.js +8 -1
- package/dist/engine/ingest-export.js +7 -6
- package/dist/engine/peak-demos.js +8 -1
- package/dist/engine/person-dimension-summary.js +8 -1
- package/dist/engine/person-facet-lines.js +8 -1
- package/dist/engine/person-headline.js +8 -1
- package/dist/engine/person-report.js +8 -1
- package/dist/engine/person-self-image.js +8 -1
- package/dist/engine/public-report.js +15 -7
- package/dist/engine/run-analysis.js +8 -1
- package/dist/engine/run-tagger.js +8 -1
- package/dist/index.js +19600 -17706
- package/dist/pipeline/FOCUS-EXAMPLES.md +127 -0
- package/dist/pipeline/FOCUS-RUBRIC.md +418 -0
- package/dist/pipeline/coding-agglomerate.js +947 -79
- package/dist/pipeline/coding-aggregate.js +443 -23
- package/dist/pipeline/coding-build.js +569 -97
- package/dist/pipeline/coding-coaching.js +651 -101
- package/dist/pipeline/coding-day-digest.js +417 -36
- package/dist/pipeline/coding-delegation.js +564 -68
- package/dist/pipeline/coding-expertise.js +477 -59
- package/dist/pipeline/coding-flow.js +424 -15
- package/dist/pipeline/coding-focus.js +507 -51
- package/dist/pipeline/coding-frontier-detail.js +465 -47
- package/dist/pipeline/coding-frontier.js +7 -6
- package/dist/pipeline/coding-gap-dist.js +424 -15
- package/dist/pipeline/coding-gap.js +679 -128
- package/dist/pipeline/coding-grade.js +469 -42
- package/dist/pipeline/coding-growth.js +17041 -0
- package/dist/pipeline/coding-nutshell.js +168 -151
- package/dist/pipeline/coding-projects.js +7 -6
- package/dist/pipeline/coding-walkthrough.js +461 -37
- package/dist/pipeline/coding-workbrief.js +16387 -0
- package/dist/web/app.js +2095 -1396
- package/dist/web/styles.css +1 -1
- package/package.json +1 -1
|
@@ -134,8 +134,55 @@ var require_secure_json_parse = __commonJS({
|
|
|
134
134
|
});
|
|
135
135
|
|
|
136
136
|
// ../../scripts/coding-gap.mts
|
|
137
|
-
import { promises as
|
|
138
|
-
import
|
|
137
|
+
import { promises as fs13 } from "fs";
|
|
138
|
+
import path14 from "path";
|
|
139
|
+
|
|
140
|
+
// ../../lib/agents/coding/stageLock.ts
|
|
141
|
+
import { promises as fs } from "fs";
|
|
142
|
+
var STALE_UNKNOWN_MS = 12 * 60 * 60 * 1e3;
|
|
143
|
+
function pidAlive(pid) {
|
|
144
|
+
try {
|
|
145
|
+
process.kill(pid, 0);
|
|
146
|
+
return true;
|
|
147
|
+
} catch (e) {
|
|
148
|
+
return e.code === "EPERM";
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
async function acquireStageLock(lockPath, stage) {
|
|
152
|
+
const mine = String(process.pid);
|
|
153
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
154
|
+
try {
|
|
155
|
+
await fs.writeFile(lockPath, mine, { flag: "wx" });
|
|
156
|
+
return async () => {
|
|
157
|
+
const held = await fs.readFile(lockPath, "utf8").catch(() => null);
|
|
158
|
+
if (held === mine) await fs.unlink(lockPath).catch(() => {
|
|
159
|
+
});
|
|
160
|
+
};
|
|
161
|
+
} catch {
|
|
162
|
+
const raw = (await fs.readFile(lockPath, "utf8").catch(() => "")).trim();
|
|
163
|
+
const pid = /^\d{1,9}$/.test(raw) ? Number(raw) : null;
|
|
164
|
+
if (pid != null && pidAlive(pid)) {
|
|
165
|
+
throw new Error(
|
|
166
|
+
`another ${stage} run is ACTIVE (pid ${pid} is alive, ${lockPath}) \u2014 concurrent runs overwrite each other's output. Wait for it to finish.`
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
if (pid == null) {
|
|
170
|
+
const age = Date.now() - (await fs.stat(lockPath).catch(() => null))?.mtimeMs;
|
|
171
|
+
if (!(age > STALE_UNKNOWN_MS)) {
|
|
172
|
+
throw new Error(
|
|
173
|
+
`a ${stage} lock exists with an unreadable holder (${lockPath}, ${Math.round(age / 6e4)}m old) \u2014 not old enough to declare stale. Wait, or delete it if you know the run is gone.`
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
console.warn(
|
|
178
|
+
`[${stage}] stale lock from ${pid != null ? `dead pid ${pid}` : "an unreadable holder"} \u2014 removing it and proceeding (a crashed run must never strand the next one)`
|
|
179
|
+
);
|
|
180
|
+
await fs.unlink(lockPath).catch(() => {
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
throw new Error(`could not acquire the ${stage} lock (${lockPath}) \u2014 another run raced the stale takeover`);
|
|
185
|
+
}
|
|
139
186
|
|
|
140
187
|
// ../../lib/agents/shared/agent.ts
|
|
141
188
|
import { readFileSync } from "fs";
|
|
@@ -143,7 +190,7 @@ import path8 from "path";
|
|
|
143
190
|
|
|
144
191
|
// ../../lib/agents/shared/cliAdapter.ts
|
|
145
192
|
import { spawn } from "child_process";
|
|
146
|
-
import { promises as
|
|
193
|
+
import { promises as fs3 } from "fs";
|
|
147
194
|
import path2 from "path";
|
|
148
195
|
|
|
149
196
|
// ../coding-core/dist/env.js
|
|
@@ -187,7 +234,7 @@ function extractJson(text2) {
|
|
|
187
234
|
}
|
|
188
235
|
|
|
189
236
|
// ../../lib/agents/shared/toolLog.ts
|
|
190
|
-
import { promises as
|
|
237
|
+
import { promises as fs2 } from "fs";
|
|
191
238
|
import path from "path";
|
|
192
239
|
async function writeToolLog(logPath, d) {
|
|
193
240
|
const counts = {};
|
|
@@ -204,8 +251,8 @@ async function writeToolLog(logPath, d) {
|
|
|
204
251
|
L.push(``);
|
|
205
252
|
L.push(`## Full call sequence (${d.toolCalls.length})`);
|
|
206
253
|
d.toolCalls.forEach((c, i) => L.push(` ${String(i + 1).padStart(3, "0")} ${c.tool.padEnd(5)} ${c.target}`));
|
|
207
|
-
await
|
|
208
|
-
await
|
|
254
|
+
await fs2.mkdir(path.dirname(logPath), { recursive: true });
|
|
255
|
+
await fs2.writeFile(logPath, L.join("\n"), "utf-8");
|
|
209
256
|
const json = {
|
|
210
257
|
roots: d.roots,
|
|
211
258
|
toolCounts: counts,
|
|
@@ -215,7 +262,7 @@ async function writeToolLog(logPath, d) {
|
|
|
215
262
|
filesRead: d.filesRead,
|
|
216
263
|
callSequence: d.toolCalls
|
|
217
264
|
};
|
|
218
|
-
await
|
|
265
|
+
await fs2.writeFile(logPath.replace(/\.log$/, ".json"), JSON.stringify(json, null, 2), "utf-8");
|
|
219
266
|
}
|
|
220
267
|
|
|
221
268
|
// ../../lib/agents/shared/cliAdapter.ts
|
|
@@ -224,8 +271,8 @@ var USAGE_LEDGER = () => path2.join(process.env.POLYMATH_DATA_DIR ? path2.resolv
|
|
|
224
271
|
async function appendUsageLedger(line) {
|
|
225
272
|
try {
|
|
226
273
|
const f = USAGE_LEDGER();
|
|
227
|
-
await
|
|
228
|
-
await
|
|
274
|
+
await fs3.mkdir(path2.dirname(f), { recursive: true });
|
|
275
|
+
await fs3.appendFile(f, JSON.stringify(line) + "\n", "utf8");
|
|
229
276
|
} catch {
|
|
230
277
|
}
|
|
231
278
|
}
|
|
@@ -503,6 +550,13 @@ ${report}`);
|
|
|
503
550
|
}
|
|
504
551
|
|
|
505
552
|
// ../../lib/agents/shared/codexAdapter.ts
|
|
553
|
+
var CODEX_DEFAULT_MODEL = "gpt-5.5";
|
|
554
|
+
var CODEX_MINI_MODEL = "gpt-5.4-mini";
|
|
555
|
+
function mapCodexTier(model, env = process.env) {
|
|
556
|
+
if (model && !/^(claude|haiku|sonnet|opus)/i.test(model)) return model;
|
|
557
|
+
if (model && /^haiku/i.test(model)) return env.POLYMATH_CODEX_MODEL_MINI || CODEX_MINI_MODEL;
|
|
558
|
+
return env.POLYMATH_CODEX_MODEL || CODEX_DEFAULT_MODEL;
|
|
559
|
+
}
|
|
506
560
|
function composePrompt(inv, roots) {
|
|
507
561
|
return [
|
|
508
562
|
inv.systemPrompt ? `<system>
|
|
@@ -543,7 +597,7 @@ var codexAdapter = {
|
|
|
543
597
|
"read-only",
|
|
544
598
|
"--json"
|
|
545
599
|
];
|
|
546
|
-
|
|
600
|
+
args.push("--model", mapCodexTier(inv.model));
|
|
547
601
|
args.push(composePrompt(inv, roots));
|
|
548
602
|
const started = Date.now();
|
|
549
603
|
const toolCalls = [];
|
|
@@ -2171,8 +2225,8 @@ function getErrorMap() {
|
|
|
2171
2225
|
|
|
2172
2226
|
// ../../node_modules/zod/v3/helpers/parseUtil.js
|
|
2173
2227
|
var makeIssue = (params) => {
|
|
2174
|
-
const { data, path:
|
|
2175
|
-
const fullPath = [...
|
|
2228
|
+
const { data, path: path15, errorMaps, issueData } = params;
|
|
2229
|
+
const fullPath = [...path15, ...issueData.path || []];
|
|
2176
2230
|
const fullIssue = {
|
|
2177
2231
|
...issueData,
|
|
2178
2232
|
path: fullPath
|
|
@@ -2288,11 +2342,11 @@ var errorUtil;
|
|
|
2288
2342
|
|
|
2289
2343
|
// ../../node_modules/zod/v3/types.js
|
|
2290
2344
|
var ParseInputLazyPath = class {
|
|
2291
|
-
constructor(parent, value,
|
|
2345
|
+
constructor(parent, value, path15, key) {
|
|
2292
2346
|
this._cachedPath = [];
|
|
2293
2347
|
this.parent = parent;
|
|
2294
2348
|
this.data = value;
|
|
2295
|
-
this._path =
|
|
2349
|
+
this._path = path15;
|
|
2296
2350
|
this._key = key;
|
|
2297
2351
|
}
|
|
2298
2352
|
get path() {
|
|
@@ -15079,39 +15133,39 @@ function createOpenAI(options = {}) {
|
|
|
15079
15133
|
});
|
|
15080
15134
|
const createChatModel = (modelId, settings = {}) => new OpenAIChatLanguageModel(modelId, settings, {
|
|
15081
15135
|
provider: `${providerName}.chat`,
|
|
15082
|
-
url: ({ path:
|
|
15136
|
+
url: ({ path: path15 }) => `${baseURL}${path15}`,
|
|
15083
15137
|
headers: getHeaders,
|
|
15084
15138
|
compatibility,
|
|
15085
15139
|
fetch: options.fetch
|
|
15086
15140
|
});
|
|
15087
15141
|
const createCompletionModel = (modelId, settings = {}) => new OpenAICompletionLanguageModel(modelId, settings, {
|
|
15088
15142
|
provider: `${providerName}.completion`,
|
|
15089
|
-
url: ({ path:
|
|
15143
|
+
url: ({ path: path15 }) => `${baseURL}${path15}`,
|
|
15090
15144
|
headers: getHeaders,
|
|
15091
15145
|
compatibility,
|
|
15092
15146
|
fetch: options.fetch
|
|
15093
15147
|
});
|
|
15094
15148
|
const createEmbeddingModel = (modelId, settings = {}) => new OpenAIEmbeddingModel(modelId, settings, {
|
|
15095
15149
|
provider: `${providerName}.embedding`,
|
|
15096
|
-
url: ({ path:
|
|
15150
|
+
url: ({ path: path15 }) => `${baseURL}${path15}`,
|
|
15097
15151
|
headers: getHeaders,
|
|
15098
15152
|
fetch: options.fetch
|
|
15099
15153
|
});
|
|
15100
15154
|
const createImageModel = (modelId, settings = {}) => new OpenAIImageModel(modelId, settings, {
|
|
15101
15155
|
provider: `${providerName}.image`,
|
|
15102
|
-
url: ({ path:
|
|
15156
|
+
url: ({ path: path15 }) => `${baseURL}${path15}`,
|
|
15103
15157
|
headers: getHeaders,
|
|
15104
15158
|
fetch: options.fetch
|
|
15105
15159
|
});
|
|
15106
15160
|
const createTranscriptionModel = (modelId) => new OpenAITranscriptionModel(modelId, {
|
|
15107
15161
|
provider: `${providerName}.transcription`,
|
|
15108
|
-
url: ({ path:
|
|
15162
|
+
url: ({ path: path15 }) => `${baseURL}${path15}`,
|
|
15109
15163
|
headers: getHeaders,
|
|
15110
15164
|
fetch: options.fetch
|
|
15111
15165
|
});
|
|
15112
15166
|
const createSpeechModel = (modelId) => new OpenAISpeechModel(modelId, {
|
|
15113
15167
|
provider: `${providerName}.speech`,
|
|
15114
|
-
url: ({ path:
|
|
15168
|
+
url: ({ path: path15 }) => `${baseURL}${path15}`,
|
|
15115
15169
|
headers: getHeaders,
|
|
15116
15170
|
fetch: options.fetch
|
|
15117
15171
|
});
|
|
@@ -15132,7 +15186,7 @@ function createOpenAI(options = {}) {
|
|
|
15132
15186
|
const createResponsesModel = (modelId) => {
|
|
15133
15187
|
return new OpenAIResponsesLanguageModel(modelId, {
|
|
15134
15188
|
provider: `${providerName}.responses`,
|
|
15135
|
-
url: ({ path:
|
|
15189
|
+
url: ({ path: path15 }) => `${baseURL}${path15}`,
|
|
15136
15190
|
headers: getHeaders,
|
|
15137
15191
|
fetch: options.fetch
|
|
15138
15192
|
});
|
|
@@ -15162,7 +15216,7 @@ var openai = createOpenAI({
|
|
|
15162
15216
|
});
|
|
15163
15217
|
|
|
15164
15218
|
// ../../lib/agents/shared/tools.ts
|
|
15165
|
-
import { promises as
|
|
15219
|
+
import { promises as fs4 } from "fs";
|
|
15166
15220
|
import { execFile } from "child_process";
|
|
15167
15221
|
import { promisify } from "util";
|
|
15168
15222
|
import path5 from "path";
|
|
@@ -15182,7 +15236,7 @@ function fileTools(root) {
|
|
|
15182
15236
|
parameters: external_exports.object({ path: external_exports.string().describe("dir path relative to source root") }),
|
|
15183
15237
|
execute: async ({ path: p }) => {
|
|
15184
15238
|
const dir = safeResolve(root, p);
|
|
15185
|
-
const entries = await
|
|
15239
|
+
const entries = await fs4.readdir(dir, { withFileTypes: true });
|
|
15186
15240
|
return entries.filter((e) => !e.name.startsWith(".git") && e.name !== ".obsidian").map((e) => e.isDirectory() ? `${e.name}/` : e.name).slice(0, 500).join("\n");
|
|
15187
15241
|
}
|
|
15188
15242
|
}),
|
|
@@ -15195,7 +15249,7 @@ function fileTools(root) {
|
|
|
15195
15249
|
}),
|
|
15196
15250
|
execute: async ({ path: p, offset = 0, limit = 600 }) => {
|
|
15197
15251
|
const file2 = safeResolve(root, p);
|
|
15198
|
-
const text2 = await
|
|
15252
|
+
const text2 = await fs4.readFile(file2, "utf-8");
|
|
15199
15253
|
const lines = text2.split("\n");
|
|
15200
15254
|
return lines.slice(offset, offset + limit).join("\n").slice(0, 6e4);
|
|
15201
15255
|
}
|
|
@@ -15629,8 +15683,8 @@ function invokeAgent(inv, opts = {}) {
|
|
|
15629
15683
|
}
|
|
15630
15684
|
|
|
15631
15685
|
// ../../lib/agents/coding/profile.ts
|
|
15632
|
-
import { promises as
|
|
15633
|
-
import
|
|
15686
|
+
import { promises as fs8 } from "fs";
|
|
15687
|
+
import path11 from "path";
|
|
15634
15688
|
|
|
15635
15689
|
// ../../lib/calibration/fingerprint.ts
|
|
15636
15690
|
import { createHash } from "node:crypto";
|
|
@@ -15776,7 +15830,7 @@ var GRADED_CRITERIA = CODING_CRITERIA.filter((c) => c.graded);
|
|
|
15776
15830
|
var RUBRIC_FINGERPRINT = rubricFingerprint(GRADED_CRITERIA);
|
|
15777
15831
|
|
|
15778
15832
|
// ../coding-core/dist/messages.js
|
|
15779
|
-
import { promises as
|
|
15833
|
+
import { promises as fs6 } from "fs";
|
|
15780
15834
|
|
|
15781
15835
|
// ../coding-core/dist/injected.js
|
|
15782
15836
|
var SYSTEM_REMINDER_RE = /<system-reminder>[\s\S]*?<\/system-reminder>/g;
|
|
@@ -15811,6 +15865,377 @@ function isHarnessEntry(e) {
|
|
|
15811
15865
|
return e.isMeta === true || e.isCompactSummary === true;
|
|
15812
15866
|
}
|
|
15813
15867
|
|
|
15868
|
+
// ../coding-core/dist/codex.js
|
|
15869
|
+
var SYSTEM_REMINDER_RE2 = /<system-reminder>[\s\S]*?<\/system-reminder>/g;
|
|
15870
|
+
var CODEX_INJECTED_TEXT_RE = /^\s*(<(environment_context|user_instructions|ENVIRONMENT_CONTEXT|turn_aborted)\b|#\s*AGENTS\.md instructions\b)/;
|
|
15871
|
+
function isCodexInjectedUserText(text2) {
|
|
15872
|
+
return CODEX_INJECTED_TEXT_RE.test(text2);
|
|
15873
|
+
}
|
|
15874
|
+
function codexContentText(content) {
|
|
15875
|
+
if (typeof content === "string")
|
|
15876
|
+
return content;
|
|
15877
|
+
if (!Array.isArray(content))
|
|
15878
|
+
return "";
|
|
15879
|
+
const parts = [];
|
|
15880
|
+
for (const item of content) {
|
|
15881
|
+
if (typeof item === "string") {
|
|
15882
|
+
parts.push(item);
|
|
15883
|
+
continue;
|
|
15884
|
+
}
|
|
15885
|
+
if (item && typeof item === "object") {
|
|
15886
|
+
const it = item;
|
|
15887
|
+
if (it.type === "input_text" || it.type === "output_text" || it.type === "text")
|
|
15888
|
+
parts.push(it.text || "");
|
|
15889
|
+
}
|
|
15890
|
+
}
|
|
15891
|
+
return parts.join("\n");
|
|
15892
|
+
}
|
|
15893
|
+
function sniffCodexRaw(raw) {
|
|
15894
|
+
let checked = 0;
|
|
15895
|
+
for (const lineRaw of raw.split("\n")) {
|
|
15896
|
+
const line = lineRaw.trim();
|
|
15897
|
+
if (!line)
|
|
15898
|
+
continue;
|
|
15899
|
+
if (checked++ >= 5)
|
|
15900
|
+
break;
|
|
15901
|
+
try {
|
|
15902
|
+
const e = JSON.parse(line);
|
|
15903
|
+
if (e.type === "session_meta" || e.type === "response_item" || e.type === "turn_context")
|
|
15904
|
+
return true;
|
|
15905
|
+
if (e.type === "user" || e.type === "assistant" || e.type === "summary" || e.type === "queue-operation")
|
|
15906
|
+
return false;
|
|
15907
|
+
} catch {
|
|
15908
|
+
}
|
|
15909
|
+
}
|
|
15910
|
+
return false;
|
|
15911
|
+
}
|
|
15912
|
+
var EXIT_CODE_RE = /(?:Process exited with code|Exit code:)\s+(\d+)/;
|
|
15913
|
+
function extractCodexEvents(raw) {
|
|
15914
|
+
const out = [];
|
|
15915
|
+
for (const lineRaw of raw.split("\n")) {
|
|
15916
|
+
const line = lineRaw.trim();
|
|
15917
|
+
if (!line)
|
|
15918
|
+
continue;
|
|
15919
|
+
let e;
|
|
15920
|
+
try {
|
|
15921
|
+
e = JSON.parse(line);
|
|
15922
|
+
} catch {
|
|
15923
|
+
continue;
|
|
15924
|
+
}
|
|
15925
|
+
if (e.type !== "response_item")
|
|
15926
|
+
continue;
|
|
15927
|
+
const p = e.payload ?? {};
|
|
15928
|
+
const t = typeof e.timestamp === "string" ? Date.parse(e.timestamp) : NaN;
|
|
15929
|
+
const ptype = p.type;
|
|
15930
|
+
if (ptype === "message") {
|
|
15931
|
+
const role = p.role;
|
|
15932
|
+
const text2 = codexContentText(p.content).replace(SYSTEM_REMINDER_RE2, "").trim();
|
|
15933
|
+
if (!text2)
|
|
15934
|
+
continue;
|
|
15935
|
+
if (role === "user") {
|
|
15936
|
+
if (isCodexInjectedUserText(text2))
|
|
15937
|
+
continue;
|
|
15938
|
+
out.push({ kind: "user", t, text: text2 });
|
|
15939
|
+
} else if (role === "assistant") {
|
|
15940
|
+
out.push({ kind: "assistant", t, text: text2 });
|
|
15941
|
+
}
|
|
15942
|
+
continue;
|
|
15943
|
+
}
|
|
15944
|
+
if (ptype === "function_call" || ptype === "custom_tool_call" || ptype === "local_shell_call") {
|
|
15945
|
+
const name17 = typeof p.name === "string" && p.name ? p.name : ptype === "local_shell_call" ? "shell" : String(ptype);
|
|
15946
|
+
const input = typeof p.arguments === "string" ? p.arguments : typeof p.input === "string" ? p.input : "";
|
|
15947
|
+
out.push({ kind: "tool", t, name: name17, input });
|
|
15948
|
+
continue;
|
|
15949
|
+
}
|
|
15950
|
+
if (ptype === "function_call_output" || ptype === "custom_tool_call_output") {
|
|
15951
|
+
const output = typeof p.output === "string" ? p.output : "";
|
|
15952
|
+
const m = EXIT_CODE_RE.exec(output.slice(0, 200));
|
|
15953
|
+
out.push({ kind: "tool_output", t, output, isError: !!m && m[1] !== "0" });
|
|
15954
|
+
}
|
|
15955
|
+
}
|
|
15956
|
+
return out;
|
|
15957
|
+
}
|
|
15958
|
+
|
|
15959
|
+
// ../coding-core/dist/cursor.js
|
|
15960
|
+
import { promises as fs5 } from "fs";
|
|
15961
|
+
var NODE_SQLITE = "node:sqlite";
|
|
15962
|
+
async function openCursorSqlite(dbPath) {
|
|
15963
|
+
try {
|
|
15964
|
+
await fs5.access(dbPath);
|
|
15965
|
+
} catch {
|
|
15966
|
+
return null;
|
|
15967
|
+
}
|
|
15968
|
+
let mod;
|
|
15969
|
+
try {
|
|
15970
|
+
mod = await import(NODE_SQLITE);
|
|
15971
|
+
} catch {
|
|
15972
|
+
return null;
|
|
15973
|
+
}
|
|
15974
|
+
const DatabaseSync = mod?.DatabaseSync;
|
|
15975
|
+
if (!DatabaseSync)
|
|
15976
|
+
return null;
|
|
15977
|
+
let db;
|
|
15978
|
+
try {
|
|
15979
|
+
db = new DatabaseSync(dbPath, { readOnly: true });
|
|
15980
|
+
} catch {
|
|
15981
|
+
try {
|
|
15982
|
+
db = new DatabaseSync(dbPath);
|
|
15983
|
+
} catch {
|
|
15984
|
+
return null;
|
|
15985
|
+
}
|
|
15986
|
+
}
|
|
15987
|
+
const asText = (v) => v == null ? null : typeof v === "string" ? v : Buffer.from(v).toString("utf-8");
|
|
15988
|
+
return {
|
|
15989
|
+
prefix(prefix) {
|
|
15990
|
+
try {
|
|
15991
|
+
const rows = db.prepare("SELECT key, value FROM cursorDiskKV WHERE key LIKE ? ESCAPE '\\'").all(likePrefix(prefix));
|
|
15992
|
+
return rows.map((r) => ({ key: r.key, value: asText(r.value) ?? "" }));
|
|
15993
|
+
} catch {
|
|
15994
|
+
return [];
|
|
15995
|
+
}
|
|
15996
|
+
},
|
|
15997
|
+
get(key) {
|
|
15998
|
+
try {
|
|
15999
|
+
const row = db.prepare("SELECT value FROM cursorDiskKV WHERE key = ?").get(key);
|
|
16000
|
+
return row ? asText(row.value) : null;
|
|
16001
|
+
} catch {
|
|
16002
|
+
return null;
|
|
16003
|
+
}
|
|
16004
|
+
},
|
|
16005
|
+
close() {
|
|
16006
|
+
try {
|
|
16007
|
+
db.close();
|
|
16008
|
+
} catch {
|
|
16009
|
+
}
|
|
16010
|
+
}
|
|
16011
|
+
};
|
|
16012
|
+
}
|
|
16013
|
+
function likePrefix(prefix) {
|
|
16014
|
+
return prefix.replace(/[\\%_]/g, (c) => "\\" + c) + "%";
|
|
16015
|
+
}
|
|
16016
|
+
var CURSOR_USER_QUERY_RE = /<user_query>\s*([\s\S]*?)\s*<\/user_query>/;
|
|
16017
|
+
function cleanUserText(raw) {
|
|
16018
|
+
let t = raw.replace(SYSTEM_REMINDER_RE, "");
|
|
16019
|
+
const m = t.match(CURSOR_USER_QUERY_RE);
|
|
16020
|
+
if (m)
|
|
16021
|
+
t = m[1];
|
|
16022
|
+
return t.trim();
|
|
16023
|
+
}
|
|
16024
|
+
var msFrom = (v) => {
|
|
16025
|
+
if (typeof v === "number" && Number.isFinite(v))
|
|
16026
|
+
return v;
|
|
16027
|
+
if (typeof v === "string") {
|
|
16028
|
+
const n = Date.parse(v);
|
|
16029
|
+
return Number.isFinite(n) ? n : null;
|
|
16030
|
+
}
|
|
16031
|
+
return null;
|
|
16032
|
+
};
|
|
16033
|
+
function readCursorComposer(db, composerId) {
|
|
16034
|
+
const cdRaw = db.get(`composerData:${composerId}`);
|
|
16035
|
+
if (!cdRaw)
|
|
16036
|
+
return null;
|
|
16037
|
+
let cd;
|
|
16038
|
+
try {
|
|
16039
|
+
cd = JSON.parse(cdRaw);
|
|
16040
|
+
} catch {
|
|
16041
|
+
return null;
|
|
16042
|
+
}
|
|
16043
|
+
const headers = Array.isArray(cd.fullConversationHeadersOnly) ? cd.fullConversationHeadersOnly : [];
|
|
16044
|
+
if (headers.length === 0)
|
|
16045
|
+
return null;
|
|
16046
|
+
const bubbles = /* @__PURE__ */ new Map();
|
|
16047
|
+
for (const row of db.prefix(`bubbleId:${composerId}:`)) {
|
|
16048
|
+
const bid = row.key.slice(`bubbleId:${composerId}:`.length);
|
|
16049
|
+
try {
|
|
16050
|
+
bubbles.set(bid, JSON.parse(row.value));
|
|
16051
|
+
} catch {
|
|
16052
|
+
}
|
|
16053
|
+
}
|
|
16054
|
+
const turns = [];
|
|
16055
|
+
let clock = msFrom(cd.createdAt) ?? 0;
|
|
16056
|
+
for (const h of headers) {
|
|
16057
|
+
const b = bubbles.get(h.bubbleId);
|
|
16058
|
+
if (!b)
|
|
16059
|
+
continue;
|
|
16060
|
+
const type = h.type === 1 ? 1 : 2;
|
|
16061
|
+
const tool2 = type === 2 && b.toolFormerData && typeof b.toolFormerData.name === "string" ? b.toolFormerData.name : null;
|
|
16062
|
+
const rawText = typeof b.text === "string" ? b.text : "";
|
|
16063
|
+
const text2 = type === 1 ? cleanUserText(rawText) : rawText.replace(SYSTEM_REMINDER_RE, "").trim();
|
|
16064
|
+
if (!text2 && !tool2)
|
|
16065
|
+
continue;
|
|
16066
|
+
const t = msFrom(b.createdAt);
|
|
16067
|
+
clock = Math.max(clock, t ?? clock + 1);
|
|
16068
|
+
const model = b.modelInfo && typeof b.modelInfo.modelName === "string" ? b.modelInfo.modelName : null;
|
|
16069
|
+
turns.push({ t: clock, type, text: text2, tool: tool2, model });
|
|
16070
|
+
}
|
|
16071
|
+
if (turns.length === 0)
|
|
16072
|
+
return null;
|
|
16073
|
+
const gitRepo = Array.isArray(cd.trackedGitRepos) && cd.trackedGitRepos[0] && typeof cd.trackedGitRepos[0].repoPath === "string" ? cd.trackedGitRepos[0].repoPath : null;
|
|
16074
|
+
return {
|
|
16075
|
+
composerId,
|
|
16076
|
+
createdAt: msFrom(cd.createdAt),
|
|
16077
|
+
updatedAt: msFrom(cd.lastUpdatedAt),
|
|
16078
|
+
name: typeof cd.name === "string" && cd.name.trim() ? cd.name.trim() : null,
|
|
16079
|
+
gitRepo,
|
|
16080
|
+
turns
|
|
16081
|
+
};
|
|
16082
|
+
}
|
|
16083
|
+
function sniffCursorRaw(raw) {
|
|
16084
|
+
for (const lineRaw of raw.split("\n")) {
|
|
16085
|
+
const line = lineRaw.trim();
|
|
16086
|
+
if (!line)
|
|
16087
|
+
continue;
|
|
16088
|
+
try {
|
|
16089
|
+
const e = JSON.parse(line);
|
|
16090
|
+
return (e.role === "user" || e.role === "assistant") && typeof e.message === "object" && e.message !== null && "content" in e.message && !("type" in e);
|
|
16091
|
+
} catch {
|
|
16092
|
+
return false;
|
|
16093
|
+
}
|
|
16094
|
+
}
|
|
16095
|
+
return false;
|
|
16096
|
+
}
|
|
16097
|
+
function jsonlText(content) {
|
|
16098
|
+
const parts = [];
|
|
16099
|
+
const tools = [];
|
|
16100
|
+
if (Array.isArray(content)) {
|
|
16101
|
+
for (const item of content) {
|
|
16102
|
+
if (!item || typeof item !== "object")
|
|
16103
|
+
continue;
|
|
16104
|
+
const it = item;
|
|
16105
|
+
if (it.type === "text" && it.text)
|
|
16106
|
+
parts.push(it.text);
|
|
16107
|
+
else if (it.type === "tool_use" && it.name)
|
|
16108
|
+
tools.push(it.name);
|
|
16109
|
+
}
|
|
16110
|
+
} else if (typeof content === "string")
|
|
16111
|
+
parts.push(content);
|
|
16112
|
+
return { text: parts.join("\n"), tools };
|
|
16113
|
+
}
|
|
16114
|
+
function parseCursorJsonl(raw, base) {
|
|
16115
|
+
const turns = [];
|
|
16116
|
+
let clock = base;
|
|
16117
|
+
for (const lineRaw of raw.split("\n")) {
|
|
16118
|
+
const line = lineRaw.trim();
|
|
16119
|
+
if (!line)
|
|
16120
|
+
continue;
|
|
16121
|
+
let e;
|
|
16122
|
+
try {
|
|
16123
|
+
e = JSON.parse(line);
|
|
16124
|
+
} catch {
|
|
16125
|
+
continue;
|
|
16126
|
+
}
|
|
16127
|
+
if (e.role !== "user" && e.role !== "assistant")
|
|
16128
|
+
continue;
|
|
16129
|
+
const { text: rawText, tools } = jsonlText(e.message?.content);
|
|
16130
|
+
const type = e.role === "user" ? 1 : 2;
|
|
16131
|
+
const text2 = type === 1 ? cleanUserText(rawText) : rawText.replace(SYSTEM_REMINDER_RE, "").trim();
|
|
16132
|
+
if (type === 2 && tools.length) {
|
|
16133
|
+
for (const tool2 of tools) {
|
|
16134
|
+
clock += 1;
|
|
16135
|
+
turns.push({ t: clock, type: 2, text: "", tool: tool2, model: null });
|
|
16136
|
+
}
|
|
16137
|
+
}
|
|
16138
|
+
if (!text2)
|
|
16139
|
+
continue;
|
|
16140
|
+
clock += 1;
|
|
16141
|
+
turns.push({ t: clock, type, text: text2, tool: null, model: null });
|
|
16142
|
+
}
|
|
16143
|
+
if (turns.length === 0)
|
|
16144
|
+
return null;
|
|
16145
|
+
return { composerId: "", createdAt: base, updatedAt: clock, name: null, gitRepo: null, turns };
|
|
16146
|
+
}
|
|
16147
|
+
var AI_GIST = 500;
|
|
16148
|
+
function renderCursorTranscript(c) {
|
|
16149
|
+
const lines = [];
|
|
16150
|
+
let humanTurns = 0, humanChars = 0;
|
|
16151
|
+
let aiProse = "";
|
|
16152
|
+
const aiTools = /* @__PURE__ */ new Map();
|
|
16153
|
+
const flushAI = () => {
|
|
16154
|
+
if (!aiProse && aiTools.size === 0)
|
|
16155
|
+
return;
|
|
16156
|
+
const tools = [...aiTools.entries()].map(([n, k]) => k > 1 ? `${n}\xD7${k}` : n).join(", ");
|
|
16157
|
+
const gist = aiProse ? aiProse.length > AI_GIST ? aiProse.slice(0, AI_GIST) + "\u2026" : aiProse : "";
|
|
16158
|
+
const bits = [];
|
|
16159
|
+
if (gist)
|
|
16160
|
+
bits.push(gist);
|
|
16161
|
+
if (tools)
|
|
16162
|
+
bits.push(`ran ${tools}`);
|
|
16163
|
+
lines.push(`[AI: ${bits.join(" \xB7 ")}]`);
|
|
16164
|
+
aiProse = "";
|
|
16165
|
+
aiTools.clear();
|
|
16166
|
+
};
|
|
16167
|
+
for (const turn of c.turns) {
|
|
16168
|
+
if (turn.type === 1) {
|
|
16169
|
+
flushAI();
|
|
16170
|
+
humanTurns++;
|
|
16171
|
+
humanChars += turn.text.length;
|
|
16172
|
+
lines.push(`>> ${turn.text}`);
|
|
16173
|
+
} else {
|
|
16174
|
+
if (turn.tool)
|
|
16175
|
+
aiTools.set(turn.tool, (aiTools.get(turn.tool) ?? 0) + 1);
|
|
16176
|
+
if (turn.text)
|
|
16177
|
+
aiProse = turn.text.replace(/\s+/g, " ").trim();
|
|
16178
|
+
}
|
|
16179
|
+
}
|
|
16180
|
+
flushAI();
|
|
16181
|
+
return { text: lines.join("\n"), humanTurns, humanChars };
|
|
16182
|
+
}
|
|
16183
|
+
function composerIdFromFile(file2) {
|
|
16184
|
+
const m = file2.match(/agent-transcripts\/([^/]+)\/[^/]+\.jsonl$/);
|
|
16185
|
+
return m ? m[1] : null;
|
|
16186
|
+
}
|
|
16187
|
+
async function loadCursorComposer(file2, raw, dbPath) {
|
|
16188
|
+
const cid = composerIdFromFile(file2);
|
|
16189
|
+
if (cid && dbPath) {
|
|
16190
|
+
const db = await openCursorSqlite(dbPath);
|
|
16191
|
+
if (db) {
|
|
16192
|
+
try {
|
|
16193
|
+
const c = readCursorComposer(db, cid);
|
|
16194
|
+
if (c)
|
|
16195
|
+
return c;
|
|
16196
|
+
} finally {
|
|
16197
|
+
db.close();
|
|
16198
|
+
}
|
|
16199
|
+
}
|
|
16200
|
+
}
|
|
16201
|
+
return parseCursorJsonl(raw, 0);
|
|
16202
|
+
}
|
|
16203
|
+
|
|
16204
|
+
// ../coding-core/dist/raw.js
|
|
16205
|
+
import path9 from "path";
|
|
16206
|
+
import os2 from "os";
|
|
16207
|
+
var SOURCE_ROOT_ENV_VARS = [
|
|
16208
|
+
"CLAUDE_PROJECTS_DIR",
|
|
16209
|
+
"CODEX_SESSIONS_DIR",
|
|
16210
|
+
"CURSOR_WORKSPACE_DIR",
|
|
16211
|
+
"CURSOR_PROJECTS_DIR",
|
|
16212
|
+
// Cursor's globalStorage dir (holds state.vscdb — the composer bubbles that
|
|
16213
|
+
// carry a Cursor session's real per-turn timestamps + content). Same
|
|
16214
|
+
// isolation contract: overriding any root disables every unset source.
|
|
16215
|
+
"CURSOR_GLOBAL_DIR"
|
|
16216
|
+
];
|
|
16217
|
+
var anyRootOverridden = () => SOURCE_ROOT_ENV_VARS.some((v) => !!process.env[v]);
|
|
16218
|
+
function resolveSourceRoot(envVar, ...defaultSegments) {
|
|
16219
|
+
const explicit = process.env[envVar];
|
|
16220
|
+
if (explicit)
|
|
16221
|
+
return explicit;
|
|
16222
|
+
if (anyRootOverridden())
|
|
16223
|
+
return null;
|
|
16224
|
+
return path9.join(os2.homedir(), ...defaultSegments);
|
|
16225
|
+
}
|
|
16226
|
+
var cursorGlobalRoot = () => resolveSourceRoot("CURSOR_GLOBAL_DIR", "Library", "Application Support", "Cursor", "User", "globalStorage");
|
|
16227
|
+
function cursorGlobalDbPath() {
|
|
16228
|
+
const root = cursorGlobalRoot();
|
|
16229
|
+
return root === null ? null : path9.join(root, "state.vscdb");
|
|
16230
|
+
}
|
|
16231
|
+
var MACHINE_CURSOR_FILE_RE = /^(.*[/\\]machines[/\\][^/\\]+[/\\]\.cursor)[/\\]projects[/\\]/;
|
|
16232
|
+
function cursorDbPathForFile(file2) {
|
|
16233
|
+
const m = file2.match(MACHINE_CURSOR_FILE_RE);
|
|
16234
|
+
if (m)
|
|
16235
|
+
return path9.join(m[1], "globalStorage", "state.vscdb");
|
|
16236
|
+
return cursorGlobalDbPath();
|
|
16237
|
+
}
|
|
16238
|
+
|
|
15814
16239
|
// ../coding-core/dist/messages.js
|
|
15815
16240
|
function extractText(content) {
|
|
15816
16241
|
if (typeof content === "string")
|
|
@@ -15822,13 +16247,51 @@ function extractText(content) {
|
|
|
15822
16247
|
function isToolResultOnly(content) {
|
|
15823
16248
|
return Array.isArray(content) && content.length > 0 && content.every((c) => c && typeof c === "object" && c.type === "tool_result");
|
|
15824
16249
|
}
|
|
16250
|
+
function extractUserMessagesCodex(raw) {
|
|
16251
|
+
const out = [];
|
|
16252
|
+
let lastTs = null;
|
|
16253
|
+
for (const ev of extractCodexEvents(raw)) {
|
|
16254
|
+
const t = ev.t;
|
|
16255
|
+
const gapMs = Number.isFinite(t) && lastTs != null ? t - lastTs : NaN;
|
|
16256
|
+
if (Number.isFinite(t))
|
|
16257
|
+
lastTs = t;
|
|
16258
|
+
if (ev.kind !== "user")
|
|
16259
|
+
continue;
|
|
16260
|
+
const text2 = humanTypedText(ev.text);
|
|
16261
|
+
if (text2 && Number.isFinite(t))
|
|
16262
|
+
out.push({ t, text: text2, gapMs });
|
|
16263
|
+
}
|
|
16264
|
+
return out.sort((a, b) => a.t - b.t);
|
|
16265
|
+
}
|
|
16266
|
+
function extractUserMessagesCursor(c) {
|
|
16267
|
+
const out = [];
|
|
16268
|
+
let lastTs = null;
|
|
16269
|
+
for (const turn of c.turns) {
|
|
16270
|
+
const t = turn.t;
|
|
16271
|
+
const gapMs = Number.isFinite(t) && lastTs != null ? t - lastTs : NaN;
|
|
16272
|
+
if (Number.isFinite(t))
|
|
16273
|
+
lastTs = t;
|
|
16274
|
+
if (turn.type !== 1)
|
|
16275
|
+
continue;
|
|
16276
|
+
const text2 = humanTypedText(turn.text);
|
|
16277
|
+
if (text2 && Number.isFinite(t))
|
|
16278
|
+
out.push({ t, text: text2, gapMs });
|
|
16279
|
+
}
|
|
16280
|
+
return out.sort((a, b) => a.t - b.t);
|
|
16281
|
+
}
|
|
15825
16282
|
async function extractUserMessages(file2) {
|
|
15826
16283
|
let raw;
|
|
15827
16284
|
try {
|
|
15828
|
-
raw = await
|
|
16285
|
+
raw = await fs6.readFile(file2, "utf-8");
|
|
15829
16286
|
} catch {
|
|
15830
16287
|
return [];
|
|
15831
16288
|
}
|
|
16289
|
+
if (sniffCodexRaw(raw))
|
|
16290
|
+
return extractUserMessagesCodex(raw);
|
|
16291
|
+
if (sniffCursorRaw(raw)) {
|
|
16292
|
+
const c = await loadCursorComposer(file2, raw, cursorDbPathForFile(file2));
|
|
16293
|
+
return c ? extractUserMessagesCursor(c) : [];
|
|
16294
|
+
}
|
|
15832
16295
|
const out = [];
|
|
15833
16296
|
const userTexts = /* @__PURE__ */ new Set();
|
|
15834
16297
|
const seenUuids = /* @__PURE__ */ new Set();
|
|
@@ -15875,11 +16338,11 @@ async function extractUserMessages(file2) {
|
|
|
15875
16338
|
}
|
|
15876
16339
|
|
|
15877
16340
|
// ../../lib/agents/coding/walkthrough.ts
|
|
15878
|
-
import { promises as
|
|
15879
|
-
import
|
|
16341
|
+
import { promises as fs7 } from "fs";
|
|
16342
|
+
import path10 from "path";
|
|
15880
16343
|
var IDLE_CAP_MS = 12 * 6e4;
|
|
15881
16344
|
async function readWalkthrough(outDir, sessionId) {
|
|
15882
|
-
return
|
|
16345
|
+
return fs7.readFile(path10.join(outDir, `${sessionId}.json`), "utf8").then(JSON.parse).catch(() => null);
|
|
15883
16346
|
}
|
|
15884
16347
|
|
|
15885
16348
|
// ../coding-core/dist/words.js
|
|
@@ -16291,7 +16754,7 @@ function computeWorkstyle(inp) {
|
|
|
16291
16754
|
|
|
16292
16755
|
// ../../lib/calibration/index.ts
|
|
16293
16756
|
var DEFAULT_CALIBRATION = {
|
|
16294
|
-
version: "2026-07-
|
|
16757
|
+
version: "2026-07-21.1",
|
|
16295
16758
|
// = RUBRIC_FINGERPRINT of the shipped npm rubric (packages/coding-analyzer/
|
|
16296
16759
|
// src/grade/criteria.ts). A unit test fails loud when the rubric changes
|
|
16297
16760
|
// without this being updated (and re-pushed to the server).
|
|
@@ -16387,13 +16850,14 @@ var DEFAULT_CALIBRATION = {
|
|
|
16387
16850
|
},
|
|
16388
16851
|
codingBenchmarks: {
|
|
16389
16852
|
flow: {
|
|
16390
|
-
// typical knowledge worker ≈ 35% of an 8h day focused; ~4h/day
|
|
16391
|
-
//
|
|
16853
|
+
// typical knowledge worker ≈ 35% of an 8h day focused; the ~4h/day
|
|
16854
|
+
// deep-work ceiling (Newport) sits nearer ~40% of a real (9-10h) top
|
|
16855
|
+
// performer's day — 50% overstated it (owner call 2026-07-21).
|
|
16392
16856
|
typicalPctOfDay: 0.35,
|
|
16393
|
-
topPctOfDay: 0.
|
|
16857
|
+
topPctOfDay: 0.4,
|
|
16394
16858
|
tag: "measured",
|
|
16395
|
-
source: "RescueTime 2019 (~2h48m focused/day) \xB7 Cal Newport, Deep Work (~4h/day deep-work ceiling)",
|
|
16396
|
-
line: "the best spend ~
|
|
16859
|
+
source: "RescueTime 2019 (~2h48m focused/day) \xB7 Cal Newport, Deep Work (~4h/day deep-work ceiling against a 9-10h day)",
|
|
16860
|
+
line: "the best spend ~40% of the workday in true deep flow; ~4h/day is the human ceiling"
|
|
16397
16861
|
},
|
|
16398
16862
|
longestRun: {
|
|
16399
16863
|
typicalHours: 0.67,
|
|
@@ -16442,13 +16906,20 @@ function bandLabel(score, doc = DEFAULT_CALIBRATION) {
|
|
|
16442
16906
|
for (const b of doc.scoreBands) if (b.score <= s && (!best || b.score > best.score)) best = b;
|
|
16443
16907
|
return (best ?? doc.scoreBands[0]).label;
|
|
16444
16908
|
}
|
|
16909
|
+
function scoreForTopPct(topPct, doc = DEFAULT_CALIBRATION) {
|
|
16910
|
+
for (const b of doc.scoreBands) {
|
|
16911
|
+
const x = parseFloat(b.label.replace(/^Top\s+/i, ""));
|
|
16912
|
+
if (Number.isFinite(x) && topPct <= x) return b.score;
|
|
16913
|
+
}
|
|
16914
|
+
return 1;
|
|
16915
|
+
}
|
|
16445
16916
|
|
|
16446
16917
|
// ../../lib/agents/coding/benchmarks.ts
|
|
16447
16918
|
var BEST = DEFAULT_CALIBRATION.codingBenchmarks;
|
|
16448
16919
|
|
|
16449
16920
|
// ../../lib/agents/coding/profile.ts
|
|
16450
16921
|
var ROOT = process.cwd();
|
|
16451
|
-
var CODING_DIR = process.env.POLYMATH_DATA_DIR ?
|
|
16922
|
+
var CODING_DIR = process.env.POLYMATH_DATA_DIR ? path11.join(process.env.POLYMATH_DATA_DIR, "coding") : path11.join(ROOT, ".data", "coding");
|
|
16452
16923
|
var UMETA = /* @__PURE__ */ new Map();
|
|
16453
16924
|
async function userMeta(sessionId, file2) {
|
|
16454
16925
|
const hit = UMETA.get(sessionId);
|
|
@@ -16458,9 +16929,9 @@ async function userMeta(sessionId, file2) {
|
|
|
16458
16929
|
UMETA.set(sessionId, meta);
|
|
16459
16930
|
return meta;
|
|
16460
16931
|
}
|
|
16461
|
-
var GRADES =
|
|
16932
|
+
var GRADES = path11.join(CODING_DIR, "grades");
|
|
16462
16933
|
async function readJson(p, fallback) {
|
|
16463
|
-
return
|
|
16934
|
+
return fs8.readFile(p, "utf8").then((s) => JSON.parse(s)).catch(() => fallback);
|
|
16464
16935
|
}
|
|
16465
16936
|
function cadenceScore(fraction, multiRatio) {
|
|
16466
16937
|
let s;
|
|
@@ -16488,21 +16959,39 @@ function distOf(takes) {
|
|
|
16488
16959
|
const hist = [...h.keys()].sort((a, b) => b - a).map((level) => ({ level, count: h.get(level) }));
|
|
16489
16960
|
return { n, observed, mean, median: median2, hist };
|
|
16490
16961
|
}
|
|
16962
|
+
var phi = (z) => {
|
|
16963
|
+
const t = 1 / (1 + 0.2316419 * Math.abs(z));
|
|
16964
|
+
const d = 0.3989423 * Math.exp(-z * z / 2);
|
|
16965
|
+
let pr = d * t * (0.3193815 + t * (-0.3565638 + t * (1.781478 + t * (-1.821256 + t * 1.330274))));
|
|
16966
|
+
if (z > 0) pr = 1 - pr;
|
|
16967
|
+
return pr;
|
|
16968
|
+
};
|
|
16969
|
+
var lognPct = (x, c) => x == null || !c || x <= 0 ? null : Math.min(99.9, Math.max(0.1, Math.round(phi(Math.log(x / c.median) / c.sigma) * 1e3) / 10));
|
|
16970
|
+
var NO_GRADES_GAP = "no sessions graded for this yet \u2014 this fills in once grading has run";
|
|
16971
|
+
function estimateRowParts(score, nTakes, evidenceGap) {
|
|
16972
|
+
return nTakes === 0 && score == null ? { score: null, gap: NO_GRADES_GAP } : { score, gap: evidenceGap };
|
|
16973
|
+
}
|
|
16974
|
+
function verdictRowParts(v, fallback) {
|
|
16975
|
+
if (!v) return fallback;
|
|
16976
|
+
const ranged = v.confidence === "provisional" || (v.qualifying ?? 0) < 2;
|
|
16977
|
+
if (ranged) return { score: null, gap: `best ${v.best} inside an honest ${v.low}-${v.high} range so far. ${v.verdictLine} (${v.statsLine})`.trim() };
|
|
16978
|
+
return { score: v.best, gap: `${v.verdictLine} (${v.statsLine})`.trim() };
|
|
16979
|
+
}
|
|
16491
16980
|
async function compileCodingProfile() {
|
|
16492
|
-
const allRecords = await readJson(
|
|
16981
|
+
const allRecords = await readJson(path11.join(CODING_DIR, "sessions.json"), []);
|
|
16493
16982
|
const dupIds = new Set(allRecords.filter((s) => s.duplicateOf).map((s) => s.sessionId));
|
|
16494
16983
|
const sessions = allRecords.filter((s) => !s.duplicateOf);
|
|
16495
|
-
const conc = await readJson(
|
|
16496
|
-
const renames = await readJson(
|
|
16984
|
+
const conc = await readJson(path11.join(CODING_DIR, "concurrency.json"), null);
|
|
16985
|
+
const renames = await readJson(path11.join(CODING_DIR, "renames.json"), []);
|
|
16497
16986
|
const byId = new Map(sessions.map((s) => [s.sessionId, s]));
|
|
16498
16987
|
let gradeFiles = [];
|
|
16499
16988
|
try {
|
|
16500
|
-
gradeFiles = (await
|
|
16989
|
+
gradeFiles = (await fs8.readdir(GRADES)).filter((f) => f.endsWith(".json"));
|
|
16501
16990
|
} catch {
|
|
16502
16991
|
}
|
|
16503
16992
|
const grades = [];
|
|
16504
16993
|
for (const f of gradeFiles) {
|
|
16505
|
-
const g = await readJson(
|
|
16994
|
+
const g = await readJson(path11.join(GRADES, f), null);
|
|
16506
16995
|
if (g && byId.has(g.sessionId)) grades.push(g);
|
|
16507
16996
|
}
|
|
16508
16997
|
const takesByCriterion = /* @__PURE__ */ new Map();
|
|
@@ -16579,9 +17068,12 @@ async function compileCodingProfile() {
|
|
|
16579
17068
|
const timeline = [...dayMap.values()].sort((a, b) => b.date.localeCompare(a.date));
|
|
16580
17069
|
const levelHist = conc?.levelHistogramMin ?? {};
|
|
16581
17070
|
const sumFrom = (min) => Object.entries(levelHist).filter(([k]) => Number(k) >= min).reduce((a, [, v]) => a + v, 0);
|
|
17071
|
+
const totalParallelMin = Object.values(levelHist).reduce((a, v) => a + v, 0);
|
|
17072
|
+
const avgConcurrency = totalParallelMin > 0 ? Math.round(Object.entries(levelHist).reduce((a, [k, v]) => a + Number(k) * v, 0) / totalParallelMin * 10) / 10 : 0;
|
|
16582
17073
|
const topWindows = (conc?.segments ?? []).slice().sort((a, b) => b.level - a.level || b.minutes - a.minutes).slice(0, 12).map((s) => ({ start: s.start, end: s.end, minutes: s.minutes, level: s.level, titles: [...new Set(s.sessions.map((x) => x.title))] }));
|
|
16583
17074
|
const parallelism = {
|
|
16584
17075
|
maxConcurrency: conc?.maxConcurrency ?? 0,
|
|
17076
|
+
avgConcurrency,
|
|
16585
17077
|
levelHistogramMin: levelHist,
|
|
16586
17078
|
minutesAt2plus: Math.round(sumFrom(2)),
|
|
16587
17079
|
minutesAt6plus: Math.round(sumFrom(6)),
|
|
@@ -16611,13 +17103,13 @@ async function compileCodingProfile() {
|
|
|
16611
17103
|
models: Object.fromEntries([...models.entries()].sort((a, b) => b[1] - a[1])),
|
|
16612
17104
|
lateNightSessions: lateNight
|
|
16613
17105
|
};
|
|
16614
|
-
const agglomeration = await readJson(
|
|
16615
|
-
const dayDigest = await readJson(
|
|
17106
|
+
const agglomeration = await readJson(path11.join(CODING_DIR, "agglomerate.json"), null);
|
|
17107
|
+
const dayDigest = await readJson(path11.join(CODING_DIR, "day-digest.json"), null);
|
|
16616
17108
|
if (dayDigest?.days) dayDigest.days = dayDigest.days.map((day) => {
|
|
16617
17109
|
const convs = day.conversations.filter((c) => byId.has(c.sessionId));
|
|
16618
17110
|
return { ...day, conversations: convs, conversationsTouched: convs.length, totalMessages: convs.reduce((a, c) => a + c.messageCount, 0) };
|
|
16619
17111
|
}).filter((day) => day.conversations.length > 0);
|
|
16620
|
-
const dayChart = await readJson(
|
|
17112
|
+
const dayChart = await readJson(path11.join(CODING_DIR, "day-chart.json"), []);
|
|
16621
17113
|
const intervalsBy = /* @__PURE__ */ new Map();
|
|
16622
17114
|
const titleBy = /* @__PURE__ */ new Map();
|
|
16623
17115
|
const fileById = new Map(sessions.map((s) => [s.sessionId, s.file]));
|
|
@@ -16636,8 +17128,8 @@ async function compileCodingProfile() {
|
|
|
16636
17128
|
return ms;
|
|
16637
17129
|
};
|
|
16638
17130
|
const walkthroughs = {};
|
|
16639
|
-
const wdir =
|
|
16640
|
-
for (const f of await
|
|
17131
|
+
const wdir = path11.join(CODING_DIR, "walkthroughs");
|
|
17132
|
+
for (const f of await fs8.readdir(wdir).catch(() => [])) {
|
|
16641
17133
|
if (!f.endsWith(".json")) continue;
|
|
16642
17134
|
const w = await readWalkthrough(wdir, f.replace(".json", ""));
|
|
16643
17135
|
if (!w || !byId.has(w.sessionId)) continue;
|
|
@@ -16684,17 +17176,19 @@ async function compileCodingProfile() {
|
|
|
16684
17176
|
const tCeiling = throughputCeiling(Object.values(wordsByDay));
|
|
16685
17177
|
const criteriaMean = {};
|
|
16686
17178
|
for (const c of criteria) criteriaMean[c.key] = { mean: c.dist.mean, n: c.dist.n };
|
|
16687
|
-
const flow = await readJson(
|
|
16688
|
-
const focus = await readJson(
|
|
16689
|
-
const expertiseMap = await readJson(
|
|
16690
|
-
const frontierArsenal = await readJson(
|
|
16691
|
-
const frontierDetail = await readJson(
|
|
16692
|
-
const coaching = await readJson(
|
|
16693
|
-
const gap = await readJson(
|
|
16694
|
-
const aggregate = await readJson(
|
|
16695
|
-
const delegationRollup = await readJson(
|
|
16696
|
-
const gapDist = await readJson(
|
|
16697
|
-
const projects = await readJson(
|
|
17179
|
+
const flow = await readJson(path11.join(CODING_DIR, "flow.json"), null);
|
|
17180
|
+
const focus = await readJson(path11.join(CODING_DIR, "focus.json"), null);
|
|
17181
|
+
const expertiseMap = await readJson(path11.join(CODING_DIR, "expertise.json"), null);
|
|
17182
|
+
const frontierArsenal = await readJson(path11.join(CODING_DIR, "frontier.json"), null);
|
|
17183
|
+
const frontierDetail = await readJson(path11.join(CODING_DIR, "frontier-detail.json"), null);
|
|
17184
|
+
const coaching = await readJson(path11.join(CODING_DIR, "coaching.json"), null);
|
|
17185
|
+
const gap = await readJson(path11.join(CODING_DIR, "gap.json"), null);
|
|
17186
|
+
const aggregate = await readJson(path11.join(CODING_DIR, "aggregate.json"), null);
|
|
17187
|
+
const delegationRollup = await readJson(path11.join(CODING_DIR, "delegation-rollup.json"), null);
|
|
17188
|
+
const gapDist = await readJson(path11.join(CODING_DIR, "gap-dist.json"), null);
|
|
17189
|
+
const projects = await readJson(path11.join(CODING_DIR, "projects.json"), null);
|
|
17190
|
+
const growth = await readJson(path11.join(CODING_DIR, "growth.json"), null);
|
|
17191
|
+
const workbrief = await readJson(path11.join(CODING_DIR, "workbrief.json"), null);
|
|
16698
17192
|
const workstyle = computeWorkstyle({
|
|
16699
17193
|
dayChart,
|
|
16700
17194
|
tz,
|
|
@@ -16742,15 +17236,11 @@ async function compileCodingProfile() {
|
|
|
16742
17236
|
const unb = ceilOf("unblocking");
|
|
16743
17237
|
const agency = out2 != null && unb != null ? Math.round((out2 + unb) / 2) : out2 ?? unb;
|
|
16744
17238
|
const sRow = (label, score, gap2) => ({ label, score, percentile: pctOf(score), gap: gap2 });
|
|
16745
|
-
const
|
|
16746
|
-
|
|
16747
|
-
|
|
16748
|
-
const d = 0.3989423 * Math.exp(-z * z / 2);
|
|
16749
|
-
let pr = d * t * (0.3193815 + t * (-0.3565638 + t * (1.781478 + t * (-1.821256 + t * 1.330274))));
|
|
16750
|
-
if (z > 0) pr = 1 - pr;
|
|
16751
|
-
return pr;
|
|
17239
|
+
const est = (label, score, key, evidenceGap) => {
|
|
17240
|
+
const e = estimateRowParts(score, nTk(key), evidenceGap);
|
|
17241
|
+
return sRow(label, e.score, e.gap);
|
|
16752
17242
|
};
|
|
16753
|
-
const
|
|
17243
|
+
const tiers = DEFAULT_CALIBRATION.codingTiers;
|
|
16754
17244
|
const avgWords = aggregate?.throughput?.avgWordsPerDay ?? null;
|
|
16755
17245
|
const pushPctl = lognPct(avgWords, tiers?.push);
|
|
16756
17246
|
const focusPctl = lognPct(flowPctDay, tiers?.focus);
|
|
@@ -16758,21 +17248,37 @@ async function compileCodingProfile() {
|
|
|
16758
17248
|
const hoursPctl = lognPct(workDayHrs, tiers?.hours);
|
|
16759
17249
|
const hoursAt = (min) => Object.entries(pHist).reduce((a, [k, v]) => Number(k) >= min ? a + v : a, 0) / 60;
|
|
16760
17250
|
const orchPctl = hoursAt(5) >= 5 || hoursAt(3) >= 10 && parallelism.queueOps >= 1e3 ? 99.5 : hoursAt(3) >= 10 ? 99 : hoursAt(2) >= 0.1 * (soloMin + parMin) / 60 ? 97 : hoursAt(2) >= 2 ? 90 : 70;
|
|
17251
|
+
const estScore = (pctl) => pctl == null ? null : scoreForTopPct(100 - pctl);
|
|
16761
17252
|
const stackUp = [
|
|
17253
|
+
// The subtext leads with the AVERAGE — that is the number this row is
|
|
17254
|
+
// scored and pool-ranked on (wordsPerDay); a peak-led line once shipped
|
|
17255
|
+
// next to an average-based rank and read as a mismatch (owner call
|
|
17256
|
+
// 2026-07-21). The peak rides along as color.
|
|
16762
17257
|
sRow(
|
|
16763
17258
|
"How hard you push",
|
|
16764
|
-
aggregate?.throughput?.score ?? tCeiling,
|
|
16765
|
-
`you
|
|
17259
|
+
estScore(pushPctl) ?? aggregate?.throughput?.score ?? tCeiling,
|
|
17260
|
+
avgWords != null ? `you average ~${Math.round(avgWords).toLocaleString()} words of pure direction a day (peak day ~${peakWords.toLocaleString()}) \u2014 the very top sustain ~${BEST.throughput.topAvgWordsPerDay.toLocaleString()} every day, week after week; the wildest single days on record push ~${BEST.throughput.topPeakWordsPerDay.toLocaleString()}` : `you peak at ~${peakWords.toLocaleString()} words of pure direction in a single day \u2014 the very top sustain ~${BEST.throughput.topAvgWordsPerDay.toLocaleString()} every day, week after week`
|
|
16766
17261
|
),
|
|
17262
|
+
// Graded like its siblings from the SAME fitted hours curve that ranks it
|
|
17263
|
+
// (tiers.hours → hoursPctl → estScore) and feeds the shared pool, so the
|
|
17264
|
+
// 1-11 badge can never contradict the pooled rank. Was `null` until
|
|
17265
|
+
// 2026-07-21, which left this the only measured row with no grade shown —
|
|
17266
|
+
// it read as broken next to push/parallelism/focus (owner call).
|
|
16767
17267
|
sRow(
|
|
16768
17268
|
"Hours you put in",
|
|
16769
|
-
|
|
17269
|
+
estScore(hoursPctl),
|
|
16770
17270
|
workDayHrs != null ? `~${workDayHrs}h of active building on a typical work day \u2014 engaged builders average ~3h, and sustaining 7h+ day after day, week after week, is top-1% territory` : "not enough dated activity yet to measure a typical work day"
|
|
16771
17271
|
),
|
|
17272
|
+
// The copy FOLLOWS the person's actual orchestration band (orchPctl above) —
|
|
17273
|
+
// a hardcoded "single biggest speed-up still on the table" once shipped to a
|
|
17274
|
+
// user at orchPctl 99.5 (18 agents peak, 48% of hours at 2+), flatly
|
|
17275
|
+
// contradicting the gap section's "already strong" on the same page
|
|
17276
|
+
// (2026-07-17). The still-on-the-table claim is reserved for genuinely low
|
|
17277
|
+
// orchestration.
|
|
16772
17278
|
sRow(
|
|
16773
17279
|
"Your AI parallelism",
|
|
16774
|
-
|
|
16775
|
-
soloPct != null ? `~${soloPct}% of your hours you drive a single agent (${Math.round(soloMin / 60)}h solo vs ${Math.round(parMin / 60)}h with 2+ live) \u2014 the Claude Code lead keeps 10\u201315 going at once, so this is the single biggest speed-up still on the table` : "you brief the AI sharply, but mostly drive one agent at a time \u2014 the top run 10\u201315 in parallel, a several-fold speed-up"
|
|
17280
|
+
estScore(orchPctl),
|
|
17281
|
+
soloPct != null ? orchPctl >= 97 ? `you already run parallel at the frontier \u2014 ${Math.round(parMin / 60)}h of your hours with 2+ agents live vs ${Math.round(soloMin / 60)}h solo; the Claude Code lead keeps 10\u201315 going at once, and you work the same way` : `~${soloPct}% of your hours you drive a single agent (${Math.round(soloMin / 60)}h solo vs ${Math.round(parMin / 60)}h with 2+ live) \u2014 the Claude Code lead keeps 10\u201315 going at once, so this is the single biggest speed-up still on the table` : "you brief the AI sharply, but mostly drive one agent at a time \u2014 the top run 10\u201315 in parallel, a several-fold speed-up"
|
|
16776
17282
|
),
|
|
16777
17283
|
// The evidence line cites the RANKING metric (flow as a share of the work
|
|
16778
17284
|
// day), never absolute hours — a friend with MORE flow hours over a longer
|
|
@@ -16782,28 +17288,31 @@ async function compileCodingProfile() {
|
|
|
16782
17288
|
// the volume of hours is its own chip above.
|
|
16783
17289
|
sRow(
|
|
16784
17290
|
"Focus quality when you work",
|
|
16785
|
-
focusScore,
|
|
17291
|
+
estScore(focusPctl) ?? focusScore,
|
|
16786
17292
|
flowPctDay != null ? `~${Math.round(flowPctDay * 100)}% of your work day is true deep flow${flowHrsDay != null ? ` (~${flowHrsDay}h)` : ""} \u2014 the very best hold ~${Math.round(BEST.flow.topPctOfDay * 100)}% of theirs in one unbroken block; yours fragments across parallel sessions, so the gain is directing your attention at one thread for longer` : "your attention scatters across parallel sessions \u2014 directing it at one thread for longer is the unlock"
|
|
16787
17293
|
),
|
|
16788
17294
|
// The four estimates LEAD with a concrete moment from their own sessions, then an
|
|
16789
17295
|
// HONEST caveat — how many graded sessions back the read. No invented weakness, no
|
|
16790
17296
|
// claim about what they "didn't" do (false specifics churn a real user); it's an estimate.
|
|
16791
|
-
|
|
17297
|
+
est(
|
|
16792
17298
|
"Agency",
|
|
16793
17299
|
agency,
|
|
17300
|
+
"outcomes",
|
|
16794
17301
|
`${proud("outcomes", "you ship working systems and unblock yourself")} \u2014 one of ${nTk("outcomes")} sessions behind this read; a strong, consistent signal, still an estimate from your logs`
|
|
16795
17302
|
),
|
|
16796
17303
|
// Judgement/Taste use the SAME numbers their ability cards prove (aggregate
|
|
16797
17304
|
// peak-with-consistency over near-peak instances) — a chip saying "top 1%"
|
|
16798
17305
|
// above a card proving 10/Top 0.1% with ten receipts reads as a bug.
|
|
16799
|
-
|
|
17306
|
+
est(
|
|
16800
17307
|
"Judgement",
|
|
16801
17308
|
aggregate?.ability?.abstraction?.score ?? ceilOf("generative"),
|
|
17309
|
+
"generative",
|
|
16802
17310
|
`${proud("generative", "you make sharp, non-obvious calls on what actually matters")} \u2014 one of ${nTk("generative")} sessions we've graded for this; clear so far, not yet a final verdict`
|
|
16803
17311
|
),
|
|
16804
|
-
|
|
17312
|
+
est(
|
|
16805
17313
|
"Taste",
|
|
16806
17314
|
aggregate?.ability?.taste?.score ?? ceilOf("taste"),
|
|
17315
|
+
"taste",
|
|
16807
17316
|
`${proud("taste", "you hold a high, opinionated quality bar")} \u2014 one of ${nTk("taste")} sessions behind this read; a real signal, still an estimate`
|
|
16808
17317
|
)
|
|
16809
17318
|
// Expertise: NO chip — the scored criterion is deprecated; the real judge is
|
|
@@ -16828,24 +17337,39 @@ async function compileCodingProfile() {
|
|
|
16828
17337
|
}
|
|
16829
17338
|
if (r.label === "Your AI parallelism") r.percentile = orchPctl;
|
|
16830
17339
|
}
|
|
16831
|
-
|
|
17340
|
+
if (agglomeration?.verdicts) {
|
|
17341
|
+
const byLabel = {
|
|
17342
|
+
Judgement: agglomeration.verdicts.judgement,
|
|
17343
|
+
Agency: agglomeration.verdicts.agency,
|
|
17344
|
+
Taste: agglomeration.verdicts.taste
|
|
17345
|
+
};
|
|
17346
|
+
for (const r of stackUp) {
|
|
17347
|
+
const v = byLabel[r.label];
|
|
17348
|
+
if (!v) continue;
|
|
17349
|
+
const p = verdictRowParts(v, { score: r.score, gap: r.gap });
|
|
17350
|
+
r.score = p.score;
|
|
17351
|
+
r.gap = p.gap;
|
|
17352
|
+
r.percentile = pctOf(p.score);
|
|
17353
|
+
}
|
|
17354
|
+
}
|
|
17355
|
+
return { generatedAt: (/* @__PURE__ */ new Date()).toISOString(), gradedSessions: grades.length, agglomeration, outcomeCadence, dayDigest, dayChart, timeline, walkthroughs, rubric, wordsByDay, dayThroughput, throughputCeiling: tCeiling, stackUp, criteria, parallelism, throughput, workstyle, flow, focus, expertiseMap, frontierArsenal, frontierDetail, coaching, gap, aggregate, delegationRollup, gapDist, projects, growth, workbrief };
|
|
16832
17356
|
}
|
|
16833
17357
|
|
|
16834
17358
|
// ../../lib/agents/coding/assets.ts
|
|
16835
|
-
import { promises as
|
|
16836
|
-
import
|
|
17359
|
+
import { promises as fs9 } from "fs";
|
|
17360
|
+
import path12 from "path";
|
|
16837
17361
|
import { fileURLToPath } from "url";
|
|
16838
|
-
var MODULE_DIR =
|
|
17362
|
+
var MODULE_DIR = path12.dirname(fileURLToPath(import.meta.url));
|
|
16839
17363
|
async function readCodingAsset(name17) {
|
|
16840
17364
|
const candidates = [
|
|
16841
|
-
|
|
17365
|
+
path12.join(MODULE_DIR, name17),
|
|
16842
17366
|
// dev: beside this file · bundled: beside the bundle
|
|
16843
|
-
|
|
17367
|
+
path12.resolve("lib", "agents", "coding", name17)
|
|
16844
17368
|
// legacy cwd-relative (repo-root cwd)
|
|
16845
17369
|
];
|
|
16846
17370
|
for (const p of candidates) {
|
|
16847
17371
|
try {
|
|
16848
|
-
return { text: await
|
|
17372
|
+
return { text: await fs9.readFile(p, "utf8"), path: p };
|
|
16849
17373
|
} catch {
|
|
16850
17374
|
}
|
|
16851
17375
|
}
|
|
@@ -16855,12 +17379,12 @@ async function readCodingAsset(name17) {
|
|
|
16855
17379
|
}
|
|
16856
17380
|
|
|
16857
17381
|
// ../../lib/agents/coding/docsDir.ts
|
|
16858
|
-
import { promises as
|
|
16859
|
-
import
|
|
17382
|
+
import { promises as fs11 } from "fs";
|
|
17383
|
+
import path13 from "path";
|
|
16860
17384
|
|
|
16861
17385
|
// ../../lib/agents/coding/materialize.ts
|
|
16862
|
-
import { promises as
|
|
16863
|
-
var
|
|
17386
|
+
import { promises as fs10 } from "fs";
|
|
17387
|
+
var SYSTEM_REMINDER_RE3 = /<system-reminder>[\s\S]*?<\/system-reminder>/g;
|
|
16864
17388
|
var INJECT_GIST = 120;
|
|
16865
17389
|
var INJECTED = [
|
|
16866
17390
|
{ re: /<task-notification>[\s\S]*?<\/task-notification>/g, label: "bg task", gistRe: /<summary>([\s\S]*?)<\/summary>/ },
|
|
@@ -16880,7 +17404,7 @@ function collapseInjected(input) {
|
|
|
16880
17404
|
return "";
|
|
16881
17405
|
});
|
|
16882
17406
|
}
|
|
16883
|
-
return { text: text2.replace(
|
|
17407
|
+
return { text: text2.replace(SYSTEM_REMINDER_RE3, "").trim(), markers };
|
|
16884
17408
|
}
|
|
16885
17409
|
function extractText2(content) {
|
|
16886
17410
|
if (typeof content === "string") return content;
|
|
@@ -16896,14 +17420,52 @@ function extractText2(content) {
|
|
|
16896
17420
|
function isToolResultOnly2(content) {
|
|
16897
17421
|
return Array.isArray(content) && content.length > 0 && content.every((c) => c && typeof c === "object" && c.type === "tool_result");
|
|
16898
17422
|
}
|
|
16899
|
-
var
|
|
17423
|
+
var AI_GIST2 = 160;
|
|
17424
|
+
function materializeCodex(raw) {
|
|
17425
|
+
const lines = [];
|
|
17426
|
+
let humanTurns = 0, humanChars = 0;
|
|
17427
|
+
let aiLastProse = "";
|
|
17428
|
+
const aiTools = /* @__PURE__ */ new Map();
|
|
17429
|
+
const flushAI = () => {
|
|
17430
|
+
if (!aiLastProse && aiTools.size === 0) return;
|
|
17431
|
+
const tools = [...aiTools.entries()].map(([n, c]) => c > 1 ? `${n}\xD7${c}` : n).join(", ");
|
|
17432
|
+
const gist = aiLastProse ? aiLastProse.length > AI_GIST2 ? aiLastProse.slice(0, AI_GIST2) + "\u2026" : aiLastProse : "";
|
|
17433
|
+
const bits = [];
|
|
17434
|
+
if (gist) bits.push(gist);
|
|
17435
|
+
if (tools) bits.push(`ran ${tools}`);
|
|
17436
|
+
lines.push(`[AI: ${bits.join(" \xB7 ")}]`);
|
|
17437
|
+
aiLastProse = "";
|
|
17438
|
+
aiTools.clear();
|
|
17439
|
+
};
|
|
17440
|
+
for (const ev of extractCodexEvents(raw)) {
|
|
17441
|
+
if (ev.kind === "user") {
|
|
17442
|
+
flushAI();
|
|
17443
|
+
humanTurns++;
|
|
17444
|
+
humanChars += ev.text.length;
|
|
17445
|
+
lines.push(`>> ${ev.text}`);
|
|
17446
|
+
} else if (ev.kind === "assistant") {
|
|
17447
|
+
const prose = ev.text.replace(/\s+/g, " ").trim();
|
|
17448
|
+
if (prose) aiLastProse = prose;
|
|
17449
|
+
} else if (ev.kind === "tool") {
|
|
17450
|
+
aiTools.set(ev.name, (aiTools.get(ev.name) ?? 0) + 1);
|
|
17451
|
+
}
|
|
17452
|
+
}
|
|
17453
|
+
flushAI();
|
|
17454
|
+
return { text: lines.join("\n"), humanTurns, humanChars };
|
|
17455
|
+
}
|
|
17456
|
+
async function materializeCursor(file2, raw) {
|
|
17457
|
+
const composer = await loadCursorComposer(file2, raw, cursorDbPathForFile(file2));
|
|
17458
|
+
return composer ? renderCursorTranscript(composer) : { text: "", humanTurns: 0, humanChars: 0 };
|
|
17459
|
+
}
|
|
16900
17460
|
async function materializeSession(file2) {
|
|
16901
17461
|
let raw;
|
|
16902
17462
|
try {
|
|
16903
|
-
raw = await
|
|
17463
|
+
raw = await fs10.readFile(file2, "utf-8");
|
|
16904
17464
|
} catch {
|
|
16905
17465
|
return null;
|
|
16906
17466
|
}
|
|
17467
|
+
if (sniffCodexRaw(raw)) return materializeCodex(raw);
|
|
17468
|
+
if (sniffCursorRaw(raw)) return materializeCursor(file2, raw);
|
|
16907
17469
|
const lines = [];
|
|
16908
17470
|
let humanTurns = 0, humanChars = 0;
|
|
16909
17471
|
const pendingQueued = [];
|
|
@@ -16916,7 +17478,7 @@ async function materializeSession(file2) {
|
|
|
16916
17478
|
const flushAI = () => {
|
|
16917
17479
|
if (!aiLastProse && aiTools.size === 0) return;
|
|
16918
17480
|
const tools = [...aiTools.entries()].map(([n, c]) => c > 1 ? `${n}\xD7${c}` : n).join(", ");
|
|
16919
|
-
const gist = aiLastProse ? aiLastProse.length >
|
|
17481
|
+
const gist = aiLastProse ? aiLastProse.length > AI_GIST2 ? aiLastProse.slice(0, AI_GIST2) + "\u2026" : aiLastProse : "";
|
|
16920
17482
|
const bits = [];
|
|
16921
17483
|
if (gist) bits.push(gist);
|
|
16922
17484
|
if (tools) bits.push(`ran ${tools}`);
|
|
@@ -16996,10 +17558,10 @@ async function materializeSession(file2) {
|
|
|
16996
17558
|
|
|
16997
17559
|
// ../../lib/agents/coding/docsDir.ts
|
|
16998
17560
|
async function writeScoreboard(codingDir, docs) {
|
|
16999
|
-
const gradesDir =
|
|
17561
|
+
const gradesDir = path13.join(codingDir, "grades");
|
|
17000
17562
|
let files = [];
|
|
17001
17563
|
try {
|
|
17002
|
-
files = (await
|
|
17564
|
+
files = (await fs11.readdir(gradesDir)).filter((f) => f.endsWith(".json")).sort();
|
|
17003
17565
|
} catch {
|
|
17004
17566
|
return;
|
|
17005
17567
|
}
|
|
@@ -17007,7 +17569,7 @@ async function writeScoreboard(codingDir, docs) {
|
|
|
17007
17569
|
for (const f of files) {
|
|
17008
17570
|
let g;
|
|
17009
17571
|
try {
|
|
17010
|
-
g = JSON.parse(await
|
|
17572
|
+
g = JSON.parse(await fs11.readFile(path13.join(gradesDir, f), "utf8"));
|
|
17011
17573
|
} catch {
|
|
17012
17574
|
continue;
|
|
17013
17575
|
}
|
|
@@ -17023,8 +17585,8 @@ async function writeScoreboard(codingDir, docs) {
|
|
|
17023
17585
|
([key, rows]) => `## ${key}
|
|
17024
17586
|
${rows.sort((a, b) => b.s - a.s).map((r) => r.line).join("\n")}`
|
|
17025
17587
|
);
|
|
17026
|
-
await
|
|
17027
|
-
|
|
17588
|
+
await fs11.writeFile(
|
|
17589
|
+
path13.join(docs, "_scoreboard.md"),
|
|
17028
17590
|
`# Scoreboard \u2014 every graded session per criterion, best first.
|
|
17029
17591
|
# Lx~ = estimate. Format: level \xB7 date \xB7 title \xB7 sessionId \u2014 graded instance.
|
|
17030
17592
|
|
|
@@ -17033,24 +17595,24 @@ ${blocks.join("\n\n")}
|
|
|
17033
17595
|
);
|
|
17034
17596
|
}
|
|
17035
17597
|
async function ensureCodingDocs(codingDir, sessions) {
|
|
17036
|
-
const docs =
|
|
17037
|
-
await
|
|
17598
|
+
const docs = path13.join(codingDir, "docs");
|
|
17599
|
+
await fs11.mkdir(docs, { recursive: true });
|
|
17038
17600
|
const user = sessions.filter((s) => s.sessionId && !s.duplicateOf && (!("klass" in s) || s.klass === "interactive"));
|
|
17039
17601
|
let written = 0;
|
|
17040
17602
|
for (const s of user) {
|
|
17041
|
-
const out =
|
|
17603
|
+
const out = path13.join(docs, `${s.sessionId}.txt`);
|
|
17042
17604
|
try {
|
|
17043
|
-
await
|
|
17605
|
+
await fs11.access(out);
|
|
17044
17606
|
continue;
|
|
17045
17607
|
} catch {
|
|
17046
17608
|
}
|
|
17047
17609
|
const mat = await materializeSession(s.file).catch(() => null);
|
|
17048
17610
|
if (!mat?.text) continue;
|
|
17049
|
-
await
|
|
17611
|
+
await fs11.writeFile(out, mat.text);
|
|
17050
17612
|
written++;
|
|
17051
17613
|
}
|
|
17052
17614
|
const rows = user.sort((a, b) => (a.start ?? "") < (b.start ?? "") ? -1 : 1).map((s) => `${(s.start ?? "").slice(0, 10)} \xB7 ${(s.title ?? "").replace(/\n.*/s, "").slice(0, 80)} \xB7 ${s.sessionId}`);
|
|
17053
|
-
await
|
|
17615
|
+
await fs11.writeFile(path13.join(docs, "_map.md"), rows.join("\n") + "\n");
|
|
17054
17616
|
await writeScoreboard(codingDir, docs);
|
|
17055
17617
|
if (written) console.log(`[docs] materialized ${written} new transcript(s) \u2192 ${docs}`);
|
|
17056
17618
|
return docs;
|
|
@@ -17063,7 +17625,7 @@ SOURCE LOOKUP \u2014 you have Read/Grep/Glob over the working directory, which h
|
|
|
17063
17625
|
|
|
17064
17626
|
// ../../lib/agents/coding/promptCache.ts
|
|
17065
17627
|
import { createHash as createHash2 } from "crypto";
|
|
17066
|
-
import { promises as
|
|
17628
|
+
import { promises as fs12 } from "fs";
|
|
17067
17629
|
function promptSha(parts) {
|
|
17068
17630
|
const h = createHash2("sha256");
|
|
17069
17631
|
for (const p of parts) {
|
|
@@ -17074,7 +17636,7 @@ function promptSha(parts) {
|
|
|
17074
17636
|
}
|
|
17075
17637
|
async function reusableOutput(outPath, sha, valid, key = "promptSha") {
|
|
17076
17638
|
try {
|
|
17077
|
-
const o = JSON.parse(await
|
|
17639
|
+
const o = JSON.parse(await fs12.readFile(outPath, "utf8"));
|
|
17078
17640
|
if (o[key] === sha && valid(o)) return o;
|
|
17079
17641
|
} catch {
|
|
17080
17642
|
}
|
|
@@ -17094,7 +17656,7 @@ var CLAUDE_AUTO_CAP = /* @__PURE__ */ new Set(["queue-ahead", "deferred-tools",
|
|
|
17094
17656
|
var CLAUDE_AUTO_MCP = /^(visualize|Claude[_ ]?Preview|ccd[_ ]?session|ccd[_ ]?session[_ ]?mgmt|mcp[_ ]?registry)$/i;
|
|
17095
17657
|
async function entrypointOf(file2) {
|
|
17096
17658
|
try {
|
|
17097
|
-
const head = (await
|
|
17659
|
+
const head = (await fs13.readFile(file2, "utf8")).slice(0, 2e4);
|
|
17098
17660
|
if (/[\/."]\.?conductor/i.test(head)) return "conductor";
|
|
17099
17661
|
const m = /"entrypoint":"([^"]+)"/.exec(head);
|
|
17100
17662
|
return m ? m[1] : "unknown";
|
|
@@ -17116,25 +17678,15 @@ var MOBILE_WEB = /^claude-(web|mobile|ios|android)$/;
|
|
|
17116
17678
|
function sumTool(recs, name17) {
|
|
17117
17679
|
return recs.reduce((a, s) => a + (s.toolCounts?.[name17] ?? 0), 0);
|
|
17118
17680
|
}
|
|
17119
|
-
var LOCK =
|
|
17120
|
-
var lockHeld = false;
|
|
17121
|
-
async function acquireLock() {
|
|
17122
|
-
try {
|
|
17123
|
-
await fs11.writeFile(LOCK, String(process.pid), { flag: "wx" });
|
|
17124
|
-
lockHeld = true;
|
|
17125
|
-
} catch {
|
|
17126
|
-
const pid = await fs11.readFile(LOCK, "utf8").catch(() => "?");
|
|
17127
|
-
throw new Error(`another coding-gap run appears active (pid ${pid}, ${LOCK}). Wait for it or delete the lock if it's stale \u2014 concurrent runs overwrite each other's gap.json.`);
|
|
17128
|
-
}
|
|
17129
|
-
}
|
|
17681
|
+
var LOCK = path14.join(CODING, ".gap.lock");
|
|
17130
17682
|
async function main() {
|
|
17131
|
-
await
|
|
17683
|
+
releaseLock = await acquireStageLock(LOCK, "coding-gap");
|
|
17132
17684
|
const p = await compileCodingProfile();
|
|
17133
17685
|
const techniquesAsset = await readCodingAsset("TECHNIQUES.md");
|
|
17134
17686
|
const techniques = techniquesAsset.text;
|
|
17135
|
-
console.log(` rubric: ${techniquesAsset.path} (${(await
|
|
17687
|
+
console.log(` rubric: ${techniquesAsset.path} (${(await fs13.stat(techniquesAsset.path)).mtime.toISOString()})`);
|
|
17136
17688
|
const writing = (await readCodingAsset("WRITING.md")).text;
|
|
17137
|
-
const all = JSON.parse(await
|
|
17689
|
+
const all = JSON.parse(await fs13.readFile(path14.join(CODING, "sessions.json"), "utf8"));
|
|
17138
17690
|
const interactive = all.filter((s) => s.klass === "interactive" && s.start);
|
|
17139
17691
|
const latestMs = Math.max(...interactive.map((s) => Date.parse(s.start)));
|
|
17140
17692
|
const cutoffMs = latestMs - 14 * 864e5;
|
|
@@ -17191,7 +17743,7 @@ async function main() {
|
|
|
17191
17743
|
return m ? `--- "${s.title}" \xB7 ${(s.start || "").slice(0, 10)} ---
|
|
17192
17744
|
${m.text.slice(0, 3e3)}` : "";
|
|
17193
17745
|
}))).filter(Boolean);
|
|
17194
|
-
const digestDays = (await
|
|
17746
|
+
const digestDays = (await fs13.readFile(path14.join(CODING, "day-digest.json"), "utf-8").then(JSON.parse).catch(() => ({ days: [] }))).days ?? [];
|
|
17195
17747
|
const digestLines = digestDays.slice().sort((a, b) => a.date < b.date ? -1 : 1).slice(-21).map((d) => `${d.date}: ${d.overall ?? ""}
|
|
17196
17748
|
${(d.conversations ?? []).slice(0, 4).map((c) => ` - ${c.title ?? ""}: ${c.summary ?? ""}`).join("\n")}`).join("\n").slice(0, 12e3);
|
|
17197
17749
|
const SYS = "You are a Claude Code power-user coach. You judge ONE person against the COMPLETE catalog of best ways to use Claude Code (the rubric below, sourced from Boris Cherny + first-party Claude Code features) and write a comprehensive, honest gap analysis, ORDERED most-difference-making \u2192 least. Rules: (1) Go through the whole catalog and surface the techniques they are NOT doing (or under-using) that would genuinely help \u2014 respecting each tip's [EMPHASIZE]/[DE-EMPHASIZE]/[GATE] curation. (2) ORDER by differenceRank (1 = biggest unlock for THIS person). Follow the rubric's PRIME DIRECTIVE: if usage.parallelism.alreadyParallel is FALSE \u2192 'Do more in parallel' is rank 1; else \u2192 'Invest in your CLAUDE.md / tune your context' is rank 1. Then Plan mode, then 'Give Claude test cases so it can auto-verify and run longer' (Boris's 'most important thing' \u2014 rank it high, right after plan mode), then subagents, and the rest per the rubric order, skipping any that don't apply. (3) GATE the conditional tips on the STRUCTURAL usage facts, NOT on keywords \u2014 and a tip whose gate FAILS is OMITTED from recommendations entirely, never included as a softened/conditional card (recommending something their data says doesn't apply, or that they already do, reads as not having looked): loops require real PR/branch volume in usage.collaboration, else OMIT; the Chrome tip requires ~zero browser-driving in usage.chrome, else OMIT and credit in alreadyStrong; forking uses the RECENT count in usage.forking \u2014 if they fork in the recent window they already do it, OMIT and credit; remote/mobile/EC2 fires only when usage.surface.workstationBound is TRUE; plan mode by usage.planMode; subagents by usage.subagents. If they already do a thing, it goes in alreadyStrong, NOT in recommendations. (4) \u26D4 CRITICAL \u2014 this person BUILDS Claude Code tooling, so their transcripts are full of the words 'worktree', 'pull request', 'fork', 'plan mode', 'by the way', 'teleport'. A keyword in the transcript is NOT evidence they use the feature. Rely on the STRUCTURAL facts only. (5) Ground every recommendation in a RECEIPT \u2014 a structural fact from their usage or a concrete session pain point \u2014 and CONVINCE with a specific case for how it helps THIS person, not a generic benefit. (6) Tailor every action to the Claude Desktop Mac app; NEVER give terminal-only `claude -p` advice. (7) Honor config.deliberateChoices (they stay on `main` on purpose \u2014 do NOT tell them to hand-juggle worktrees; parallel SESSIONS instead) and config.claudeAutoTools (never tell them to 'use' a tool Claude drives itself; for 'explain with visuals' the user just ASKS for a visual \u2014 do not name the tool). (8) Also name what they ALREADY do well. (9) SELF-CONTAINED but not verbose \u2014 lead with the PROBLEM, then the SOLUTION, then HOW to use it in their context. Plain language, no jargon, no enumerating multiple dates. An essay-like rec is a failed rec; so is a cryptic one. Follow this writing rubric strictly:\n\n" + writing + sourceLookupNote();
|
|
@@ -17221,7 +17773,7 @@ Produce the gap analysis. Be thorough: cover every relevant catalog item they're
|
|
|
17221
17773
|
\`applyItHere\` HARD RULES: 3 entries per recommendation when the material supports 3, minimum 2 \u2014 and every moment must be VISIBLY present in THEIR RECENT DAYS or the excerpts (a real dated task, named the way they name it). NEVER invent, generalize, or reuse the same moment across recommendations. If the material truly supports only one real moment, give that one \u2014 a fabricated example is worse than a short list.`;
|
|
17222
17774
|
const sha = promptSha([SYS, prompt, "sonnet"]);
|
|
17223
17775
|
if (!process.argv.includes("--refresh")) {
|
|
17224
|
-
const prev = await reusableOutput(
|
|
17776
|
+
const prev = await reusableOutput(path14.join(CODING, "gap.json"), sha, (o) => Array.isArray(o.recommendations) && o.recommendations.length > 0);
|
|
17225
17777
|
if (prev) {
|
|
17226
17778
|
console.log(`[gap] inputs unchanged \u2014 reusing output from ${prev.generatedAt} (--refresh to regenerate)`);
|
|
17227
17779
|
return;
|
|
@@ -17244,13 +17796,12 @@ Produce the gap analysis. Be thorough: cover every relevant catalog item they're
|
|
|
17244
17796
|
throw new Error("gap run produced 0 recommendations \u2014 refusing to overwrite the existing gap.json. Re-run the builder.");
|
|
17245
17797
|
}
|
|
17246
17798
|
const result = { generatedAt: (/* @__PURE__ */ new Date()).toISOString(), promptSha: sha, ...out };
|
|
17247
|
-
await
|
|
17799
|
+
await fs13.writeFile(path14.join(CODING, "gap.json"), JSON.stringify(result, null, 2));
|
|
17248
17800
|
console.log(`WROTE ${CODING}/gap.json \u2014 recommendations:${(out.recommendations || []).length} \xB7 alreadyStrong:${(out.alreadyStrong || []).length}`);
|
|
17249
17801
|
}
|
|
17802
|
+
var releaseLock = null;
|
|
17250
17803
|
main().catch((e) => {
|
|
17251
17804
|
console.error(e);
|
|
17252
17805
|
process.exitCode = 1;
|
|
17253
|
-
}).finally(() => {
|
|
17254
|
-
|
|
17255
|
-
});
|
|
17256
|
-
});
|
|
17806
|
+
}).finally(() => releaseLock?.().catch(() => {
|
|
17807
|
+
}));
|