mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-08 16:39:42 +02:00
chore: bump version to 0.1619
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+68
-11
@@ -16057,22 +16057,76 @@ class ClaudemanApp {
|
||||
let html = '';
|
||||
for (const muxSession of this.muxSessions) {
|
||||
const stats = muxSession.stats || { memoryMB: 0, cpuPercent: 0, childCount: 0 };
|
||||
const modeClass = muxSession.mode === 'shell' ? 'shell' : '';
|
||||
|
||||
// Look up rich session data by sessionId
|
||||
const session = this.sessions.get(muxSession.sessionId);
|
||||
const status = session ? session.status : 'unknown';
|
||||
const isWorking = session ? session.isWorking : false;
|
||||
|
||||
// Status badge
|
||||
let statusLabel, statusClass;
|
||||
if (status === 'idle' && !isWorking) {
|
||||
statusLabel = 'IDLE';
|
||||
statusClass = 'status-idle';
|
||||
} else if (status === 'busy' || isWorking) {
|
||||
statusLabel = 'WORKING';
|
||||
statusClass = 'status-working';
|
||||
} else if (status === 'stopped') {
|
||||
statusLabel = 'STOPPED';
|
||||
statusClass = 'status-stopped';
|
||||
} else {
|
||||
statusLabel = status.toUpperCase();
|
||||
statusClass = '';
|
||||
}
|
||||
|
||||
// Token and cost info
|
||||
const tokens = session && session.tokens ? session.tokens : null;
|
||||
const totalCost = session ? session.totalCost : 0;
|
||||
const model = session ? (session.cliModel || '') : '';
|
||||
const modelShort = model.includes('opus') ? 'opus' : model.includes('sonnet') ? 'sonnet' : model.includes('haiku') ? 'haiku' : '';
|
||||
|
||||
// Ralph/Todo progress
|
||||
const todoStats = session ? session.ralphTodoStats : null;
|
||||
let todoHtml = '';
|
||||
if (todoStats && todoStats.total > 0) {
|
||||
const pct = Math.round((todoStats.completed / todoStats.total) * 100);
|
||||
todoHtml = `<span class="process-stat todo-progress">${todoStats.completed}/${todoStats.total} (${pct}%)</span>`;
|
||||
}
|
||||
|
||||
// Format tokens
|
||||
let tokenHtml = '';
|
||||
if (tokens && tokens.total > 0) {
|
||||
const totalK = (tokens.total / 1000).toFixed(1);
|
||||
tokenHtml = `<span class="process-stat tokens">${totalK}k tok</span>`;
|
||||
}
|
||||
|
||||
// Format cost
|
||||
let costHtml = '';
|
||||
if (totalCost > 0) {
|
||||
costHtml = `<span class="process-stat cost">$${totalCost.toFixed(2)}</span>`;
|
||||
}
|
||||
|
||||
// Model badge
|
||||
let modelHtml = '';
|
||||
if (modelShort) {
|
||||
modelHtml = `<span class="monitor-model-badge ${modelShort}">${modelShort}</span>`;
|
||||
}
|
||||
|
||||
html += `
|
||||
<div class="process-item">
|
||||
<span class="process-mode ${modeClass}">${muxSession.mode}</span>
|
||||
<span class="monitor-status-badge ${statusClass}">${statusLabel}</span>
|
||||
<div class="process-info">
|
||||
<div class="process-name">${this.escapeHtml(muxSession.name || muxSession.muxName)}</div>
|
||||
<div class="process-name">${modelHtml} ${this.escapeHtml(muxSession.name || muxSession.muxName)}</div>
|
||||
<div class="process-meta">
|
||||
${tokenHtml}
|
||||
${costHtml}
|
||||
${todoHtml}
|
||||
<span class="process-stat memory">${stats.memoryMB}MB</span>
|
||||
<span class="process-stat cpu">${stats.cpuPercent}%</span>
|
||||
<span class="process-stat children">${stats.childCount} children</span>
|
||||
<span>PID: ${muxSession.pid}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="process-actions">
|
||||
<button class="btn-toolbar btn-sm btn-danger" onclick="app.killMuxSession('${this.escapeHtml(muxSession.sessionId)}')" title="Kill tmux session">Kill</button>
|
||||
<button class="btn-toolbar btn-sm btn-danger" onclick="app.killMuxSession('${this.escapeHtml(muxSession.sessionId)}')" title="Kill session">Kill</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -16128,13 +16182,16 @@ class ClaudemanApp {
|
||||
if (!confirm('Kill this mux session?')) return;
|
||||
|
||||
try {
|
||||
await fetch(`/api/mux-sessions/${sessionId}`, { method: 'DELETE' });
|
||||
this.muxSessions = this.muxSessions.filter(s => s.sessionId !== sessionId);
|
||||
this.renderMuxSessions();
|
||||
this.showToast('Tmux session killed', 'success');
|
||||
// Use closeSession to properly clean up both the session tab and tmux process
|
||||
// (closeSession handles its own toast messaging)
|
||||
await this.closeSession(sessionId, true);
|
||||
} catch (err) {
|
||||
this.showToast('Failed to kill tmux session', 'error');
|
||||
// Fallback: kill mux directly if session cleanup fails
|
||||
try { await fetch(`/api/mux-sessions/${sessionId}`, { method: 'DELETE' }); } catch (_ignored) {}
|
||||
this.showToast('Tmux session killed', 'success');
|
||||
}
|
||||
this.muxSessions = this.muxSessions.filter(s => s.sessionId !== sessionId);
|
||||
this.renderMuxSessions();
|
||||
}
|
||||
|
||||
async reconcileMuxSessions() {
|
||||
|
||||
Reference in New Issue
Block a user