mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-09-30 12: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:
@@ -35,7 +35,7 @@ When user says "COM":
|
||||
1. Increment version in BOTH `package.json` AND `CLAUDE.md` (verify they match with `grep version package.json && grep Version 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.1618 (must match `package.json`)
|
||||
**Version**: 0.1619 (must match `package.json`)
|
||||
|
||||
## Project Overview
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "claudeman",
|
||||
"version": "0.1618",
|
||||
"version": "0.1619",
|
||||
"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",
|
||||
|
||||
+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' });
|
||||
// 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) {
|
||||
// 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();
|
||||
this.showToast('Tmux session killed', 'success');
|
||||
} catch (err) {
|
||||
this.showToast('Failed to kill tmux session', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
async reconcileMuxSessions() {
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
<meta name="google" content="notranslate">
|
||||
<title>Claudeman</title>
|
||||
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Cdefs%3E%3ClinearGradient id='g' x1='0%25' y1='0%25' x2='100%25' y2='100%25'%3E%3Cstop offset='0%25' stop-color='%2360a5fa'/%3E%3Cstop offset='100%25' stop-color='%233b82f6'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='32' height='32' rx='6' fill='%230a0a0a'/%3E%3Cpath d='M18 4L8 18h6l-2 10 10-14h-6z' fill='url(%23g)'/%3E%3C/svg%3E">
|
||||
<link rel="stylesheet" href="styles.css?v=0.1597">
|
||||
<link rel="stylesheet" href="mobile.css?v=0.1597" media="(max-width: 1023px)">
|
||||
<link rel="stylesheet" href="styles.css?v=0.1618">
|
||||
<link rel="stylesheet" href="mobile.css?v=0.1618" media="(max-width: 1023px)">
|
||||
<!-- xterm.css loaded async — terminal won't display until xterm.js runs anyway -->
|
||||
<link rel="preload" href="vendor/xterm.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
|
||||
<noscript><link rel="stylesheet" href="vendor/xterm.css"></noscript>
|
||||
@@ -1560,6 +1560,6 @@
|
||||
<!-- Lines drawn dynamically -->
|
||||
</svg>
|
||||
|
||||
<script defer src="app.js?v=0.1597"></script>
|
||||
<script defer src="app.js?v=0.1618"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -4291,6 +4291,53 @@ kbd {
|
||||
color: var(--yellow);
|
||||
}
|
||||
|
||||
/* Monitor status badges */
|
||||
.monitor-status-badge {
|
||||
font-size: 0.55rem;
|
||||
font-weight: 700;
|
||||
padding: 2px 6px;
|
||||
border-radius: 3px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
white-space: nowrap;
|
||||
min-width: 52px;
|
||||
text-align: center;
|
||||
}
|
||||
.monitor-status-badge.status-idle {
|
||||
background: rgba(234, 179, 8, 0.2);
|
||||
color: var(--yellow);
|
||||
}
|
||||
.monitor-status-badge.status-working {
|
||||
background: rgba(74, 222, 128, 0.2);
|
||||
color: var(--green);
|
||||
animation: pulse-working 2s ease-in-out infinite;
|
||||
}
|
||||
.monitor-status-badge.status-stopped {
|
||||
background: rgba(239, 68, 68, 0.2);
|
||||
color: var(--red, #ef4444);
|
||||
}
|
||||
@keyframes pulse-working {
|
||||
0%, 100% { opacity: 1; }
|
||||
50% { opacity: 0.6; }
|
||||
}
|
||||
|
||||
/* Monitor model badges */
|
||||
.monitor-model-badge {
|
||||
font-size: 0.55rem;
|
||||
padding: 1px 4px;
|
||||
border-radius: 2px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.monitor-model-badge.opus { background: rgba(168, 85, 247, 0.2); color: #c084fc; }
|
||||
.monitor-model-badge.sonnet { background: rgba(59, 130, 246, 0.2); color: #60a5fa; }
|
||||
.monitor-model-badge.haiku { background: rgba(74, 222, 128, 0.2); color: #4ade80; }
|
||||
|
||||
/* Monitor stat colors */
|
||||
.process-stat.tokens { color: var(--accent-hover); }
|
||||
.process-stat.cost { color: #f59e0b; }
|
||||
.process-stat.todo-progress { color: #c084fc; }
|
||||
|
||||
/* Combined Monitor Panel (Tmux Sessions + Background Tasks) */
|
||||
.monitor-panel {
|
||||
position: fixed;
|
||||
|
||||
Reference in New Issue
Block a user