@threadbase-sh/scanner 0.14.6 → 0.15.0
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 +25 -15
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +36 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +35 -14
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -50,6 +50,7 @@ __export(index_exports, {
|
|
|
50
50
|
getLogger: () => getLogger,
|
|
51
51
|
getProjectsDir: () => getProjectsDir,
|
|
52
52
|
loadProfiles: () => loadProfiles,
|
|
53
|
+
parseCodexJsonlLine: () => parseCodexJsonlLine,
|
|
53
54
|
parseJsonlLine: () => parseJsonlLine,
|
|
54
55
|
readGitBranch: () => readGitBranch,
|
|
55
56
|
readSidecar: () => readSidecar,
|
|
@@ -1057,6 +1058,26 @@ function extractCodexText(content) {
|
|
|
1057
1058
|
return "";
|
|
1058
1059
|
}).filter(Boolean).map(cleanSystemTags).join(" ");
|
|
1059
1060
|
}
|
|
1061
|
+
function parseCodexJsonlLine(line) {
|
|
1062
|
+
if (!line.trim()) return null;
|
|
1063
|
+
let entry;
|
|
1064
|
+
try {
|
|
1065
|
+
entry = JSON.parse(line);
|
|
1066
|
+
} catch {
|
|
1067
|
+
return null;
|
|
1068
|
+
}
|
|
1069
|
+
return codexEntryToMessage(entry);
|
|
1070
|
+
}
|
|
1071
|
+
function codexEntryToMessage(entry) {
|
|
1072
|
+
const payload = entry.payload;
|
|
1073
|
+
if (!payload || typeof payload !== "object") return null;
|
|
1074
|
+
if (entry.type !== "response_item" || payload.type !== "message") return null;
|
|
1075
|
+
const role = payload.role;
|
|
1076
|
+
if (role !== "user" && role !== "assistant") return null;
|
|
1077
|
+
const text = extractCodexText(payload.content);
|
|
1078
|
+
if (!text) return null;
|
|
1079
|
+
return { role, text, timestamp: asString(entry.timestamp) };
|
|
1080
|
+
}
|
|
1060
1081
|
function reduceCodexEntry(acc, entry, tier) {
|
|
1061
1082
|
const ts = asString(entry.timestamp);
|
|
1062
1083
|
if (ts && (!acc.latestTimestamp || ts > acc.latestTimestamp)) acc.latestTimestamp = ts;
|
|
@@ -1167,14 +1188,11 @@ async function parseCodexConversation(filePath, account) {
|
|
|
1167
1188
|
if (!cwd) cwd = asString(payload.cwd);
|
|
1168
1189
|
continue;
|
|
1169
1190
|
}
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
if (
|
|
1175
|
-
messages.push({ role, text, timestamp: ts });
|
|
1176
|
-
textParts.push(text);
|
|
1177
|
-
if (role === "user") lastUserText = text;
|
|
1191
|
+
const message = codexEntryToMessage(entry);
|
|
1192
|
+
if (!message) continue;
|
|
1193
|
+
messages.push(message);
|
|
1194
|
+
textParts.push(message.text);
|
|
1195
|
+
if (message.role === "user") lastUserText = message.text;
|
|
1178
1196
|
}
|
|
1179
1197
|
} catch (err) {
|
|
1180
1198
|
log.warn({ filePath, err }, "parseCodexConversation: read failed");
|
|
@@ -3522,7 +3540,8 @@ var ConversationScanner = class {
|
|
|
3522
3540
|
// feeds the conversation's account field; "default" is the single-profile
|
|
3523
3541
|
// fallback, matching refreshFile.
|
|
3524
3542
|
async parseSingleFilePage(filePath, account, options) {
|
|
3525
|
-
const
|
|
3543
|
+
const provider = await this.resolveProviderForFile(filePath, null);
|
|
3544
|
+
const conversation = provider?.name === CODEX_CLI_PROVIDER ? await parseCodexConversation(filePath, account ?? "default") : await parseConversation(filePath, account ?? "default");
|
|
3526
3545
|
if (!conversation) return null;
|
|
3527
3546
|
const { messages } = conversation;
|
|
3528
3547
|
const total = messages.length;
|
|
@@ -3566,7 +3585,7 @@ var ConversationScanner = class {
|
|
|
3566
3585
|
const engine = this.engine();
|
|
3567
3586
|
const previous2 = engine.getByIdOrSession(filePath);
|
|
3568
3587
|
const resolvedAccount2 = account ?? previous2?.account ?? "default";
|
|
3569
|
-
const
|
|
3588
|
+
const provider2 = await this.resolveProviderForFile(filePath, previous2);
|
|
3570
3589
|
const { meta: meta2, change } = await engine.indexFile(
|
|
3571
3590
|
filePath,
|
|
3572
3591
|
resolvedAccount2,
|
|
@@ -3574,7 +3593,7 @@ var ConversationScanner = class {
|
|
|
3574
3593
|
void 0,
|
|
3575
3594
|
readGitBranch,
|
|
3576
3595
|
false,
|
|
3577
|
-
|
|
3596
|
+
provider2
|
|
3578
3597
|
);
|
|
3579
3598
|
const cacheKeys = /* @__PURE__ */ new Set();
|
|
3580
3599
|
for (const m of [previous2, meta2]) {
|
|
@@ -3595,10 +3614,12 @@ var ConversationScanner = class {
|
|
|
3595
3614
|
const resolvedAccount = account ?? previous?.account ?? "default";
|
|
3596
3615
|
let meta = null;
|
|
3597
3616
|
let searchDoc = emptySearchDocument();
|
|
3617
|
+
const onEntry = (entry) => {
|
|
3618
|
+
searchDoc = appendSearchDelta(searchDoc, extractSearchDelta(entry));
|
|
3619
|
+
};
|
|
3620
|
+
const provider = await this.resolveProviderForFile(filePath, previous ?? null);
|
|
3598
3621
|
try {
|
|
3599
|
-
meta = await
|
|
3600
|
-
searchDoc = appendSearchDelta(searchDoc, extractSearchDelta(entry));
|
|
3601
|
-
});
|
|
3622
|
+
meta = provider ? await parseMetaWithProvider(provider, filePath, resolvedAccount, this.lastTier, onEntry) : await parseMeta(filePath, resolvedAccount, this.lastTier, onEntry);
|
|
3602
3623
|
} catch (err) {
|
|
3603
3624
|
log.warn({ filePath, err }, "refreshFile: parseMeta threw");
|
|
3604
3625
|
meta = null;
|
|
@@ -3975,6 +3996,7 @@ async function getConversation(id, options, scanner) {
|
|
|
3975
3996
|
getLogger,
|
|
3976
3997
|
getProjectsDir,
|
|
3977
3998
|
loadProfiles,
|
|
3999
|
+
parseCodexJsonlLine,
|
|
3978
4000
|
parseJsonlLine,
|
|
3979
4001
|
readGitBranch,
|
|
3980
4002
|
readSidecar,
|