@webdevtoday/grok-cli
Version:
A sophisticated CLI tool for interacting with xAI Grok 4, featuring conversation history, file reference, custom commands, memory system, and genetic development workflows
242 lines • 7.75 kB
JavaScript
"use strict";
/**
* Session management for Grok CLI
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.SessionManager = void 0;
const nanoid_1 = require("nanoid");
const path_1 = require("path");
const os_1 = require("os");
const fs_extra_1 = require("fs-extra");
const history_1 = require("./history");
/**
* Session manager handles conversation sessions and transcripts
*/
class SessionManager {
constructor(config) {
this.currentSession = null;
this.config = config;
this.historyManager = new history_1.HistoryManager();
}
/**
* Create a new session
*/
async createSession(cwd = process.cwd()) {
const sessionId = (0, nanoid_1.nanoid)();
const transcriptPath = await this.getTranscriptPath(sessionId);
this.currentSession = {
id: sessionId,
cwd,
startTime: new Date(),
config: this.config,
history: [],
transcriptPath,
};
await this.saveSession();
return this.currentSession;
}
/**
* Load an existing session
*/
async loadSession(sessionId) {
const transcriptPath = await this.getTranscriptPath(sessionId);
if (!(await (0, fs_extra_1.pathExists)(transcriptPath))) {
return null;
}
try {
const content = await (0, fs_extra_1.readFile)(transcriptPath, 'utf-8');
const lines = content.trim().split('\n').filter(line => line.trim());
const history = [];
let session = {};
for (const line of lines) {
try {
const record = JSON.parse(line);
if (record.type === 'session') {
session = {
id: record.sessionId,
cwd: record.cwd,
startTime: new Date(record.startTime),
config: record.config || this.config,
transcriptPath,
history: [],
};
}
else if (record.type === 'message') {
history.push({
role: record.role,
content: record.content,
timestamp: new Date(record.timestamp),
toolCalls: record.toolCalls,
});
}
}
catch {
// Skip malformed lines
}
}
if (session.id) {
this.currentSession = {
...session,
history,
};
return this.currentSession;
}
}
catch (error) {
console.error(`Failed to load session ${sessionId}:`, error);
}
return null;
}
/**
* Get current session
*/
getCurrentSession() {
return this.currentSession;
}
/**
* Add message to current session
*/
async addMessage(message) {
if (!this.currentSession) {
throw new Error('No active session');
}
this.currentSession.history.push(message);
await this.appendToTranscript({
type: 'message',
sessionId: this.currentSession.id,
...message,
});
// Save to history after each message
await this.saveToHistory();
}
/**
* Save current session
*/
async saveSession() {
if (!this.currentSession) {
return;
}
// Write session metadata
await this.appendToTranscript({
type: 'session',
sessionId: this.currentSession.id,
cwd: this.currentSession.cwd,
startTime: this.currentSession.startTime.toISOString(),
config: this.currentSession.config,
});
}
/**
* Get transcript file path for session
*/
async getTranscriptPath(sessionId) {
const grokDir = (0, path_1.join)((0, os_1.homedir)(), '.grok', 'sessions');
await (0, fs_extra_1.ensureDir)(grokDir);
return (0, path_1.join)(grokDir, `${sessionId}.jsonl`);
}
/**
* Append record to transcript file
*/
async appendToTranscript(record) {
if (!this.currentSession) {
return;
}
const line = JSON.stringify(record) + '\n';
await (0, fs_extra_1.writeFile)(this.currentSession.transcriptPath, line, { flag: 'a' });
}
/**
* Update session configuration
*/
updateConfig(config) {
this.config = config;
if (this.currentSession) {
this.currentSession.config = config;
}
}
/**
* List recent sessions
*/
async getRecentSessions(limit = 10) {
const conversations = await this.historyManager.getRecentConversations(limit);
const sessions = [];
for (const conv of conversations) {
const historySession = await this.historyManager.loadConversation(conv.id);
if (historySession) {
sessions.push(historySession.session);
}
}
return sessions;
}
/**
* Continue from the last conversation
*/
async continueLastConversation() {
const lastConversation = await this.historyManager.getLastConversation();
if (!lastConversation) {
return null;
}
return await this.continueFromSession(lastConversation.id);
}
/**
* Continue from a specific session
*/
async continueFromSession(sessionId) {
const historySession = await this.historyManager.loadConversation(sessionId);
if (!historySession) {
return null;
}
// Create new session with history
const newSessionId = (0, nanoid_1.nanoid)();
const transcriptPath = await this.getTranscriptPath(newSessionId);
this.currentSession = {
id: newSessionId,
cwd: historySession.session.cwd,
startTime: new Date(),
config: this.config,
history: [...historySession.messages], // Copy previous messages
transcriptPath,
};
await this.saveSession();
// Add a system message to indicate continuation
await this.addMessage({
role: 'system',
content: `Continuing from previous conversation (${sessionId}) with ${historySession.messages.length} messages.`,
timestamp: new Date(),
});
return this.currentSession;
}
/**
* Save current session to history
*/
async saveToHistory() {
if (!this.currentSession || this.currentSession.history.length === 0) {
return;
}
await this.historyManager.saveConversation(this.currentSession, this.currentSession.history);
}
/**
* Search conversation history
*/
async searchHistory(query, limit = 10) {
return await this.historyManager.searchConversations(query, limit);
}
/**
* Get history statistics
*/
async getHistoryStatistics() {
return await this.historyManager.getStatistics();
}
/**
* Delete a conversation from history
*/
async deleteFromHistory(sessionId) {
return await this.historyManager.deleteConversation(sessionId);
}
/**
* Get history manager instance
*/
getHistoryManager() {
return this.historyManager;
}
}
exports.SessionManager = SessionManager;
//# sourceMappingURL=session.js.map