Skip to main content
Glama
session.ts3.4 kB
import { randomUUID } from 'node:crypto'; import { writeFileSync, readFileSync, existsSync, unlinkSync } from 'node:fs'; import { resolve } from 'node:path'; import { DebugLogServer } from './server.js'; import type { DebugSession, Instrument, InstrumentOptions, Language } from './types.js'; export class SessionManager { private session: DebugSession | null = null; private server: DebugLogServer | null = null; private workingDirectory: string; constructor(workingDirectory: string) { this.workingDirectory = workingDirectory; } async startSession(port: number = 9876): Promise<DebugSession> { if (this.session) { throw new Error('Debug session already active. Stop it first.'); } const logFile = resolve(this.workingDirectory, 'debug.log'); // Clear any existing log file if (existsSync(logFile)) { unlinkSync(logFile); } writeFileSync(logFile, ''); this.server = new DebugLogServer(port, logFile); await this.server.start(); this.session = { id: randomUUID(), port, startedAt: Date.now(), logFile, instruments: new Map() }; return this.session; } async stopSession(): Promise<void> { if (this.server) { await this.server.stop(); this.server = null; } this.session = null; } getSession(): DebugSession | null { return this.session; } isActive(): boolean { return this.session !== null; } addInstrument(options: InstrumentOptions): Instrument { if (!this.session) { throw new Error('No active debug session'); } const language = this.detectLanguage(options.file); const instrument: Instrument = { id: `dbg-${randomUUID().slice(0, 8)}`, file: resolve(this.workingDirectory, options.file), line: options.line, language, capture: options.capture, createdAt: Date.now() }; this.session.instruments.set(instrument.id, instrument); return instrument; } removeInstrument(id: string): boolean { if (!this.session) { throw new Error('No active debug session'); } return this.session.instruments.delete(id); } getInstruments(): Instrument[] { if (!this.session) { return []; } return Array.from(this.session.instruments.values()); } getInstrumentsByFile(file: string): Instrument[] { const resolvedFile = resolve(this.workingDirectory, file); return this.getInstruments().filter(i => i.file === resolvedFile); } clearInstruments(): void { if (this.session) { this.session.instruments.clear(); } } readLogs(): string { if (!this.session) { throw new Error('No active debug session'); } if (!existsSync(this.session.logFile)) { return ''; } return readFileSync(this.session.logFile, 'utf-8'); } clearLogs(): void { if (!this.session) { throw new Error('No active debug session'); } writeFileSync(this.session.logFile, ''); } private detectLanguage(file: string): Language { const ext = file.split('.').pop()?.toLowerCase(); switch (ext) { case 'ts': case 'tsx': return 'typescript'; case 'js': case 'jsx': case 'mjs': case 'cjs': return 'javascript'; case 'py': return 'python'; default: return 'javascript'; // Default fallback } } }

Implementation Reference

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/iarmankhan/agentic-debugger'

If you have feedback or need assistance with the MCP directory API, please join our Discord server