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
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import{createRequire as __cr}from'module';const require=__cr(import.meta.url);
|
|
2
2
|
|
|
3
3
|
// ../../scripts/coding-flow.mts
|
|
4
|
-
import { promises as
|
|
5
|
-
import
|
|
4
|
+
import { promises as fs3 } from "fs";
|
|
5
|
+
import path3 from "path";
|
|
6
6
|
|
|
7
7
|
// ../../lib/agents/shared/cliAdapter.ts
|
|
8
8
|
var CLAUDE_BIN = process.env.CLAUDE_BIN || "claude";
|
|
@@ -50,7 +50,7 @@ var LIBERAL = [
|
|
|
50
50
|
var ALS = new AsyncLocalStorage();
|
|
51
51
|
|
|
52
52
|
// ../coding-core/dist/messages.js
|
|
53
|
-
import { promises as
|
|
53
|
+
import { promises as fs2 } from "fs";
|
|
54
54
|
|
|
55
55
|
// ../coding-core/dist/injected.js
|
|
56
56
|
var SYSTEM_REMINDER_RE = /<system-reminder>[\s\S]*?<\/system-reminder>/g;
|
|
@@ -85,6 +85,365 @@ function isHarnessEntry(e) {
|
|
|
85
85
|
return e.isMeta === true || e.isCompactSummary === true;
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
+
// ../coding-core/dist/codex.js
|
|
89
|
+
var SYSTEM_REMINDER_RE2 = /<system-reminder>[\s\S]*?<\/system-reminder>/g;
|
|
90
|
+
var CODEX_INJECTED_TEXT_RE = /^\s*(<(environment_context|user_instructions|ENVIRONMENT_CONTEXT|turn_aborted)\b|#\s*AGENTS\.md instructions\b)/;
|
|
91
|
+
function isCodexInjectedUserText(text) {
|
|
92
|
+
return CODEX_INJECTED_TEXT_RE.test(text);
|
|
93
|
+
}
|
|
94
|
+
function codexContentText(content) {
|
|
95
|
+
if (typeof content === "string")
|
|
96
|
+
return content;
|
|
97
|
+
if (!Array.isArray(content))
|
|
98
|
+
return "";
|
|
99
|
+
const parts = [];
|
|
100
|
+
for (const item of content) {
|
|
101
|
+
if (typeof item === "string") {
|
|
102
|
+
parts.push(item);
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
if (item && typeof item === "object") {
|
|
106
|
+
const it = item;
|
|
107
|
+
if (it.type === "input_text" || it.type === "output_text" || it.type === "text")
|
|
108
|
+
parts.push(it.text || "");
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return parts.join("\n");
|
|
112
|
+
}
|
|
113
|
+
function sniffCodexRaw(raw) {
|
|
114
|
+
let checked = 0;
|
|
115
|
+
for (const lineRaw of raw.split("\n")) {
|
|
116
|
+
const line = lineRaw.trim();
|
|
117
|
+
if (!line)
|
|
118
|
+
continue;
|
|
119
|
+
if (checked++ >= 5)
|
|
120
|
+
break;
|
|
121
|
+
try {
|
|
122
|
+
const e = JSON.parse(line);
|
|
123
|
+
if (e.type === "session_meta" || e.type === "response_item" || e.type === "turn_context")
|
|
124
|
+
return true;
|
|
125
|
+
if (e.type === "user" || e.type === "assistant" || e.type === "summary" || e.type === "queue-operation")
|
|
126
|
+
return false;
|
|
127
|
+
} catch {
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
var EXIT_CODE_RE = /(?:Process exited with code|Exit code:)\s+(\d+)/;
|
|
133
|
+
function extractCodexEvents(raw) {
|
|
134
|
+
const out = [];
|
|
135
|
+
for (const lineRaw of raw.split("\n")) {
|
|
136
|
+
const line = lineRaw.trim();
|
|
137
|
+
if (!line)
|
|
138
|
+
continue;
|
|
139
|
+
let e;
|
|
140
|
+
try {
|
|
141
|
+
e = JSON.parse(line);
|
|
142
|
+
} catch {
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
if (e.type !== "response_item")
|
|
146
|
+
continue;
|
|
147
|
+
const p = e.payload ?? {};
|
|
148
|
+
const t = typeof e.timestamp === "string" ? Date.parse(e.timestamp) : NaN;
|
|
149
|
+
const ptype = p.type;
|
|
150
|
+
if (ptype === "message") {
|
|
151
|
+
const role = p.role;
|
|
152
|
+
const text = codexContentText(p.content).replace(SYSTEM_REMINDER_RE2, "").trim();
|
|
153
|
+
if (!text)
|
|
154
|
+
continue;
|
|
155
|
+
if (role === "user") {
|
|
156
|
+
if (isCodexInjectedUserText(text))
|
|
157
|
+
continue;
|
|
158
|
+
out.push({ kind: "user", t, text });
|
|
159
|
+
} else if (role === "assistant") {
|
|
160
|
+
out.push({ kind: "assistant", t, text });
|
|
161
|
+
}
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
if (ptype === "function_call" || ptype === "custom_tool_call" || ptype === "local_shell_call") {
|
|
165
|
+
const name = typeof p.name === "string" && p.name ? p.name : ptype === "local_shell_call" ? "shell" : String(ptype);
|
|
166
|
+
const input = typeof p.arguments === "string" ? p.arguments : typeof p.input === "string" ? p.input : "";
|
|
167
|
+
out.push({ kind: "tool", t, name, input });
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
if (ptype === "function_call_output" || ptype === "custom_tool_call_output") {
|
|
171
|
+
const output = typeof p.output === "string" ? p.output : "";
|
|
172
|
+
const m = EXIT_CODE_RE.exec(output.slice(0, 200));
|
|
173
|
+
out.push({ kind: "tool_output", t, output, isError: !!m && m[1] !== "0" });
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return out;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// ../coding-core/dist/cursor.js
|
|
180
|
+
import { promises as fs } from "fs";
|
|
181
|
+
var NODE_SQLITE = "node:sqlite";
|
|
182
|
+
async function openCursorSqlite(dbPath) {
|
|
183
|
+
try {
|
|
184
|
+
await fs.access(dbPath);
|
|
185
|
+
} catch {
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
let mod;
|
|
189
|
+
try {
|
|
190
|
+
mod = await import(NODE_SQLITE);
|
|
191
|
+
} catch {
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
const DatabaseSync = mod?.DatabaseSync;
|
|
195
|
+
if (!DatabaseSync)
|
|
196
|
+
return null;
|
|
197
|
+
let db;
|
|
198
|
+
try {
|
|
199
|
+
db = new DatabaseSync(dbPath, { readOnly: true });
|
|
200
|
+
} catch {
|
|
201
|
+
try {
|
|
202
|
+
db = new DatabaseSync(dbPath);
|
|
203
|
+
} catch {
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
const asText = (v) => v == null ? null : typeof v === "string" ? v : Buffer.from(v).toString("utf-8");
|
|
208
|
+
return {
|
|
209
|
+
prefix(prefix) {
|
|
210
|
+
try {
|
|
211
|
+
const rows = db.prepare("SELECT key, value FROM cursorDiskKV WHERE key LIKE ? ESCAPE '\\'").all(likePrefix(prefix));
|
|
212
|
+
return rows.map((r) => ({ key: r.key, value: asText(r.value) ?? "" }));
|
|
213
|
+
} catch {
|
|
214
|
+
return [];
|
|
215
|
+
}
|
|
216
|
+
},
|
|
217
|
+
get(key) {
|
|
218
|
+
try {
|
|
219
|
+
const row = db.prepare("SELECT value FROM cursorDiskKV WHERE key = ?").get(key);
|
|
220
|
+
return row ? asText(row.value) : null;
|
|
221
|
+
} catch {
|
|
222
|
+
return null;
|
|
223
|
+
}
|
|
224
|
+
},
|
|
225
|
+
close() {
|
|
226
|
+
try {
|
|
227
|
+
db.close();
|
|
228
|
+
} catch {
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
function likePrefix(prefix) {
|
|
234
|
+
return prefix.replace(/[\\%_]/g, (c) => "\\" + c) + "%";
|
|
235
|
+
}
|
|
236
|
+
var CURSOR_USER_QUERY_RE = /<user_query>\s*([\s\S]*?)\s*<\/user_query>/;
|
|
237
|
+
function cleanUserText(raw) {
|
|
238
|
+
let t = raw.replace(SYSTEM_REMINDER_RE, "");
|
|
239
|
+
const m = t.match(CURSOR_USER_QUERY_RE);
|
|
240
|
+
if (m)
|
|
241
|
+
t = m[1];
|
|
242
|
+
return t.trim();
|
|
243
|
+
}
|
|
244
|
+
var msFrom = (v) => {
|
|
245
|
+
if (typeof v === "number" && Number.isFinite(v))
|
|
246
|
+
return v;
|
|
247
|
+
if (typeof v === "string") {
|
|
248
|
+
const n = Date.parse(v);
|
|
249
|
+
return Number.isFinite(n) ? n : null;
|
|
250
|
+
}
|
|
251
|
+
return null;
|
|
252
|
+
};
|
|
253
|
+
function readCursorComposer(db, composerId) {
|
|
254
|
+
const cdRaw = db.get(`composerData:${composerId}`);
|
|
255
|
+
if (!cdRaw)
|
|
256
|
+
return null;
|
|
257
|
+
let cd;
|
|
258
|
+
try {
|
|
259
|
+
cd = JSON.parse(cdRaw);
|
|
260
|
+
} catch {
|
|
261
|
+
return null;
|
|
262
|
+
}
|
|
263
|
+
const headers = Array.isArray(cd.fullConversationHeadersOnly) ? cd.fullConversationHeadersOnly : [];
|
|
264
|
+
if (headers.length === 0)
|
|
265
|
+
return null;
|
|
266
|
+
const bubbles = /* @__PURE__ */ new Map();
|
|
267
|
+
for (const row of db.prefix(`bubbleId:${composerId}:`)) {
|
|
268
|
+
const bid = row.key.slice(`bubbleId:${composerId}:`.length);
|
|
269
|
+
try {
|
|
270
|
+
bubbles.set(bid, JSON.parse(row.value));
|
|
271
|
+
} catch {
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
const turns = [];
|
|
275
|
+
let clock = msFrom(cd.createdAt) ?? 0;
|
|
276
|
+
for (const h of headers) {
|
|
277
|
+
const b = bubbles.get(h.bubbleId);
|
|
278
|
+
if (!b)
|
|
279
|
+
continue;
|
|
280
|
+
const type = h.type === 1 ? 1 : 2;
|
|
281
|
+
const tool = type === 2 && b.toolFormerData && typeof b.toolFormerData.name === "string" ? b.toolFormerData.name : null;
|
|
282
|
+
const rawText = typeof b.text === "string" ? b.text : "";
|
|
283
|
+
const text = type === 1 ? cleanUserText(rawText) : rawText.replace(SYSTEM_REMINDER_RE, "").trim();
|
|
284
|
+
if (!text && !tool)
|
|
285
|
+
continue;
|
|
286
|
+
const t = msFrom(b.createdAt);
|
|
287
|
+
clock = Math.max(clock, t ?? clock + 1);
|
|
288
|
+
const model = b.modelInfo && typeof b.modelInfo.modelName === "string" ? b.modelInfo.modelName : null;
|
|
289
|
+
turns.push({ t: clock, type, text, tool, model });
|
|
290
|
+
}
|
|
291
|
+
if (turns.length === 0)
|
|
292
|
+
return null;
|
|
293
|
+
const gitRepo = Array.isArray(cd.trackedGitRepos) && cd.trackedGitRepos[0] && typeof cd.trackedGitRepos[0].repoPath === "string" ? cd.trackedGitRepos[0].repoPath : null;
|
|
294
|
+
return {
|
|
295
|
+
composerId,
|
|
296
|
+
createdAt: msFrom(cd.createdAt),
|
|
297
|
+
updatedAt: msFrom(cd.lastUpdatedAt),
|
|
298
|
+
name: typeof cd.name === "string" && cd.name.trim() ? cd.name.trim() : null,
|
|
299
|
+
gitRepo,
|
|
300
|
+
turns
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
function sniffCursorRaw(raw) {
|
|
304
|
+
for (const lineRaw of raw.split("\n")) {
|
|
305
|
+
const line = lineRaw.trim();
|
|
306
|
+
if (!line)
|
|
307
|
+
continue;
|
|
308
|
+
try {
|
|
309
|
+
const e = JSON.parse(line);
|
|
310
|
+
return (e.role === "user" || e.role === "assistant") && typeof e.message === "object" && e.message !== null && "content" in e.message && !("type" in e);
|
|
311
|
+
} catch {
|
|
312
|
+
return false;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
return false;
|
|
316
|
+
}
|
|
317
|
+
function jsonlText(content) {
|
|
318
|
+
const parts = [];
|
|
319
|
+
const tools = [];
|
|
320
|
+
if (Array.isArray(content)) {
|
|
321
|
+
for (const item of content) {
|
|
322
|
+
if (!item || typeof item !== "object")
|
|
323
|
+
continue;
|
|
324
|
+
const it = item;
|
|
325
|
+
if (it.type === "text" && it.text)
|
|
326
|
+
parts.push(it.text);
|
|
327
|
+
else if (it.type === "tool_use" && it.name)
|
|
328
|
+
tools.push(it.name);
|
|
329
|
+
}
|
|
330
|
+
} else if (typeof content === "string")
|
|
331
|
+
parts.push(content);
|
|
332
|
+
return { text: parts.join("\n"), tools };
|
|
333
|
+
}
|
|
334
|
+
function parseCursorJsonl(raw, base) {
|
|
335
|
+
const turns = [];
|
|
336
|
+
let clock = base;
|
|
337
|
+
for (const lineRaw of raw.split("\n")) {
|
|
338
|
+
const line = lineRaw.trim();
|
|
339
|
+
if (!line)
|
|
340
|
+
continue;
|
|
341
|
+
let e;
|
|
342
|
+
try {
|
|
343
|
+
e = JSON.parse(line);
|
|
344
|
+
} catch {
|
|
345
|
+
continue;
|
|
346
|
+
}
|
|
347
|
+
if (e.role !== "user" && e.role !== "assistant")
|
|
348
|
+
continue;
|
|
349
|
+
const { text: rawText, tools } = jsonlText(e.message?.content);
|
|
350
|
+
const type = e.role === "user" ? 1 : 2;
|
|
351
|
+
const text = type === 1 ? cleanUserText(rawText) : rawText.replace(SYSTEM_REMINDER_RE, "").trim();
|
|
352
|
+
if (type === 2 && tools.length) {
|
|
353
|
+
for (const tool of tools) {
|
|
354
|
+
clock += 1;
|
|
355
|
+
turns.push({ t: clock, type: 2, text: "", tool, model: null });
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
if (!text)
|
|
359
|
+
continue;
|
|
360
|
+
clock += 1;
|
|
361
|
+
turns.push({ t: clock, type, text, tool: null, model: null });
|
|
362
|
+
}
|
|
363
|
+
if (turns.length === 0)
|
|
364
|
+
return null;
|
|
365
|
+
return { composerId: "", createdAt: base, updatedAt: clock, name: null, gitRepo: null, turns };
|
|
366
|
+
}
|
|
367
|
+
function cursorMessages(c) {
|
|
368
|
+
const out = [];
|
|
369
|
+
let aiStart = 0;
|
|
370
|
+
let aiParts = [];
|
|
371
|
+
const flushAI = () => {
|
|
372
|
+
if (!aiParts.length)
|
|
373
|
+
return;
|
|
374
|
+
out.push({ t: aiStart, role: "ai", text: aiParts.join("\n") });
|
|
375
|
+
aiParts = [];
|
|
376
|
+
};
|
|
377
|
+
for (const turn of c.turns) {
|
|
378
|
+
if (turn.type === 1) {
|
|
379
|
+
flushAI();
|
|
380
|
+
out.push({ t: turn.t, role: "user", text: turn.text });
|
|
381
|
+
} else {
|
|
382
|
+
if (aiParts.length === 0)
|
|
383
|
+
aiStart = turn.t;
|
|
384
|
+
if (turn.text)
|
|
385
|
+
aiParts.push(turn.text);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
flushAI();
|
|
389
|
+
return out;
|
|
390
|
+
}
|
|
391
|
+
function composerIdFromFile(file) {
|
|
392
|
+
const m = file.match(/agent-transcripts\/([^/]+)\/[^/]+\.jsonl$/);
|
|
393
|
+
return m ? m[1] : null;
|
|
394
|
+
}
|
|
395
|
+
async function loadCursorComposer(file, raw, dbPath) {
|
|
396
|
+
const cid = composerIdFromFile(file);
|
|
397
|
+
if (cid && dbPath) {
|
|
398
|
+
const db = await openCursorSqlite(dbPath);
|
|
399
|
+
if (db) {
|
|
400
|
+
try {
|
|
401
|
+
const c = readCursorComposer(db, cid);
|
|
402
|
+
if (c)
|
|
403
|
+
return c;
|
|
404
|
+
} finally {
|
|
405
|
+
db.close();
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
return parseCursorJsonl(raw, 0);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
// ../coding-core/dist/raw.js
|
|
413
|
+
import path from "path";
|
|
414
|
+
import os2 from "os";
|
|
415
|
+
var SOURCE_ROOT_ENV_VARS = [
|
|
416
|
+
"CLAUDE_PROJECTS_DIR",
|
|
417
|
+
"CODEX_SESSIONS_DIR",
|
|
418
|
+
"CURSOR_WORKSPACE_DIR",
|
|
419
|
+
"CURSOR_PROJECTS_DIR",
|
|
420
|
+
// Cursor's globalStorage dir (holds state.vscdb — the composer bubbles that
|
|
421
|
+
// carry a Cursor session's real per-turn timestamps + content). Same
|
|
422
|
+
// isolation contract: overriding any root disables every unset source.
|
|
423
|
+
"CURSOR_GLOBAL_DIR"
|
|
424
|
+
];
|
|
425
|
+
var anyRootOverridden = () => SOURCE_ROOT_ENV_VARS.some((v) => !!process.env[v]);
|
|
426
|
+
function resolveSourceRoot(envVar, ...defaultSegments) {
|
|
427
|
+
const explicit = process.env[envVar];
|
|
428
|
+
if (explicit)
|
|
429
|
+
return explicit;
|
|
430
|
+
if (anyRootOverridden())
|
|
431
|
+
return null;
|
|
432
|
+
return path.join(os2.homedir(), ...defaultSegments);
|
|
433
|
+
}
|
|
434
|
+
var cursorGlobalRoot = () => resolveSourceRoot("CURSOR_GLOBAL_DIR", "Library", "Application Support", "Cursor", "User", "globalStorage");
|
|
435
|
+
function cursorGlobalDbPath() {
|
|
436
|
+
const root = cursorGlobalRoot();
|
|
437
|
+
return root === null ? null : path.join(root, "state.vscdb");
|
|
438
|
+
}
|
|
439
|
+
var MACHINE_CURSOR_FILE_RE = /^(.*[/\\]machines[/\\][^/\\]+[/\\]\.cursor)[/\\]projects[/\\]/;
|
|
440
|
+
function cursorDbPathForFile(file) {
|
|
441
|
+
const m = file.match(MACHINE_CURSOR_FILE_RE);
|
|
442
|
+
if (m)
|
|
443
|
+
return path.join(m[1], "globalStorage", "state.vscdb");
|
|
444
|
+
return cursorGlobalDbPath();
|
|
445
|
+
}
|
|
446
|
+
|
|
88
447
|
// ../coding-core/dist/messages.js
|
|
89
448
|
function extractText(content) {
|
|
90
449
|
if (typeof content === "string")
|
|
@@ -96,13 +455,62 @@ function extractText(content) {
|
|
|
96
455
|
function isToolResultOnly(content) {
|
|
97
456
|
return Array.isArray(content) && content.length > 0 && content.every((c) => c && typeof c === "object" && c.type === "tool_result");
|
|
98
457
|
}
|
|
458
|
+
function extractMessagesCodex(raw) {
|
|
459
|
+
const out = [];
|
|
460
|
+
let aiProse = [];
|
|
461
|
+
let aiTools = {};
|
|
462
|
+
let aiStart = 0;
|
|
463
|
+
const flushAI = () => {
|
|
464
|
+
if (!aiProse.length && Object.keys(aiTools).length === 0)
|
|
465
|
+
return;
|
|
466
|
+
const toolStr = Object.entries(aiTools).map(([n, c]) => c > 1 ? `${n}\xD7${c}` : n).join(", ");
|
|
467
|
+
let prose = aiProse.join(" ").replace(/\s+/g, " ").trim();
|
|
468
|
+
if (prose.length > 2200)
|
|
469
|
+
prose = prose.slice(0, 2200) + "\u2026";
|
|
470
|
+
let text = prose;
|
|
471
|
+
if (toolStr)
|
|
472
|
+
text = (text ? text + " " : "") + `[ran ${toolStr}]`;
|
|
473
|
+
if (text)
|
|
474
|
+
out.push({ t: aiStart, role: "ai", text });
|
|
475
|
+
aiProse = [];
|
|
476
|
+
aiTools = {};
|
|
477
|
+
};
|
|
478
|
+
for (const ev of extractCodexEvents(raw)) {
|
|
479
|
+
if (!Number.isFinite(ev.t))
|
|
480
|
+
continue;
|
|
481
|
+
if (ev.kind === "user") {
|
|
482
|
+
const text = humanTypedText(ev.text);
|
|
483
|
+
if (text) {
|
|
484
|
+
flushAI();
|
|
485
|
+
out.push({ t: ev.t, role: "user", text });
|
|
486
|
+
}
|
|
487
|
+
} else if (ev.kind === "assistant") {
|
|
488
|
+
if (!aiProse.length && Object.keys(aiTools).length === 0)
|
|
489
|
+
aiStart = ev.t;
|
|
490
|
+
if (ev.text)
|
|
491
|
+
aiProse.push(ev.text);
|
|
492
|
+
} else if (ev.kind === "tool") {
|
|
493
|
+
if (!aiProse.length && Object.keys(aiTools).length === 0)
|
|
494
|
+
aiStart = ev.t;
|
|
495
|
+
aiTools[ev.name] = (aiTools[ev.name] ?? 0) + 1;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
flushAI();
|
|
499
|
+
return out.sort((a, b) => a.t - b.t);
|
|
500
|
+
}
|
|
99
501
|
async function extractMessages(file) {
|
|
100
502
|
let raw;
|
|
101
503
|
try {
|
|
102
|
-
raw = await
|
|
504
|
+
raw = await fs2.readFile(file, "utf-8");
|
|
103
505
|
} catch {
|
|
104
506
|
return [];
|
|
105
507
|
}
|
|
508
|
+
if (sniffCodexRaw(raw))
|
|
509
|
+
return extractMessagesCodex(raw);
|
|
510
|
+
if (sniffCursorRaw(raw)) {
|
|
511
|
+
const c = await loadCursorComposer(file, raw, cursorDbPathForFile(file));
|
|
512
|
+
return c ? cursorMessages(c) : [];
|
|
513
|
+
}
|
|
106
514
|
const out = [];
|
|
107
515
|
const userTexts = /* @__PURE__ */ new Set();
|
|
108
516
|
const seenUuids = /* @__PURE__ */ new Set();
|
|
@@ -244,7 +652,7 @@ function proseWords(text) {
|
|
|
244
652
|
}
|
|
245
653
|
|
|
246
654
|
// ../../lib/agents/coding/profile.ts
|
|
247
|
-
import
|
|
655
|
+
import path2 from "path";
|
|
248
656
|
|
|
249
657
|
// ../../lib/calibration/fingerprint.ts
|
|
250
658
|
import { createHash } from "node:crypto";
|
|
@@ -394,7 +802,7 @@ var IDLE_CAP_MS = 12 * 6e4;
|
|
|
394
802
|
|
|
395
803
|
// ../../lib/calibration/index.ts
|
|
396
804
|
var DEFAULT_CALIBRATION = {
|
|
397
|
-
version: "2026-07-
|
|
805
|
+
version: "2026-07-21.1",
|
|
398
806
|
// = RUBRIC_FINGERPRINT of the shipped npm rubric (packages/coding-analyzer/
|
|
399
807
|
// src/grade/criteria.ts). A unit test fails loud when the rubric changes
|
|
400
808
|
// without this being updated (and re-pushed to the server).
|
|
@@ -490,13 +898,14 @@ var DEFAULT_CALIBRATION = {
|
|
|
490
898
|
},
|
|
491
899
|
codingBenchmarks: {
|
|
492
900
|
flow: {
|
|
493
|
-
// typical knowledge worker ≈ 35% of an 8h day focused; ~4h/day
|
|
494
|
-
//
|
|
901
|
+
// typical knowledge worker ≈ 35% of an 8h day focused; the ~4h/day
|
|
902
|
+
// deep-work ceiling (Newport) sits nearer ~40% of a real (9-10h) top
|
|
903
|
+
// performer's day — 50% overstated it (owner call 2026-07-21).
|
|
495
904
|
typicalPctOfDay: 0.35,
|
|
496
|
-
topPctOfDay: 0.
|
|
905
|
+
topPctOfDay: 0.4,
|
|
497
906
|
tag: "measured",
|
|
498
|
-
source: "RescueTime 2019 (~2h48m focused/day) \xB7 Cal Newport, Deep Work (~4h/day deep-work ceiling)",
|
|
499
|
-
line: "the best spend ~
|
|
907
|
+
source: "RescueTime 2019 (~2h48m focused/day) \xB7 Cal Newport, Deep Work (~4h/day deep-work ceiling against a 9-10h day)",
|
|
908
|
+
line: "the best spend ~40% of the workday in true deep flow; ~4h/day is the human ceiling"
|
|
500
909
|
},
|
|
501
910
|
longestRun: {
|
|
502
911
|
typicalHours: 0.67,
|
|
@@ -545,8 +954,8 @@ var BEST = DEFAULT_CALIBRATION.codingBenchmarks;
|
|
|
545
954
|
|
|
546
955
|
// ../../lib/agents/coding/profile.ts
|
|
547
956
|
var ROOT = process.cwd();
|
|
548
|
-
var CODING_DIR = process.env.POLYMATH_DATA_DIR ?
|
|
549
|
-
var GRADES =
|
|
957
|
+
var CODING_DIR = process.env.POLYMATH_DATA_DIR ? path2.join(process.env.POLYMATH_DATA_DIR, "coding") : path2.join(ROOT, ".data", "coding");
|
|
958
|
+
var GRADES = path2.join(CODING_DIR, "grades");
|
|
550
959
|
|
|
551
960
|
// ../../scripts/coding-flow.mts
|
|
552
961
|
var WPM = 130;
|
|
@@ -562,7 +971,7 @@ var slotOfDay = (t) => {
|
|
|
562
971
|
};
|
|
563
972
|
async function main() {
|
|
564
973
|
const CODING = CODING_DIR;
|
|
565
|
-
const sess = JSON.parse(await
|
|
974
|
+
const sess = JSON.parse(await fs3.readFile(path3.join(CODING, "sessions.json"), "utf8")).filter((s) => !s.duplicateOf);
|
|
566
975
|
const ev = [];
|
|
567
976
|
for (const s of sess) {
|
|
568
977
|
let ms = [];
|
|
@@ -607,7 +1016,7 @@ async function main() {
|
|
|
607
1016
|
}
|
|
608
1017
|
const fs22 = days.reduce((a, d) => a + d.flowSlots, 0), as = days.reduce((a, d) => a + d.activeSlots, 0);
|
|
609
1018
|
const out = { generatedAt: (/* @__PURE__ */ new Date()).toISOString(), params: { wpm: WPM, flowGapMin: FLOW_GAP, breakMin: BREAK, windowMin: WIN, tz: TZ }, totals: { activeDays: days.length, flowSlots: fs22, activeSlots: as, flowFraction: Math.round(fs22 / as * 100) / 100 }, days };
|
|
610
|
-
await
|
|
1019
|
+
await fs3.writeFile(path3.join(CODING, "flow.json"), JSON.stringify(out, null, 2));
|
|
611
1020
|
console.log(`wrote .data/coding/flow.json \u2014 ${days.length} days \xB7 ${fs22}/${as} slots in flow (${Math.round(100 * fs22 / as)}%)`);
|
|
612
1021
|
console.log(`top flow days:`);
|
|
613
1022
|
[...days].sort((a, b) => b.flowSlots - a.flowSlots).slice(0, 5).forEach((d) => console.log(` ${d.date} ${d.flowSlots} flow slots (${d.flowHours}h) \xB7 ${Math.round(d.flowFraction * 100)}% of active`));
|