mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-08 00:19:42 +02:00
chore: bump version to 0.1500
This commit is contained in:
@@ -25,7 +25,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`)
|
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`
|
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.1499 (must match `package.json` for npm publish)
|
**Version**: 0.1500 (must match `package.json` for npm publish)
|
||||||
|
|
||||||
## Project Overview
|
## Project Overview
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "claudeman",
|
"name": "claudeman",
|
||||||
"version": "0.1499",
|
"version": "0.1500",
|
||||||
"description": "The missing control plane for Claude Code - run 20 autonomous agents with real-time monitoring and session persistence",
|
"description": "The missing control plane for Claude Code - run 20 autonomous agents with real-time monitoring and session persistence",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
|
|||||||
@@ -1242,6 +1242,16 @@ class ClaudemanApp {
|
|||||||
// Sequential input send chain — ensures keystroke ordering across async fetches
|
// Sequential input send chain — ensures keystroke ordering across async fetches
|
||||||
this._inputSendChain = Promise.resolve();
|
this._inputSendChain = Promise.resolve();
|
||||||
|
|
||||||
|
// Local echo with output hold — shows typed chars instantly on high-latency connections.
|
||||||
|
// Instead of stripping echoed chars from Ink output (fragile), we simply hold ALL server
|
||||||
|
// output while typing and flush it when the user pauses. Ink's final redraw replaces
|
||||||
|
// any locally-echoed chars with the correct server state.
|
||||||
|
this._localEchoActive = false; // Whether we have unconfirmed locally-echoed chars
|
||||||
|
this._localEchoCount = 0; // Number of unconfirmed chars
|
||||||
|
this._localEchoHoldBuffer = []; // Server output held during typing
|
||||||
|
this._localEchoFlushTimer = null; // Timer to flush after typing pause
|
||||||
|
this._localEchoFlushDelay = 200; // ms after last keystroke before flushing server output
|
||||||
|
|
||||||
// Accessibility: Focus trap for modals
|
// Accessibility: Focus trap for modals
|
||||||
this.activeFocusTrap = null;
|
this.activeFocusTrap = null;
|
||||||
|
|
||||||
@@ -1571,6 +1581,33 @@ class ClaudemanApp {
|
|||||||
// Patterns: \x1b[?...c (DA1), \x1b[>...c (DA2), \x1b[...R (CPR), \x1b[...n (DSR)
|
// Patterns: \x1b[?...c (DA1), \x1b[>...c (DA2), \x1b[...R (CPR), \x1b[...n (DSR)
|
||||||
if (/^\x1b\[[\?>=]?[\d;]*[cnR]$/.test(data)) return;
|
if (/^\x1b\[[\?>=]?[\d;]*[cnR]$/.test(data)) return;
|
||||||
|
|
||||||
|
// Local echo: show printable chars instantly during idle state.
|
||||||
|
// Reduces perceived latency on remote connections (e.g., 100-300ms RTT).
|
||||||
|
// Server output is held while typing and flushed when user pauses.
|
||||||
|
const session = this.sessions.get(this.activeSessionId);
|
||||||
|
const isIdle = session && session.status === 'idle';
|
||||||
|
if (isIdle && data.length === 1) {
|
||||||
|
const code = data.charCodeAt(0);
|
||||||
|
if (code >= 32 && code < 127) {
|
||||||
|
// Printable ASCII — echo immediately
|
||||||
|
this.terminal.write(data);
|
||||||
|
this._localEchoActive = true;
|
||||||
|
this._localEchoCount++;
|
||||||
|
this._resetLocalEchoFlush();
|
||||||
|
} else if ((code === 0x7f || code === 0x08) && this._localEchoCount > 0) {
|
||||||
|
// Backspace — undo last local echo char
|
||||||
|
this.terminal.write('\b \b');
|
||||||
|
this._localEchoCount--;
|
||||||
|
if (this._localEchoCount === 0) this._localEchoActive = false;
|
||||||
|
this._resetLocalEchoFlush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Control chars (Enter, Ctrl+C) clear local echo immediately
|
||||||
|
if (data.charCodeAt(0) < 32 || data.length > 1) {
|
||||||
|
this._clearLocalEcho();
|
||||||
|
}
|
||||||
|
|
||||||
this._pendingInput += data;
|
this._pendingInput += data;
|
||||||
|
|
||||||
// Flush immediately for control characters (Enter, Ctrl+C, etc.)
|
// Flush immediately for control characters (Enter, Ctrl+C, etc.)
|
||||||
@@ -1717,6 +1754,15 @@ class ClaudemanApp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
batchTerminalWrite(data) {
|
batchTerminalWrite(data) {
|
||||||
|
// Local echo output hold: while user is actively typing (local echo active),
|
||||||
|
// buffer server output instead of writing it. This prevents Ink's intermediate
|
||||||
|
// redraws from overwriting locally-echoed characters. The buffer is flushed
|
||||||
|
// when typing pauses (200ms), giving the server time to catch up.
|
||||||
|
if (this._localEchoActive) {
|
||||||
|
this._localEchoHoldBuffer.push(data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if at bottom BEFORE adding data (captures user's scroll position)
|
// Check if at bottom BEFORE adding data (captures user's scroll position)
|
||||||
// Only update if not already scheduled (preserve the first check's result)
|
// Only update if not already scheduled (preserve the first check's result)
|
||||||
if (!this.writeFrameScheduled) {
|
if (!this.writeFrameScheduled) {
|
||||||
@@ -2250,6 +2296,10 @@ class ClaudemanApp {
|
|||||||
const session = this.sessions.get(data.id);
|
const session = this.sessions.get(data.id);
|
||||||
if (session) {
|
if (session) {
|
||||||
session.status = 'busy';
|
session.status = 'busy';
|
||||||
|
// Clear local echo — server is now generating output
|
||||||
|
if (data.id === this.activeSessionId) {
|
||||||
|
this._clearLocalEcho();
|
||||||
|
}
|
||||||
// Only clear tab alert if no pending hooks (permission_prompt, elicitation_dialog, etc.)
|
// Only clear tab alert if no pending hooks (permission_prompt, elicitation_dialog, etc.)
|
||||||
if (!this.pendingHooks.has(data.id)) {
|
if (!this.pendingHooks.has(data.id)) {
|
||||||
this.tabAlerts.delete(data.id);
|
this.tabAlerts.delete(data.id);
|
||||||
@@ -2994,6 +3044,47 @@ class ClaudemanApp {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset the local echo flush timer. Called on each keystroke.
|
||||||
|
* After the user stops typing for _localEchoFlushDelay ms, flushes
|
||||||
|
* held server output to the terminal.
|
||||||
|
*/
|
||||||
|
_resetLocalEchoFlush() {
|
||||||
|
if (this._localEchoFlushTimer) clearTimeout(this._localEchoFlushTimer);
|
||||||
|
this._localEchoFlushTimer = setTimeout(() => {
|
||||||
|
this._flushLocalEcho();
|
||||||
|
}, this._localEchoFlushDelay);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flush held server output and clear local echo state.
|
||||||
|
* Called when typing pauses, session goes busy, or control char sent.
|
||||||
|
*/
|
||||||
|
_flushLocalEcho() {
|
||||||
|
if (this._localEchoFlushTimer) {
|
||||||
|
clearTimeout(this._localEchoFlushTimer);
|
||||||
|
this._localEchoFlushTimer = null;
|
||||||
|
}
|
||||||
|
this._localEchoActive = false;
|
||||||
|
this._localEchoCount = 0;
|
||||||
|
|
||||||
|
// Flush all held server output through the normal write path
|
||||||
|
if (this._localEchoHoldBuffer.length > 0) {
|
||||||
|
const held = this._localEchoHoldBuffer;
|
||||||
|
this._localEchoHoldBuffer = [];
|
||||||
|
for (const chunk of held) {
|
||||||
|
this.batchTerminalWrite(chunk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear local echo state immediately (on Enter, Ctrl+C, session busy).
|
||||||
|
*/
|
||||||
|
_clearLocalEcho() {
|
||||||
|
this._flushLocalEcho();
|
||||||
|
}
|
||||||
|
|
||||||
_enqueueInput(sessionId, input) {
|
_enqueueInput(sessionId, input) {
|
||||||
const existing = this._inputQueue.get(sessionId) || '';
|
const existing = this._inputQueue.get(sessionId) || '';
|
||||||
let combined = existing + input;
|
let combined = existing + input;
|
||||||
|
|||||||
Reference in New Issue
Block a user