chore: bump version to 0.1438

This commit is contained in:
arkon
2026-01-30 17:20:53 +01:00
parent f4612278ef
commit 5b6dd078f1
20 changed files with 2757 additions and 182 deletions
+29 -17
View File
@@ -6504,8 +6504,14 @@ class ClaudemanApp {
if (total > 0) {
tokensEl.style.display = '';
const tokenStr = this.formatTokens(total);
const estimatedCost = this.estimateCost(input, output);
tokensEl.textContent = `${tokenStr} tokens · $${estimatedCost.toFixed(2)}`;
const settings = this.loadAppSettingsFromStorage();
const showCost = settings.showCost ?? false;
if (showCost) {
const estimatedCost = this.estimateCost(input, output);
tokensEl.textContent = `${tokenStr} tokens · $${estimatedCost.toFixed(2)}`;
} else {
tokensEl.textContent = `${tokenStr} tokens`;
}
} else {
tokensEl.style.display = 'none';
}
@@ -6865,10 +6871,14 @@ class ClaudemanApp {
const estimatedCost = this.estimateCost(totalInput, totalOutput);
const tokenEl = this.$('headerTokens');
if (tokenEl) {
tokenEl.textContent = total > 0 ? `${display} tokens · $${estimatedCost.toFixed(2)}` : '0 tokens';
const settings = this.loadAppSettingsFromStorage();
const showCost = settings.showCost ?? false;
tokenEl.textContent = total > 0
? (showCost ? `${display} tokens · $${estimatedCost.toFixed(2)}` : `${display} tokens`)
: '0 tokens';
tokenEl.title = this.globalStats
? `Lifetime: ${this.globalStats.totalSessionsCreated} sessions created\nEstimated cost based on Claude Opus pricing`
: 'Token usage across active sessions\nEstimated cost based on Claude Opus pricing';
? `Lifetime: ${this.globalStats.totalSessionsCreated} sessions created${showCost ? '\nEstimated cost based on Claude Opus pricing' : ''}`
: `Token usage across active sessions${showCost ? '\nEstimated cost based on Claude Opus pricing' : ''}`;
}
}
@@ -7781,16 +7791,17 @@ class ClaudemanApp {
document.getElementById('appSettingsDefaultDir').value = settings.defaultWorkingDir || '';
document.getElementById('appSettingsRalphEnabled').checked = settings.ralphTrackerEnabled ?? false;
// Header visibility settings (default to true/enabled)
document.getElementById('appSettingsShowFontControls').checked = settings.showFontControls ?? true;
document.getElementById('appSettingsShowFontControls').checked = settings.showFontControls ?? false;
document.getElementById('appSettingsShowSystemStats').checked = settings.showSystemStats ?? true;
document.getElementById('appSettingsShowTokenCount').checked = settings.showTokenCount ?? true;
document.getElementById('appSettingsShowCost').checked = settings.showCost ?? false;
document.getElementById('appSettingsShowMonitor').checked = settings.showMonitor ?? true;
document.getElementById('appSettingsShowProjectInsights').checked = settings.showProjectInsights ?? true;
document.getElementById('appSettingsShowProjectInsights').checked = settings.showProjectInsights ?? false;
document.getElementById('appSettingsShowFileBrowser').checked = settings.showFileBrowser ?? false;
document.getElementById('appSettingsShowSubagents').checked = settings.showSubagents ?? true;
document.getElementById('appSettingsShowSubagents').checked = settings.showSubagents ?? false;
document.getElementById('appSettingsSubagentTracking').checked = settings.subagentTrackingEnabled ?? true;
document.getElementById('appSettingsSubagentActiveTabOnly').checked = settings.subagentActiveTabOnly ?? false;
document.getElementById('appSettingsImageWatcherEnabled').checked = settings.imageWatcherEnabled ?? true;
document.getElementById('appSettingsSubagentActiveTabOnly').checked = settings.subagentActiveTabOnly ?? true;
document.getElementById('appSettingsImageWatcherEnabled').checked = settings.imageWatcherEnabled ?? false;
// Claude CLI settings
const claudeModeSelect = document.getElementById('appSettingsClaudeMode');
const allowedToolsRow = document.getElementById('allowedToolsRow');
@@ -7906,6 +7917,7 @@ class ClaudemanApp {
showFontControls: document.getElementById('appSettingsShowFontControls').checked,
showSystemStats: document.getElementById('appSettingsShowSystemStats').checked,
showTokenCount: document.getElementById('appSettingsShowTokenCount').checked,
showCost: document.getElementById('appSettingsShowCost').checked,
showMonitor: document.getElementById('appSettingsShowMonitor').checked,
showProjectInsights: document.getElementById('appSettingsShowProjectInsights').checked,
showFileBrowser: document.getElementById('appSettingsShowFileBrowser').checked,
@@ -8107,7 +8119,7 @@ class ClaudemanApp {
applyHeaderVisibilitySettings() {
const settings = this.loadAppSettingsFromStorage();
// Default all to true (enabled) if not set
const showFontControls = settings.showFontControls ?? true;
const showFontControls = settings.showFontControls ?? false;
const showSystemStats = settings.showSystemStats ?? true;
const showTokenCount = settings.showTokenCount ?? true;
@@ -8141,7 +8153,7 @@ class ClaudemanApp {
applyMonitorVisibility() {
const settings = this.loadAppSettingsFromStorage();
const showMonitor = settings.showMonitor ?? true;
const showSubagents = settings.showSubagents ?? true;
const showSubagents = settings.showSubagents ?? false;
const showFileBrowser = settings.showFileBrowser ?? false;
const monitorPanel = document.getElementById('monitorPanel');
@@ -10679,7 +10691,7 @@ class ClaudemanApp {
*/
updateSubagentWindowVisibility() {
const settings = this.loadAppSettingsFromStorage();
const activeTabOnly = settings.subagentActiveTabOnly ?? false;
const activeTabOnly = settings.subagentActiveTabOnly ?? true;
for (const [agentId, windowInfo] of this.subagentWindows) {
// Get parent from PERSISTENT map (THE source of truth)
@@ -10722,7 +10734,7 @@ class ClaudemanApp {
const existing = this.subagentWindows.get(agentId);
const agent = this.subagents.get(agentId);
const settings = this.loadAppSettingsFromStorage();
const activeTabOnly = settings.subagentActiveTabOnly ?? false;
const activeTabOnly = settings.subagentActiveTabOnly ?? true;
// If window is hidden (different tab) and activeTabOnly is enabled, switch to parent tab
if (existing.hidden && agent?.parentSessionId && activeTabOnly) {
@@ -10883,7 +10895,7 @@ class ClaudemanApp {
// Check if this window should be visible based on settings
// Use the PERSISTENT parent map for accurate tab-based visibility
const settings = this.loadAppSettingsFromStorage();
const activeTabOnly = settings.subagentActiveTabOnly ?? false;
const activeTabOnly = settings.subagentActiveTabOnly ?? true;
let shouldHide = false;
if (activeTabOnly) {
const storedParent = this.subagentParentMap.get(agentId);
@@ -11132,7 +11144,7 @@ class ClaudemanApp {
if (windowData) {
const settings = this.loadAppSettingsFromStorage();
const activeTabOnly = settings.subagentActiveTabOnly ?? false;
const activeTabOnly = settings.subagentActiveTabOnly ?? true;
// Get parent from PERSISTENT map (THE source of truth)
const storedParent = this.subagentParentMap.get(agentId);
@@ -11559,7 +11571,7 @@ class ClaudemanApp {
// Check if panel is enabled in settings
const settings = this.loadAppSettingsFromStorage();
const showProjectInsights = settings.showProjectInsights ?? true;
const showProjectInsights = settings.showProjectInsights ?? false;
if (!showProjectInsights) {
panel.classList.remove('visible');
this.projectInsightsPanelVisible = false;
+7
View File
@@ -731,6 +731,13 @@
<span class="slider"></span>
</label>
</div>
<div class="settings-item" title="Show estimated cost next to token count">
<span class="settings-item-label">Show Cost ($)</span>
<label class="switch switch-sm">
<input type="checkbox" id="appSettingsShowCost" checked>
<span class="slider"></span>
</label>
</div>
<!-- Panels Section -->
<div class="settings-section-header">Panels</div>
+24 -20
View File
@@ -5118,22 +5118,24 @@ kbd {
}
.connection-line {
stroke: #00ff41;
stroke-width: 2.5;
stroke: #3b82f6;
stroke-width: 3;
stroke-dasharray: 5 3;
fill: none;
opacity: 0.75;
/* Dark outline for contrast, subtle glow */
filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.7))
drop-shadow(0 0 3px rgba(0, 255, 65, 0.5));
opacity: 0.9;
/* Dark outline for contrast, vibrant blue glow */
filter: drop-shadow(0 0 2px rgba(0, 0, 0, 0.8))
drop-shadow(0 0 4px rgba(59, 130, 246, 0.8))
drop-shadow(0 0 8px rgba(59, 130, 246, 0.5));
transition: opacity 0.2s, stroke-width 0.2s, filter 0.2s;
}
.connection-line:hover {
opacity: 0.9;
stroke-width: 3;
filter: drop-shadow(0 0 2px rgba(0, 0, 0, 0.8))
drop-shadow(0 0 5px rgba(0, 255, 65, 0.7));
opacity: 1;
stroke-width: 3.5;
filter: drop-shadow(0 0 2px rgba(0, 0, 0, 0.9))
drop-shadow(0 0 6px rgba(59, 130, 246, 1))
drop-shadow(0 0 12px rgba(59, 130, 246, 0.7));
}
.connection-line.spawning-line {
@@ -5160,24 +5162,26 @@ kbd {
/* Plan subagent to regular subagent connection lines (Opus → Haiku) */
.connection-line.plan-to-subagent-line {
stroke: #00ff41;
stroke-width: 2.5;
/* Dark outline for contrast, subtle glow */
filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.7))
drop-shadow(0 0 3px rgba(0, 255, 65, 0.5));
stroke: #3b82f6;
stroke-width: 3;
/* Dark outline for contrast, vibrant blue glow */
filter: drop-shadow(0 0 2px rgba(0, 0, 0, 0.8))
drop-shadow(0 0 4px rgba(59, 130, 246, 0.8))
drop-shadow(0 0 8px rgba(59, 130, 246, 0.5));
stroke-dasharray: 5 3;
animation: plan-subagent-pulse 1.2s ease-in-out infinite;
}
.connection-line.plan-to-subagent-line:hover {
stroke-width: 3;
filter: drop-shadow(0 0 2px rgba(0, 0, 0, 0.8))
drop-shadow(0 0 5px rgba(0, 255, 65, 0.7));
stroke-width: 3.5;
filter: drop-shadow(0 0 2px rgba(0, 0, 0, 0.9))
drop-shadow(0 0 6px rgba(59, 130, 246, 1))
drop-shadow(0 0 12px rgba(59, 130, 246, 0.7));
}
@keyframes plan-subagent-pulse {
0%, 100% { opacity: 0.65; }
50% { opacity: 0.85; }
0%, 100% { opacity: 0.8; }
50% { opacity: 1; }
}
/* ========== Project Insights Panel (Bash File Viewers) ========== */
+18 -6
View File
@@ -1121,8 +1121,12 @@ export class WebServer extends EventEmitter {
if (enabled !== undefined) {
if (enabled) {
session.ralphTracker.enable();
// Allow re-enabling on restart if user explicitly enabled
session.ralphTracker.enableAutoEnable();
} else {
session.ralphTracker.disable();
// Prevent re-enabling on restart when user explicitly disabled
session.ralphTracker.disableAutoEnable();
}
// Persist Ralph enabled state
this.screenManager.updateRalphEnabled(id, enabled);
@@ -1369,8 +1373,8 @@ export class WebServer extends EventEmitter {
}
try {
// Auto-detect completion phrase from CLAUDE.md BEFORE starting (only if globally enabled)
if (this.store.getConfig().ralphEnabled) {
// Auto-detect completion phrase from CLAUDE.md BEFORE starting (only if globally enabled and not explicitly disabled by user)
if (this.store.getConfig().ralphEnabled && !session.ralphTracker.autoEnableDisabled) {
autoConfigureRalph(session, session.workingDir, () => {});
if (!session.ralphTracker.enabled) {
session.ralphTracker.enable();
@@ -1688,8 +1692,8 @@ export class WebServer extends EventEmitter {
}
try {
// Auto-detect completion phrase from CLAUDE.md BEFORE starting (only if globally enabled)
if (this.store.getConfig().ralphEnabled) {
// Auto-detect completion phrase from CLAUDE.md BEFORE starting (only if globally enabled and not explicitly disabled by user)
if (this.store.getConfig().ralphEnabled && !session.ralphTracker.autoEnableDisabled) {
autoConfigureRalph(session, session.workingDir, () => {});
if (!session.ralphTracker.enabled) {
session.ralphTracker.enable();
@@ -2288,6 +2292,7 @@ export class WebServer extends EventEmitter {
autoConfigureRalph(session, casePath, () => {}); // no broadcast yet
if (!session.ralphTracker.enabled) {
session.ralphTracker.enable();
session.ralphTracker.enableAutoEnable(); // Allow re-enabling on restart
}
}
@@ -4561,6 +4566,13 @@ NOW: Generate the implementation plan for the task above. Think step by step.`;
}
}
// Ralph / Todo tracker
if (savedState.ralphAutoEnableDisabled) {
session.ralphTracker.disableAutoEnable();
console.log(`[Server] Restored Ralph auto-enable disabled for session ${session.id}`);
} else if (savedState.ralphEnabled) {
// If Ralph was enabled and not explicitly disabled, allow re-enabling on restart
session.ralphTracker.enableAutoEnable();
}
if (savedState.ralphEnabled) {
session.ralphTracker.enable();
if (savedState.ralphCompletionPhrase) {
@@ -4594,8 +4606,8 @@ NOW: Generate the implementation plan for the task above. Think step by step.`;
}
}
// Fallback: restore Ralph state from state-inner.json if not already set
if (!session.ralphTracker.enabled) {
// Fallback: restore Ralph state from state-inner.json if not already set and not explicitly disabled
if (!session.ralphTracker.enabled && !session.ralphTracker.autoEnableDisabled) {
const ralphState = this.store.getRalphState(screen.sessionId);
if (ralphState?.loop?.enabled) {
session.ralphTracker.restoreState(ralphState.loop, ralphState.todos);