mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-02 13:39:41 +02:00
chore: bump version to 0.1634
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.1633 (must match `package.json`)
|
||||
**Version**: 0.1634 (must match `package.json`)
|
||||
|
||||
## Project Overview
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "claudeman",
|
||||
"version": "0.1633",
|
||||
"version": "0.1634",
|
||||
"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",
|
||||
|
||||
+42
-1
@@ -861,6 +861,16 @@ const KeyboardAccessoryBar = {
|
||||
<button class="accessory-btn" data-action="init" title="/init">/init</button>
|
||||
<button class="accessory-btn" data-action="clear" title="/clear">/clear</button>
|
||||
<button class="accessory-btn" data-action="compact" title="/compact">/compact</button>
|
||||
<button class="accessory-btn accessory-btn-voice" data-action="voice" title="Voice input"
|
||||
aria-label="Start voice input" aria-pressed="false"
|
||||
style="${VoiceInput.supported ? '' : 'display:none'}">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"/>
|
||||
<path d="M19 10v2a7 7 0 0 1-14 0v-2"/>
|
||||
<line x1="12" y1="19" x2="12" y2="23"/>
|
||||
<line x1="8" y1="23" x2="16" y2="23"/>
|
||||
</svg>
|
||||
</button>
|
||||
<button class="accessory-btn" data-action="paste" title="Paste from clipboard">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/>
|
||||
@@ -929,6 +939,9 @@ const KeyboardAccessoryBar = {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'voice':
|
||||
VoiceInput.toggle();
|
||||
break;
|
||||
case 'paste':
|
||||
this.pasteFromClipboard();
|
||||
break;
|
||||
@@ -1420,7 +1433,8 @@ class ZerolagInputAddon {
|
||||
if (!this._terminal) return;
|
||||
const t = this._terminal;
|
||||
this._font.fontFamily = t.options.fontFamily || 'monospace';
|
||||
this._font.fontSize = (t.options.fontSize || 14) + 'px';
|
||||
const baseFontSize = t.options.fontSize || 14;
|
||||
this._font.fontSize = baseFontSize + 'px';
|
||||
this._font.fontWeight = String(t.options.fontWeight || 'normal');
|
||||
this._font.backgroundColor = this._options.backgroundColor ?? t.options.theme?.background ?? _ZL_DEFAULT_BG;
|
||||
this._font.color = this._options.foregroundColor ?? t.options.theme?.foreground ?? _ZL_DEFAULT_FG;
|
||||
@@ -1431,6 +1445,23 @@ class ZerolagInputAddon {
|
||||
this._font.letterSpacing = cs.letterSpacing;
|
||||
if (!this._options.foregroundColor && cs.color) this._font.color = cs.color;
|
||||
}
|
||||
// Correct font size: DOM text renders larger than xterm's canvas/WebGL text
|
||||
// at the same nominal font-size. Measure actual DOM char width and scale to
|
||||
// match the terminal's cell width so the overlay text matches exactly.
|
||||
const dims = _zl_getCellDimensions(t);
|
||||
if (dims && dims.width > 0) {
|
||||
const probe = document.createElement('span');
|
||||
probe.style.cssText = `position:absolute;visibility:hidden;white-space:pre;font-family:${this._font.fontFamily};font-size:${baseFontSize}px;font-weight:${this._font.fontWeight};font-feature-settings:'liga' 0,'calt' 0`;
|
||||
if (this._font.letterSpacing) probe.style.letterSpacing = this._font.letterSpacing;
|
||||
probe.textContent = 'W';
|
||||
document.body.appendChild(probe);
|
||||
const domCharW = probe.getBoundingClientRect().width;
|
||||
document.body.removeChild(probe);
|
||||
if (domCharW > 0 && Math.abs(domCharW - dims.width) > 0.1) {
|
||||
const corrected = baseFontSize * (dims.width / domCharW);
|
||||
this._font.fontSize = corrected + 'px';
|
||||
}
|
||||
}
|
||||
}
|
||||
_hide() {
|
||||
if (!this._overlay) return;
|
||||
@@ -2206,6 +2237,7 @@ class ClaudemanApp {
|
||||
KeyboardHandler.init();
|
||||
SwipeHandler.init();
|
||||
KeyboardAccessoryBar.init();
|
||||
VoiceInput.init();
|
||||
this.applyHeaderVisibilitySettings();
|
||||
this.applyTabWrapSettings();
|
||||
this.applyMonitorVisibility();
|
||||
@@ -3171,6 +3203,12 @@ class ClaudemanApp {
|
||||
e.preventDefault();
|
||||
this.decreaseFontSize();
|
||||
}
|
||||
|
||||
// Ctrl/Cmd + Shift + V - toggle voice input
|
||||
if ((e.ctrlKey || e.metaKey) && e.shiftKey && e.key === 'V') {
|
||||
e.preventDefault();
|
||||
VoiceInput.toggle();
|
||||
}
|
||||
}, true); // Use capture phase to handle before terminal
|
||||
|
||||
// Token stats click handler (with guard to prevent duplicate handlers on reconnect)
|
||||
@@ -4405,6 +4443,9 @@ class ClaudemanApp {
|
||||
}
|
||||
}
|
||||
|
||||
// Stop any active voice recording on reconnect
|
||||
VoiceInput.cleanup();
|
||||
|
||||
this.sessions.clear();
|
||||
this.ralphStates.clear();
|
||||
this.terminalBuffers.clear();
|
||||
|
||||
@@ -361,6 +361,16 @@
|
||||
</div>
|
||||
|
||||
<div class="toolbar-right">
|
||||
<button class="btn-toolbar btn-sm btn-voice" id="voiceInputBtn" onclick="VoiceInput.toggle()"
|
||||
title="Voice input (Ctrl+Shift+V)" aria-label="Start voice input" aria-pressed="false"
|
||||
style="display: none;">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"/>
|
||||
<path d="M19 10v2a7 7 0 0 1-14 0v-2"/>
|
||||
<line x1="12" y1="19" x2="12" y2="23"/>
|
||||
<line x1="8" y1="23" x2="16" y2="23"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
@@ -382,6 +392,7 @@
|
||||
<div><kbd>Ctrl</kbd>+<kbd>+</kbd></div><div>Increase Font</div>
|
||||
<div><kbd>Ctrl</kbd>+<kbd>-</kbd></div><div>Decrease Font</div>
|
||||
<div><kbd>Ctrl</kbd>+<kbd>?</kbd></div><div>Show Help</div>
|
||||
<div><kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>V</kbd></div><div>Voice Input</div>
|
||||
<div><kbd>Escape</kbd></div><div>Close Panels</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -746,6 +746,32 @@ html.mobile-init .file-browser-panel {
|
||||
background: #3a3a3a;
|
||||
}
|
||||
|
||||
/* Voice input button */
|
||||
.accessory-btn-voice {
|
||||
background: #1a2a3f;
|
||||
border-color: rgba(59, 130, 246, 0.25);
|
||||
color: #93c5fd;
|
||||
}
|
||||
|
||||
.accessory-btn-voice:active {
|
||||
background: #2a3a5f;
|
||||
}
|
||||
|
||||
.accessory-btn-voice.recording {
|
||||
background: rgba(239, 68, 68, 0.2);
|
||||
border-color: rgba(239, 68, 68, 0.5);
|
||||
color: #ef4444;
|
||||
animation: voice-pulse 1.5s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* Voice preview — positioned above accessory bar on mobile */
|
||||
.voice-preview {
|
||||
bottom: calc(var(--safe-area-bottom) + 94px);
|
||||
font-size: 0.8rem;
|
||||
max-width: 90%;
|
||||
padding: 6px 14px;
|
||||
}
|
||||
|
||||
/* Add case button - compact (keeping for when shown via menu) */
|
||||
.btn-case-add {
|
||||
display: none !important;
|
||||
|
||||
@@ -1977,6 +1977,58 @@ body {
|
||||
border-color: var(--red);
|
||||
}
|
||||
|
||||
/* Voice Input Button */
|
||||
.btn-toolbar.btn-voice {
|
||||
padding: 0.3rem 0.5rem;
|
||||
}
|
||||
|
||||
.btn-toolbar.btn-voice:hover {
|
||||
color: var(--text);
|
||||
border-color: rgba(59, 130, 246, 0.4);
|
||||
}
|
||||
|
||||
.btn-toolbar.btn-voice.recording {
|
||||
background: rgba(239, 68, 68, 0.15);
|
||||
border-color: rgba(239, 68, 68, 0.5);
|
||||
color: #ef4444;
|
||||
animation: voice-pulse 1.5s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.btn-toolbar.btn-voice.recording:hover {
|
||||
background: rgba(239, 68, 68, 0.25);
|
||||
border-color: rgba(239, 68, 68, 0.7);
|
||||
color: #f87171;
|
||||
}
|
||||
|
||||
@keyframes voice-pulse {
|
||||
0%, 100% { transform: scale(1); opacity: 1; }
|
||||
50% { transform: scale(1.1); opacity: 0.75; }
|
||||
}
|
||||
|
||||
/* Voice preview overlay — shows interim transcription */
|
||||
.voice-preview {
|
||||
position: fixed;
|
||||
bottom: 48px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background: rgba(0, 0, 0, 0.88);
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
font-style: italic;
|
||||
font-family: var(--font-mono, monospace);
|
||||
padding: 8px 20px;
|
||||
border-radius: 8px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
font-size: 0.85rem;
|
||||
max-width: 80%;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
z-index: 100;
|
||||
pointer-events: none;
|
||||
backdrop-filter: blur(8px);
|
||||
-webkit-backdrop-filter: blur(8px);
|
||||
}
|
||||
|
||||
.btn-icon-only {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
Reference in New Issue
Block a user