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)}
${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}`);
}
}
}