mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-08 16:39:42 +02:00
refactor: optimize history endpoint — reuse buffer, extract readFileHead, use line iterator
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -965,7 +965,12 @@ export function registerSessionRoutes(
|
|||||||
/** Extract the text of the first user message from a JSONL transcript head. */
|
/** Extract the text of the first user message from a JSONL transcript head. */
|
||||||
function extractFirstUserPrompt(head: string): string | undefined {
|
function extractFirstUserPrompt(head: string): string | undefined {
|
||||||
const MAX_PROMPT_LEN = 120;
|
const MAX_PROMPT_LEN = 120;
|
||||||
for (const line of head.split('\n')) {
|
// Iterate lines without allocating a full split array
|
||||||
|
let start = 0;
|
||||||
|
while (start < head.length) {
|
||||||
|
const end = head.indexOf('\n', start);
|
||||||
|
const line = end === -1 ? head.slice(start) : head.slice(start, end);
|
||||||
|
start = end === -1 ? head.length : end + 1;
|
||||||
if (!line.includes('"type":"user"')) continue;
|
if (!line.includes('"type":"user"')) continue;
|
||||||
try {
|
try {
|
||||||
const entry = JSON.parse(line);
|
const entry = JSON.parse(line);
|
||||||
@@ -995,6 +1000,18 @@ export function registerSessionRoutes(
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Read the first 16KB of a file for content sniffing. */
|
||||||
|
async function readFileHead(path: string, buf: Buffer): Promise<string | null> {
|
||||||
|
try {
|
||||||
|
const fd = await fs.open(path, 'r');
|
||||||
|
const { bytesRead } = await fd.read(buf, 0, buf.length, 0);
|
||||||
|
await fd.close();
|
||||||
|
return buf.toString('utf8', 0, bytesRead);
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
app.get('/api/history/sessions', async () => {
|
app.get('/api/history/sessions', async () => {
|
||||||
const projectsDir = join(process.env.HOME || '/tmp', '.claude', 'projects');
|
const projectsDir = join(process.env.HOME || '/tmp', '.claude', 'projects');
|
||||||
const results: Array<{
|
const results: Array<{
|
||||||
@@ -1005,6 +1022,7 @@ export function registerSessionRoutes(
|
|||||||
lastModified: string;
|
lastModified: string;
|
||||||
firstPrompt?: string;
|
firstPrompt?: string;
|
||||||
}> = [];
|
}> = [];
|
||||||
|
const headBuf = Buffer.alloc(16384);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const projectDirs = await fs.readdir(projectsDir);
|
const projectDirs = await fs.readdir(projectsDir);
|
||||||
@@ -1042,20 +1060,9 @@ export function registerSessionRoutes(
|
|||||||
// no "user"/"assistant" messages and will fail claude --resume.
|
// no "user"/"assistant" messages and will fail claude --resume.
|
||||||
// Read first 16KB to check content and extract first user prompt.
|
// Read first 16KB to check content and extract first user prompt.
|
||||||
let firstPrompt: string | undefined;
|
let firstPrompt: string | undefined;
|
||||||
const readHead = async (): Promise<string | null> => {
|
const head = await readFileHead(filePath, headBuf);
|
||||||
try {
|
|
||||||
const fd = await fs.open(filePath, 'r');
|
|
||||||
const buf = Buffer.alloc(16384);
|
|
||||||
const { bytesRead } = await fd.read(buf, 0, 16384, 0);
|
|
||||||
await fd.close();
|
|
||||||
return buf.toString('utf8', 0, bytesRead);
|
|
||||||
} catch {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (fileStat.size < 50000) {
|
if (fileStat.size < 50000) {
|
||||||
const head = await readHead();
|
|
||||||
if (
|
if (
|
||||||
!head ||
|
!head ||
|
||||||
(!head.includes('"type":"user"') &&
|
(!head.includes('"type":"user"') &&
|
||||||
@@ -1064,12 +1071,8 @@ export function registerSessionRoutes(
|
|||||||
) {
|
) {
|
||||||
continue; // No conversation content — skip
|
continue; // No conversation content — skip
|
||||||
}
|
}
|
||||||
firstPrompt = extractFirstUserPrompt(head);
|
|
||||||
} else {
|
|
||||||
// Large files are almost certainly real conversations; still read head for prompt
|
|
||||||
const head = await readHead();
|
|
||||||
if (head) firstPrompt = extractFirstUserPrompt(head);
|
|
||||||
}
|
}
|
||||||
|
if (head) firstPrompt = extractFirstUserPrompt(head);
|
||||||
|
|
||||||
results.push({
|
results.push({
|
||||||
sessionId,
|
sessionId,
|
||||||
|
|||||||
Reference in New Issue
Block a user