diff --git a/CLAUDE.md b/CLAUDE.md index 6b803ac6..858ba886 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -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.1528 (must match `package.json` for npm publish) +**Version**: 0.1529 (must match `package.json` for npm publish) ## Project Overview diff --git a/package.json b/package.json index 3863d73e..05d46efe 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "claudeman", - "version": "0.1528", + "version": "0.1529", "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", diff --git a/scripts/postinstall.js b/scripts/postinstall.js index 49b0f541..911c9027 100644 --- a/scripts/postinstall.js +++ b/scripts/postinstall.js @@ -6,9 +6,10 @@ */ import { execSync } from 'child_process'; -import { existsSync } from 'fs'; +import { chmodSync, existsSync } from 'fs'; import { homedir, platform } from 'os'; import { join } from 'path'; +import { createRequire } from 'module'; // ============================================================================ // Configuration @@ -115,6 +116,38 @@ if (majorVersion < MIN_NODE_VERSION) { console.log(colors.green(`✓ Node.js v${nodeVersion}`) + colors.dim(` (meets >=v${MIN_NODE_VERSION} requirement)`)); } +// ---------------------------------------------------------------------------- +// 1b. Fix node-pty spawn-helper permissions (macOS posix_spawnp fix) +// ---------------------------------------------------------------------------- + +try { + const require = createRequire(import.meta.url); + const ptyPath = join(require.resolve('node-pty'), '..'); + const spawnHelper = join(ptyPath, 'build', 'Release', 'spawn-helper'); + if (existsSync(spawnHelper)) { + chmodSync(spawnHelper, 0o755); + console.log(colors.green('✓ node-pty spawn-helper permissions fixed')); + } +} catch { + // Non-critical — only affects macOS with prebuilt binaries +} + +// ---------------------------------------------------------------------------- +// 1c. Rebuild node-pty from source for Node.js 22+ compatibility +// ---------------------------------------------------------------------------- + +if (majorVersion >= 22) { + try { + console.log(colors.dim(' Rebuilding node-pty from source for Node.js 22+...')); + execSync('npm rebuild node-pty --build-from-source', { stdio: 'pipe', timeout: 120000 }); + console.log(colors.green('✓ node-pty rebuilt from source')); + } catch { + hasWarnings = true; + console.log(colors.yellow('⚠ Failed to rebuild node-pty from source')); + console.log(colors.dim(' You may need to run: npm rebuild node-pty --build-from-source')); + } +} + // ---------------------------------------------------------------------------- // 2. Check if terminal multiplexer is installed (tmux preferred, screen fallback) // ---------------------------------------------------------------------------- diff --git a/src/session.ts b/src/session.ts index 7845e633..4520c477 100644 --- a/src/session.ts +++ b/src/session.ts @@ -869,7 +869,7 @@ export class Session extends EventEmitter { cols: 120, rows: 40, cwd: this.workingDir, - env: { ...process.env, TERM: 'xterm-256color' }, + env: { ...process.env, TERM: 'xterm-256color', COLORTERM: undefined, CLAUDECODE: undefined }, }); // Set claudeSessionId immediately since we passed --session-id to Claude @@ -939,6 +939,8 @@ export class Session extends EventEmitter { ...process.env, PATH: getAugmentedPath(), TERM: 'xterm-256color', + COLORTERM: undefined, + CLAUDECODE: undefined, // Inform Claude it's running within Claudeman (helps prevent self-termination) CLAUDEMAN_SCREEN: '1', CLAUDEMAN_SESSION_ID: this.id, @@ -1147,7 +1149,7 @@ export class Session extends EventEmitter { cols: 120, rows: 40, cwd: this.workingDir, - env: { ...process.env, TERM: 'xterm-256color' }, + env: { ...process.env, TERM: 'xterm-256color', COLORTERM: undefined, CLAUDECODE: undefined }, }); } catch (spawnErr) { console.error('[Session] Failed to spawn PTY for shell mux attachment:', spawnErr); @@ -1293,6 +1295,7 @@ export class Session extends EventEmitter { const args = [ '-p', + '--verbose', '--dangerously-skip-permissions', '--output-format', 'stream-json', ]; @@ -1311,6 +1314,8 @@ export class Session extends EventEmitter { ...process.env, PATH: getAugmentedPath(), TERM: 'xterm-256color', + COLORTERM: undefined, + CLAUDECODE: undefined, // Inform Claude it's running within Claudeman CLAUDEMAN_SCREEN: '1', CLAUDEMAN_SESSION_ID: this.id, diff --git a/src/tmux-manager.ts b/src/tmux-manager.ts index 3d9fa8c1..a8974f95 100644 --- a/src/tmux-manager.ts +++ b/src/tmux-manager.ts @@ -257,6 +257,8 @@ export class TmuxManager extends EventEmitter implements TerminalMultiplexer { const pathExport = claudeDir ? `export PATH="${claudeDir}:$PATH" && ` : ''; const envExports = [ + 'unset CLAUDECODE', + 'unset COLORTERM', 'export CLAUDEMAN_SCREEN=1', `export CLAUDEMAN_SESSION_ID=${sessionId}`, `export CLAUDEMAN_SCREEN_NAME=${muxName}`, diff --git a/src/web/public/app.js b/src/web/public/app.js index 06c0e39d..61a1eb2a 100644 --- a/src/web/public/app.js +++ b/src/web/public/app.js @@ -3719,10 +3719,19 @@ class ClaudemanApp { const minimizedCount = minimizedAgents?.size || 0; const subagentBadge = minimizedCount > 0 ? this.renderSubagentTabBadge(id, minimizedAgents) : ''; - parts.push(`