import { exportSession, latestSessionId, loadSession } from "../agent/session"; import * as fs from "node:fs/promises"; import * as path from "node:path"; export function renderSessionHtml( meta: { id: string; timestamp?: string; [key: string]: any }, messages: { role: string; content: string }[] ): string { const escapeHtml = (text: string): string => { return text .replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """) .replace(/'/g, "'"); }; const messageHtml = messages .map(m => { const roleClass = (m.role === "system" || m.role === "user" || m.role === "assistant") ? m.role : "other"; return `
${escapeHtml(m.role)}
${escapeHtml(m.content)}
`; }) .join("\n"); return ` Session ${escapeHtml(meta.id)}

Session: ${escapeHtml(meta.id)}

${meta.timestamp ? `

Timestamp: ${escapeHtml(meta.timestamp)}

` : ""}
${messageHtml} `; } /** * `jeo export [id] [--json] [--system] [--html] [--out ]` — print a saved session transcript * (Markdown by default; `--json` for structured; `--system` to include system * messages). Defaults to the latest session when no id is given. */ export async function runExportCommand(args: string[] = []): Promise { const htmlMode = args.includes("--html"); const jsonMode = args.includes("--json"); const includeSystem = args.includes("--system"); if (htmlMode && jsonMode) { console.error("Error: --html and --json options are mutually exclusive."); process.exitCode = 1; return; } // Parse --out let outPath: string | undefined; const outIdx = args.indexOf("--out"); if (outIdx !== -1 && outIdx + 1 < args.length) { outPath = args[outIdx + 1]; } // Find the session ID: first non-flag argument that is not the value after --out let id: string | undefined; for (let i = 0; i < args.length; i++) { const arg = args[i]; if (arg.startsWith("--")) { continue; } if (outIdx !== -1 && i === outIdx + 1) { continue; } id = arg; break; } if (!id) { id = await latestSessionId(); } if (!id) { console.log("No session to export. Pass a session id or run a session first."); return; } if (htmlMode) { try { const { header, messages } = await loadSession(id, process.cwd()); const picked = includeSystem ? messages : messages.filter(m => m.role !== "system"); const html = renderSessionHtml(header, picked); const resolvedOutPath = outPath ? path.resolve(process.cwd(), outPath) : path.join(process.cwd(), `jeo-session-${id}.html`); await fs.writeFile(resolvedOutPath, html, "utf8"); console.log(resolvedOutPath); } catch (err) { console.log(`Could not export session ${id}: ${(err as Error).message}`); } } else { const format: "markdown" | "json" = jsonMode ? "json" : "markdown"; try { console.log(await exportSession(id, format, process.cwd(), { includeSystem })); } catch (err) { console.log(`Could not export session ${id}: ${(err as Error).message}`); } } }