import type { Argv } from "yargs" import { cmd } from "./cmd" import { Session } from "../../session" import { bootstrap } from "../bootstrap" import { UI } from "../ui" import { Locale } from "../../util/locale" import { EOL } from "os" export const SessionCommand = cmd({ command: "session", describe: "manage sessions", builder: (yargs: Argv) => yargs.command(SessionListCommand).demandCommand(), async handler() {}, }) export const SessionListCommand = cmd({ command: "list", describe: "list sessions", builder: (yargs: Argv) => { return yargs .option("max-count", { alias: "n", describe: "limit to N most recent sessions", type: "number", }) .option("format", { describe: "output format", type: "string", choices: ["table", "json"], default: "table", }) }, handler: async (args) => { await bootstrap(process.cwd(), async () => { const sessions = [] for await (const session of Session.list()) { if (!session.parentID) { sessions.push(session) } } sessions.sort((a, b) => b.time.updated - a.time.updated) const limitedSessions = args.maxCount ? sessions.slice(0, args.maxCount) : sessions if (limitedSessions.length === 0) { return } let output: string if (args.format === "json") { output = formatSessionJSON(limitedSessions) } else { output = formatSessionTable(limitedSessions) } const shouldPaginate = process.stdout.isTTY && !args.maxCount && args.format === "table" if (shouldPaginate) { const proc = Bun.spawn({ cmd: ["less", "-R", "-S"], stdin: "pipe", stdout: "inherit", stderr: "inherit", }) proc.stdin.write(output) proc.stdin.end() await proc.exited } else { console.log(output) } }) }, }) function formatSessionTable(sessions: Session.Info[]): string { const lines: string[] = [] const maxIdWidth = Math.max(20, ...sessions.map((s) => s.id.length)) const maxTitleWidth = Math.max(25, ...sessions.map((s) => s.title.length)) const header = `Session ID${" ".repeat(maxIdWidth - 10)} Title${" ".repeat(maxTitleWidth - 5)} Updated` lines.push(header) lines.push("─".repeat(header.length)) for (const session of sessions) { const truncatedTitle = Locale.truncate(session.title, maxTitleWidth) const timeStr = Locale.todayTimeOrDateTime(session.time.updated) const line = `${session.id.padEnd(maxIdWidth)} ${truncatedTitle.padEnd(maxTitleWidth)} ${timeStr}` lines.push(line) } return lines.join(EOL) } function formatSessionJSON(sessions: Session.Info[]): string { const jsonData = sessions.map((session) => ({ id: session.id, title: session.title, updated: session.time.updated, created: session.time.created, projectId: session.projectID, directory: session.directory, })) return JSON.stringify(jsonData, null, 2) }