mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-09-30 12:39:42 +02:00
chore: bump version to 0.1439
This commit is contained in:
@@ -16,7 +16,7 @@ When user says "COM":
|
||||
1. Increment version in BOTH `package.json` AND `CLAUDE.md`
|
||||
2. Run: `git add -A && git commit -m "chore: bump version to X.XXXX" && git push && npm run build && systemctl --user restart claudeman-web`
|
||||
|
||||
**Version**: 0.1438 (must match `package.json`)
|
||||
**Version**: 0.1439 (must match `package.json`)
|
||||
|
||||
## Project Overview
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "claudeman",
|
||||
"version": "0.1438",
|
||||
"version": "0.1439",
|
||||
"description": "The missing control plane for Claude Code - run 20 autonomous agents with real-time monitoring and session persistence",
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
|
||||
@@ -338,6 +338,9 @@ export class Session extends EventEmitter {
|
||||
// Image watcher setting (per-session toggle)
|
||||
private _imageWatcherEnabled: boolean = true;
|
||||
|
||||
// Flicker filter setting (per-session toggle, applied on frontend)
|
||||
private _flickerFilterEnabled: boolean = false;
|
||||
|
||||
// Timer tracking for cleanup (prevents memory leaks)
|
||||
private _autoCompactTimer: NodeJS.Timeout | null = null;
|
||||
private _autoClearTimer: NodeJS.Timeout | null = null;
|
||||
@@ -694,6 +697,14 @@ export class Session extends EventEmitter {
|
||||
this._imageWatcherEnabled = enabled;
|
||||
}
|
||||
|
||||
get flickerFilterEnabled(): boolean {
|
||||
return this._flickerFilterEnabled;
|
||||
}
|
||||
|
||||
set flickerFilterEnabled(enabled: boolean) {
|
||||
this._flickerFilterEnabled = enabled;
|
||||
}
|
||||
|
||||
isIdle(): boolean {
|
||||
return this._status === 'idle';
|
||||
}
|
||||
@@ -734,6 +745,7 @@ export class Session extends EventEmitter {
|
||||
niceEnabled: this._niceConfig.enabled,
|
||||
niceValue: this._niceConfig.niceValue,
|
||||
color: this._color,
|
||||
flickerFilterEnabled: this._flickerFilterEnabled,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -180,6 +180,8 @@ export interface SessionState {
|
||||
niceValue?: number;
|
||||
/** User-assigned color for visual differentiation */
|
||||
color?: SessionColor;
|
||||
/** Flicker filter enabled (buffers output after screen clears) */
|
||||
flickerFilterEnabled?: boolean;
|
||||
}
|
||||
|
||||
// ========== Global Stats Types ==========
|
||||
|
||||
+132
-2
@@ -631,6 +631,7 @@ class ClaudemanApp {
|
||||
// Once set, never recalculated. Persisted to localStorage and server.
|
||||
this.subagentParentMap = new Map();
|
||||
this.ralphStatePanelCollapsed = true; // Default to collapsed
|
||||
this.ralphClosedSessions = new Set(); // Sessions where user explicitly closed Ralph panel
|
||||
|
||||
// Plan subagent windows (visible agents during plan generation)
|
||||
this.planSubagents = new Map(); // Map<agentId, { type, model, status, startTime, element, relativePos }>
|
||||
@@ -667,6 +668,11 @@ class ClaudemanApp {
|
||||
this._wasAtBottomBeforeWrite = true; // Default to true for sticky scroll
|
||||
this.syncWaitTimeout = null; // Timeout for incomplete sync blocks
|
||||
|
||||
// Flicker filter state (buffers output after screen clears)
|
||||
this.flickerFilterBuffer = '';
|
||||
this.flickerFilterActive = false;
|
||||
this.flickerFilterTimeout = null;
|
||||
|
||||
// Render debouncing
|
||||
this.renderSessionTabsTimeout = null;
|
||||
this.renderRalphStatePanelTimeout = null;
|
||||
@@ -1053,6 +1059,44 @@ class ClaudemanApp {
|
||||
this._wasAtBottomBeforeWrite = this.isTerminalAtBottom();
|
||||
}
|
||||
|
||||
// Check if flicker filter is enabled for current session
|
||||
const session = this.activeSessionId ? this.sessions.get(this.activeSessionId) : null;
|
||||
const flickerFilterEnabled = session?.flickerFilterEnabled ?? false;
|
||||
|
||||
// Flicker filter: detect screen clear patterns and buffer output
|
||||
if (flickerFilterEnabled) {
|
||||
// Detect Ink's screen clear patterns:
|
||||
// - ESC[2J (clear entire screen)
|
||||
// - ESC[H ESC[J (cursor home + clear to end)
|
||||
// - ESC[?25l ESC[H (hide cursor + home - common Ink pattern)
|
||||
const hasScreenClear = data.includes('\x1b[2J') ||
|
||||
data.includes('\x1b[H\x1b[J') ||
|
||||
(data.includes('\x1b[H') && data.includes('\x1b[?25l'));
|
||||
|
||||
if (hasScreenClear) {
|
||||
// Screen clear detected - activate flicker filter
|
||||
this.flickerFilterActive = true;
|
||||
this.flickerFilterBuffer += data;
|
||||
|
||||
// Clear any existing timeout and set a new one
|
||||
if (this.flickerFilterTimeout) {
|
||||
clearTimeout(this.flickerFilterTimeout);
|
||||
}
|
||||
this.flickerFilterTimeout = setTimeout(() => {
|
||||
this.flickerFilterTimeout = null;
|
||||
this.flushFlickerBuffer();
|
||||
}, SYNC_WAIT_TIMEOUT_MS); // 50ms buffer window
|
||||
|
||||
return; // Don't process normally, wait for buffer window
|
||||
}
|
||||
|
||||
if (this.flickerFilterActive) {
|
||||
// Filter is active, accumulate data
|
||||
this.flickerFilterBuffer += data;
|
||||
return; // Continue buffering
|
||||
}
|
||||
}
|
||||
|
||||
// Accumulate raw data (may contain DEC 2026 markers)
|
||||
this.pendingWrites += data;
|
||||
|
||||
@@ -1090,6 +1134,28 @@ class ClaudemanApp {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush the flicker filter buffer to the terminal.
|
||||
* Called after the buffer window expires.
|
||||
*/
|
||||
flushFlickerBuffer() {
|
||||
if (!this.flickerFilterBuffer) return;
|
||||
|
||||
// Transfer buffered data to normal pending writes
|
||||
this.pendingWrites += this.flickerFilterBuffer;
|
||||
this.flickerFilterBuffer = '';
|
||||
this.flickerFilterActive = false;
|
||||
|
||||
// Trigger a normal flush
|
||||
if (!this.writeFrameScheduled) {
|
||||
this.writeFrameScheduled = true;
|
||||
requestAnimationFrame(() => {
|
||||
this.flushPendingWrites();
|
||||
this.writeFrameScheduled = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush pending writes to terminal, processing DEC 2026 sync markers.
|
||||
* Strips markers and writes content atomically within a single frame.
|
||||
@@ -1366,6 +1432,7 @@ class ClaudemanApp {
|
||||
}
|
||||
this.terminalBuffers.delete(data.id);
|
||||
this.ralphStates.delete(data.id); // Clean up ralph state for this session
|
||||
this.ralphClosedSessions.delete(data.id); // Clean up closed tracking for this session
|
||||
this.projectInsights.delete(data.id); // Clean up project insights for this session
|
||||
this.closeSessionLogViewerWindows(data.id); // Close log viewer windows for this session
|
||||
this.closeSessionImagePopups(data.id); // Close image popup windows for this session
|
||||
@@ -1803,16 +1870,22 @@ class ClaudemanApp {
|
||||
// Ralph loop/todo events
|
||||
addListener('session:ralphLoopUpdate', (e) => {
|
||||
const data = JSON.parse(e.data);
|
||||
// Skip if user explicitly closed this session's Ralph panel
|
||||
if (this.ralphClosedSessions.has(data.sessionId)) return;
|
||||
this.updateRalphState(data.sessionId, { loop: data.state });
|
||||
});
|
||||
|
||||
addListener('session:ralphTodoUpdate', (e) => {
|
||||
const data = JSON.parse(e.data);
|
||||
// Skip if user explicitly closed this session's Ralph panel
|
||||
if (this.ralphClosedSessions.has(data.sessionId)) return;
|
||||
this.updateRalphState(data.sessionId, { todos: data.todos });
|
||||
});
|
||||
|
||||
addListener('session:ralphCompletionDetected', (e) => {
|
||||
const data = JSON.parse(e.data);
|
||||
// Skip if user explicitly closed this session's Ralph panel
|
||||
if (this.ralphClosedSessions.has(data.sessionId)) return;
|
||||
// Prevent duplicate notifications for the same completion
|
||||
const completionKey = `${data.sessionId}:${data.phrase}`;
|
||||
if (this._shownCompletions?.has(completionKey)) {
|
||||
@@ -1846,11 +1919,15 @@ class ClaudemanApp {
|
||||
// RALPH_STATUS block and circuit breaker events
|
||||
addListener('session:ralphStatusUpdate', (e) => {
|
||||
const data = JSON.parse(e.data);
|
||||
// Skip if user explicitly closed this session's Ralph panel
|
||||
if (this.ralphClosedSessions.has(data.sessionId)) return;
|
||||
this.updateRalphState(data.sessionId, { statusBlock: data.block });
|
||||
});
|
||||
|
||||
addListener('session:circuitBreakerUpdate', (e) => {
|
||||
const data = JSON.parse(e.data);
|
||||
// Skip if user explicitly closed this session's Ralph panel
|
||||
if (this.ralphClosedSessions.has(data.sessionId)) return;
|
||||
this.updateRalphState(data.sessionId, { circuitBreaker: data.status });
|
||||
// Notify if circuit breaker opens
|
||||
if (data.status.state === 'OPEN') {
|
||||
@@ -2222,6 +2299,13 @@ class ClaudemanApp {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
this.idleTimers.clear();
|
||||
// Clear flicker filter state
|
||||
if (this.flickerFilterTimeout) {
|
||||
clearTimeout(this.flickerFilterTimeout);
|
||||
this.flickerFilterTimeout = null;
|
||||
}
|
||||
this.flickerFilterBuffer = '';
|
||||
this.flickerFilterActive = false;
|
||||
// Clear pending hooks
|
||||
this.pendingHooks.clear();
|
||||
// Clear tab alerts
|
||||
@@ -2250,8 +2334,8 @@ class ClaudemanApp {
|
||||
}
|
||||
data.sessions.forEach(s => {
|
||||
this.sessions.set(s.id, s);
|
||||
// Load ralph state from session data
|
||||
if (s.ralphLoop || s.ralphTodos) {
|
||||
// Load ralph state from session data (only if not explicitly closed by user)
|
||||
if ((s.ralphLoop || s.ralphTodos) && !this.ralphClosedSessions.has(s.id)) {
|
||||
this.ralphStates.set(s.id, {
|
||||
loop: s.ralphLoop || null,
|
||||
todos: s.ralphTodos || []
|
||||
@@ -2842,6 +2926,14 @@ class ClaudemanApp {
|
||||
async selectSession(sessionId) {
|
||||
if (this.activeSessionId === sessionId) return;
|
||||
|
||||
// Clean up flicker filter state when switching sessions
|
||||
if (this.flickerFilterTimeout) {
|
||||
clearTimeout(this.flickerFilterTimeout);
|
||||
this.flickerFilterTimeout = null;
|
||||
}
|
||||
this.flickerFilterBuffer = '';
|
||||
this.flickerFilterActive = false;
|
||||
|
||||
this.activeSessionId = sessionId;
|
||||
this.hideWelcome();
|
||||
// Clear idle hooks on view, but keep action hooks until user interacts
|
||||
@@ -5754,6 +5846,9 @@ class ClaudemanApp {
|
||||
|
||||
const sessionId = data.sessionId;
|
||||
|
||||
// Clear from closed set in case user previously closed Ralph for this session
|
||||
this.ralphClosedSessions.delete(sessionId);
|
||||
|
||||
// Step 2: Configure Ralph tracker for this session
|
||||
await fetch(`/api/sessions/${sessionId}/ralph-config`, {
|
||||
method: 'POST',
|
||||
@@ -6932,6 +7027,7 @@ class ClaudemanApp {
|
||||
document.getElementById('modalAutoClearEnabled').checked = session.autoClearEnabled ?? false;
|
||||
document.getElementById('modalAutoClearThreshold').value = session.autoClearThreshold ?? 140000;
|
||||
document.getElementById('modalImageWatcherEnabled').checked = session.imageWatcherEnabled ?? true;
|
||||
document.getElementById('modalFlickerFilterEnabled').checked = session.flickerFilterEnabled ?? false;
|
||||
|
||||
// Initialize color picker with current session color
|
||||
const currentColor = session.color || 'default';
|
||||
@@ -7010,6 +7106,26 @@ class ClaudemanApp {
|
||||
}
|
||||
}
|
||||
|
||||
async toggleFlickerFilter() {
|
||||
if (!this.editingSessionId) return;
|
||||
const enabled = document.getElementById('modalFlickerFilterEnabled').checked;
|
||||
try {
|
||||
await fetch(`/api/sessions/${this.editingSessionId}/flicker-filter`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ enabled })
|
||||
});
|
||||
// Update local session state
|
||||
const session = this.sessions.get(this.editingSessionId);
|
||||
if (session) {
|
||||
session.flickerFilterEnabled = enabled;
|
||||
}
|
||||
this.showToast(`Flicker filter ${enabled ? 'enabled' : 'disabled'}`, 'success');
|
||||
} catch (err) {
|
||||
this.showToast('Failed to toggle flicker filter', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
async autoSaveRespawnConfig() {
|
||||
if (!this.editingSessionId) return;
|
||||
const config = {
|
||||
@@ -7715,6 +7831,11 @@ class ClaudemanApp {
|
||||
|
||||
const config = this.getRalphConfig();
|
||||
|
||||
// If user is enabling Ralph, clear from closed set
|
||||
if (config.enabled) {
|
||||
this.ralphClosedSessions.delete(this.editingSessionId);
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await fetch(`/api/sessions/${this.editingSessionId}/ralph-config`, {
|
||||
method: 'POST',
|
||||
@@ -9045,6 +9166,9 @@ class ClaudemanApp {
|
||||
async closeRalphTracker() {
|
||||
if (!this.activeSessionId) return;
|
||||
|
||||
// Mark this session as explicitly closed - will stay hidden until user re-enables
|
||||
this.ralphClosedSessions.add(this.activeSessionId);
|
||||
|
||||
// Disable tracker via API
|
||||
await fetch(`/api/sessions/${this.activeSessionId}/ralph-config`, {
|
||||
method: 'POST',
|
||||
@@ -9343,6 +9467,12 @@ class ClaudemanApp {
|
||||
|
||||
if (!panel) return;
|
||||
|
||||
// If user explicitly closed this session's Ralph panel, keep it hidden
|
||||
if (this.ralphClosedSessions.has(this.activeSessionId)) {
|
||||
panel.style.display = 'none';
|
||||
return;
|
||||
}
|
||||
|
||||
const state = this.ralphStates.get(this.activeSessionId);
|
||||
|
||||
// Check if there's anything to show
|
||||
|
||||
@@ -583,6 +583,16 @@
|
||||
</label>
|
||||
<span class="form-hint">Auto-popup new images (screenshots, generated files) in this session's directory</span>
|
||||
</div>
|
||||
|
||||
<div class="form-section-header">Performance</div>
|
||||
<div class="form-row form-row-switch">
|
||||
<label>Flicker Filter</label>
|
||||
<label class="switch">
|
||||
<input type="checkbox" id="modalFlickerFilterEnabled" onchange="app.toggleFlickerFilter()">
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
<span class="form-hint">Buffers output after screen clears to reduce Ink UI flickering (adds ~50ms latency)</span>
|
||||
</div>
|
||||
</div><!-- End context-tab -->
|
||||
|
||||
<!-- Ralph Wiggum Tab Content -->
|
||||
|
||||
+39
-4
@@ -280,6 +280,7 @@ export class WebServer extends EventEmitter {
|
||||
private store = getStore();
|
||||
private port: number;
|
||||
private https: boolean;
|
||||
private testMode: boolean;
|
||||
private screenManager: ScreenManager;
|
||||
// Terminal batching for performance
|
||||
private terminalBatches: Map<string, string> = new Map();
|
||||
@@ -325,10 +326,11 @@ export class WebServer extends EventEmitter {
|
||||
error: (error: Error, sessionId?: string) => void;
|
||||
} | null = null;
|
||||
|
||||
constructor(port: number = 3000, https: boolean = false) {
|
||||
constructor(port: number = 3000, https: boolean = false, testMode: boolean = false) {
|
||||
super();
|
||||
this.port = port;
|
||||
this.https = https;
|
||||
this.testMode = testMode;
|
||||
|
||||
if (https) {
|
||||
const { key, cert } = getOrCreateSelfSignedCert();
|
||||
@@ -1879,6 +1881,32 @@ export class WebServer extends EventEmitter {
|
||||
};
|
||||
});
|
||||
|
||||
// Toggle flicker filter for a session
|
||||
this.app.post('/api/sessions/:id/flicker-filter', async (req) => {
|
||||
const { id } = req.params as { id: string };
|
||||
const body = req.body as { enabled: boolean };
|
||||
const session = this.sessions.get(id);
|
||||
|
||||
if (!session) {
|
||||
return createErrorResponse(ApiErrorCode.NOT_FOUND, 'Session not found');
|
||||
}
|
||||
|
||||
if (body.enabled === undefined) {
|
||||
return createErrorResponse(ApiErrorCode.INVALID_INPUT, 'enabled field is required');
|
||||
}
|
||||
|
||||
session.flickerFilterEnabled = body.enabled;
|
||||
this.persistSessionState(session);
|
||||
this.broadcast('session:updated', this.getSessionStateWithRespawn(session));
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: {
|
||||
flickerFilterEnabled: body.enabled,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
// Quick run (create session, run prompt, return result, then cleanup)
|
||||
this.app.post('/api/run', async (req) => {
|
||||
// Prevent unbounded session creation
|
||||
@@ -4414,7 +4442,10 @@ NOW: Generate the implementation plan for the task above. Think step by step.`;
|
||||
|
||||
// Restore screen sessions BEFORE accepting connections
|
||||
// This prevents race conditions where clients connect before state is ready
|
||||
await this.restoreScreenSessions();
|
||||
// CRITICAL: Skip in test mode to prevent tests from picking up user sessions
|
||||
if (!this.testMode) {
|
||||
await this.restoreScreenSessions();
|
||||
}
|
||||
|
||||
// Clean up stale sessions from state file that don't have active screens
|
||||
this.cleanupStaleSessions();
|
||||
@@ -4587,6 +4618,10 @@ NOW: Generate the implementation plan for the task above. Think step by step.`;
|
||||
niceValue: savedState.niceValue,
|
||||
});
|
||||
}
|
||||
// Flicker filter (frontend-applied but persisted)
|
||||
if (savedState.flickerFilterEnabled !== undefined) {
|
||||
session.flickerFilterEnabled = savedState.flickerFilterEnabled;
|
||||
}
|
||||
// Respawn controller
|
||||
if (savedState.respawnEnabled && savedState.respawnConfig) {
|
||||
try {
|
||||
@@ -4751,8 +4786,8 @@ NOW: Generate the implementation plan for the task above. Think step by step.`;
|
||||
}
|
||||
}
|
||||
|
||||
export async function startWebServer(port: number = 3000, https: boolean = false): Promise<WebServer> {
|
||||
const server = new WebServer(port, https);
|
||||
export async function startWebServer(port: number = 3000, https: boolean = false, testMode: boolean = false): Promise<WebServer> {
|
||||
const server = new WebServer(port, https, testMode);
|
||||
await server.start();
|
||||
return server;
|
||||
}
|
||||
|
||||
@@ -171,7 +171,7 @@ describe('Agent-Browser Enhanced Tests', () => {
|
||||
closeBrowser();
|
||||
|
||||
// Start web server
|
||||
server = new WebServer(TEST_PORT);
|
||||
server = new WebServer(TEST_PORT, false, true);
|
||||
await server.start();
|
||||
await new Promise(r => setTimeout(r, 1000));
|
||||
|
||||
|
||||
@@ -135,7 +135,7 @@ describe('Browser Framework Comparison Benchmark', () => {
|
||||
|
||||
// Start web servers for each framework
|
||||
for (const [name, port] of Object.entries(PORTS)) {
|
||||
const server = new WebServer(port);
|
||||
const server = new WebServer(port, false, true);
|
||||
await server.start();
|
||||
servers.push(server);
|
||||
console.log(`✅ Started server for ${name} on port ${port}`);
|
||||
|
||||
@@ -92,7 +92,7 @@ describe('Browser E2E Tests', () => {
|
||||
beforeAll(async () => {
|
||||
closeBrowser();
|
||||
|
||||
server = new WebServer(TEST_PORT_BROWSER);
|
||||
server = new WebServer(TEST_PORT_BROWSER, false, true);
|
||||
await server.start();
|
||||
await new Promise(r => setTimeout(r, 1000));
|
||||
|
||||
@@ -211,7 +211,7 @@ describe('SSE Events API', () => {
|
||||
let createdSessions: string[] = [];
|
||||
|
||||
beforeAll(async () => {
|
||||
server = new WebServer(TEST_PORT_SSE);
|
||||
server = new WebServer(TEST_PORT_SSE, false, true);
|
||||
await server.start();
|
||||
await new Promise(r => setTimeout(r, 1000));
|
||||
}, 30000);
|
||||
@@ -280,7 +280,7 @@ describe('Hook Events API', () => {
|
||||
let createdSessions: string[] = [];
|
||||
|
||||
beforeAll(async () => {
|
||||
server = new WebServer(TEST_PORT_HOOK);
|
||||
server = new WebServer(TEST_PORT_HOOK, false, true);
|
||||
await server.start();
|
||||
await new Promise(r => setTimeout(r, 1000));
|
||||
}, 30000);
|
||||
@@ -345,7 +345,7 @@ describe('Ralph API', () => {
|
||||
let createdSessions: string[] = [];
|
||||
|
||||
beforeAll(async () => {
|
||||
server = new WebServer(TEST_PORT_RALPH);
|
||||
server = new WebServer(TEST_PORT_RALPH, false, true);
|
||||
await server.start();
|
||||
await new Promise(r => setTimeout(r, 1000));
|
||||
}, 30000);
|
||||
|
||||
@@ -32,7 +32,7 @@ let setupComplete = false;
|
||||
describe('Playwright Direct API Tests', () => {
|
||||
beforeAll(async () => {
|
||||
// Start web server
|
||||
server = new WebServer(TEST_PORT);
|
||||
server = new WebServer(TEST_PORT, false, true);
|
||||
await server.start();
|
||||
await new Promise(r => setTimeout(r, 1000));
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ describe('Puppeteer/Chrome Tests', () => {
|
||||
|
||||
beforeAll(async () => {
|
||||
// Start web server
|
||||
server = new WebServer(TEST_PORT);
|
||||
server = new WebServer(TEST_PORT, false, true);
|
||||
await server.start();
|
||||
await new Promise(r => setTimeout(r, 1000));
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ export interface ServerFixture {
|
||||
* @returns ServerFixture with server instance and connection info
|
||||
*/
|
||||
export async function createServerFixture(port: number): Promise<ServerFixture> {
|
||||
const server = new WebServer(port);
|
||||
const server = new WebServer(port, false, true);
|
||||
await server.start();
|
||||
|
||||
// Wait for server to be fully ready
|
||||
|
||||
@@ -13,7 +13,7 @@ describe('Edge Cases and Error Handling', () => {
|
||||
const createdCases: string[] = [];
|
||||
|
||||
beforeAll(async () => {
|
||||
server = new WebServer(TEST_PORT);
|
||||
server = new WebServer(TEST_PORT, false, true);
|
||||
await server.start();
|
||||
baseUrl = `http://localhost:${TEST_PORT}`;
|
||||
});
|
||||
@@ -261,7 +261,7 @@ describe('Concurrent Session Handling', () => {
|
||||
let baseUrl: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
server = new WebServer(TEST_PORT + 1);
|
||||
server = new WebServer(TEST_PORT + 1, false, true);
|
||||
await server.start();
|
||||
baseUrl = `http://localhost:${TEST_PORT + 1}`;
|
||||
});
|
||||
@@ -362,7 +362,7 @@ describe('API Request Validation', () => {
|
||||
let baseUrl: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
server = new WebServer(TEST_PORT + 2);
|
||||
server = new WebServer(TEST_PORT + 2, false, true);
|
||||
await server.start();
|
||||
baseUrl = `http://localhost:${TEST_PORT + 2}`;
|
||||
});
|
||||
|
||||
@@ -93,7 +93,7 @@ describe('File Link Click Tests', () => {
|
||||
testLogFile = join(testDir, 'test.log');
|
||||
writeFileSync(testLogFile, '=== Test Log Started ===\n');
|
||||
|
||||
server = new WebServer(TEST_PORT);
|
||||
server = new WebServer(TEST_PORT, false, true);
|
||||
await server.start();
|
||||
await new Promise(r => setTimeout(r, 1000));
|
||||
|
||||
|
||||
@@ -200,7 +200,7 @@ describe('Hook Event API', () => {
|
||||
let testSessionId: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
server = new WebServer(TEST_PORT);
|
||||
server = new WebServer(TEST_PORT, false, true);
|
||||
await server.start();
|
||||
baseUrl = `http://localhost:${TEST_PORT}`;
|
||||
|
||||
@@ -382,7 +382,7 @@ describe('Hook Data Sanitization', () => {
|
||||
let testSessionId: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
server = new WebServer(TEST_PORT + 1); // Port 3131
|
||||
server = new WebServer(TEST_PORT + 1, false, true); // Port 3131
|
||||
await server.start();
|
||||
baseUrl = `http://localhost:${TEST_PORT + 1}`;
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ describe('Integration Flows', () => {
|
||||
const createdSessions: string[] = [];
|
||||
|
||||
beforeAll(async () => {
|
||||
server = new WebServer(TEST_PORT);
|
||||
server = new WebServer(TEST_PORT, false, true);
|
||||
await server.start();
|
||||
baseUrl = `http://localhost:${TEST_PORT}`;
|
||||
});
|
||||
@@ -278,7 +278,7 @@ describe('SSE Event Flow', () => {
|
||||
const createdSessions: string[] = [];
|
||||
|
||||
beforeAll(async () => {
|
||||
server = new WebServer(TEST_PORT + 1);
|
||||
server = new WebServer(TEST_PORT + 1, false, true);
|
||||
await server.start();
|
||||
baseUrl = `http://localhost:${TEST_PORT + 1}`;
|
||||
});
|
||||
|
||||
@@ -13,7 +13,7 @@ describe('Quick Start API', () => {
|
||||
const createdCases: string[] = [];
|
||||
|
||||
beforeAll(async () => {
|
||||
server = new WebServer(TEST_PORT);
|
||||
server = new WebServer(TEST_PORT, false, true);
|
||||
await server.start();
|
||||
baseUrl = `http://localhost:${TEST_PORT}`;
|
||||
});
|
||||
@@ -147,7 +147,7 @@ describe('Session Management', () => {
|
||||
let baseUrl: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
server = new WebServer(TEST_PORT + 1);
|
||||
server = new WebServer(TEST_PORT + 1, false, true);
|
||||
await server.start();
|
||||
baseUrl = `http://localhost:${TEST_PORT + 1}`;
|
||||
});
|
||||
@@ -204,7 +204,7 @@ describe('Case Management', () => {
|
||||
const createdCases: string[] = [];
|
||||
|
||||
beforeAll(async () => {
|
||||
server = new WebServer(TEST_PORT + 2);
|
||||
server = new WebServer(TEST_PORT + 2, false, true);
|
||||
await server.start();
|
||||
baseUrl = `http://localhost:${TEST_PORT + 2}`;
|
||||
});
|
||||
|
||||
@@ -27,7 +27,7 @@ describe('Ralph Integration Tests', () => {
|
||||
const createdSessions: string[] = [];
|
||||
|
||||
beforeAll(async () => {
|
||||
server = new WebServer(TEST_PORT);
|
||||
server = new WebServer(TEST_PORT, false, true);
|
||||
await server.start();
|
||||
baseUrl = `http://localhost:${TEST_PORT}`;
|
||||
});
|
||||
|
||||
@@ -9,7 +9,7 @@ describe('Scheduled Runs API', () => {
|
||||
const createdRuns: string[] = [];
|
||||
|
||||
beforeAll(async () => {
|
||||
server = new WebServer(TEST_PORT);
|
||||
server = new WebServer(TEST_PORT, false, true);
|
||||
await server.start();
|
||||
baseUrl = `http://localhost:${TEST_PORT}`;
|
||||
});
|
||||
@@ -181,7 +181,7 @@ describe('Quick Run API', () => {
|
||||
let baseUrl: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
server = new WebServer(TEST_PORT + 1);
|
||||
server = new WebServer(TEST_PORT + 1, false, true);
|
||||
await server.start();
|
||||
baseUrl = `http://localhost:${TEST_PORT + 1}`;
|
||||
});
|
||||
|
||||
@@ -19,7 +19,7 @@ describe('Session Cleanup', () => {
|
||||
const createdSessions: string[] = [];
|
||||
|
||||
beforeAll(async () => {
|
||||
server = new WebServer(TEST_PORT);
|
||||
server = new WebServer(TEST_PORT, false, true);
|
||||
await server.start();
|
||||
baseUrl = `http://localhost:${TEST_PORT}`;
|
||||
});
|
||||
@@ -186,7 +186,7 @@ describe('Resource Management', () => {
|
||||
const createdCases: string[] = [];
|
||||
|
||||
beforeAll(async () => {
|
||||
server = new WebServer(TEST_PORT + 1);
|
||||
server = new WebServer(TEST_PORT + 1, false, true);
|
||||
await server.start();
|
||||
baseUrl = `http://localhost:${TEST_PORT + 1}`;
|
||||
});
|
||||
|
||||
@@ -8,7 +8,7 @@ describe('Interactive Session Lifecycle', () => {
|
||||
let baseUrl: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
server = new WebServer(TEST_PORT);
|
||||
server = new WebServer(TEST_PORT, false, true);
|
||||
await server.start();
|
||||
baseUrl = `http://localhost:${TEST_PORT}`;
|
||||
});
|
||||
|
||||
@@ -37,7 +37,7 @@ describe('SSE Events', () => {
|
||||
let baseUrl: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
server = new WebServer(TEST_PORT);
|
||||
server = new WebServer(TEST_PORT, false, true);
|
||||
await server.start();
|
||||
baseUrl = `http://localhost:${TEST_PORT}`;
|
||||
});
|
||||
@@ -180,7 +180,7 @@ describe('SSE Event Types', () => {
|
||||
let baseUrl: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
server = new WebServer(TEST_PORT + 1);
|
||||
server = new WebServer(TEST_PORT + 1, false, true);
|
||||
await server.start();
|
||||
baseUrl = `http://localhost:${TEST_PORT + 1}`;
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user