chore: bump version to 0.1582

This commit is contained in:
arkon
2026-02-20 15:58:28 +01:00
parent bad074756d
commit c561c41146
4 changed files with 33 additions and 47 deletions
+1 -1
View File
@@ -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.1581 (must match `package.json` for npm publish)
**Version**: 0.1582 (must match `package.json` for npm publish)
## Project Overview
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "claudeman",
"version": "0.1581",
"version": "0.1582",
"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",
+19 -10
View File
@@ -967,22 +967,31 @@ class LocalEchoOverlay {
this.overlay.style.display = 'none';
}
// Create a styled line div with opaque background
_makeLine(text, leftPx, topPx, widthPx, cellH) {
// Create a styled line div with per-character grid positioning.
// Each char is placed at exact col*cellW to match xterm's canvas renderer
// (DOM text flow drifts vs canvas due to sub-pixel glyph width differences).
_makeLine(text, leftPx, topPx, widthPx, cellH, cellW) {
const el = document.createElement('div');
el.style.cssText = `position:absolute;white-space:pre;font-kerning:none;pointer-events:none`;
el.style.fontFamily = this._fontFamily;
el.style.fontSize = this._fontSize;
el.style.fontWeight = this._fontWeight;
el.style.letterSpacing = this._letterSpacing;
el.style.color = this._color;
el.style.cssText = `position:absolute;pointer-events:none`;
el.style.backgroundColor = this._bg;
el.style.left = leftPx + 'px';
el.style.top = topPx + 'px';
el.style.width = widthPx + 'px';
el.style.height = (cellH + 1) + 'px';
el.style.lineHeight = cellH + 'px';
el.textContent = text;
// Place each character at its exact grid position
for (let i = 0; i < text.length; i++) {
const span = document.createElement('span');
span.style.cssText = `position:absolute;display:inline-block;text-align:center;pointer-events:none`;
span.style.left = (i * cellW) + 'px';
span.style.width = cellW + 'px';
span.style.fontFamily = this._fontFamily;
span.style.fontSize = this._fontSize;
span.style.fontWeight = this._fontWeight;
span.style.color = this._color;
span.textContent = text[i];
el.appendChild(span);
}
return el;
}
@@ -1038,7 +1047,7 @@ class LocalEchoOverlay {
const leftPx = i === 0 ? startCol * cellW : 0;
const widthPx = i === 0 ? (fullWidthPx - leftPx) : fullWidthPx;
const topPx = i * cellH;
const lineEl = this._makeLine(lines[i], leftPx, topPx, widthPx, cellH);
const lineEl = this._makeLine(lines[i], leftPx, topPx, widthPx, cellH, cellW);
this.overlay.appendChild(lineEl);
}
+12 -35
View File
@@ -662,51 +662,28 @@ describe('Subagent window simulation', () => {
expect(timing).toBeLessThan(THRESHOLDS.SUBAGENT_WINDOW_OPEN);
});
it('closes subagent window within threshold', async () => {
// Ensure a window is open
const hasWindow = await page.locator('.subagent-window').count().then(c => c > 0);
if (!hasWindow) {
const claudeSessionId = await page.evaluate((sid: string) => {
const app = (window as unknown as { app: { sessions: Map<string, { claudeSessionId?: string }> } }).app;
return app.sessions.get(sid)?.claudeSessionId || 'fake-claude-session';
}, sessionId);
await page.evaluate(({ cSessionId }: { cSessionId: string }) => {
const app = (window as unknown as {
app: {
subagents: Map<string, Record<string, unknown>>;
openSubagentWindow: (id: string) => void;
}
}).app;
app.subagents.set('perf-agent-close', {
agentId: 'perf-agent-close',
sessionId: cSessionId,
status: 'active',
description: 'Close test agent',
startedAt: Date.now(),
lastActivityAt: Date.now(),
toolCallCount: 0,
entryCount: 0,
fileSize: 0,
});
app.openSubagentWindow('perf-agent-close');
}, { cSessionId: claudeSessionId });
await page.waitForSelector('.subagent-window', { timeout: 3000 });
}
it('closes (minimizes) subagent window within threshold', async () => {
// perf-agent-1 should still be open from the previous test
// Note: closeSubagentWindow minimizes to tab (display:none), doesn't remove from DOM
const isVisible = await page.locator('#subagent-window-perf-agent-1').isVisible();
expect(isVisible).toBe(true);
const timing = await measure(async () => {
await page.evaluate(() => {
const app = (window as unknown as { app: { closeSubagentWindow: (id: string) => void } }).app;
const win = document.querySelector('.subagent-window');
const id = win?.id?.replace('subagent-window-', '') || 'perf-agent-close';
app.closeSubagentWindow(id);
app.closeSubagentWindow('perf-agent-1');
});
// Wait for element to become hidden (display: none)
await page.waitForFunction(
() => document.querySelectorAll('.subagent-window').length === 0,
() => {
const el = document.getElementById('subagent-window-perf-agent-1');
return el && el.style.display === 'none';
},
{ timeout: 2000 },
);
});
console.log(`[subagent window] close: ${timing.toFixed(0)}ms`);
console.log(`[subagent window] close (minimize): ${timing.toFixed(0)}ms`);
expect(timing).toBeLessThan(THRESHOLDS.SUBAGENT_WINDOW_CLOSE);
});