mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-06 07:29:42 +02:00
chore: rename Claudeman to Codeman
Full product rename across 109 files (~834 occurrences): - Env vars: CLAUDEMAN_* → CODEMAN_* - Data dirs: ~/.claudeman/ → ~/.codeman/, ~/claudeman-cases/ → ~/codeman-cases/ - tmux prefix: claudeman- → codeman- - localStorage: claudeman-* → codeman-* - Package/CLI: claudeman → codeman - GitHub repo: Ark0N/Claudeman → Ark0N/Codeman - systemd service: claudeman-web → codeman-web - Class: ClaudemanApp → CodemanApp Migration infrastructure for seamless transition: - state-store.ts: auto-migrates data directories on startup - tmux-manager.ts: dual-prefix detection (legacy claudeman- sessions) - app.js: localStorage key migration (preserves old keys) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -149,7 +149,7 @@ describe('AiIdleChecker', () => {
|
||||
// Verify tmux was spawned with correct args
|
||||
expect(mockedSpawn).toHaveBeenCalledWith(
|
||||
'tmux',
|
||||
expect.arrayContaining(['new-session', '-d', '-s', expect.stringContaining('claudeman-aicheck-')]),
|
||||
expect.arrayContaining(['new-session', '-d', '-s', expect.stringContaining('codeman-aicheck-')]),
|
||||
expect.objectContaining({ detached: true, stdio: 'ignore' })
|
||||
);
|
||||
});
|
||||
@@ -163,7 +163,7 @@ describe('AiIdleChecker', () => {
|
||||
|
||||
// First call should try to kill existing session
|
||||
expect(mockedExecSync).toHaveBeenCalledWith(
|
||||
expect.stringContaining('tmux kill-session -t "claudeman-aicheck-'),
|
||||
expect.stringContaining('tmux kill-session -t "codeman-aicheck-'),
|
||||
expect.any(Object)
|
||||
);
|
||||
});
|
||||
@@ -176,7 +176,7 @@ describe('AiIdleChecker', () => {
|
||||
await checkPromise;
|
||||
|
||||
expect(mockedWriteFileSync).toHaveBeenCalledWith(
|
||||
expect.stringContaining('claudeman-aicheck-'),
|
||||
expect.stringContaining('codeman-aicheck-'),
|
||||
''
|
||||
);
|
||||
});
|
||||
|
||||
@@ -537,7 +537,7 @@ describe('API Response Structures', () => {
|
||||
it('should validate case info', () => {
|
||||
const caseInfo: CaseInfo = {
|
||||
name: 'my-project',
|
||||
path: '/home/user/claudeman-cases/my-project',
|
||||
path: '/home/user/codeman-cases/my-project',
|
||||
hasClaudeMd: true,
|
||||
};
|
||||
|
||||
@@ -549,7 +549,7 @@ describe('API Response Structures', () => {
|
||||
it('should handle optional hasClaudeMd', () => {
|
||||
const caseInfo: CaseInfo = {
|
||||
name: 'new-project',
|
||||
path: '/home/user/claudeman-cases/new-project',
|
||||
path: '/home/user/codeman-cases/new-project',
|
||||
};
|
||||
|
||||
expect(caseInfo.hasClaudeMd).toBeUndefined();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @fileoverview Tests for buffer management and memory limits
|
||||
*
|
||||
* Tests the buffer management strategies used in Claudeman sessions
|
||||
* Tests the buffer management strategies used in Codeman sessions
|
||||
* for handling large terminal output and message storage.
|
||||
*/
|
||||
|
||||
|
||||
@@ -318,7 +318,7 @@ describe('CLI Command Parsing', () => {
|
||||
|
||||
describe('Help Text Generation', () => {
|
||||
const generateHelp = (command: string, description: string, options: string[]): string => {
|
||||
let help = `Usage: claudeman ${command}\n\n`;
|
||||
let help = `Usage: codeman ${command}\n\n`;
|
||||
help += `${description}\n`;
|
||||
if (options.length > 0) {
|
||||
help += '\nOptions:\n';
|
||||
@@ -331,7 +331,7 @@ describe('CLI Command Parsing', () => {
|
||||
|
||||
it('should generate basic help', () => {
|
||||
const help = generateHelp('status', 'Show overall status', []);
|
||||
expect(help).toContain('Usage: claudeman status');
|
||||
expect(help).toContain('Usage: codeman status');
|
||||
expect(help).toContain('Show overall status');
|
||||
});
|
||||
|
||||
@@ -724,8 +724,8 @@ describe('CLI Configuration', () => {
|
||||
maxConcurrentSessions: 5,
|
||||
defaultPort: 3000,
|
||||
defaultHost: '0.0.0.0',
|
||||
casesDirectory: '~/claudeman-cases',
|
||||
stateDirectory: '~/.claudeman',
|
||||
casesDirectory: '~/codeman-cases',
|
||||
stateDirectory: '~/.codeman',
|
||||
};
|
||||
|
||||
const expandPath = (path: string): string => {
|
||||
@@ -742,8 +742,8 @@ describe('CLI Configuration', () => {
|
||||
});
|
||||
|
||||
it('should expand home directory paths', () => {
|
||||
expect(expandPath('~/claudeman-cases')).toBe('/home/user/claudeman-cases');
|
||||
expect(expandPath('~/.claudeman')).toBe('/home/user/.claudeman');
|
||||
expect(expandPath('~/codeman-cases')).toBe('/home/user/codeman-cases');
|
||||
expect(expandPath('~/.codeman')).toBe('/home/user/.codeman');
|
||||
});
|
||||
|
||||
it('should not modify absolute paths', () => {
|
||||
|
||||
@@ -5,7 +5,7 @@ import { join } from 'node:path';
|
||||
import { homedir } from 'node:os';
|
||||
|
||||
const TEST_PORT = 3110;
|
||||
const CASES_DIR = join(homedir(), 'claudeman-cases');
|
||||
const CASES_DIR = join(homedir(), 'codeman-cases');
|
||||
|
||||
describe('Edge Cases and Error Handling', () => {
|
||||
let server: WebServer;
|
||||
@@ -349,7 +349,7 @@ describe('Concurrent Session Handling', () => {
|
||||
const { join } = await import('node:path');
|
||||
const { homedir } = await import('node:os');
|
||||
for (const name of createdCases) {
|
||||
const path = join(homedir(), 'claudeman-cases', name);
|
||||
const path = join(homedir(), 'codeman-cases', name);
|
||||
if (existsSync(path)) {
|
||||
rmSync(path, { recursive: true, force: true });
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* File Link Click Tests for Claudeman Web UI
|
||||
* File Link Click Tests for Codeman Web UI
|
||||
*
|
||||
* Tests that file paths displayed in terminal output are clickable
|
||||
* and open the log viewer window correctly.
|
||||
@@ -88,7 +88,7 @@ describe('File Link Click Tests', () => {
|
||||
closeBrowser();
|
||||
|
||||
// Create test directory and log file
|
||||
testDir = join(tmpdir(), `claudeman-link-test-${Date.now()}`);
|
||||
testDir = join(tmpdir(), `codeman-link-test-${Date.now()}`);
|
||||
mkdirSync(testDir, { recursive: true });
|
||||
testLogFile = join(testDir, 'test.log');
|
||||
writeFileSync(testLogFile, '=== Test Log Started ===\n');
|
||||
@@ -102,7 +102,7 @@ describe('File Link Click Tests', () => {
|
||||
browser(`open ${baseUrl}`);
|
||||
await new Promise(r => setTimeout(r, 2000));
|
||||
const title = browserJson<{ title: string }>('get title');
|
||||
browserAvailable = title.title === 'Claudeman';
|
||||
browserAvailable = title.title === 'Codeman';
|
||||
} catch (e) {
|
||||
console.warn('Browser not available, skipping browser tests:', (e as Error).message);
|
||||
browserAvailable = false;
|
||||
|
||||
@@ -54,8 +54,8 @@ describe('generateHooksConfig', () => {
|
||||
const config = generateHooksConfig();
|
||||
const notifHooks = config.hooks.Notification as Array<{ hooks: Array<{ command: string }> }>;
|
||||
const cmd = notifHooks[0].hooks[0].command;
|
||||
expect(cmd).toContain('$CLAUDEMAN_API_URL');
|
||||
expect(cmd).toContain('$CLAUDEMAN_SESSION_ID');
|
||||
expect(cmd).toContain('$CODEMAN_API_URL');
|
||||
expect(cmd).toContain('$CODEMAN_SESSION_ID');
|
||||
expect(cmd).not.toContain('localhost');
|
||||
});
|
||||
|
||||
@@ -99,7 +99,7 @@ describe('generateHooksConfig', () => {
|
||||
});
|
||||
|
||||
describe('writeHooksConfig', () => {
|
||||
const testDir = join(tmpdir(), 'claudeman-hooks-test-' + Date.now());
|
||||
const testDir = join(tmpdir(), 'codeman-hooks-test-' + Date.now());
|
||||
|
||||
beforeEach(() => {
|
||||
if (!existsSync(testDir)) {
|
||||
@@ -648,8 +648,8 @@ describe('Hook Config Generation - Extended', () => {
|
||||
const config = generateHooksConfig();
|
||||
const notifHooks = config.hooks.Notification as Array<{ hooks: Array<{ command: string }> }>;
|
||||
const cmd = notifHooks[0].hooks[0].command;
|
||||
expect(cmd).toContain('$CLAUDEMAN_API_URL');
|
||||
expect(cmd).toContain('$CLAUDEMAN_SESSION_ID');
|
||||
expect(cmd).toContain('$CODEMAN_API_URL');
|
||||
expect(cmd).toContain('$CODEMAN_SESSION_ID');
|
||||
});
|
||||
|
||||
it('should generate POST curl commands', () => {
|
||||
|
||||
@@ -96,7 +96,7 @@ async function main() {
|
||||
page.on('console', msg => consoleLogs.push(`[${msg.type()}] ${msg.text()}`));
|
||||
|
||||
try {
|
||||
console.log('Opening Claudeman...');
|
||||
console.log('Opening Codeman...');
|
||||
await page.goto(BASE);
|
||||
await page.waitForSelector('.xterm-screen', { timeout: 10000 });
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
@@ -5,7 +5,7 @@ import { join } from 'node:path';
|
||||
import { homedir } from 'node:os';
|
||||
|
||||
const TEST_PORT = 3115;
|
||||
const CASES_DIR = join(homedir(), 'claudeman-cases');
|
||||
const CASES_DIR = join(homedir(), 'codeman-cases');
|
||||
|
||||
/**
|
||||
* Integration tests for complete user flows
|
||||
|
||||
@@ -149,9 +149,9 @@ async function main() {
|
||||
|
||||
// Enable local echo
|
||||
await page.evaluate(() => {
|
||||
const s = JSON.parse(localStorage.getItem('claudeman-app-settings') || '{}');
|
||||
const s = JSON.parse(localStorage.getItem('codeman-app-settings') || '{}');
|
||||
s.localEchoEnabled = true;
|
||||
localStorage.setItem('claudeman-app-settings', JSON.stringify(s));
|
||||
localStorage.setItem('codeman-app-settings', JSON.stringify(s));
|
||||
window.app?._updateLocalEchoState?.();
|
||||
});
|
||||
|
||||
|
||||
@@ -117,9 +117,9 @@ async function main() {
|
||||
|
||||
// Enable local echo
|
||||
await page.evaluate(() => {
|
||||
const s = JSON.parse(localStorage.getItem('claudeman-app-settings') || '{}');
|
||||
const s = JSON.parse(localStorage.getItem('codeman-app-settings') || '{}');
|
||||
s.localEchoEnabled = true;
|
||||
localStorage.setItem('claudeman-app-settings', JSON.stringify(s));
|
||||
localStorage.setItem('codeman-app-settings', JSON.stringify(s));
|
||||
window.app?._updateLocalEchoState?.();
|
||||
});
|
||||
|
||||
|
||||
@@ -120,9 +120,9 @@ async function main() {
|
||||
|
||||
// Enable local echo
|
||||
await page.evaluate(() => {
|
||||
const s = JSON.parse(localStorage.getItem('claudeman-app-settings') || '{}');
|
||||
const s = JSON.parse(localStorage.getItem('codeman-app-settings') || '{}');
|
||||
s.localEchoEnabled = true;
|
||||
localStorage.setItem('claudeman-app-settings', JSON.stringify(s));
|
||||
localStorage.setItem('codeman-app-settings', JSON.stringify(s));
|
||||
window.app?._updateLocalEchoState?.();
|
||||
});
|
||||
|
||||
@@ -307,7 +307,7 @@ async function main() {
|
||||
await page.keyboard.type('will-be-lost', { delay: 20 });
|
||||
await page.waitForTimeout(200);
|
||||
|
||||
const lsBefore = await page.evaluate(() => localStorage.getItem('claudeman_local_echo_pending'));
|
||||
const lsBefore = await page.evaluate(() => localStorage.getItem('codeman_local_echo_pending'));
|
||||
if (!lsBefore) pass('localStorage not written (persist is no-op)');
|
||||
else fail('localStorage written', `value="${lsBefore}"`);
|
||||
|
||||
|
||||
@@ -227,7 +227,7 @@ async function main() {
|
||||
|
||||
try {
|
||||
// ── SETUP ──
|
||||
console.log('Opening Claudeman...');
|
||||
console.log('Opening Codeman...');
|
||||
await page.goto(BASE, { waitUntil: 'domcontentloaded' });
|
||||
await page.waitForSelector('.xterm-screen', { timeout: 10000 });
|
||||
await page.waitForTimeout(2000);
|
||||
@@ -235,9 +235,9 @@ async function main() {
|
||||
// Enable local echo via settings
|
||||
console.log('Enabling local echo...');
|
||||
await page.evaluate(() => {
|
||||
const settings = JSON.parse(localStorage.getItem('claudeman-app-settings') || '{}');
|
||||
const settings = JSON.parse(localStorage.getItem('codeman-app-settings') || '{}');
|
||||
settings.localEchoEnabled = true;
|
||||
localStorage.setItem('claudeman-app-settings', JSON.stringify(settings));
|
||||
localStorage.setItem('codeman-app-settings', JSON.stringify(settings));
|
||||
window.app?._updateLocalEchoState?.();
|
||||
});
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
@@ -126,9 +126,9 @@ async function main() {
|
||||
|
||||
// Enable local echo
|
||||
await page.evaluate(() => {
|
||||
const s = JSON.parse(localStorage.getItem('claudeman-app-settings') || '{}');
|
||||
const s = JSON.parse(localStorage.getItem('codeman-app-settings') || '{}');
|
||||
s.localEchoEnabled = true;
|
||||
localStorage.setItem('claudeman-app-settings', JSON.stringify(s));
|
||||
localStorage.setItem('codeman-app-settings', JSON.stringify(s));
|
||||
window.app?._updateLocalEchoState?.();
|
||||
});
|
||||
|
||||
|
||||
@@ -144,7 +144,7 @@ async function main() {
|
||||
|
||||
try {
|
||||
// ── SETUP ──
|
||||
console.log('Opening Claudeman...');
|
||||
console.log('Opening Codeman...');
|
||||
await page.goto(BASE, { waitUntil: 'domcontentloaded' });
|
||||
await page.waitForSelector('.xterm-screen', { timeout: 10000 });
|
||||
await page.waitForTimeout(2500);
|
||||
@@ -152,7 +152,7 @@ async function main() {
|
||||
// Enable local echo
|
||||
console.log('Enabling local echo...');
|
||||
await page.evaluate(() => {
|
||||
const key = window.app?.getSettingsStorageKey?.() || 'claudeman-app-settings';
|
||||
const key = window.app?.getSettingsStorageKey?.() || 'codeman-app-settings';
|
||||
const settings = JSON.parse(localStorage.getItem(key) || '{}');
|
||||
settings.localEchoEnabled = true;
|
||||
localStorage.setItem(key, JSON.stringify(settings));
|
||||
|
||||
@@ -241,9 +241,9 @@ async function main() {
|
||||
|
||||
// Enable local echo
|
||||
await page.evaluate(() => {
|
||||
const s = JSON.parse(localStorage.getItem('claudeman-app-settings') || '{}');
|
||||
const s = JSON.parse(localStorage.getItem('codeman-app-settings') || '{}');
|
||||
s.localEchoEnabled = true;
|
||||
localStorage.setItem('claudeman-app-settings', JSON.stringify(s));
|
||||
localStorage.setItem('codeman-app-settings', JSON.stringify(s));
|
||||
window.app?._updateLocalEchoState?.();
|
||||
});
|
||||
|
||||
@@ -916,9 +916,9 @@ async function main() {
|
||||
await page.evaluate((id) => document.querySelector(`.session-tab[data-id="${id}"]`)?.click(), sA);
|
||||
await page.waitForTimeout(2000);
|
||||
await page.evaluate(() => {
|
||||
const s = JSON.parse(localStorage.getItem('claudeman-app-settings') || '{}');
|
||||
const s = JSON.parse(localStorage.getItem('codeman-app-settings') || '{}');
|
||||
s.localEchoEnabled = true;
|
||||
localStorage.setItem('claudeman-app-settings', JSON.stringify(s));
|
||||
localStorage.setItem('codeman-app-settings', JSON.stringify(s));
|
||||
window.app?._updateLocalEchoState?.();
|
||||
});
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @fileoverview Tests for memory leak prevention patterns
|
||||
*
|
||||
* These tests verify the cleanup patterns used to prevent memory leaks
|
||||
* in long-running Claudeman sessions (P1 improvements from P0 fixes).
|
||||
* in long-running Codeman sessions (P1 improvements from P0 fixes).
|
||||
*
|
||||
* Port: N/A (unit tests, no server)
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Performance tests: Claudeman responsiveness under subagent load
|
||||
* Performance tests: Codeman responsiveness under subagent load
|
||||
*
|
||||
* Measures event loop lag caused by:
|
||||
* 1. SubagentWatcher processing many agent files simultaneously
|
||||
@@ -112,7 +112,7 @@ describe('SubagentWatcher performance', () => {
|
||||
let projectsDir: string;
|
||||
|
||||
beforeEach(() => {
|
||||
tmpDir = mkdtempSync(join(tmpdir(), 'claudeman-perf-'));
|
||||
tmpDir = mkdtempSync(join(tmpdir(), 'codeman-perf-'));
|
||||
projectsDir = join(tmpDir, 'projects');
|
||||
mkdirSync(projectsDir, { recursive: true });
|
||||
});
|
||||
|
||||
@@ -5,7 +5,7 @@ import { join } from 'node:path';
|
||||
import { homedir } from 'node:os';
|
||||
|
||||
const TEST_PORT = 3099;
|
||||
const CASES_DIR = join(homedir(), 'claudeman-cases');
|
||||
const CASES_DIR = join(homedir(), 'codeman-cases');
|
||||
|
||||
describe('Quick Start API', () => {
|
||||
let server: WebServer;
|
||||
|
||||
@@ -18,7 +18,7 @@ import { join } from 'node:path';
|
||||
import { homedir } from 'node:os';
|
||||
|
||||
const TEST_PORT = 3125;
|
||||
const CASES_DIR = join(homedir(), 'claudeman-cases');
|
||||
const CASES_DIR = join(homedir(), 'codeman-cases');
|
||||
|
||||
describe('Ralph Integration Tests', () => {
|
||||
let server: WebServer;
|
||||
|
||||
+11
-11
@@ -2,10 +2,10 @@
|
||||
|
||||
**Date**: 2026-01-25
|
||||
**Analyzed Files**:
|
||||
- `/home/arkon/default/claudeman/src/respawn-controller.ts`
|
||||
- `/home/arkon/default/claudeman/src/ai-idle-checker.ts`
|
||||
- `/home/arkon/default/claudeman/src/ai-plan-checker.ts`
|
||||
- `/home/arkon/default/claudeman/test/respawn-controller.test.ts`
|
||||
- `/home/arkon/default/codeman/src/respawn-controller.ts`
|
||||
- `/home/arkon/default/codeman/src/ai-idle-checker.ts`
|
||||
- `/home/arkon/default/codeman/src/ai-plan-checker.ts`
|
||||
- `/home/arkon/default/codeman/test/respawn-controller.test.ts`
|
||||
|
||||
---
|
||||
|
||||
@@ -55,7 +55,7 @@ The following areas lack test coverage:
|
||||
|
||||
### Issue 1: E2BIG Error in ai-plan-checker.ts (HIGH)
|
||||
|
||||
**File**: `/home/arkon/default/claudeman/src/ai-plan-checker.ts`
|
||||
**File**: `/home/arkon/default/codeman/src/ai-plan-checker.ts`
|
||||
**Lines**: 341-346
|
||||
**Severity**: HIGH
|
||||
|
||||
@@ -84,7 +84,7 @@ const claudeCmd = `cat "${this.checkPromptFile}" | claude -p ${modelArg} --outpu
|
||||
|
||||
### Issue 2: Missing Prompt File Cleanup on Timeout (MEDIUM)
|
||||
|
||||
**File**: `/home/arkon/default/claudeman/src/ai-idle-checker.ts`
|
||||
**File**: `/home/arkon/default/codeman/src/ai-idle-checker.ts`
|
||||
**Lines**: 392-398
|
||||
**Severity**: MEDIUM
|
||||
|
||||
@@ -98,7 +98,7 @@ const claudeCmd = `cat "${this.checkPromptFile}" | claude -p ${modelArg} --outpu
|
||||
|
||||
### Issue 3: Race Condition in cancel() with Promise Resolution (MEDIUM)
|
||||
|
||||
**File**: `/home/arkon/default/claudeman/src/ai-idle-checker.ts`
|
||||
**File**: `/home/arkon/default/codeman/src/ai-idle-checker.ts`
|
||||
**Lines**: 265-279
|
||||
**Severity**: MEDIUM
|
||||
|
||||
@@ -127,7 +127,7 @@ cancel(): void {
|
||||
|
||||
### Issue 4: Stale Screen Name Collision (LOW)
|
||||
|
||||
**File**: `/home/arkon/default/claudeman/src/ai-idle-checker.ts`, `ai-plan-checker.ts`
|
||||
**File**: `/home/arkon/default/codeman/src/ai-idle-checker.ts`, `ai-plan-checker.ts`
|
||||
**Lines**: 326-329 (idle), 333-336 (plan)
|
||||
**Severity**: LOW
|
||||
|
||||
@@ -135,21 +135,21 @@ cancel(): void {
|
||||
|
||||
**Code**:
|
||||
```typescript
|
||||
this.checkScreenName = `claudeman-aicheck-${shortId}`;
|
||||
this.checkScreenName = `codeman-aicheck-${shortId}`;
|
||||
```
|
||||
|
||||
**Impact**: Very unlikely in practice since checks have cooldowns, but theoretically possible.
|
||||
|
||||
**Suggested Fix**: Already partially mitigated by the `timestamp` in temp file names. Could add timestamp to screen name too:
|
||||
```typescript
|
||||
this.checkScreenName = `claudeman-aicheck-${shortId}-${timestamp}`;
|
||||
this.checkScreenName = `codeman-aicheck-${shortId}-${timestamp}`;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Issue 5: DetectionStatus Calculation During ai_checking State (LOW)
|
||||
|
||||
**File**: `/home/arkon/default/claudeman/src/respawn-controller.ts`
|
||||
**File**: `/home/arkon/default/codeman/src/respawn-controller.ts`
|
||||
**Lines**: 759-762
|
||||
**Severity**: LOW
|
||||
|
||||
|
||||
@@ -243,7 +243,7 @@ afterEach(() => {
|
||||
|
||||
The global `test/setup.ts` handles:
|
||||
|
||||
1. **Screen Cleanup**: Kills any orphaned `claudeman-*` screens created during tests
|
||||
1. **Screen Cleanup**: Kills any orphaned `codeman-*` screens created during tests
|
||||
2. **Process Cleanup**: Kills any Claude processes spawned by tests
|
||||
3. **Pre-existing Protection**: Never kills screens that existed before tests started
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ export class MockSession extends EventEmitter {
|
||||
constructor(id: string = 'mock-session-id') {
|
||||
super();
|
||||
this.id = id;
|
||||
this._muxName = `claudeman-test-${id.slice(0, 8)}`;
|
||||
this._muxName = `codeman-test-${id.slice(0, 8)}`;
|
||||
}
|
||||
|
||||
/** Direct PTY write (used by session.write()) */
|
||||
|
||||
@@ -5,7 +5,7 @@ import { join } from 'node:path';
|
||||
import { homedir } from 'node:os';
|
||||
|
||||
const TEST_PORT = 3120;
|
||||
const CASES_DIR = join(homedir(), 'claudeman-cases');
|
||||
const CASES_DIR = join(homedir(), 'codeman-cases');
|
||||
|
||||
/**
|
||||
* Session Cleanup Tests
|
||||
|
||||
+19
-19
@@ -280,41 +280,41 @@ describe('Session State Management', () => {
|
||||
|
||||
describe('Mux Session Environment', () => {
|
||||
interface MuxEnv {
|
||||
CLAUDEMAN_MUX: string;
|
||||
CLAUDEMAN_SESSION_ID: string;
|
||||
CLAUDEMAN_MUX_NAME: string;
|
||||
CODEMAN_MUX: string;
|
||||
CODEMAN_SESSION_ID: string;
|
||||
CODEMAN_MUX_NAME: string;
|
||||
}
|
||||
|
||||
const createMuxEnv = (sessionId: string, muxName: string): MuxEnv => ({
|
||||
CLAUDEMAN_MUX: '1',
|
||||
CLAUDEMAN_SESSION_ID: sessionId,
|
||||
CLAUDEMAN_MUX_NAME: muxName,
|
||||
CODEMAN_MUX: '1',
|
||||
CODEMAN_SESSION_ID: sessionId,
|
||||
CODEMAN_MUX_NAME: muxName,
|
||||
});
|
||||
|
||||
const isClaudemanSession = (env: Record<string, string | undefined>): boolean => {
|
||||
return env.CLAUDEMAN_MUX === '1';
|
||||
const isCodemanSession = (env: Record<string, string | undefined>): boolean => {
|
||||
return env.CODEMAN_MUX === '1';
|
||||
};
|
||||
|
||||
it('should create valid mux environment', () => {
|
||||
const env = createMuxEnv('session-123', 'claudeman-test');
|
||||
expect(env.CLAUDEMAN_MUX).toBe('1');
|
||||
expect(env.CLAUDEMAN_SESSION_ID).toBe('session-123');
|
||||
expect(env.CLAUDEMAN_MUX_NAME).toBe('claudeman-test');
|
||||
const env = createMuxEnv('session-123', 'codeman-test');
|
||||
expect(env.CODEMAN_MUX).toBe('1');
|
||||
expect(env.CODEMAN_SESSION_ID).toBe('session-123');
|
||||
expect(env.CODEMAN_MUX_NAME).toBe('codeman-test');
|
||||
});
|
||||
|
||||
it('should detect claudeman session', () => {
|
||||
const env = createMuxEnv('session-123', 'claudeman-test');
|
||||
expect(isClaudemanSession(env)).toBe(true);
|
||||
it('should detect codeman session', () => {
|
||||
const env = createMuxEnv('session-123', 'codeman-test');
|
||||
expect(isCodemanSession(env)).toBe(true);
|
||||
});
|
||||
|
||||
it('should detect non-claudeman session', () => {
|
||||
const env = { CLAUDEMAN_MUX: '0' };
|
||||
expect(isClaudemanSession(env)).toBe(false);
|
||||
it('should detect non-codeman session', () => {
|
||||
const env = { CODEMAN_MUX: '0' };
|
||||
expect(isCodemanSession(env)).toBe(false);
|
||||
});
|
||||
|
||||
it('should handle missing environment variable', () => {
|
||||
const env = {};
|
||||
expect(isClaudemanSession(env)).toBe(false);
|
||||
expect(isCodemanSession(env)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* @fileoverview Global test setup for Claudeman tests
|
||||
* @fileoverview Global test setup for Codeman tests
|
||||
*
|
||||
* SAFETY: TmuxManager has built-in test mode detection
|
||||
* (via process.env.VITEST) that makes ALL shell commands no-ops.
|
||||
|
||||
@@ -293,7 +293,7 @@ describe('SSE Event Types', () => {
|
||||
const { join } = await import('node:path');
|
||||
const { homedir } = await import('node:os');
|
||||
try {
|
||||
rmSync(join(homedir(), 'claudeman-cases', caseName), { recursive: true });
|
||||
rmSync(join(homedir(), 'codeman-cases', caseName), { recursive: true });
|
||||
} catch {}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -17,7 +17,7 @@ import type { AppState, SessionState, TaskState, RalphSessionState } from '../sr
|
||||
import { StateStore, getStore } from '../src/state-store.js';
|
||||
|
||||
describe('StateStore', () => {
|
||||
const testDir = join(tmpdir(), 'claudeman-test-' + Date.now());
|
||||
const testDir = join(tmpdir(), 'codeman-test-' + Date.now());
|
||||
const testFilePath = join(testDir, 'state.json');
|
||||
const testInnerPath = join(testDir, 'state-inner.json');
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @fileoverview Tests for TeamWatcher - Agent Teams filesystem polling
|
||||
*
|
||||
* Test port: 3150 (if server needed)
|
||||
* SAFETY: Never uses port 3000, never kills w1-claudeman/w2/w3-claudeman
|
||||
* SAFETY: Never uses port 3000, never kills w1-codeman/w2/w3-codeman
|
||||
*/
|
||||
|
||||
import { mkdirSync, writeFileSync, rmSync, existsSync } from 'node:fs';
|
||||
@@ -13,7 +13,7 @@ import { TeamWatcher } from '../src/team-watcher.js';
|
||||
import type { TeamConfig, TeamTask, InboxMessage } from '../src/types.js';
|
||||
|
||||
// Unique temp dir per test run
|
||||
const TEST_BASE = join(tmpdir(), `claudeman-test-teams-${randomUUID().substring(0, 8)}`);
|
||||
const TEST_BASE = join(tmpdir(), `codeman-test-teams-${randomUUID().substring(0, 8)}`);
|
||||
const TEAMS_DIR = join(TEST_BASE, 'teams');
|
||||
const TASKS_DIR = join(TEST_BASE, 'tasks');
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import { tmpdir } from 'node:os';
|
||||
import { generateClaudeMd } from '../src/templates/claude-md.js';
|
||||
|
||||
describe('generateClaudeMd', () => {
|
||||
const testDir = join(tmpdir(), 'claudeman-template-test-' + Date.now());
|
||||
const testDir = join(tmpdir(), 'codeman-template-test-' + Date.now());
|
||||
|
||||
beforeEach(() => {
|
||||
if (!existsSync(testDir)) {
|
||||
@@ -54,11 +54,11 @@ describe('generateClaudeMd', () => {
|
||||
expect(result).toContain(`**Last Updated**: ${today}`);
|
||||
});
|
||||
|
||||
it('should include Claudeman environment section', () => {
|
||||
it('should include Codeman environment section', () => {
|
||||
const result = generateClaudeMd('my-project');
|
||||
|
||||
expect(result).toContain('## Claudeman Environment');
|
||||
expect(result).toContain('CLAUDEMAN_MUX=1');
|
||||
expect(result).toContain('## Codeman Environment');
|
||||
expect(result).toContain('CODEMAN_MUX=1');
|
||||
});
|
||||
|
||||
it('should include work principles', () => {
|
||||
@@ -146,20 +146,20 @@ About [PROJECT_NAME]: [PROJECT_DESCRIPTION]
|
||||
const result = generateClaudeMd('my-project', 'desc', '/nonexistent/template.md');
|
||||
|
||||
// Should get default template content
|
||||
expect(result).toContain('## Claudeman Environment');
|
||||
expect(result).toContain('## Codeman Environment');
|
||||
expect(result).toContain('**Project Name**: my-project');
|
||||
});
|
||||
|
||||
it('should fall back to default template if custom path is empty', () => {
|
||||
const result = generateClaudeMd('my-project', 'desc', '');
|
||||
|
||||
expect(result).toContain('## Claudeman Environment');
|
||||
expect(result).toContain('## Codeman Environment');
|
||||
});
|
||||
|
||||
it('should fall back to default template if custom path is undefined', () => {
|
||||
const result = generateClaudeMd('my-project', 'desc', undefined);
|
||||
|
||||
expect(result).toContain('## Claudeman Environment');
|
||||
expect(result).toContain('## Codeman Environment');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @fileoverview Tests for terminal output parsing utilities
|
||||
*
|
||||
* Tests various terminal output parsing patterns used throughout
|
||||
* the Claudeman application.
|
||||
* the Codeman application.
|
||||
*/
|
||||
|
||||
import { describe, it, expect } from 'vitest';
|
||||
|
||||
+20
-20
@@ -78,8 +78,8 @@ describe('TmuxManager (unit)', () => {
|
||||
|
||||
describe('getAttachArgs', () => {
|
||||
it('should return attach-session args', () => {
|
||||
const args = manager.getAttachArgs('claudeman-abc12345');
|
||||
expect(args).toEqual(['attach-session', '-t', 'claudeman-abc12345']);
|
||||
const args = manager.getAttachArgs('codeman-abc12345');
|
||||
expect(args).toEqual(['attach-session', '-t', 'codeman-abc12345']);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -111,7 +111,7 @@ describe('TmuxManager (unit)', () => {
|
||||
beforeEach(() => {
|
||||
manager.registerSession({
|
||||
sessionId: 'test-id',
|
||||
muxName: 'claudeman-1e571234',
|
||||
muxName: 'codeman-1e571234',
|
||||
pid: 12345,
|
||||
createdAt: Date.now(),
|
||||
workingDir: '/tmp',
|
||||
@@ -145,7 +145,7 @@ describe('TmuxManager (unit)', () => {
|
||||
it('should return all registered sessions as alive', async () => {
|
||||
manager.registerSession({
|
||||
sessionId: 'alive-1',
|
||||
muxName: 'claudeman-a11ce111',
|
||||
muxName: 'codeman-a11ce111',
|
||||
pid: 100,
|
||||
createdAt: Date.now(),
|
||||
workingDir: '/tmp',
|
||||
@@ -181,7 +181,7 @@ describe('TmuxManager (unit)', () => {
|
||||
it('should remove session from memory in test mode', async () => {
|
||||
manager.registerSession({
|
||||
sessionId: 'kill-test',
|
||||
muxName: 'claudeman-5e1f1111',
|
||||
muxName: 'codeman-5e1f1111',
|
||||
pid: 999,
|
||||
createdAt: Date.now(),
|
||||
workingDir: '/tmp',
|
||||
@@ -194,14 +194,14 @@ describe('TmuxManager (unit)', () => {
|
||||
expect(manager.getSession('kill-test')).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should allow kill when session does NOT match CLAUDEMAN_MUX_NAME', async () => {
|
||||
const originalEnv = process.env.CLAUDEMAN_MUX_NAME;
|
||||
process.env.CLAUDEMAN_MUX_NAME = 'claudeman-0ther1111';
|
||||
it('should allow kill when session does NOT match CODEMAN_MUX_NAME', async () => {
|
||||
const originalEnv = process.env.CODEMAN_MUX_NAME;
|
||||
process.env.CODEMAN_MUX_NAME = 'codeman-0ther1111';
|
||||
|
||||
try {
|
||||
manager.registerSession({
|
||||
sessionId: 'other-kill-test',
|
||||
muxName: 'claudeman-d1ff1111',
|
||||
muxName: 'codeman-d1ff1111',
|
||||
pid: 888,
|
||||
createdAt: Date.now(),
|
||||
workingDir: '/tmp',
|
||||
@@ -219,21 +219,21 @@ describe('TmuxManager (unit)', () => {
|
||||
expect(manager.getSession('other-kill-test')).toBeUndefined();
|
||||
} finally {
|
||||
if (originalEnv === undefined) {
|
||||
delete process.env.CLAUDEMAN_MUX_NAME;
|
||||
delete process.env.CODEMAN_MUX_NAME;
|
||||
} else {
|
||||
process.env.CLAUDEMAN_MUX_NAME = originalEnv;
|
||||
process.env.CODEMAN_MUX_NAME = originalEnv;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it('should allow kill when CLAUDEMAN_MUX_NAME is not set', async () => {
|
||||
const originalEnv = process.env.CLAUDEMAN_MUX_NAME;
|
||||
delete process.env.CLAUDEMAN_MUX_NAME;
|
||||
it('should allow kill when CODEMAN_MUX_NAME is not set', async () => {
|
||||
const originalEnv = process.env.CODEMAN_MUX_NAME;
|
||||
delete process.env.CODEMAN_MUX_NAME;
|
||||
|
||||
try {
|
||||
manager.registerSession({
|
||||
sessionId: 'no-env-test',
|
||||
muxName: 'claudeman-aaa11111',
|
||||
muxName: 'codeman-aaa11111',
|
||||
pid: 777,
|
||||
createdAt: Date.now(),
|
||||
workingDir: '/tmp',
|
||||
@@ -247,9 +247,9 @@ describe('TmuxManager (unit)', () => {
|
||||
expect(result).toBe(true);
|
||||
} finally {
|
||||
if (originalEnv === undefined) {
|
||||
delete process.env.CLAUDEMAN_MUX_NAME;
|
||||
delete process.env.CODEMAN_MUX_NAME;
|
||||
} else {
|
||||
process.env.CLAUDEMAN_MUX_NAME = originalEnv;
|
||||
process.env.CODEMAN_MUX_NAME = originalEnv;
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -259,7 +259,7 @@ describe('TmuxManager (unit)', () => {
|
||||
beforeEach(() => {
|
||||
manager.registerSession({
|
||||
sessionId: 'meta-test',
|
||||
muxName: 'claudeman-ae1a1234',
|
||||
muxName: 'codeman-ae1a1234',
|
||||
pid: 300,
|
||||
createdAt: Date.now(),
|
||||
workingDir: '/tmp',
|
||||
@@ -308,7 +308,7 @@ describe('TmuxManager (unit)', () => {
|
||||
it('should return all registered sessions', () => {
|
||||
manager.registerSession({
|
||||
sessionId: 's1',
|
||||
muxName: 'claudeman-51111111',
|
||||
muxName: 'codeman-51111111',
|
||||
pid: 1,
|
||||
createdAt: Date.now(),
|
||||
workingDir: '/tmp',
|
||||
@@ -317,7 +317,7 @@ describe('TmuxManager (unit)', () => {
|
||||
});
|
||||
manager.registerSession({
|
||||
sessionId: 's2',
|
||||
muxName: 'claudeman-52222222',
|
||||
muxName: 'codeman-52222222',
|
||||
pid: 2,
|
||||
createdAt: Date.now(),
|
||||
workingDir: '/tmp',
|
||||
|
||||
@@ -59,7 +59,7 @@ describe('TmuxManager restart recovery (test mode safety)', () => {
|
||||
it('should report all registered sessions as alive in test mode', async () => {
|
||||
manager.registerSession({
|
||||
sessionId: 'test-recovery-1',
|
||||
muxName: 'claudeman-de51ecaf',
|
||||
muxName: 'codeman-de51ecaf',
|
||||
pid: 1,
|
||||
createdAt: Date.now(),
|
||||
workingDir: '/tmp',
|
||||
@@ -89,7 +89,7 @@ describe('TmuxManager restart recovery (test mode safety)', () => {
|
||||
it('should not execute any tmux commands in test mode', async () => {
|
||||
manager.registerSession({
|
||||
sessionId: 'alive-session',
|
||||
muxName: 'claudeman-a11eeaaa',
|
||||
muxName: 'codeman-a11eeaaa',
|
||||
pid: 1,
|
||||
createdAt: Date.now(),
|
||||
workingDir: '/tmp',
|
||||
@@ -110,7 +110,7 @@ describe('TmuxManager restart recovery (test mode safety)', () => {
|
||||
it('should handle multiple sessions correctly in test mode', async () => {
|
||||
manager.registerSession({
|
||||
sessionId: 'session-1',
|
||||
muxName: 'claudeman-a11eeaaa',
|
||||
muxName: 'codeman-a11eeaaa',
|
||||
pid: 1,
|
||||
createdAt: Date.now(),
|
||||
workingDir: '/tmp',
|
||||
@@ -120,7 +120,7 @@ describe('TmuxManager restart recovery (test mode safety)', () => {
|
||||
});
|
||||
manager.registerSession({
|
||||
sessionId: 'session-2',
|
||||
muxName: 'claudeman-b22ffbbb',
|
||||
muxName: 'codeman-b22ffbbb',
|
||||
pid: 2,
|
||||
createdAt: Date.now(),
|
||||
workingDir: '/tmp',
|
||||
@@ -140,7 +140,7 @@ describe('TmuxManager restart recovery (test mode safety)', () => {
|
||||
it('should safely remove sessions via killSession in test mode', async () => {
|
||||
manager.registerSession({
|
||||
sessionId: 'kill-me',
|
||||
muxName: 'claudeman-deadbeef',
|
||||
muxName: 'codeman-deadbeef',
|
||||
pid: 99999,
|
||||
createdAt: Date.now(),
|
||||
workingDir: '/tmp',
|
||||
|
||||
Reference in New Issue
Block a user