From 3795c45cc178d5206a4caa3f3d4035b151598b7e Mon Sep 17 00:00:00 2001
From: arkon
Date: Thu, 26 Feb 2026 16:44:34 +0100
Subject: [PATCH] chore: rename Claudeman to Codeman
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
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
---
CLAUDE.md | 60 ++++-----
README.md | 32 ++---
agent-teams/README.md | 10 +-
agent-teams/design.md | 12 +-
agent-teams/experiment-log.md | 42 +++----
...ground-keystroke-forwarding-merged-plan.md | 2 +-
docs/background-keystroke-forwarding-plan.md | 2 +-
docs/browser-testing-guide.md | 8 +-
docs/cleanup-findings.md | 2 +-
docs/first-load-optimization-plan.md | 2 +-
.../{claudeman-demo.gif => codeman-demo.gif} | Bin
...{claudeman-title.svg => codeman-title.svg} | 2 +-
docs/local-echo-overlay-plan.md | 2 +-
docs/opencode-integration.md | 114 +++++++++---------
docs/perf-audit-first-load.md | 4 +-
docs/performance-investigation-report.md | 6 +-
docs/plan-improvement-roadmap.md | 2 +-
docs/ralph-improvement-plan.md | 4 +-
docs/ralph-wiggum-guide.md | 16 +--
docs/reports/notification-audit-summary.md | 2 +-
docs/reports/notification-backend.md | 14 +--
docs/reports/notification-blinking.md | 14 +--
docs/reports/notification-frontend.md | 26 ++--
docs/reports/notification-settings.md | 20 +--
docs/terminal-anti-flicker.md | 2 +-
docs/typescript-improvement-suggestions.md | 16 +--
docs/voice-input-plan.md | 2 +-
install.sh | 80 ++++++------
mobile-test/README.md | 6 +-
mobile-test/helpers/constants.ts | 6 +-
mobile-test/settings.test.ts | 6 +-
package-lock.json | 6 +-
package.json | 10 +-
packages/xterm-zerolag-input/LICENSE | 2 +-
packages/xterm-zerolag-input/README.md | 4 +-
packages/xterm-zerolag-input/package.json | 4 +-
scripts/browser-comparison.mjs | 16 +--
scripts/capture-readme-screenshots.mjs | 20 +--
scripts/capture-subagent-gif.mjs | 12 +-
scripts/capture-subagent-screenshots.mjs | 16 +--
...udeman-web.service => codeman-web.service} | 6 +-
scripts/mobile-screenshot.mjs | 2 +-
scripts/monitor-respawn.sh | 6 +-
scripts/postinstall.js | 8 +-
scripts/ralph-wizard-demo.mjs | 8 +-
scripts/ralph-wizard-prod.mjs | 10 +-
scripts/ralph-wizard-start.mjs | 12 +-
scripts/test-links-browser.mjs | 24 ++--
scripts/test-tail-links.sh | 4 +-
scripts/tmux-chooser.sh | 58 ++++-----
scripts/tmux-manager.sh | 16 +--
src/ai-checker-base.ts | 8 +-
src/ai-idle-checker.ts | 6 +-
src/ai-plan-checker.ts | 6 +-
src/cli.ts | 8 +-
src/config/buffer-limits.ts | 2 +-
src/hooks-config.ts | 12 +-
src/image-watcher.ts | 4 +-
src/index.ts | 4 +-
src/mux-interface.ts | 6 +-
src/run-summary.ts | 2 +-
src/session-lifecycle-log.ts | 4 +-
src/session.ts | 30 ++---
src/state-store.ts | 22 +++-
src/subagent-watcher.ts | 20 +--
src/team-watcher.ts | 4 +-
src/templates/case-template.md | 6 +-
src/templates/claude-md.ts | 2 +-
src/tmux-manager.ts | 43 ++++---
src/types.ts | 8 +-
src/web/public/app.js | 101 +++++++++-------
src/web/public/index.html | 18 +--
src/web/public/styles.css | 2 +-
src/web/public/upload.html | 4 +-
src/web/schemas.ts | 2 +-
src/web/server.ts | 70 +++++------
test/ai-idle-checker.test.ts | 6 +-
test/api-responses.test.ts | 4 +-
test/buffer-management.test.ts | 2 +-
test/cli-commands.test.ts | 12 +-
test/edge-cases.test.ts | 4 +-
test/file-link-click.test.ts | 6 +-
test/hooks-config.test.ts | 10 +-
test/input-echo-test.mjs | 2 +-
test/integration-flows.test.ts | 2 +-
test/local-echo-basic-test.mjs | 4 +-
test/local-echo-daily-test.mjs | 4 +-
test/local-echo-edge-test.mjs | 6 +-
test/local-echo-mobile-test.mjs | 6 +-
test/local-echo-scroll-test.mjs | 4 +-
test/local-echo-tabswitch-test.mjs | 4 +-
test/local-echo-user-test.mjs | 8 +-
test/memory-leak-prevention.test.ts | 2 +-
test/perf-subagent-load.test.ts | 4 +-
test/quick-start.test.ts | 2 +-
test/ralph-integration.test.ts | 2 +-
test/respawn-analysis.md | 22 ++--
test/respawn-test-plan.md | 2 +-
test/respawn-test-utils.ts | 2 +-
test/session-cleanup.test.ts | 2 +-
test/session-state.test.ts | 38 +++---
test/setup.ts | 2 +-
test/sse-events.test.ts | 2 +-
test/state-store.test.ts | 2 +-
test/team-watcher.test.ts | 4 +-
test/templates.test.ts | 14 +--
test/terminal-parsing.test.ts | 2 +-
test/tmux-manager.test.ts | 40 +++---
test/tmux-restart-recovery.test.ts | 10 +-
109 files changed, 711 insertions(+), 679 deletions(-)
rename docs/images/{claudeman-demo.gif => codeman-demo.gif} (100%)
rename docs/images/{claudeman-title.svg => codeman-title.svg} (79%)
rename scripts/{claudeman-web.service => codeman-web.service} (75%)
diff --git a/CLAUDE.md b/CLAUDE.md
index 55863eca..37041ddd 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -9,13 +9,13 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
| Dev server | `npx tsx src/index.ts web` |
| Type check | `tsc --noEmit` |
| Single test | `npx vitest run test/.test.ts` |
-| Production | `npm run build && systemctl --user restart claudeman-web` |
+| Production | `npm run build && systemctl --user restart codeman-web` |
## CRITICAL: Session Safety
-**You may be running inside a Claudeman-managed tmux session.** Before killing ANY tmux or Claude process:
+**You may be running inside a Codeman-managed tmux session.** Before killing ANY tmux or Claude process:
-1. Check: `echo $CLAUDEMAN_TMUX` - if `1`, you're in a managed session
+1. Check: `echo $CODEMAN_TMUX` - if `1`, you're in a managed session
2. **NEVER** run `tmux kill-session`, `pkill tmux`, or `pkill claude` without confirming
3. Use the web UI or `./scripts/tmux-manager.sh` instead of direct kill commands
@@ -33,13 +33,13 @@ The production server caches static files for 1 hour (`maxAge: '1h'` in `server.
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`
+2. Run: `git add -A && git commit -m "chore: bump version to X.XXXX" && git push && npm run build && systemctl --user restart codeman-web`
**Version**: 0.1650 (must match `package.json`)
## Project Overview
-Claudeman is a Claude Code session manager with web interface and autonomous Ralph Loop. Spawns Claude CLI via PTY, streams via SSE, supports respawn cycling for 24+ hour autonomous runs.
+Codeman is a Claude Code session manager with web interface and autonomous Ralph Loop. Spawns Claude CLI via PTY, streams via SSE, supports respawn cycling for 24+ hour autonomous runs.
**Tech Stack**: TypeScript (ES2022/NodeNext, strict mode), Node.js, Fastify, node-pty, xterm.js
@@ -63,24 +63,24 @@ npx tsx src/index.ts web --https # With TLS (only needed for remote access)
npm run typecheck # Type check
tsc --noEmit --watch # Continuous type checking
-# Testing (NEVER run full suite from inside Claudeman — kills tmux sessions)
-# npx vitest run # ALL tests — DANGEROUS inside Claudeman
+# Testing (NEVER run full suite from inside Codeman — kills tmux sessions)
+# npx vitest run # ALL tests — DANGEROUS inside Codeman
npx vitest run test/.test.ts # Single file (SAFE)
npx vitest run -t "pattern" # Tests matching name
npm run test:coverage # With coverage report
# Production
npm run build
-systemctl --user restart claudeman-web
-journalctl --user -u claudeman-web -f
+systemctl --user restart codeman-web
+journalctl --user -u codeman-web -f
```
## Common Gotchas
- **`npm run dev` is NOT the web server** — it shows CLI help. Use `npx tsx src/index.ts web`
- **Single-line prompts only** — `writeViaMux()` sends text and Enter separately; multi-line breaks Ink
-- **Don't kill tmux sessions blindly** — Check `$CLAUDEMAN_TMUX` first; you might be inside one
-- **Never run full test suite** — `npx vitest run` spawns/kills tmux sessions and will crash your Claudeman session. Run individual test files only.
+- **Don't kill tmux sessions blindly** — Check `$CODEMAN_TMUX` first; you might be inside one
+- **Never run full test suite** — `npx vitest run` spawns/kills tmux sessions and will crash your Codeman session. Run individual test files only.
- **Global regex `lastIndex` sharing** — `ANSI_ESCAPE_PATTERN_FULL/SIMPLE` have `g` flag; use `createAnsiPatternFull/Simple()` factory functions for fresh instances in loops
- **DEC 2026 sync blocks** — Never discard incomplete sync blocks (START without END); buffer up to 50ms then flush. See `app.js:extractSyncSegments()`
- **Terminal writes during buffer load** — Live SSE writes are queued while `_isLoadingBuffer` is true to prevent interleaving with historical data
@@ -103,7 +103,7 @@ journalctl --user -u claudeman-web -f
| `src/mux-factory.ts` | Create tmux multiplexer instance |
| `src/tmux-manager.ts` | tmux session management |
| `src/session-manager.ts` | Session lifecycle, cleanup |
-| `src/state-store.ts` | State persistence to `~/.claudeman/state.json` |
+| `src/state-store.ts` | State persistence to `~/.codeman/state.json` |
| `src/respawn-controller.ts` | State machine for autonomous cycling |
| `src/ralph-tracker.ts` | Detects `PHRASE`, todos |
| `src/ralph-loop.ts` | Autonomous task execution loop (polls queue, assigns tasks) |
@@ -120,7 +120,7 @@ journalctl --user -u claudeman-web -f
| `src/bash-tool-parser.ts` | Parses Claude's bash tool invocations from output |
| `src/transcript-watcher.ts` | Watches Claude's transcript files for changes |
| `src/hooks-config.ts` | Manages `.claude/settings.local.json` hook configuration |
-| `src/session-lifecycle-log.ts` | Append-only JSONL audit log at `~/.claudeman/session-lifecycle.jsonl` |
+| `src/session-lifecycle-log.ts` | Append-only JSONL audit log at `~/.codeman/session-lifecycle.jsonl` |
| `src/image-watcher.ts` | Watches for image file creation (screenshots, etc.) |
| `src/file-stream-manager.ts` | Manages `tail -f` processes for live log viewing |
| `src/plan-orchestrator.ts` | Multi-agent plan generation with research and planning phases |
@@ -169,7 +169,7 @@ journalctl --user -u claudeman-web -f
1. Session spawns `claude --dangerously-skip-permissions` via node-pty
2. PTY output buffered, ANSI stripped, parsed for JSON messages
3. WebServer broadcasts to SSE clients at `/api/events`
-4. State persists to `~/.claudeman/state.json` via StateStore
+4. State persists to `~/.codeman/state.json` via StateStore
### Key Patterns
@@ -214,11 +214,11 @@ The frontend is a single 16K-line vanilla JS file with these key systems:
### Security
-- **HTTP Basic Auth**: Optional via `CLAUDEMAN_USERNAME`/`CLAUDEMAN_PASSWORD` env vars
+- **HTTP Basic Auth**: Optional via `CODEMAN_USERNAME`/`CODEMAN_PASSWORD` env vars
- **CORS**: Restricted to localhost only
- **Security headers**: X-Content-Type-Options, X-Frame-Options, CSP; HSTS if HTTPS
- **Path validation** (`schemas.ts`): Strict allowlist regex, no shell metacharacters, no traversal, must be absolute
-- **Env var allowlist**: Only `CLAUDE_CODE_*` prefixes allowed; blocks `PATH`, `LD_PRELOAD`, `NODE_OPTIONS`, `CLAUDEMAN_*` keys
+- **Env var allowlist**: Only `CLAUDE_CODE_*` prefixes allowed; blocks `PATH`, `LD_PRELOAD`, `NODE_OPTIONS`, `CODEMAN_*` keys
- **File streaming TOCTOU protection**: `FileStreamManager` calls `realpathSync()` twice (at validation and before spawn) to catch symlink swaps
### SSE Event Categories
@@ -269,9 +269,9 @@ The frontend is a single 16K-line vanilla JS file with these key systems:
| File | Purpose |
|------|---------|
-| `~/.claudeman/state.json` | Sessions, settings, tokens, respawn config |
-| `~/.claudeman/mux-sessions.json` | Tmux session metadata for recovery |
-| `~/.claudeman/settings.json` | User preferences |
+| `~/.codeman/state.json` | Sessions, settings, tokens, respawn config |
+| `~/.codeman/mux-sessions.json` | Tmux session metadata for recovery |
+| `~/.codeman/settings.json` | User preferences |
## Default Settings
@@ -281,7 +281,7 @@ UI defaults are set in `src/web/public/app.js` using `??` fallbacks. To change d
## Testing
-**CRITICAL: You are running inside a Claudeman-managed tmux session.** Never run `npx vitest run` (full suite) — it spawns/kills tmux sessions and will crash your own session. Instead:
+**CRITICAL: You are running inside a Codeman-managed tmux session.** Never run `npx vitest run` (full suite) — it spawns/kills tmux sessions and will crash your own session. Instead:
```bash
# Safe: run individual test files
@@ -290,7 +290,7 @@ npx vitest run test/.test.ts
# Safe: run tests matching a pattern
npx vitest run -t "pattern"
-# DANGEROUS from inside Claudeman — will kill your tmux session:
+# DANGEROUS from inside Codeman — will kill your tmux session:
# npx vitest run ← DON'T DO THIS
```
@@ -306,10 +306,10 @@ npx vitest run -t "pattern"
## Screenshots ("sc")
-When the user says "check the sc", "screenshot", or "sc", they mean uploaded screenshots from their mobile device. Screenshots are saved to `~/.claudeman/screenshots/` and uploaded via `/upload.html` on the Claudeman web UI. To view them, use the Read tool on the image files:
+When the user says "check the sc", "screenshot", or "sc", they mean uploaded screenshots from their mobile device. Screenshots are saved to `~/.codeman/screenshots/` and uploaded via `/upload.html` on the Codeman web UI. To view them, use the Read tool on the image files:
```bash
-ls ~/.claudeman/screenshots/ # List uploaded screenshots
+ls ~/.codeman/screenshots/ # List uploaded screenshots
# Then use Read tool on individual files — Claude Code can view images natively
```
@@ -322,7 +322,7 @@ tmux list-sessions # List tmux sessions
tmux attach-session -t # Attach (Ctrl+B D to detach)
curl localhost:3000/api/sessions # Check sessions
curl localhost:3000/api/status | jq # Full app state
-cat ~/.claudeman/state.json | jq # View persisted state
+cat ~/.codeman/state.json | jq # View persisted state
curl localhost:3000/api/subagents # List background agents
curl localhost:3000/api/sessions/:id/run-summary | jq # Session timeline
```
@@ -337,7 +337,7 @@ curl localhost:3000/api/sessions/:id/run-summary | jq # Session timeline
| Respawn not triggering | Session settings → Respawn enabled? | Enable respawn, check idle timeout config |
| Terminal blank on tab switch | Network tab for `/api/sessions/:id/buffer` | Check session exists, restart server |
| Tests failing on session limits | `tmux list-sessions \| wc -l` | Clean up: `tmux list-sessions \| grep test \| awk -F: '{print $1}' \| xargs -I{} tmux kill-session -t {}` |
-| State not persisting | `cat ~/.claudeman/state.json` | Check file permissions, disk space |
+| State not persisting | `cat ~/.codeman/state.json` | Check file permissions, disk space |
## Performance Constraints
@@ -352,7 +352,7 @@ The app must stay fast with 20 sessions and 50 agent windows:
## Terminal Anti-Flicker System
-Claude Code uses Ink (React for terminals), which redraws the screen on every state change. Claudeman implements a 6-layer anti-flicker pipeline for smooth 60fps output:
+Claude Code uses Ink (React for terminals), which redraws the screen on every state change. Codeman implements a 6-layer anti-flicker pipeline for smooth 60fps output:
```
PTY Output → Server Batching (16-50ms) → DEC 2026 Wrap → SSE → Client rAF → xterm.js
@@ -395,14 +395,14 @@ Use `LRUMap` for bounded caches with eviction, `StaleExpirationMap` for TTL-base
| **Terminal anti-flicker** | `docs/terminal-anti-flicker.md` |
| **API routes** | `src/web/server.ts:buildServer()` or README.md (full endpoint tables) |
| **SSE events** | Search `broadcast(` in `server.ts` |
-| **CLI commands** | `claudeman --help` |
+| **CLI commands** | `codeman --help` |
| **Frontend patterns** | `src/web/public/app.js` (subagent windows, notifications) |
| **Session statuses** | `SessionStatus` type in `src/types.ts` |
| **Error codes** | `createErrorResponse()` in `src/types.ts` |
| **Test utilities** | `test/respawn-test-utils.ts` |
| **Memory leak patterns** | `test/memory-leak-prevention.test.ts` |
| **Keyboard shortcuts** | README.md or App Settings in web UI |
-| **Mobile/SSH access** | README.md (Claudeman Sessions / `sc` command) |
+| **Mobile/SSH access** | README.md (Codeman Sessions / `sc` command) |
| **Plan orchestrator** | `src/plan-orchestrator.ts` file header |
| **Agent prompts** | `src/prompts/` directory |
| **Agent Teams (experimental)** | `agent-teams/README.md`, `agent-teams/design.md` |
@@ -444,7 +444,7 @@ Use `LRUMap` for bounded caches with eviction, `StaleExpirationMap` for TTL-base
| `scripts/test-patterns.mjs` | Test file path link detection regex patterns |
| `scripts/watch-subagents.ts` | Real-time subagent transcript watcher (list, follow by session/agent ID) |
| `scripts/capture-readme-screenshots.mjs` | Capture screenshots for README |
-| `scripts/claudeman-web.service` | systemd service file for production deployment |
+| `scripts/codeman-web.service` | systemd service file for production deployment |
## Memory Leak Prevention
@@ -464,7 +464,7 @@ Run `npx vitest run test/memory-leak-prevention.test.ts` to verify patterns.
## Common Workflows
-**Investigating a bug**: Start dev server (`npx tsx src/index.ts web`), reproduce in browser, check terminal output and `~/.claudeman/state.json` for clues.
+**Investigating a bug**: Start dev server (`npx tsx src/index.ts web`), reproduce in browser, check terminal output and `~/.codeman/state.json` for clues.
**Adding a new API endpoint**: Define types in `types.ts`, add route in `server.ts:buildServer()`, broadcast SSE events if needed, handle in `app.js:handleSSEEvent()`.
diff --git a/README.md b/README.md
index db3b4acc..74e64087 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
-
+
The missing control plane for Claude Code
@@ -17,7 +17,7 @@
-
+
---
@@ -25,19 +25,19 @@
## Quick Start - Installation
```bash
-curl -fsSL https://raw.githubusercontent.com/Ark0N/claudeman/master/install.sh | bash
+curl -fsSL https://raw.githubusercontent.com/Ark0N/Codeman/master/install.sh | bash
```
-This installs Node.js, tmux, and Claude CLI if missing, clones Claudeman to `~/.claudeman/app`, builds it. After install:
+This installs Node.js, tmux, and Claude CLI if missing, clones Codeman to `~/.codeman/app`, builds it. After install:
```bash
-claudeman web
+codeman web
# Open http://localhost:3000 — press Ctrl+Enter to start your first session
```
**Update to latest version:**
```bash
-curl -fsSL https://raw.githubusercontent.com/Ark0N/claudeman/master/install.sh | bash -s update
+curl -fsSL https://raw.githubusercontent.com/Ark0N/Codeman/master/install.sh | bash -s update
```
@@ -45,12 +45,12 @@ curl -fsSL https://raw.githubusercontent.com/Ark0N/claudeman/master/install.sh |
**Linux (systemd):**
```bash
-mkdir -p ~/.config/systemd/user && printf '[Unit]\nDescription=Claudeman Web Server\nAfter=network.target\n\n[Service]\nType=simple\nExecStart=%s %s/dist/index.js web\nRestart=always\nRestartSec=10\n\n[Install]\nWantedBy=default.target\n' "$(which node)" "$HOME/.claudeman/app" > ~/.config/systemd/user/claudeman-web.service && systemctl --user daemon-reload && systemctl --user enable --now claudeman-web && loginctl enable-linger $USER
+mkdir -p ~/.config/systemd/user && printf '[Unit]\nDescription=Codeman Web Server\nAfter=network.target\n\n[Service]\nType=simple\nExecStart=%s %s/dist/index.js web\nRestart=always\nRestartSec=10\n\n[Install]\nWantedBy=default.target\n' "$(which node)" "$HOME/.codeman/app" > ~/.config/systemd/user/codeman-web.service && systemctl --user daemon-reload && systemctl --user enable --now codeman-web && loginctl enable-linger $USER
```
**macOS (launchd):**
```bash
-mkdir -p ~/Library/LaunchAgents && printf '\n\nLabelcom.claudeman.webProgramArguments%s%s/dist/index.jswebRunAtLoadKeepAliveStandardOutPath/tmp/claudeman.logStandardErrorPath/tmp/claudeman.log\n' "$(which node)" "$HOME/.claudeman/app" > ~/Library/LaunchAgents/com.claudeman.web.plist && launchctl load ~/Library/LaunchAgents/com.claudeman.web.plist
+mkdir -p ~/Library/LaunchAgents && printf '\n\nLabelcom.codeman.webProgramArguments%s%s/dist/index.jswebRunAtLoadKeepAliveStandardOutPath/tmp/codeman.logStandardErrorPath/tmp/codeman.log\n' "$(which node)" "$HOME/.codeman/app" > ~/Library/LaunchAgents/com.codeman.web.plist && launchctl load ~/Library/LaunchAgents/com.codeman.web.plist
```
@@ -58,10 +58,10 @@ mkdir -p ~/Library/LaunchAgents && printf 'Windows (WSL)
```powershell
-wsl bash -c "curl -fsSL https://raw.githubusercontent.com/Ark0N/claudeman/master/install.sh | bash"
+wsl bash -c "curl -fsSL https://raw.githubusercontent.com/Ark0N/Codeman/master/install.sh | bash"
```
-Claudeman requires tmux, so Windows users need [WSL](https://learn.microsoft.com/en-us/windows/wsl/install). If you don't have WSL yet: run `wsl --install` in an admin PowerShell, reboot, open Ubuntu, then install Claude CLI inside WSL: `curl -fsSL https://claude.ai/install.sh | bash`. After installing, `http://localhost:3000` is accessible from your Windows browser.
+Codeman requires tmux, so Windows users need [WSL](https://learn.microsoft.com/en-us/windows/wsl/install). If you don't have WSL yet: run `wsl --install` in an admin PowerShell, reboot, open Ubuntu, then install Claude CLI inside WSL: `curl -fsSL https://claude.ai/install.sh | bash`. After installing, `http://localhost:3000` is accessible from your Windows browser.
---
@@ -74,7 +74,7 @@ The most responsive Claude Code experience on any phone. Full xterm.js terminal
Terminal Apps
-
Claudeman Mobile
+
Codeman Mobile
200-300ms input lag over remote
Local echo — instant feedback
Tiny text, no context
Full xterm.js terminal
@@ -94,7 +94,7 @@ The most responsive Claude Code experience on any phone. Full xterm.js terminal
- **Native momentum scrolling** — `-webkit-overflow-scrolling: touch` for buttery scroll
```bash
-claudeman web --https
+codeman web --https
# Open on your phone: https://:3000
```
@@ -104,7 +104,7 @@ claudeman web --https
## Live Agent Visualization
-Watch Claude's background agents work in real-time. Claudeman monitors every `Task` tool invocation and displays each agent in a draggable floating window with animated Matrix-style connection lines back to the parent session.
+Watch Claude's background agents work in real-time. Codeman monitors every `Task` tool invocation and displays each agent in a draggable floating window with animated Matrix-style connection lines back to the parent session.
@@ -120,7 +120,7 @@ Watch Claude's background agents work in real-time. Claudeman monitors every `Ta
## Zero-Lag Input Overlay
-When accessing Claude Code remotely (VPN, Tailscale, SSH tunnel), every keystroke normally takes 200-300ms to round-trip. Claudeman implements a **Mosh-inspired local echo system** that makes typing feel instant regardless of latency.
+When accessing Claude Code remotely (VPN, Tailscale, SSH tunnel), every keystroke normally takes 200-300ms to round-trip. Codeman implements a **Mosh-inspired local echo system** that makes typing feel instant regardless of latency.
A pixel-perfect DOM overlay inside xterm.js renders keystrokes at 0ms. Background forwarding silently sends every character to the PTY in 50ms debounced batches, so Tab completion, `Ctrl+R` history search, and all shell features work normally. When the server echo arrives 200-300ms later, the overlay seamlessly disappears and the real terminal text takes over — the transition is invisible.
@@ -186,7 +186,7 @@ Click the chart icon on any session tab to see a timeline of everything that hap
### Zero-Flicker Terminal
-Claude Code uses Ink (React for terminals) which redraws the entire screen on every state change. Claudeman implements a 6-layer anti-flicker pipeline for smooth 60fps output across all sessions:
+Claude Code uses Ink (React for terminals) which redraws the entire screen on every state change. Codeman implements a 6-layer anti-flicker pipeline for smooth 60fps output across all sessions:
```
PTY Output → 16ms Server Batch → DEC 2026 Wrap → SSE → Client rAF → xterm.js (60fps)
@@ -268,7 +268,7 @@ Single-digit selection (1-9), color-coded status, token counts, auto-refresh. De
```mermaid
flowchart TB
- subgraph Claudeman["CLAUDEMAN"]
+ subgraph Codeman["CODEMAN"]
subgraph Frontend["Frontend Layer"]
UI["Web UI xterm.js + Agent Windows"]
API["REST API Fastify"]
diff --git a/agent-teams/README.md b/agent-teams/README.md
index 28c00c0b..037d4d6f 100644
--- a/agent-teams/README.md
+++ b/agent-teams/README.md
@@ -68,7 +68,7 @@ Note: Teammate transcripts appear in the **standard subagent directory** under t
}
```
-Key fields: `agentId` format is `{name}@{teamName}`, `leadSessionId` links to Claudeman session, `backendType` indicates display mode, `color` for UI theming.
+Key fields: `agentId` format is `{name}@{teamName}`, `leadSessionId` links to Codeman session, `backendType` indicates display mode, `color` for UI theming.
### Task file format (verified)
@@ -122,7 +122,7 @@ Message types observed:
**Teammates are IN-PROCESS THREADS, not separate OS processes.**
-In `in-process` mode (the default), all teammates run as threads within the single `claude` process. Only 1 claude process exists per Claudeman session, regardless of team size.
+In `in-process` mode (the default), all teammates run as threads within the single `claude` process. Only 1 claude process exists per Codeman session, regardless of team size.
This means:
- No separate PIDs to track per teammate
@@ -138,7 +138,7 @@ This means:
| **tmux** | `--teammate-mode tmux` | Split panes | tmux installed |
| **iTerm2** | Auto-detected | Native split panes | iTerm2 + `it2` CLI |
-**For Claudeman: use `in-process` only.** Claudeman manages its own tmux sessions externally.
+**For Codeman: use `in-process` only.** Codeman manages its own tmux sessions externally.
**In-process UI elements:**
- Status bar: `@main @teammate1 @teammate2 ...` with `shift+↑ to expand`
@@ -159,7 +159,7 @@ Fires when a task is being marked complete.
- Exit code 0: Allow completion
- Exit code 2: Prevent completion, send feedback
-These are configured in `.claude/settings.local.json` alongside existing Claudeman hooks.
+These are configured in `.claude/settings.local.json` alongside existing Codeman hooks.
## Subagent-Watcher Compatibility (Verified)
@@ -168,7 +168,7 @@ These are configured in `.claude/settings.local.json` alongside existing Claudem
~/.claude/projects/{hash}/{leadSessionId}/subagents/agent-{id}.jsonl
```
-Claudeman's existing `subagent-watcher.ts` discovers them automatically. They appear in `/api/subagents` with status "active".
+Codeman's existing `subagent-watcher.ts` discovers them automatically. They appear in `/api/subagents` with status "active".
**Distinguishing teammates from regular subagents:**
- Description field starts with ` Updated 2026-02-12 with experiment findings. See `experiment-log.md` for raw data.
@@ -15,7 +15,7 @@ Monitors `~/.claude/teams/` for team creation/removal and tracks active teams.
**Discovery mechanism:**
- Poll `~/.claude/teams/` for directories (team names) every 3-5 seconds
- When found: parse `config.json` to get:
- - `leadSessionId` → map to Claudeman session
+ - `leadSessionId` → map to Codeman session
- `members` array → teammate names, agentIds, colors, models
- Watch for directory deletion (cleanup signal)
@@ -25,7 +25,7 @@ Monitors `~/.claude/teams/` for team creation/removal and tracks active teams.
- Teammate transcripts are at `subagents/agent-{id}.jsonl` (standard subagent path), NOT separate session transcripts
**Association:**
-- `config.json.leadSessionId` → Claudeman session ID (direct match!)
+- `config.json.leadSessionId` → Codeman session ID (direct match!)
- Each member's `agentId` (e.g., `fs-researcher@research-watchers`) → links to subagent files
- `agentType: "team-lead"` vs `"general-purpose"` distinguishes lead from teammates
@@ -37,7 +37,7 @@ Monitors `~/.claude/teams/` for team creation/removal and tracks active teams.
### 2. Team-Aware Idle Detection (HIGHEST PRIORITY)
-**Problem (confirmed by experiment):** Lead session shows status "idle" in Claudeman while teammates are actively working. Token count continues climbing but Claudeman thinks the session is inactive.
+**Problem (confirmed by experiment):** Lead session shows status "idle" in Codeman while teammates are actively working. Token count continues climbing but Codeman thinks the session is inactive.
**Solution:**
- Before declaring a session idle, check if it's a team lead
@@ -125,7 +125,7 @@ Communication uses filesystem inbox files at `~/.claude/teams/{name}/inboxes/{te
**Potential for interaction (not tested, future work):**
- Write to teammate inbox files to inject messages
- Must respect `.json.lock` directory locking protocol
-- Could enable "nudge" or "redirect" functionality from Claudeman UI
+- Could enable "nudge" or "redirect" functionality from Codeman UI
## Answered Questions (from experiment)
@@ -161,7 +161,7 @@ Communication uses filesystem inbox files at `~/.claude/teams/{name}/inboxes/{te
3. **Teammate badge in subagent windows** — mark teammate subagents with name/color
4. **Team tasks API + UI** — `GET /api/sessions/:id/team-tasks` + task list panel
5. **Inbox monitoring** — watch inbox files, display message timeline
-6. **TeammateIdle/TaskCompleted hooks** — add to Claudeman's hooks config generator
+6. **TeammateIdle/TaskCompleted hooks** — add to Codeman's hooks config generator
## What We DON'T Need to Build
diff --git a/agent-teams/experiment-log.md b/agent-teams/experiment-log.md
index 29fc0c70..b609b04a 100644
--- a/agent-teams/experiment-log.md
+++ b/agent-teams/experiment-log.md
@@ -1,7 +1,7 @@
# Agent Teams Experiment Log
> Experiment date: 2026-02-12
-> Test case: `~/claudeman-cases/agent-teams-test/`
+> Test case: `~/codeman-cases/agent-teams-test/`
> Team name: `research-watchers`
> Teammates: 3 (fs-researcher, perf-researcher, api-researcher)
> Lead session: `461daa80-94ec-4e5e-a1bb-0518f78311bc`
@@ -56,7 +56,7 @@ Name the team research-watchers.
Subagent transcripts also appear in the standard subagent directory:
```
-~/.claude/projects/-home-arkon-claudeman-cases-agent-teams-test/
+~/.claude/projects/-home-arkon-codeman-cases-agent-teams-test/
└── 461daa80.../
├── 461daa80...jsonl # Lead session transcript
└── subagents/
@@ -102,7 +102,7 @@ Key observations:
- **File locking** via `.json.lock` directories (mkdir-based atomic lock, created then deleted)
- Lead also has an inbox (`team-lead.json`) for receiving messages FROM teammates
-**Implication for Claudeman:** We CAN intercept messages by watching inbox JSON files! We can also potentially inject messages by writing to inbox files.
+**Implication for Codeman:** We CAN intercept messages by watching inbox JSON files! We can also potentially inject messages by writing to inbox files.
---
@@ -119,7 +119,7 @@ Teammates create transcript files at:
This is the **exact same path pattern** that regular Task tool subagents use. The existing `subagent-watcher.ts` successfully discovers them.
-Claudeman's `/api/subagents` endpoint returned them with status "active":
+Codeman's `/api/subagents` endpoint returned them with status "active":
```
Agent: ae50544 Status: active Tools: 8 Model: claude-opus-4-6
Desc:
- Claudeman
+ Codeman
diff --git a/docs/local-echo-overlay-plan.md b/docs/local-echo-overlay-plan.md
index 96955c23..2f9e9ac1 100644
--- a/docs/local-echo-overlay-plan.md
+++ b/docs/local-echo-overlay-plan.md
@@ -2,7 +2,7 @@
## Context
-User accesses Claudeman remotely from Thailand to Switzerland over Tailscale (~200-300ms RTT).
+User accesses Codeman remotely from Thailand to Switzerland over Tailscale (~200-300ms RTT).
Every keystroke is invisible for 200-300ms before the server echoes it back. This makes typing
painfully slow on mobile. Previous attempts to write directly to xterm.js buffer failed because
Ink (Claude Code's terminal framework) does full-screen redraws that corrupt injected characters.
diff --git a/docs/opencode-integration.md b/docs/opencode-integration.md
index 362417e0..fd683a7b 100644
--- a/docs/opencode-integration.md
+++ b/docs/opencode-integration.md
@@ -1,4 +1,4 @@
-# OpenCode Integration Plan for Claudeman
+# OpenCode Integration Plan for Codeman
> **Author**: Claude Opus 4.6 | **Date**: 2026-02-26
> **Status**: Draft — Re-reviewed, MVP scope finalized. NOT pushed to GitHub
@@ -36,13 +36,13 @@
23. [Appendix A: OpenCode CLI Reference](#appendix-a-opencode-cli-reference)
24. [Appendix B: OpenCode Plugin Events](#appendix-b-opencode-plugin-events)
25. [Appendix C: OpenCode Permission Config](#appendix-c-opencode-permission-config)
-26. [Appendix D: Current Claudeman Session Spawn Flow (Annotated)](#appendix-d-current-claudeman-session-spawn-flow-annotated)
+26. [Appendix D: Current Codeman Session Spawn Flow (Annotated)](#appendix-d-current-codeman-session-spawn-flow-annotated)
---
## 1. Executive Summary
-This plan details how to integrate [OpenCode](https://opencode.ai) — the popular open-source AI coding CLI (111k+ GitHub stars, 75+ model providers) — into Claudeman as a first-class session type alongside Claude Code and shell sessions.
+This plan details how to integrate [OpenCode](https://opencode.ai) — the popular open-source AI coding CLI (111k+ GitHub stars, 75+ model providers) — into Codeman as a first-class session type alongside Claude Code and shell sessions.
### Core Approach
@@ -53,7 +53,7 @@ Extend the existing `SessionMode` type from `'claude' | 'shell'` to `'claude' |
| Strategy | Approach | Complexity | Value |
|----------|----------|------------|-------|
| **A: TUI-in-tmux** | Spawn `opencode` CLI in tmux, render in xterm.js | Medium | Full visual parity with Claude Code |
-| **B: Server API bridge** | Run `opencode serve` + proxy its API through Claudeman | High | Structured data, session control, token tracking |
+| **B: Server API bridge** | Run `opencode serve` + proxy its API through Codeman | High | Structured data, session control, token tracking |
**Recommended path**: Start with Strategy A (TUI-in-tmux) since it mirrors the existing Claude Code pattern exactly. Then layer Strategy B on top for advanced features like structured token tracking and model switching.
@@ -71,7 +71,7 @@ Extend the existing `SessionMode` type from `'claude' | 'shell'` to `'claude' |
> | **Hooks plugin bridge** | Plugin event names are speculative/unverified. Requires Phase 0 validation that hasn't happened. | Phase 0 plugin verification |
> | **AI idle checker** | Spawns `claude -p` for analysis. Won't work if only OpenCode is installed. | Claude CLI availability or `opencode run` fallback |
>
-> **What ships in the MVP**: Phases 0-3 (spawn in tmux, render in xterm.js) + Phase 5 (API routes, mode selector, tab badges, create/kill sessions). Users can interact with OpenCode manually — type prompts, see output, manage sessions from the Claudeman web UI. This alone is the core value: multi-model AI sessions in one management interface.
+> **What ships in the MVP**: Phases 0-3 (spawn in tmux, render in xterm.js) + Phase 5 (API routes, mode selector, tab badges, create/kill sessions). Users can interact with OpenCode manually — type prompts, see output, manage sessions from the Codeman web UI. This alone is the core value: multi-model AI sessions in one management interface.
### Why OpenCode?
@@ -79,7 +79,7 @@ Extend the existing `SessionMode` type from `'claude' | 'shell'` to `'claude' |
- **Privacy-first**: Can run fully local via Ollama — no code ever leaves the machine
- **Open source**: MIT licensed, active community (700+ contributors)
- **Client/server**: Built-in `opencode serve` mode enables richer programmatic integration
-- **Plugin system**: JS/TS plugins with rich event hooks (including `session.idle` — perfect for Claudeman)
+- **Plugin system**: JS/TS plugins with rich event hooks (including `session.idle` — perfect for Codeman)
---
@@ -222,7 +222,7 @@ OPENCODE_CLIENT=... # Client identifier (default: "cli")
## 3. Architecture Comparison: Claude Code vs OpenCode
-### Current Claudeman Session Flow (Claude Code)
+### Current Codeman Session Flow (Claude Code)
```
POST /api/sessions → new Session({mode: 'claude', mux: TmuxManager})
@@ -230,10 +230,10 @@ POST /api/sessions/:id/interactive → session.startInteractive()
↓
TmuxManager.createSession()
↓
- tmux new-session -ds "claudeman-"
+ tmux new-session -ds "codeman-"
tmux respawn-pane -k -t ... "claude --dangerously-skip-permissions --session-id "
↓
- pty.spawn('tmux', ['attach-session', '-t', 'claudeman-'])
+ pty.spawn('tmux', ['attach-session', '-t', 'codeman-'])
↓
ptyProcess.onData() → emit('terminal') → SSE broadcast → xterm.js
```
@@ -246,10 +246,10 @@ POST /api/sessions/:id/interactive → session.startInteractive()
↓
TmuxManager.createSession()
↓
- tmux new-session -ds "claudeman-"
+ tmux new-session -ds "codeman-"
tmux respawn-pane -k -t ... "opencode --model "
↓
- pty.spawn('tmux', ['attach-session', '-t', 'claudeman-'])
+ pty.spawn('tmux', ['attach-session', '-t', 'codeman-'])
↓
ptyProcess.onData() → emit('terminal') → SSE broadcast → xterm.js
```
@@ -268,7 +268,7 @@ Strategy A (TUI-in-tmux) for terminal rendering
+
opencode serve (background, port 4096+N)
↓
-Claudeman proxy routes → GET /session/current, POST /session/message, SSE /events
+Codeman proxy routes → GET /session/current, POST /session/message, SSE /events
↓
Structured data for: token tracking, session management, model switching
```
@@ -301,7 +301,7 @@ These systems work identically for OpenCode sessions:
- Terminal data streaming via `ptyProcess.onData()`
- SSE event broadcasting via `broadcast()`
- xterm.js terminal rendering in the browser
-- State persistence to `~/.claudeman/state.json`
+- State persistence to `~/.codeman/state.json`
- Session CRUD API routes (create, get, delete)
- Tab management in frontend
- Session kill/cleanup logic (`TmuxManager.killSession()`)
@@ -324,7 +324,7 @@ These systems work identically for OpenCode sessions:
| Subagent detection | `BashToolParser` + `SubagentWatcher` | Different tool output format | DEFERRED |
| Ralph completion | `PHRASE` tags | Not applicable (needs alternative) | DEFERRED |
| Hooks events | `permission_prompt`, `idle_prompt`, `stop` | `permission.asked`, `session.idle`, `session.status` | DEFERRED |
-| Auto-compact | Claudeman sends `/compact` at token threshold | OpenCode has built-in `compaction.auto: true` | DEFERRED |
+| Auto-compact | Codeman sends `/compact` at token threshold | OpenCode has built-in `compaction.auto: true` | DEFERRED |
---
@@ -346,7 +346,7 @@ opencode --version
# 3. Test interactive TUI
opencode
-# 4. Test in tmux (simulating Claudeman's spawn pattern)
+# 4. Test in tmux (simulating Codeman's spawn pattern)
tmux new-session -ds "test-opencode" -c /tmp -x 120 -y 40
tmux set-option -t "test-opencode" remain-on-exit on
tmux respawn-pane -k -t "test-opencode" 'opencode --model anthropic/claude-sonnet-4-5'
@@ -774,10 +774,10 @@ function buildEnvExports(mode: string, sessionId: string, muxName: string, openC
`export LANG=en_US.UTF-8`,
`export LC_ALL=en_US.UTF-8`,
`unset COLORTERM`, // Prevent color issues in tmux
- `export CLAUDEMAN_MUX=1`,
- `export CLAUDEMAN_SESSION_ID=${sessionId}`,
- `export CLAUDEMAN_MUX_NAME=${muxName}`,
- `export CLAUDEMAN_API_URL=${process.env.CLAUDEMAN_API_URL || 'http://localhost:3000'}`,
+ `export CODEMAN_MUX=1`,
+ `export CODEMAN_SESSION_ID=${sessionId}`,
+ `export CODEMAN_MUX_NAME=${muxName}`,
+ `export CODEMAN_API_URL=${process.env.CODEMAN_API_URL || 'http://localhost:3000'}`,
];
if (mode === 'opencode') {
@@ -905,7 +905,7 @@ const mode = cmd.includes('opencode') ? 'opencode' : 'claude';
### Known Limitations (from review)
-> **[REVIEW P1-6]** OpenCode does not have `--session-id ` for initial session creation (only `--session ` for continuing existing sessions). This means:
+> **[REVIEW P1-6]** OpenCode does not have `--session-id ` for initial session creation (only `--session ` for continuing existing sessions). This means:
> - `_claudeSessionId = this.id` correlation (session.ts:405) won't work for OpenCode
> - Subagent-session correlation via Session ID matching won't work
> - Transcript watching via Claude session ID path won't work
@@ -1121,7 +1121,7 @@ private parseTokens(data: string): void {
### Working/Idle State Tracking
-For Claude, Claudeman uses spinner characters and keywords. For OpenCode:
+For Claude, Codeman uses spinner characters and keywords. For OpenCode:
> **[REVIEW]** The original logic had a bug: `Date.now() - this._lastActivityAt > 100` is checked AFTER setting `_lastActivityAt = Date.now()`, so the condition would never be true (0 > 100 = false). Fixed below.
@@ -1373,7 +1373,7 @@ if (session.mode === 'claude' && session.pid) {
> **[REVIEW C3] Phase reordered**: This was originally Phase 7 but has been moved before Respawn. The plugin bridge provides the reliable `session.idle` event that the respawn controller needs. Without it, respawn relies on output-silence-only detection, which is unreliable with Bubble Tea TUIs (see Review C1). **Do not implement respawn (Phase 7) until this phase is complete and tested.**
### Goal
-Bridge Claudeman's hook system with OpenCode's plugin system for rich event forwarding.
+Bridge Codeman's hook system with OpenCode's plugin system for rich event forwarding.
### Background: Two Different Approaches
@@ -1383,19 +1383,19 @@ Bridge Claudeman's hook system with OpenCode's plugin system for rich event forw
| Trigger | Hook name matches event type | Event name subscription |
| Key events | `stop`, `idle_prompt`, `permission_prompt`, `elicitation_dialog` | `session.idle`, `permission.asked`, `session.status` |
| Communication | Exit codes + environment variables | Function context + return values |
-| Install | Auto-generated by Claudeman | Must be placed in `.opencode/plugins/` |
+| Install | Auto-generated by Codeman | Must be placed in `.opencode/plugins/` |
-### Claudeman Plugin for OpenCode
+### Codeman Plugin for OpenCode
-Create a Claudeman plugin that OpenCode loads, which communicates back to Claudeman's API:
+Create a Codeman plugin that OpenCode loads, which communicates back to Codeman's API:
-**File: `.opencode/plugins/claudeman-bridge.js`** (generated per session)
+**File: `.opencode/plugins/codeman-bridge.js`** (generated per session)
```javascript
-// This plugin bridges OpenCode events to Claudeman's API
-export const claudemanBridge = async ({ project, $ }) => {
- const apiUrl = process.env.CLAUDEMAN_API_URL || 'http://localhost:3000';
- const sessionId = process.env.CLAUDEMAN_SESSION_ID;
+// This plugin bridges OpenCode events to Codeman's API
+export const codemanBridge = async ({ project, $ }) => {
+ const apiUrl = process.env.CODEMAN_API_URL || 'http://localhost:3000';
+ const sessionId = process.env.CODEMAN_SESSION_ID;
if (!sessionId) return {};
@@ -1440,7 +1440,7 @@ export const claudemanBridge = async ({ project, $ }) => {
### Plugin Installation
-When creating an OpenCode session, Claudeman generates this plugin in the project's `.opencode/plugins/` directory:
+When creating an OpenCode session, Codeman generates this plugin in the project's `.opencode/plugins/` directory:
```typescript
// In session.ts or a new opencode-hooks.ts:
@@ -1448,8 +1448,8 @@ async function installOpenCodePlugin(workingDir: string, sessionId: string): Pro
const pluginDir = join(workingDir, '.opencode', 'plugins');
await mkdirp(pluginDir);
- const pluginContent = generateClaudemanBridgePlugin(sessionId);
- await writeFile(join(pluginDir, 'claudeman-bridge.js'), pluginContent);
+ const pluginContent = generateCodemanBridgePlugin(sessionId);
+ await writeFile(join(pluginDir, 'codeman-bridge.js'), pluginContent);
}
```
@@ -1458,7 +1458,7 @@ async function installOpenCodePlugin(workingDir: string, sessionId: string): Pro
> **[REVIEW]** Add `session.compacted` to the plugin bridge — it's free and useful for tracking when OpenCode auto-compacts (relevant for token tracking and respawn timing).
```javascript
-// Add to claudeman-bridge.js return object:
+// Add to codeman-bridge.js return object:
'session.compacted': async (info) => {
await notifyClademan('session_compacted', { info });
},
@@ -1472,12 +1472,12 @@ async function installOpenCodePlugin(workingDir: string, sessionId: string): Pro
### Benefits of the Plugin Bridge
-Once installed, Claudeman receives structured events from OpenCode:
+Once installed, Codeman receives structured events from OpenCode:
- **`session.idle`** → Definitive idle detection (replaces output-silence guessing)
-- **`permission.asked`** → Show permission prompts in Claudeman UI
+- **`permission.asked`** → Show permission prompts in Codeman UI
- **`tool.execute.*`** → Tool call tracking (similar to BashToolParser for Claude)
-- **`todo.updated`** → OpenCode's built-in todo system → Claudeman can display it
-- **`session.error`** → Error surfacing in Claudeman UI
+- **`todo.updated`** → OpenCode's built-in todo system → Codeman can display it
+- **`session.error`** → Error surfacing in Codeman UI
- **`session.compacted`** → Track auto-compaction events
---
@@ -1664,7 +1664,7 @@ tmux session ─── opencode TUI (interactive, port N/A)
│
├── xterm.js (terminal rendering, Strategy A)
│
-Claudeman ──── opencode serve (port 4096+N, background process)
+Codeman ──── opencode serve (port 4096+N, background process)
│
├── GET /session/* → structured session data
├── POST /session/message → send prompt programmatically
@@ -1678,7 +1678,7 @@ Claudeman ──── opencode serve (port 4096+N, background process)
> **[REVIEW M8]** Running both `opencode` (TUI) and `opencode serve` in the same project directory creates a **shared SQLite state problem**. The TUI creates sessions in SQLite; the server reads from the same SQLite. But they're separate processes — there's no guarantee of session ID consistency between them.
>
> **Consider alternatives**:
-> - (a) Use `opencode serve` INSTEAD of the TUI (not alongside it) — server becomes the single backend, Claudeman renders its own UI
+> - (a) Use `opencode serve` INSTEAD of the TUI (not alongside it) — server becomes the single backend, Codeman renders its own UI
> - (b) Use `opencode attach` to connect the TUI to the server, making the server the single source of truth
> - (c) Accept the dual-process model with explicit documentation of limitations
>
@@ -1805,7 +1805,7 @@ if (this.mode === 'opencode' && this._openCodeConfig?.serverPort) {
|------|---------|-------|--------|
| `src/utils/ansi-content-filter.ts` | Strip cosmetic ANSI sequences for idle detection | 4 | DEFERRED |
| `src/completion-detector.ts` | `CompletionDetector` interface + implementations | 7 | DEFERRED |
-| `src/opencode-plugin-generator.ts` | Generate `.opencode/plugins/claudeman-bridge.js` | 6 | DEFERRED |
+| `src/opencode-plugin-generator.ts` | Generate `.opencode/plugins/codeman-bridge.js` | 6 | DEFERRED |
| `src/opencode-api-client.ts` | Client for OpenCode's REST API (Strategy B) | 8 | DEFERRED |
| `test/opencode-respawn.test.ts` | Tests for OpenCode respawn cycle (port 3156) | 7 | DEFERRED |
| `test/ansi-content-filter.test.ts` | Tests for ANSI content filter | 4 | DEFERRED |
@@ -1898,7 +1898,7 @@ npx vitest run test/opencode-respawn.test.ts
### Safety Rules
-- **Never run OpenCode tests that spawn real tmux sessions inside Claudeman** (same safety rule as Claude tests)
+- **Never run OpenCode tests that spawn real tmux sessions inside Codeman** (same safety rule as Claude tests)
- **Use MockSession** from `test/respawn-test-utils.ts` for respawn testing
- **Mock the opencode binary** for unit tests (`jest.mock` or stub)
- **Use unique test ports** (3155+) — never port 3000
@@ -1939,12 +1939,12 @@ npx vitest run test/opencode-respawn.test.ts
5. **Should we auto-generate `opencode.json` in the working directory?**
- Option A: Let OpenCode use existing project config (respect user settings)
- - Option B: Generate a temporary one with Claudeman's settings
- - Recommendation: Option A (use `OPENCODE_CONFIG_CONTENT` env var for Claudeman-specific overrides, don't modify project files)
+ - Option B: Generate a temporary one with Codeman's settings
+ - Recommendation: Option A (use `OPENCODE_CONFIG_CONTENT` env var for Codeman-specific overrides, don't modify project files)
-6. **How should OpenCode session IDs map to Claudeman session IDs?**
+6. **How should OpenCode session IDs map to Codeman session IDs?**
- OpenCode manages its own sessions (SQLite DB)
- - We could pass `--session ` but OpenCode IDs have different format
+ - We could pass `--session ` but OpenCode IDs have different format
- Recommendation: Let OpenCode manage its own sessions, store the mapping in SessionState
---
@@ -1970,7 +1970,7 @@ Phase 3: Tmux spawn (2-3 hours) ← CRITICAL INTEGRATION POINT
↓
Phase 5: API + frontend (2-3 hours) ← FIRST USER-VISIBLE RESULT
↓
- ✅ MVP COMPLETE — OpenCode sessions managed from Claudeman web UI
+ ✅ MVP COMPLETE — OpenCode sessions managed from Codeman web UI
═══════════════════════════════════════════════════════
DEFERRED (requires real PTY data + verified APIs)
@@ -1991,7 +1991,7 @@ Phase 8: Server API — DEFERRED, optional advanced feature
| Milestone | Phase | What You Can Do | Scope |
|-----------|-------|-----------------|-------|
-| **M1: "It renders"** | 0-3 | OpenCode TUI visible in xterm.js via Claudeman | **MVP** |
+| **M1: "It renders"** | 0-3 | OpenCode TUI visible in xterm.js via Codeman | **MVP** |
| **M2: "It's usable"** | 5 | Create OpenCode sessions from web UI, type and interact, manage tabs | **MVP** |
| **M3: "It's observable"** | 4 | Idle/working state detection, ANSI content filter | Deferred |
| **M4: "It's smart"** | 6 | Plugin bridge provides definitive idle/permission/tool events | Deferred |
@@ -2012,7 +2012,7 @@ Phase 8: Server API — DEFERRED, optional advanced feature
## 21. Review Findings
-> **Reviewed**: 2026-02-26 by a 4-agent team. Each agent reviewed a different area of the plan against the actual Claudeman codebase.
+> **Reviewed**: 2026-02-26 by a 4-agent team. Each agent reviewed a different area of the plan against the actual Codeman codebase.
### Review Team
@@ -2182,7 +2182,7 @@ Environment Variables:
Full list of subscribable events in OpenCode's plugin system:
-| Category | Event | Description | Claudeman Relevance |
+| Category | Event | Description | Codeman Relevance |
|----------|-------|-------------|---------------------|
| **Command** | `command.executed` | Slash command run | Low |
| **Files** | `file.edited` | File modified | Medium (track changes) |
@@ -2194,7 +2194,7 @@ Full list of subscribable events in OpenCode's plugin system:
| | `message.updated` | Complete message | High (completion detection) |
| | `message.removed` | Message deleted | Low |
| | `message.part.removed` | Part deleted | Low |
-| **Permissions** | `permission.asked` | Tool approval needed | **Critical** (show in Claudeman) |
+| **Permissions** | `permission.asked` | Tool approval needed | **Critical** (show in Codeman) |
| | `permission.replied` | User responded | High (track approvals) |
| **Server** | `server.connected` | Server started | Medium |
| **Sessions** | `session.idle` | Agent finished working | **Critical** (idle detection!) |
@@ -2254,7 +2254,7 @@ Full list of subscribable events in OpenCode's plugin system:
- `"ask"` — Prompt user for approval
- `"deny"` — Block the action
-### Delivery Method for Claudeman
+### Delivery Method for Codeman
Use `OPENCODE_CONFIG_CONTENT` environment variable to inject permissions without modifying project files:
@@ -2265,7 +2265,7 @@ opencode --model anthropic/claude-sonnet-4-5
---
-## Appendix D: Current Claudeman Session Spawn Flow (Annotated)
+## Appendix D: Current Codeman Session Spawn Flow (Annotated)
### Exact Code Path (for reference during implementation)
@@ -2285,15 +2285,15 @@ opencode --model anthropic/claude-sonnet-4-5
→ If none: this._mux.createSession(id, workingDir, 'claude', ...)
4. TmuxManager.createSession() (tmux-manager.ts:225)
- → tmux new-session -ds "claudeman-" -c -x 120 -y 40
- → tmux set-option -t "claudeman-" remain-on-exit on
+ → tmux new-session -ds "codeman-" -c -x 120 -y 40
+ → tmux set-option -t "codeman-" remain-on-exit on
→ Build command: "export PATH=... && export LANG=... && claude --dangerously-skip-permissions --session-id "
- → tmux respawn-pane -k -t "claudeman-" ''
+ → tmux respawn-pane -k -t "codeman-" ''
→ Wait 100ms, configure tmux, get PID
→ Return MuxSession { muxName, pid, mode }
5. Back in startInteractive() (session.ts:~950)
- → pty.spawn('tmux', ['attach-session', '-t', 'claudeman-'], {
+ → pty.spawn('tmux', ['attach-session', '-t', 'codeman-'], {
name: 'xterm-256color',
cols: 120, rows: 40,
env: { LANG, LC_ALL, TERM }
diff --git a/docs/perf-audit-first-load.md b/docs/perf-audit-first-load.md
index 50357b7b..62b231d9 100644
--- a/docs/perf-audit-first-load.md
+++ b/docs/perf-audit-first-load.md
@@ -1,7 +1,7 @@
# Performance Audit: First Page Load
**Date**: 2026-02-18
-**Scope**: Browser first-load of Claudeman web UI (`/`)
+**Scope**: Browser first-load of Codeman web UI (`/`)
**Method**: Static analysis by 4 parallel audit agents (server, frontend, SSE/xterm, asset pipeline)
---
@@ -40,7 +40,7 @@ Browser hits /
│
│ [FIRST PAINT blocked until ALL CSS downloaded + parsed]
│
-├── JS executes: new ClaudemanApp().init()
+├── JS executes: new CodemanApp().init()
│ ├── initTerminal() ................... (SYNC: new Terminal() + terminal.open() → canvas creation)
│ ├── connectSSE() → /api/events ....... (SSE → fires 'init' with getLightState())
│ ├── loadState() → /api/status ........ (DUPLICATE #1: same data as SSE init!)
diff --git a/docs/performance-investigation-report.md b/docs/performance-investigation-report.md
index 74dc122c..17abb184 100644
--- a/docs/performance-investigation-report.md
+++ b/docs/performance-investigation-report.md
@@ -1,14 +1,14 @@
-# Claudeman Performance Investigation Report
+# Codeman Performance Investigation Report
**Date**: 2026-02-20
-**Scope**: Why Claudeman feels sluggish when multiple Claude tabs are very busy
+**Scope**: Why Codeman feels sluggish when multiple Claude tabs are very busy
**Method**: 4-agent parallel analysis of server, PTY pipeline, frontend, and background systems
---
## Executive Summary
-When multiple Claude sessions are actively producing heavy terminal output (e.g., building, writing files, running tests), Claudeman's UI becomes sluggish. This investigation identified **14 bottlenecks** across 4 layers of the stack. The root cause is **cumulative event loop blocking** — no single operation is catastrophically slow, but dozens of small synchronous operations run on every PTY data chunk, and with N busy sessions producing chunks every few milliseconds, the event loop gets saturated.
+When multiple Claude sessions are actively producing heavy terminal output (e.g., building, writing files, running tests), Codeman's UI becomes sluggish. This investigation identified **14 bottlenecks** across 4 layers of the stack. The root cause is **cumulative event loop blocking** — no single operation is catastrophically slow, but dozens of small synchronous operations run on every PTY data chunk, and with N busy sessions producing chunks every few milliseconds, the event loop gets saturated.
The most impactful findings are ranked by severity below.
diff --git a/docs/plan-improvement-roadmap.md b/docs/plan-improvement-roadmap.md
index 56d0bcca..9b933641 100644
--- a/docs/plan-improvement-roadmap.md
+++ b/docs/plan-improvement-roadmap.md
@@ -244,4 +244,4 @@ At iterations 5, 10, 20, 30, 50:
---
-*This document is part of the Claudeman project. See [CLAUDE.md](../CLAUDE.md) for main documentation.*
+*This document is part of the Codeman project. See [CLAUDE.md](../CLAUDE.md) for main documentation.*
diff --git a/docs/ralph-improvement-plan.md b/docs/ralph-improvement-plan.md
index dda795e5..9fd0bbb7 100644
--- a/docs/ralph-improvement-plan.md
+++ b/docs/ralph-improvement-plan.md
@@ -2,7 +2,7 @@
## Overview
-This plan details improvements to Claudeman's Ralph Loop system based on best practices from the Ralph Claude Code repository (https://github.com/frankbria/ralph-claude-code).
+This plan details improvements to Codeman's Ralph Loop system based on best practices from the Ralph Claude Code repository (https://github.com/frankbria/ralph-claude-code).
## Key Concepts to Implement
@@ -181,7 +181,7 @@ Three states: CLOSED → HALF_OPEN → OPEN
### 3.1 Template Library
- Bug Fix, Feature, Refactoring, Test Coverage, Documentation templates
- Template selector in wizard
-- Custom templates in `~/.claudeman/templates/`
+- Custom templates in `~/.codeman/templates/`
### 3.2 Tool Permissions
- Configure allowed Claude tools per loop
diff --git a/docs/ralph-wiggum-guide.md b/docs/ralph-wiggum-guide.md
index 1156d9c9..fd3cbcb7 100644
--- a/docs/ralph-wiggum-guide.md
+++ b/docs/ralph-wiggum-guide.md
@@ -19,7 +19,7 @@
8. [Prompt Templates](#prompt-templates)
9. [When to Use (and Not Use)](#when-to-use-and-not-use)
10. [Real-World Examples](#real-world-examples)
-11. [Claudeman Implementation](#claudeman-implementation)
+11. [Codeman Implementation](#codeman-implementation)
12. [Troubleshooting](#troubleshooting)
---
@@ -148,18 +148,18 @@ The completion phrase pattern is the core contract between Claude and the loop s
### False Positive Prevention
-The official implementation (and Claudeman) prevents false positives when completion phrases appear in:
+The official implementation (and Codeman) prevents false positives when completion phrases appear in:
- Initial prompts
- Documentation or examples
- Comments
-**Solution**: Claudeman uses **occurrence-based detection** to distinguish prompts from actual completions:
+**Solution**: Codeman uses **occurrence-based detection** to distinguish prompts from actual completions:
- **1st occurrence**: Store as expected phrase (likely in the prompt)
- **2nd occurrence**: Emit `completionDetected` (actual completion)
- **If loop already active**: Emit immediately (explicit loop start via `/ralph-loop:ralph-loop`)
```typescript
-// From claudeman/src/ralph-tracker.ts
+// From codeman/src/ralph-tracker.ts
private handleCompletionPhrase(phrase: string): void {
const count = (this._completionPhraseCount.get(phrase) || 0) + 1;
this._completionPhraseCount.set(phrase, count);
@@ -631,9 +631,9 @@ Ask yourself:
---
-## Claudeman Implementation
+## Codeman Implementation
-Claudeman implements Ralph Wiggum tracking via the `RalphTracker` class in `src/ralph-tracker.ts`.
+Codeman implements Ralph Wiggum tracking via the `RalphTracker` class in `src/ralph-tracker.ts`.
### Auto-Detection Patterns
@@ -833,7 +833,7 @@ POST /api/sessions/:id/auto-clear
- [Claude Fast - Autonomous Agent Loops](https://claudefa.st/blog/guide/mechanics/autonomous-agent-loops)
- [DeepWiki - Ralph Loop](https://deepwiki.com/anthropics/claude-plugins-official/5.2.2-ralph-loop)
-### Related Claudeman Files
+### Related Codeman Files
- `src/ralph-tracker.ts` - Core detection engine
- `src/ralph-loop.ts` - Task orchestration
- `src/respawn-controller.ts` - Session cycling
@@ -843,4 +843,4 @@ POST /api/sessions/:id/auto-clear
---
-*This documentation is maintained as part of the Claudeman project. For updates, see the main [CLAUDE.md](../CLAUDE.md).*
+*This documentation is maintained as part of the Codeman project. For updates, see the main [CLAUDE.md](../CLAUDE.md).*
diff --git a/docs/reports/notification-audit-summary.md b/docs/reports/notification-audit-summary.md
index b74b4d40..75470808 100644
--- a/docs/reports/notification-audit-summary.md
+++ b/docs/reports/notification-audit-summary.md
@@ -4,7 +4,7 @@ Date: 2026-02-17
## Scope
-Full audit of the Claudeman notification system covering:
+Full audit of the Codeman notification system covering:
- Backend event pipeline (server.ts, hooks-config.ts, team-watcher.ts, subagent-watcher.ts)
- Frontend notification manager (app.js NotificationManager class, 4-layer architecture)
- Settings UI and persistence (localStorage + server backup)
diff --git a/docs/reports/notification-backend.md b/docs/reports/notification-backend.md
index 203c6f2a..42e108aa 100644
--- a/docs/reports/notification-backend.md
+++ b/docs/reports/notification-backend.md
@@ -1,10 +1,10 @@
-# Claudeman Notification System - Backend Research Report
+# Codeman Notification System - Backend Research Report
Date: 2026-02-17
## Executive Summary
-The Claudeman notification system is a **multi-layer, event-driven pipeline** that flows from backend event emitters, through SSE broadcasts, to a frontend `NotificationManager` class. The backend itself has no concept of "notifications" -- it broadcasts structured SSE events, and the frontend decides which events warrant user notification (browser notifications, audio alerts, tab title flashing, in-app notification drawer, tab alert badges).
+The Codeman notification system is a **multi-layer, event-driven pipeline** that flows from backend event emitters, through SSE broadcasts, to a frontend `NotificationManager` class. The backend itself has no concept of "notifications" -- it broadcasts structured SSE events, and the frontend decides which events warrant user notification (browser notifications, audio alerts, tab title flashing, in-app notification drawer, tab alert badges).
The system handles ~25 distinct notification-triggering SSE events across 5 categories: hook events, session lifecycle, respawn state machine, Ralph Loop, and UI actions.
@@ -96,14 +96,14 @@ Terminal and output data use separate batching pipelines that bypass `broadcast(
### 2.1 Hook Configuration Generator (Lines 24-67)
-The `generateHooksConfig()` function creates `.claude/settings.local.json` entries that make Claude Code POST to Claudeman when hooks fire:
+The `generateHooksConfig()` function creates `.claude/settings.local.json` entries that make Claude Code POST to Codeman when hooks fire:
```typescript
const curlCmd = (event: HookEventType) =>
`HOOK_DATA=$(cat 2>/dev/null || echo '{}'); ` +
- `curl -s -X POST "$CLAUDEMAN_API_URL/api/hook-event" ` +
+ `curl -s -X POST "$CODEMAN_API_URL/api/hook-event" ` +
`-H 'Content-Type: application/json' ` +
- `-d "{\\"event\\":\\"${event}\\",\\"sessionId\\":\\"$CLAUDEMAN_SESSION_ID\\",\\"data\\":$HOOK_DATA}" ` +
+ `-d "{\\"event\\":\\"${event}\\",\\"sessionId\\":\\"$CODEMAN_SESSION_ID\\",\\"data\\":$HOOK_DATA}" ` +
`2>/dev/null || true`;
```
@@ -143,8 +143,8 @@ The `sanitizeHookData()` function limits what gets broadcast:
### 2.4 Environment Variables (Lines 70-101)
Two env vars are set per case directory via `updateCaseEnvVars()`:
-- `CLAUDEMAN_API_URL` -- server URL (e.g., `http://localhost:3000`)
-- `CLAUDEMAN_SESSION_ID` -- session identifier
+- `CODEMAN_API_URL` -- server URL (e.g., `http://localhost:3000`)
+- `CODEMAN_SESSION_ID` -- session identifier
These are resolved at runtime by the shell, so the hook config is static per case.
diff --git a/docs/reports/notification-blinking.md b/docs/reports/notification-blinking.md
index 4c9f5224..42902031 100644
--- a/docs/reports/notification-blinking.md
+++ b/docs/reports/notification-blinking.md
@@ -2,7 +2,7 @@
## Overview
-Claudeman implements a **4-layer notification system** managed by the `NotificationManager` class (app.js lines 860-1265). The layers are:
+Codeman implements a **4-layer notification system** managed by the `NotificationManager` class (app.js lines 860-1265). The layers are:
1. **In-app notification drawer** (Layer 1) - badge + list UI
2. **Document title flashing** (Layer 2) - tab title blinks when hidden
@@ -32,19 +32,19 @@ updateTabTitle() {
this.titleFlashInterval = setInterval(() => {
this.titleFlashState = !this.titleFlashState;
document.title = this.titleFlashState
- ? `\u26A0\uFE0F (${this.unreadCount}) Claudeman`
+ ? `\u26A0\uFE0F (${this.unreadCount}) Codeman`
: this.originalTitle;
}, TITLE_FLASH_INTERVAL_MS);
// Set immediately
- document.title = `\u26A0\uFE0F (${this.unreadCount}) Claudeman`;
+ document.title = `\u26A0\uFE0F (${this.unreadCount}) Codeman`;
}
}
}
```
The title alternates between:
-- Warning emoji + unread count: `"(3) Claudeman"`
-- Original title: `"Claudeman"`
+- Warning emoji + unread count: `"(3) Codeman"`
+- Original title: `"Codeman"`
### What Triggers It
Title flashing starts when `notify()` is called **while the tab is not visible** (`!this.isTabVisible`). The check is at lines 1026-1028:
@@ -126,7 +126,7 @@ It shows a lightning bolt icon on a dark background. The favicon is **static** a
Browser notifications reference `/favicon.ico` as their icon (line 1130):
```js
-const notif = new Notification(`Claudeman: ${title}`, {
+const notif = new Notification(`Codeman: ${title}`, {
body,
tag,
icon: '/favicon.ico',
@@ -306,7 +306,7 @@ Key detail: Title flash always stops when tab becomes visible, but **unread coun
## 5. Focus/Blur Handling
### No window focus/blur listeners
-Claudeman does **not** use `window.addEventListener('focus')` or `window.addEventListener('blur')`. It relies solely on the Page Visibility API (`visibilitychange` + `pageshow`).
+Codeman does **not** use `window.addEventListener('focus')` or `window.addEventListener('blur')`. It relies solely on the Page Visibility API (`visibilitychange` + `pageshow`).
This is the correct modern approach. The `focus`/`blur` events are unreliable (fire for devtools, iframe changes, etc.) while `visibilitychange` accurately reflects whether the user can see the tab.
diff --git a/docs/reports/notification-frontend.md b/docs/reports/notification-frontend.md
index 469e5942..c14b05a1 100644
--- a/docs/reports/notification-frontend.md
+++ b/docs/reports/notification-frontend.md
@@ -1,11 +1,11 @@
-# Claudeman Frontend Notification System -- Detailed Report
+# Codeman Frontend Notification System -- Detailed Report
> Generated: 2026-02-17
> Source files analyzed:
-> - `/home/arkon/default/claudeman/src/web/public/app.js` (main frontend, ~15k lines)
-> - `/home/arkon/default/claudeman/src/web/public/index.html`
-> - `/home/arkon/default/claudeman/src/web/public/styles.css`
-> - `/home/arkon/default/claudeman/src/web/public/mobile.css`
+> - `/home/arkon/default/codeman/src/web/public/app.js` (main frontend, ~15k lines)
+> - `/home/arkon/default/codeman/src/web/public/index.html`
+> - `/home/arkon/default/codeman/src/web/public/styles.css`
+> - `/home/arkon/default/codeman/src/web/public/mobile.css`
---
@@ -87,8 +87,8 @@ const defaults = {
#### Storage Keys (lines 952-956)
Device-specific localStorage keys prevent mobile settings from overriding desktop settings:
-- Desktop: `claudeman-notification-prefs`
-- Mobile: `claudeman-notification-prefs-mobile`
+- Desktop: `codeman-notification-prefs`
+- Mobile: `codeman-notification-prefs-mobile`
#### Version Migrations (lines 928-940)
@@ -260,8 +260,8 @@ Mobile override: full-width with safe area padding (mobile.css lines 1049-1058).
When the tab is not visible and there are unread notifications:
1. `setInterval` at 1500ms toggles between:
- - Warning emoji + unread count: `"(3) Claudeman"`
- - Original title: `"Claudeman"`
+ - Warning emoji + unread count: `"(3) Codeman"`
+ - Original title: `"Codeman"`
2. Set immediately on first notification (no wait for first interval tick)
### Stopping
@@ -311,7 +311,7 @@ sendBrowserNotif() called
### Notification Object (lines 1127-1143)
```js
-new Notification(`Claudeman: ${title}`, {
+new Notification(`Codeman: ${title}`, {
body,
tag, // Groups same-tag notifications (replaces previous with same tag)
icon: '/favicon.ico',
@@ -341,10 +341,10 @@ In settings (index.html line 993), a `=768` = desktop
- Read in `loadPreferences()` (line 896), written in `savePreferences()` (line 958)
-#### Layer 2: Server-side (`~/.claudeman/settings.json`)
+#### Layer 2: Server-side (`~/.codeman/settings.json`)
- On save, notification prefs are bundled with app settings: `{ ...settings, notificationPreferences: notifPrefsToSave }` (line 9475)
- Sent via `PUT /api/settings` to the Fastify server
-- Server does a shallow merge: `const merged = { ...existing, ...settings }` then writes to `~/.claudeman/settings.json` (line 3098 of server.ts)
+- Server does a shallow merge: `const merged = { ...existing, ...settings }` then writes to `~/.codeman/settings.json` (line 3098 of server.ts)
- The `notificationPreferences` key sits at the top level of the settings JSON alongside app settings
#### Load priority
@@ -109,8 +109,8 @@ On startup, `loadAppSettingsFromServer()` (line 9787) fetches from server and:
### App settings (separate from notification prefs)
App settings use a different device-specific localStorage key:
-- Desktop: `claudeman-app-settings`
-- Mobile: `claudeman-app-settings-mobile`
+- Desktop: `codeman-app-settings`
+- Mobile: `codeman-app-settings-mobile`
- Determined by `getSettingsStorageKey()` at line 9562
@@ -213,8 +213,8 @@ const AUTO_CLOSE_NOTIFICATION_MS = 8000; // Auto-close browser notifications
### Separate storage keys - YES
Desktop and mobile use completely separate localStorage keys:
-- **Notification prefs**: `claudeman-notification-prefs` vs `claudeman-notification-prefs-mobile`
-- **App settings**: `claudeman-app-settings` vs `claudeman-app-settings-mobile`
+- **Notification prefs**: `codeman-notification-prefs` vs `codeman-notification-prefs-mobile`
+- **App settings**: `codeman-app-settings` vs `codeman-app-settings-mobile`
### Different defaults - YES
@@ -303,7 +303,7 @@ The settings UI shows the current permission state via a status badge:
### HTTPS requirement
-Browser notifications require HTTPS for remote access. The settings UI includes a hint: _"For remote access, HTTPS is required. Start with: `claudeman web --https`"_. On localhost, HTTP works fine.
+Browser notifications require HTTPS for remote access. The settings UI includes a hint: _"For remote access, HTTPS is required. Start with: `codeman web --https`"_. On localhost, HTTP works fine.
## 7. Audio Setting
@@ -354,7 +354,7 @@ Yes, given the prerequisites above are met. However, due to the category key mis
Notification preferences are **strictly global**. There is no per-session notification configuration.
-- The `NotificationManager` is a singleton on the `ClaudemanApp` instance (line 1404)
+- The `NotificationManager` is a singleton on the `CodemanApp` instance (line 1404)
- Preferences are loaded once from localStorage (line 878)
- All sessions share the same notification rules
diff --git a/docs/terminal-anti-flicker.md b/docs/terminal-anti-flicker.md
index 0d69781d..82f45b1b 100644
--- a/docs/terminal-anti-flicker.md
+++ b/docs/terminal-anti-flicker.md
@@ -1,6 +1,6 @@
# Terminal Anti-Flicker System
-Claude Code uses [Ink](https://github.com/vadimdemedes/ink) (React for terminals), which redraws the entire screen on every state change. Without special handling, users see constant flickering. Claudeman implements a 6-layer anti-flicker pipeline.
+Claude Code uses [Ink](https://github.com/vadimdemedes/ink) (React for terminals), which redraws the entire screen on every state change. Without special handling, users see constant flickering. Codeman implements a 6-layer anti-flicker pipeline.
## Pipeline Overview
diff --git a/docs/typescript-improvement-suggestions.md b/docs/typescript-improvement-suggestions.md
index fb9d7483..a53d05d5 100644
--- a/docs/typescript-improvement-suggestions.md
+++ b/docs/typescript-improvement-suggestions.md
@@ -1,4 +1,4 @@
-# Claudeman TypeScript Improvement Suggestions
+# Codeman TypeScript Improvement Suggestions
**Generated**: February 2026
**Based on**: Research into TypeScript best practices (2024-2025) and codebase analysis
@@ -229,33 +229,33 @@ Replace string-based errors with typed errors:
```typescript
// src/errors.ts
-export class ClaudemanError extends Error {
+export class CodemanError extends Error {
constructor(
message: string,
public code: string,
public context?: Record
) {
super(message);
- Object.setPrototypeOf(this, ClaudemanError.prototype);
- this.name = 'ClaudemanError';
+ Object.setPrototypeOf(this, CodemanError.prototype);
+ this.name = 'CodemanError';
}
}
-export class SessionError extends ClaudemanError {
+export class SessionError extends CodemanError {
constructor(message: string, code: string, public sessionId: string) {
super(message, code, { sessionId });
this.name = 'SessionError';
}
}
-export class ValidationError extends ClaudemanError {
+export class ValidationError extends CodemanError {
constructor(message: string, public field: string, public value: unknown) {
super(message, 'VALIDATION_ERROR', { field, value });
this.name = 'ValidationError';
}
}
-export class ScreenError extends ClaudemanError {
+export class ScreenError extends CodemanError {
constructor(message: string, public screenName: string, public operation: string) {
super(message, 'SCREEN_ERROR', { screenName, operation });
this.name = 'ScreenError';
@@ -324,7 +324,7 @@ Enforce ID formats at compile time:
```typescript
type CycleIdFormat = `${string}:cycle-${number}`;
-type ScreenSessionName = `claudeman-${string}`;
+type ScreenSessionName = `codeman-${string}`;
interface RespawnCycleMetrics {
cycleId: CycleIdFormat; // Enforces format at compile time
diff --git a/docs/voice-input-plan.md b/docs/voice-input-plan.md
index 16f4d7a0..b46b2b7f 100644
--- a/docs/voice-input-plan.md
+++ b/docs/voice-input-plan.md
@@ -56,7 +56,7 @@ The blue-tinted voice button in the accessory bar is distinctive but subtle. Whe
Confirmed by research: Web Speech API is the right choice.
- **Free, fast (150-300ms interim), trivial complexity**
-- Chrome + Safari = ~70% of users, ~95% of Claudeman's target audience (devs on Chrome)
+- Chrome + Safari = ~70% of users, ~95% of Codeman's target audience (devs on Chrome)
- Works on localhost without HTTPS
- Accuracy is adequate for English command dictation
- Deepgram streaming (Phase 2 optional) only if accuracy complaints arise
diff --git a/install.sh b/install.sh
index aac6dbb8..6a70f500 100755
--- a/install.sh
+++ b/install.sh
@@ -1,14 +1,14 @@
#!/usr/bin/env bash
-# Claudeman Universal Installer
-# https://github.com/Ark0N/claudeman
+# Codeman Universal Installer
+# https://github.com/Ark0N/Codeman
#
-# Usage: curl -fsSL https://raw.githubusercontent.com/Ark0N/claudeman/master/install.sh | bash
+# Usage: curl -fsSL https://raw.githubusercontent.com/Ark0N/Codeman/master/install.sh | bash
#
# Environment variables:
-# CLAUDEMAN_NONINTERACTIVE=1 - Skip all prompts (for CI/automation)
-# CLAUDEMAN_INSTALL_DIR - Custom install directory (default: ~/.claudeman/app)
-# CLAUDEMAN_SKIP_SYSTEMD=1 - Skip systemd service setup prompt
-# CLAUDEMAN_NODE_VERSION - Node.js major version to install (default: 22)
+# CODEMAN_NONINTERACTIVE=1 - Skip all prompts (for CI/automation)
+# CODEMAN_INSTALL_DIR - Custom install directory (default: ~/.codeman/app)
+# CODEMAN_SKIP_SYSTEMD=1 - Skip systemd service setup prompt
+# CODEMAN_NODE_VERSION - Node.js major version to install (default: 22)
set -euo pipefail
@@ -16,12 +16,12 @@ set -euo pipefail
# Configuration
# ============================================================================
-INSTALL_DIR="${CLAUDEMAN_INSTALL_DIR:-$HOME/.claudeman/app}"
-REPO_URL="https://github.com/Ark0N/claudeman.git"
+INSTALL_DIR="${CODEMAN_INSTALL_DIR:-$HOME/.codeman/app}"
+REPO_URL="https://github.com/Ark0N/Codeman.git"
MIN_NODE_VERSION=18
-TARGET_NODE_VERSION="${CLAUDEMAN_NODE_VERSION:-22}"
-NONINTERACTIVE="${CLAUDEMAN_NONINTERACTIVE:-0}"
-SKIP_SYSTEMD="${CLAUDEMAN_SKIP_SYSTEMD:-0}"
+TARGET_NODE_VERSION="${CODEMAN_NODE_VERSION:-22}"
+NONINTERACTIVE="${CODEMAN_NONINTERACTIVE:-0}"
+SKIP_SYSTEMD="${CODEMAN_SKIP_SYSTEMD:-0}"
# Claude CLI search paths (from src/session.ts)
CLAUDE_SEARCH_PATHS=(
@@ -611,15 +611,15 @@ add_to_path() {
if [[ "$shell_name" == "fish" ]]; then
echo "" >> "$profile"
- echo "# Added by Claudeman installer" >> "$profile"
+ echo "# Added by Codeman installer" >> "$profile"
echo "fish_add_path $bin_dir" >> "$profile"
else
echo "" >> "$profile"
- echo "# Added by Claudeman installer" >> "$profile"
+ echo "# Added by Codeman installer" >> "$profile"
echo "export PATH=\"$bin_dir:\$PATH\"" >> "$profile"
fi
- # Also export for the current process so claudeman works immediately
+ # Also export for the current process so codeman works immediately
export PATH="$bin_dir:$PATH"
success "Added to $profile"
@@ -636,7 +636,7 @@ setup_sc_alias() {
fi
echo "" >> "$profile"
- echo "# Claudeman tmux session shortcut" >> "$profile"
+ echo "# Codeman tmux session shortcut" >> "$profile"
echo "alias sc='tmux-chooser'" >> "$profile"
info "Added 'sc' alias for tmux-chooser"
@@ -648,7 +648,7 @@ setup_sc_alias() {
setup_systemd_service() {
local service_dir="$HOME/.config/systemd/user"
- local service_file="$service_dir/claudeman-web.service"
+ local service_file="$service_dir/codeman-web.service"
info "Setting up systemd user service..."
@@ -661,7 +661,7 @@ setup_systemd_service() {
# Create service file
cat > "$service_file" << EOF
[Unit]
-Description=Claudeman Web Server
+Description=Codeman Web Server
After=network.target
[Service]
@@ -681,7 +681,7 @@ EOF
systemctl --user daemon-reload
# Enable service
- systemctl --user enable claudeman-web.service 2>/dev/null || true
+ systemctl --user enable codeman-web.service 2>/dev/null || true
# Enable lingering (allows service to run after logout)
if command -v loginctl &>/dev/null; then
@@ -689,7 +689,7 @@ EOF
fi
success "Systemd service installed at $service_file"
- info "Start with: systemctl --user start claudeman-web"
+ info "Start with: systemctl --user start codeman-web"
}
# ============================================================================
@@ -760,7 +760,7 @@ main() {
if prompt_yes_no "Git is not installed. Install it now?"; then
install_dependency "git" "$os" "$distro"
else
- die "Git is required to install Claudeman."
+ die "Git is required to install Codeman."
fi
else
success "Git is installed"
@@ -781,7 +781,7 @@ main() {
# Rehash to pick up new node
hash -r 2>/dev/null || true
else
- die "Node.js $MIN_NODE_VERSION+ is required to run Claudeman."
+ die "Node.js $MIN_NODE_VERSION+ is required to run Codeman."
fi
else
local node_ver
@@ -832,7 +832,7 @@ main() {
# Clone/Update Repository
# ========================================================================
- info "Installing Claudeman to $INSTALL_DIR..."
+ info "Installing Codeman to $INSTALL_DIR..."
if [[ -d "$INSTALL_DIR/.git" ]]; then
info "Existing installation found, updating..."
@@ -882,8 +882,8 @@ main() {
local symlink_dir="$HOME/.local/bin"
mkdir -p "$symlink_dir" 2>/dev/null || true
if [[ -d "$symlink_dir" ]]; then
- ln -sf "$INSTALL_DIR/dist/index.js" "$symlink_dir/claudeman"
- info "Created symlink: $symlink_dir/claudeman"
+ ln -sf "$INSTALL_DIR/dist/index.js" "$symlink_dir/codeman"
+ info "Created symlink: $symlink_dir/codeman"
# Install tmux-chooser as 'tmux-chooser' command
if [[ -f "$INSTALL_DIR/scripts/tmux-chooser.sh" ]]; then
@@ -916,16 +916,16 @@ main() {
echo ""
echo -e "${GREEN}${BOLD}============================================================${NC}"
- echo -e "${GREEN}${BOLD} Claudeman installed successfully!${NC}"
+ echo -e "${GREEN}${BOLD} Codeman installed successfully!${NC}"
echo -e "${GREEN}${BOLD}============================================================${NC}"
echo ""
echo -e " ${BOLD}Quick Start:${NC}"
echo ""
echo -e " ${CYAN}# Start the web server${NC}"
- echo -e " claudeman web"
+ echo -e " codeman web"
echo ""
echo -e " ${CYAN}# Start with HTTPS (only needed for remote access)${NC}"
- echo -e " claudeman web --https"
+ echo -e " codeman web --https"
echo ""
echo -e " ${CYAN}# Open in browser${NC}"
echo -e " http://localhost:3000"
@@ -937,21 +937,21 @@ main() {
echo -e " ${CYAN}sc -h${NC} # Help"
echo ""
- if [[ "$os" == "linux" ]] && [[ -f "$HOME/.config/systemd/user/claudeman-web.service" ]]; then
+ if [[ "$os" == "linux" ]] && [[ -f "$HOME/.config/systemd/user/codeman-web.service" ]]; then
echo -e " ${BOLD}Systemd Service:${NC}"
echo ""
- echo -e " ${CYAN}systemctl --user start claudeman-web${NC} # Start"
- echo -e " ${CYAN}systemctl --user status claudeman-web${NC} # Check status"
- echo -e " ${CYAN}journalctl --user -u claudeman-web -f${NC} # View logs"
+ echo -e " ${CYAN}systemctl --user start codeman-web${NC} # Start"
+ echo -e " ${CYAN}systemctl --user status codeman-web${NC} # Check status"
+ echo -e " ${CYAN}journalctl --user -u codeman-web -f${NC} # View logs"
echo ""
fi
echo -e " ${BOLD}Documentation:${NC}"
- echo -e " https://github.com/Ark0N/claudeman"
+ echo -e " https://github.com/Ark0N/Codeman"
echo ""
if ! check_claude; then
- echo -e " ${YELLOW}${BOLD}Reminder:${NC} Install Claude CLI to start using Claudeman:"
+ echo -e " ${YELLOW}${BOLD}Reminder:${NC} Install Claude CLI to start using Codeman:"
echo -e " ${CYAN}curl -fsSL https://claude.ai/install.sh | bash${NC}"
echo ""
fi
@@ -959,20 +959,20 @@ main() {
# Check if PATH needs reload in user's shell
local profile
profile=$(detect_shell_profile)
- if ! command -v claudeman &>/dev/null 2>&1; then
- echo -e " ${YELLOW}Run this to start using claudeman now:${NC}"
+ if ! command -v codeman &>/dev/null 2>&1; then
+ echo -e " ${YELLOW}Run this to start using codeman now:${NC}"
echo ""
- echo -e " ${CYAN}source $profile && claudeman web${NC}"
+ echo -e " ${CYAN}source $profile && codeman web${NC}"
echo ""
fi
}
update() {
if [[ ! -d "$INSTALL_DIR/.git" ]]; then
- die "Claudeman is not installed at $INSTALL_DIR. Run the installer first."
+ die "Codeman is not installed at $INSTALL_DIR. Run the installer first."
fi
- info "Updating Claudeman..."
+ info "Updating Codeman..."
cd "$INSTALL_DIR"
git fetch --quiet origin
git reset --hard origin/master --quiet
@@ -980,7 +980,7 @@ update() {
npm run build --quiet 2>/dev/null || npm run build
success "Updated to $(node -e "console.log(require('./package.json').version)")"
echo ""
- echo -e " ${DIM}Restart claudeman web to use the new version.${NC}"
+ echo -e " ${DIM}Restart codeman web to use the new version.${NC}"
echo ""
}
diff --git a/mobile-test/README.md b/mobile-test/README.md
index e971caa8..ce98c344 100644
--- a/mobile-test/README.md
+++ b/mobile-test/README.md
@@ -1,12 +1,12 @@
-# Claudeman Mobile Test Suite
+# Codeman Mobile Test Suite
-Comprehensive mobile UI testing for Claudeman's web interface using Playwright with dual-engine support (Chromium + WebKit).
+Comprehensive mobile UI testing for Codeman's web interface using Playwright with dual-engine support (Chromium + WebKit).
**325 tests across 135 devices — all passing.**
## Purpose
-Validates Claudeman's mobile UI across 135 devices, covering:
+Validates Codeman's mobile UI across 135 devices, covering:
- **Keyboard simulation** — 3-layer approach to emulate virtual keyboards in headless browsers
- **Touch/swipe interactions** — CDP trusted events (Chromium) + synthetic fallback (WebKit)
diff --git a/mobile-test/helpers/constants.ts b/mobile-test/helpers/constants.ts
index 9832b412..3ce0b112 100644
--- a/mobile-test/helpers/constants.ts
+++ b/mobile-test/helpers/constants.ts
@@ -126,7 +126,7 @@ export const BODY_CLASSES = {
// Settings localStorage keys
export const STORAGE_KEYS = {
- SETTINGS_MOBILE: 'claudeman-app-settings-mobile',
- SETTINGS_DESKTOP: 'claudeman-app-settings',
- NOTIFICATION_PREFS_MOBILE: 'claudeman-notification-prefs-mobile',
+ SETTINGS_MOBILE: 'codeman-app-settings-mobile',
+ SETTINGS_DESKTOP: 'codeman-app-settings',
+ NOTIFICATION_PREFS_MOBILE: 'codeman-notification-prefs-mobile',
} as const;
diff --git a/mobile-test/settings.test.ts b/mobile-test/settings.test.ts
index 32ea5425..c18ecf87 100644
--- a/mobile-test/settings.test.ts
+++ b/mobile-test/settings.test.ts
@@ -43,7 +43,7 @@ describe('Settings Modal', () => {
await context.close();
});
- it('uses claudeman-app-settings-mobile localStorage key', async () => {
+ it('uses codeman-app-settings-mobile localStorage key', async () => {
const key = await page.evaluate(() => {
return (window as any).app?.getSettingsStorageKey?.() ?? null;
});
@@ -53,10 +53,10 @@ describe('Settings Modal', () => {
} else {
// Verify by checking what key is used when saving settings
await page.evaluate(() => {
- localStorage.setItem('claudeman-app-settings-mobile', JSON.stringify({ testFlag: true }));
+ localStorage.setItem('codeman-app-settings-mobile', JSON.stringify({ testFlag: true }));
});
const stored = await page.evaluate(() => {
- return localStorage.getItem('claudeman-app-settings-mobile');
+ return localStorage.getItem('codeman-app-settings-mobile');
});
expect(stored).toContain('testFlag');
}
diff --git a/package-lock.json b/package-lock.json
index 3c958e6c..d42811e6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,11 +1,11 @@
{
- "name": "claudeman",
+ "name": "codeman",
"version": "0.1619",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
- "name": "claudeman",
+ "name": "codeman",
"version": "0.1619",
"hasInstallScript": true,
"license": "MIT",
@@ -25,7 +25,7 @@
"zod": "^4.3.6"
},
"bin": {
- "claudeman": "dist/index.js"
+ "codeman": "dist/index.js"
},
"devDependencies": {
"@types/node": "^20.19.33",
diff --git a/package.json b/package.json
index 1ba69dcc..0ed91982 100644
--- a/package.json
+++ b/package.json
@@ -1,12 +1,12 @@
{
- "name": "claudeman",
+ "name": "codeman",
"version": "0.1650",
"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",
"types": "dist/index.d.ts",
"bin": {
- "claudeman": "./dist/index.js"
+ "codeman": "./dist/index.js"
},
"scripts": {
"postinstall": "node scripts/postinstall.js",
@@ -71,12 +71,12 @@
},
"repository": {
"type": "git",
- "url": "git+https://github.com/Ark0N/claudeman.git"
+ "url": "git+https://github.com/Ark0N/Codeman.git"
},
"bugs": {
- "url": "https://github.com/Ark0N/claudeman/issues"
+ "url": "https://github.com/Ark0N/Codeman/issues"
},
- "homepage": "https://github.com/Ark0N/claudeman#readme",
+ "homepage": "https://github.com/Ark0N/Codeman#readme",
"files": [
"dist",
"scripts/postinstall.js",
diff --git a/packages/xterm-zerolag-input/LICENSE b/packages/xterm-zerolag-input/LICENSE
index f3d77e8e..4ea287bd 100644
--- a/packages/xterm-zerolag-input/LICENSE
+++ b/packages/xterm-zerolag-input/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2026 Claudeman Contributors
+Copyright (c) 2026 Codeman Contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/packages/xterm-zerolag-input/README.md b/packages/xterm-zerolag-input/README.md
index f6a069f0..b4207e1f 100644
--- a/packages/xterm-zerolag-input/README.md
+++ b/packages/xterm-zerolag-input/README.md
@@ -39,7 +39,7 @@ Server echoes 'h' ←───────────────────
## Origin
-This library was extracted from [Claudeman](https://github.com/Ark0N/Claudeman), a Claude Code session manager that runs 20+ autonomous AI agents over 24-hour sessions. The local echo system was built to make mobile and remote access feel instant, then battle-tested across thousands of hours of real usage. After 3 deep code audits, it was extracted into this standalone library with 78 tests covering every state transition.
+This library was extracted from [Codeman](https://github.com/Ark0N/Codeman), a Claude Code session manager that runs 20+ autonomous AI agents over 24-hour sessions. The local echo system was built to make mobile and remote access feel instant, then battle-tested across thousands of hours of real usage. After 3 deep code audits, it was extracted into this standalone library with 78 tests covering every state transition.
## Install
@@ -375,4 +375,4 @@ Overlay hides when scrolled up (`viewportY !== baseY`). Debounced re-render when
## License
-MIT — [Claudeman](https://github.com/Ark0N/Claudeman) Contributors
+MIT — [Codeman](https://github.com/Ark0N/Codeman) Contributors
diff --git a/packages/xterm-zerolag-input/package.json b/packages/xterm-zerolag-input/package.json
index 65284329..2846ed7a 100644
--- a/packages/xterm-zerolag-input/package.json
+++ b/packages/xterm-zerolag-input/package.json
@@ -32,10 +32,10 @@
"addon"
],
"license": "MIT",
- "homepage": "https://github.com/Ark0N/Claudeman/tree/master/packages/xterm-zerolag-input#readme",
+ "homepage": "https://github.com/Ark0N/Codeman/tree/master/packages/xterm-zerolag-input#readme",
"repository": {
"type": "git",
- "url": "git+https://github.com/Ark0N/Claudeman.git",
+ "url": "git+https://github.com/Ark0N/Codeman.git",
"directory": "packages/xterm-zerolag-input"
},
"devDependencies": {
diff --git a/scripts/browser-comparison.mjs b/scripts/browser-comparison.mjs
index 934bdf1d..f780f8e6 100644
--- a/scripts/browser-comparison.mjs
+++ b/scripts/browser-comparison.mjs
@@ -2,7 +2,7 @@
/**
* Browser Framework Comparison Script
*
- * Compares Playwright, Puppeteer, and Agent-Browser for testing Claudeman web UI.
+ * Compares Playwright, Puppeteer, and Agent-Browser for testing Codeman web UI.
* Run: node scripts/browser-comparison.mjs
*/
@@ -88,7 +88,7 @@ async function main() {
const page = await playwrightBrowser.newPage();
await page.goto(`http://localhost:${PORTS.playwright}`);
const title = await page.title();
- if (title !== 'Claudeman') throw new Error(`Expected Claudeman, got ${title}`);
+ if (title !== 'Codeman') throw new Error(`Expected Codeman, got ${title}`);
await page.close();
});
@@ -98,7 +98,7 @@ async function main() {
await page.goto(`http://localhost:${PORTS.playwright}`);
const logo = await page.locator('.header-brand .logo').textContent();
const version = await page.locator('#versionDisplay').textContent();
- if (logo !== 'Claudeman') throw new Error('Logo mismatch');
+ if (logo !== 'Codeman') throw new Error('Logo mismatch');
if (!version.match(/v\d+/)) throw new Error('Version mismatch');
await page.close();
});
@@ -149,7 +149,7 @@ async function main() {
const page = await puppeteerBrowser.newPage();
await page.goto(`http://localhost:${PORTS.puppeteer}`);
const title = await page.title();
- if (title !== 'Claudeman') throw new Error(`Expected Claudeman, got ${title}`);
+ if (title !== 'Codeman') throw new Error(`Expected Codeman, got ${title}`);
await page.close();
});
@@ -159,7 +159,7 @@ async function main() {
await page.goto(`http://localhost:${PORTS.puppeteer}`);
const logo = await page.$eval('.header-brand .logo', el => el.textContent);
const version = await page.$eval('#versionDisplay', el => el.textContent);
- if (logo !== 'Claudeman') throw new Error('Logo mismatch');
+ if (logo !== 'Codeman') throw new Error('Logo mismatch');
if (!version.match(/v\d+/)) throw new Error('Version mismatch');
await page.close();
});
@@ -202,7 +202,7 @@ async function main() {
agentBrowser(`open http://localhost:${PORTS.agentBrowser}`);
await new Promise(r => setTimeout(r, 2000));
const title = agentBrowserJson('get title');
- agentBrowserAvailable = title.title === 'Claudeman';
+ agentBrowserAvailable = title.title === 'Codeman';
console.log(' Browser launched');
// Test 1: Page load
@@ -210,14 +210,14 @@ async function main() {
agentBrowser(`open http://localhost:${PORTS.agentBrowser}`);
await new Promise(r => setTimeout(r, 1000));
const title = agentBrowserJson('get title');
- if (title.title !== 'Claudeman') throw new Error(`Expected Claudeman, got ${title.title}`);
+ if (title.title !== 'Codeman') throw new Error(`Expected Codeman, got ${title.title}`);
});
// Test 2: Element selection
await runBenchmark('element-selection', 'agent-browser', async () => {
const logo = agentBrowserJson('get text ".header-brand .logo"');
const version = agentBrowserJson('get text "#versionDisplay"');
- if (logo.text !== 'Claudeman') throw new Error('Logo mismatch');
+ if (logo.text !== 'Codeman') throw new Error('Logo mismatch');
if (!version.text.match(/v\d+/)) throw new Error('Version mismatch');
});
diff --git a/scripts/capture-readme-screenshots.mjs b/scripts/capture-readme-screenshots.mjs
index c758948b..f4b34f49 100644
--- a/scripts/capture-readme-screenshots.mjs
+++ b/scripts/capture-readme-screenshots.mjs
@@ -98,7 +98,7 @@ function makeSession(id, name, mode, status, extra = {}) {
id,
pid: status === 'idle' ? null : 12345 + Math.floor(Math.random() * 10000),
status,
- workingDir: '/home/arkon/claudeman-cases/testcase',
+ workingDir: '/home/arkon/codeman-cases/testcase',
currentTaskId: null,
createdAt: Date.now() - 3600000,
lastActivityAt: Date.now() - (status === 'idle' ? 60000 : 5000),
@@ -336,7 +336,7 @@ const TERMINAL_INIT = [
'',
` ${RED}████${RST} ${BOLD}Claude Code${RST} v2.1.47`,
` ${RED}████${RST} ${GRY}Opus 4.6${RST} ${DIM}·${RST} ${GRY}Claude Max${RST}`,
- ` ${RED}██${RST} ${RED}██${RST} ${GRY}~/claudeman-cases/testcase${RST}`,
+ ` ${RED}██${RST} ${RED}██${RST} ${GRY}~/codeman-cases/testcase${RST}`,
'',
'',
`${GRY}❯ Try "how do I log an error?"${RST}`,
@@ -353,7 +353,7 @@ const TERMINAL_WORKING = [
`${GRN}●${RST} The codebase is essentially a template/scaffold with just a CLAUDE.md file and empty ${BOLD}src/${RST} directory. Since there's already a comprehensive`,
`CLAUDE.md file present, let me read it fully and suggest improvements based on the /init command requirements:`,
'',
- `${GRN}●${RST} ${BOLD}Read${RST}(/home/arkon/claudeman-cases/testcase/CLAUDE.md)`,
+ `${GRN}●${RST} ${BOLD}Read${RST}(/home/arkon/codeman-cases/testcase/CLAUDE.md)`,
` ${GRY}░${RST} Read ${BOLD}407${RST} lines`,
'',
`${GRN}●${RST} Now I understand the situation. This is a ${BOLD}template CLAUDE.md file${RST} designed for the Claude Code framework with the "Ralph Loop" autonomous work`,
@@ -420,15 +420,15 @@ const TERMINAL_RALPH = [
const SUBAGENT_ACTIVITY = {
'agent-001': [
{ type: 'tool', tool: 'Glob', input: { pattern: 'src/**/*.ts' }, timestamp: new Date().toISOString(), agentId: 'agent-001' },
- { type: 'tool', tool: 'Read', input: { file_path: '/home/arkon/claudeman/src/web/server.ts' }, timestamp: new Date().toISOString(), agentId: 'agent-001' },
+ { type: 'tool', tool: 'Read', input: { file_path: '/home/arkon/codeman/src/web/server.ts' }, timestamp: new Date().toISOString(), agentId: 'agent-001' },
{ type: 'tool', tool: 'Grep', input: { pattern: 'app\\.get|app\\.post|app\\.put|app\\.delete', path: 'src/' }, timestamp: new Date().toISOString(), agentId: 'agent-001' },
- { type: 'tool', tool: 'Read', input: { file_path: '/home/arkon/claudeman/src/web/schemas.ts' }, timestamp: new Date().toISOString(), agentId: 'agent-001' },
+ { type: 'tool', tool: 'Read', input: { file_path: '/home/arkon/codeman/src/web/schemas.ts' }, timestamp: new Date().toISOString(), agentId: 'agent-001' },
{ type: 'message', role: 'assistant', text: 'Found 47 API endpoints across server.ts. Documenting REST paths...', timestamp: new Date().toISOString(), agentId: 'agent-001' },
],
'agent-002': [
{ type: 'tool', tool: 'Glob', input: { pattern: 'test/**/*.test.ts' }, timestamp: new Date().toISOString(), agentId: 'agent-002' },
- { type: 'tool', tool: 'Read', input: { file_path: '/home/arkon/claudeman/test/respawn-test-utils.ts' }, timestamp: new Date().toISOString(), agentId: 'agent-002' },
- { type: 'tool', tool: 'Read', input: { file_path: '/home/arkon/claudeman/vitest.config.ts' }, timestamp: new Date().toISOString(), agentId: 'agent-002' },
+ { type: 'tool', tool: 'Read', input: { file_path: '/home/arkon/codeman/test/respawn-test-utils.ts' }, timestamp: new Date().toISOString(), agentId: 'agent-002' },
+ { type: 'tool', tool: 'Read', input: { file_path: '/home/arkon/codeman/vitest.config.ts' }, timestamp: new Date().toISOString(), agentId: 'agent-002' },
{ type: 'message', role: 'assistant', text: 'Analyzing test patterns: MockSession, unique ports, fileParallelism: false...', timestamp: new Date().toISOString(), agentId: 'agent-002' },
],
};
@@ -436,9 +436,9 @@ const SUBAGENT_ACTIVITY = {
// Subagent spawn terminal content
const TERMINAL_SUBAGENT = [
'',
- `${GRN}●${RST} Working on ${CYN}/home/arkon/claudeman-cases/testcase${RST} - I'll use the ${BOLD}Task tool${RST} to spawn parallel agents.`,
+ `${GRN}●${RST} Working on ${CYN}/home/arkon/codeman-cases/testcase${RST} - I'll use the ${BOLD}Task tool${RST} to spawn parallel agents.`,
'',
- `${GRN}●${RST} ${BOLD}Read${RST}(/home/arkon/claudeman-cases/testcase/CLAUDE.md)`,
+ `${GRN}●${RST} ${BOLD}Read${RST}(/home/arkon/codeman-cases/testcase/CLAUDE.md)`,
` ${GRY}░${RST} Read ${BOLD}127${RST} lines ${GRY}│${RST} ${CYN}1.2KB${RST}`,
'',
`${GRN}●${RST} ${BOLD}Bash${RST}(find . -name "*.ts" -not -path "*/node_modules/*" | head -20)`,
@@ -864,7 +864,7 @@ async function captureMultiSessionMonitor(page) {
async function main() {
console.log('='.repeat(60));
- console.log('Claudeman README Screenshot Capture');
+ console.log('Codeman README Screenshot Capture');
console.log('='.repeat(60));
console.log(`Port: ${PORT} | Viewport: ${VIEWPORT.width}x${VIEWPORT.height}`);
console.log('');
diff --git a/scripts/capture-subagent-gif.mjs b/scripts/capture-subagent-gif.mjs
index 613d2e3e..0efac224 100644
--- a/scripts/capture-subagent-gif.mjs
+++ b/scripts/capture-subagent-gif.mjs
@@ -1,6 +1,6 @@
#!/usr/bin/env node
/**
- * Capture a GIF of subagent spawning on the LIVE Claudeman server.
+ * Capture a GIF of subagent spawning on the LIVE Codeman server.
*
* Connects to the running server on port 3000, creates a test session,
* sends a prompt that spawns 3 parallel agents, and captures a tight
@@ -69,7 +69,7 @@ async function capture() {
try {
// Create case and seed with real source files
console.log(`Creating case: ${CASE_NAME}`);
- const caseDir = join(process.env.HOME, 'claudeman-cases', CASE_NAME);
+ const caseDir = join(process.env.HOME, 'codeman-cases', CASE_NAME);
const caseSrc = join(caseDir, 'src');
const caseTest = join(caseDir, 'test');
mkdirSync(caseSrc, { recursive: true });
@@ -123,7 +123,7 @@ async function capture() {
// Configure settings: enable subagents, disable Files pane
await setupPage.evaluate(() => {
- const existing = JSON.parse(localStorage.getItem('claudeman-app-settings') || '{}');
+ const existing = JSON.parse(localStorage.getItem('codeman-app-settings') || '{}');
Object.assign(existing, {
showSubagents: true,
subagentTrackingEnabled: true,
@@ -132,7 +132,7 @@ async function capture() {
showProjectInsights: false,
showFileBrowser: false,
});
- localStorage.setItem('claudeman-app-settings', JSON.stringify(existing));
+ localStorage.setItem('codeman-app-settings', JSON.stringify(existing));
});
await setupPage.reload({ waitUntil: 'domcontentloaded' });
await sleep(1000);
@@ -227,7 +227,7 @@ async function capture() {
// Re-apply settings (new context = fresh localStorage)
await recordPage.evaluate(() => {
- const existing = JSON.parse(localStorage.getItem('claudeman-app-settings') || '{}');
+ const existing = JSON.parse(localStorage.getItem('codeman-app-settings') || '{}');
Object.assign(existing, {
showSubagents: true,
subagentTrackingEnabled: true,
@@ -236,7 +236,7 @@ async function capture() {
showProjectInsights: false,
showFileBrowser: false,
});
- localStorage.setItem('claudeman-app-settings', JSON.stringify(existing));
+ localStorage.setItem('codeman-app-settings', JSON.stringify(existing));
});
await recordPage.reload({ waitUntil: 'domcontentloaded' });
await sleep(1000);
diff --git a/scripts/capture-subagent-screenshots.mjs b/scripts/capture-subagent-screenshots.mjs
index 6a572d5e..d90411c1 100755
--- a/scripts/capture-subagent-screenshots.mjs
+++ b/scripts/capture-subagent-screenshots.mjs
@@ -1,6 +1,6 @@
#!/usr/bin/env node
/**
- * Capture screenshots and GIFs of Claudeman's subagent visualization
+ * Capture screenshots and GIFs of Codeman's subagent visualization
*
* Uses real Claude sessions that spawn actual subagents via the Task tool.
*
@@ -23,7 +23,7 @@ import { mkdirSync, existsSync, unlinkSync, rmSync } from 'fs';
const __dirname = dirname(fileURLToPath(import.meta.url));
const PROJECT_ROOT = join(__dirname, '..');
const OUTPUT_DIR = join(PROJECT_ROOT, 'docs', 'images');
-const CASES_DIR = join(process.env.HOME, 'claudeman-cases');
+const CASES_DIR = join(process.env.HOME, 'codeman-cases');
// Configuration
const PORT = 3198; // Unique port for capture script (avoid 3199 conflicts)
@@ -58,10 +58,10 @@ let serverProcess = null;
let browser = null;
/**
- * Start the Claudeman web server
+ * Start the Codeman web server
*/
async function startServer() {
- console.log(`Starting Claudeman server on port ${PORT}...`);
+ console.log(`Starting Codeman server on port ${PORT}...`);
serverProcess = spawn('npx', ['tsx', 'src/index.ts', 'web', '--port', String(PORT)], {
cwd: PROJECT_ROOT,
@@ -222,7 +222,7 @@ async function configureSettings(page) {
subagentActiveTabOnly: false, // Show all subagents regardless of active tab
showMonitor: true,
};
- localStorage.setItem('claudeman-app-settings', JSON.stringify(settings));
+ localStorage.setItem('codeman-app-settings', JSON.stringify(settings));
});
await page.reload({ waitUntil: 'domcontentloaded' });
await sleep(500);
@@ -292,7 +292,7 @@ function convertToGif(inputPath, outputPath) {
*/
async function capture() {
console.log('='.repeat(60));
- console.log('Claudeman Subagent Screenshot Capture');
+ console.log('Codeman Subagent Screenshot Capture');
console.log('='.repeat(60));
console.log(`Output directory: ${OUTPUT_DIR}`);
console.log(`Case name: ${CASE_NAME}`);
@@ -323,8 +323,8 @@ async function capture() {
const page = await context.newPage();
page.setDefaultTimeout(30000);
- // Navigate to Claudeman
- console.log('Loading Claudeman...');
+ // Navigate to Codeman
+ console.log('Loading Codeman...');
await page.goto(BASE_URL, { waitUntil: 'domcontentloaded' });
await sleep(1000);
diff --git a/scripts/claudeman-web.service b/scripts/codeman-web.service
similarity index 75%
rename from scripts/claudeman-web.service
rename to scripts/codeman-web.service
index 597c9981..d6f60429 100644
--- a/scripts/claudeman-web.service
+++ b/scripts/codeman-web.service
@@ -1,10 +1,10 @@
[Unit]
-Description=Claudeman Web Server
+Description=Codeman Web Server
After=network.target
[Service]
Type=simple
-WorkingDirectory=/home/arkon/default/claudeman
+WorkingDirectory=/home/arkon/default/codeman
ExecStart=/usr/bin/node dist/index.js web --https
Restart=always
RestartSec=5
@@ -15,7 +15,7 @@ Environment=HOME=/home/arkon
# Logging
StandardOutput=journal
StandardError=journal
-SyslogIdentifier=claudeman
+SyslogIdentifier=codeman
# Resource limits
LimitNOFILE=65536
diff --git a/scripts/mobile-screenshot.mjs b/scripts/mobile-screenshot.mjs
index 25f3f4ea..f91bc0c4 100644
--- a/scripts/mobile-screenshot.mjs
+++ b/scripts/mobile-screenshot.mjs
@@ -1,6 +1,6 @@
#!/usr/bin/env node
/**
- * Take mobile screenshots of Claudeman using Playwright
+ * Take mobile screenshots of Codeman using Playwright
* Emulates iPhone 15 Pro (closest to iPhone 17 Pro)
* Includes keyboard simulation
*/
diff --git a/scripts/monitor-respawn.sh b/scripts/monitor-respawn.sh
index 9432f8b4..ad5340f0 100755
--- a/scripts/monitor-respawn.sh
+++ b/scripts/monitor-respawn.sh
@@ -4,8 +4,8 @@
SESSION_ID="${1:-5ecdf859-3605-42d8-b0a2-f8f0a1b5ff98}"
DURATION_HOURS="${2:-12}"
-ISSUES_FILE="/home/arkon/default/claudeman/respawn-monitor-issues.md"
-FIXES_FILE="/home/arkon/default/claudeman/respawn-monitor-fixes.md"
+ISSUES_FILE="/home/arkon/default/codeman/respawn-monitor-issues.md"
+FIXES_FILE="/home/arkon/default/codeman/respawn-monitor-fixes.md"
API_URL="https://localhost:3000"
POLL_INTERVAL=60 # seconds
@@ -54,7 +54,7 @@ while [ $(date +%s) -lt $END_TIME ]; do
if [ -z "$RESP" ]; then
log_issue "ERROR" "API not responding - server may be down"
- add_fix "API not responding" "Check if claudeman-web service is running:\n\`\`\`bash\nsystemctl --user status claudeman-web\nsystemctl --user restart claudeman-web\n\`\`\`"
+ add_fix "API not responding" "Check if codeman-web service is running:\n\`\`\`bash\nsystemctl --user status codeman-web\nsystemctl --user restart codeman-web\n\`\`\`"
sleep $POLL_INTERVAL
continue
fi
diff --git a/scripts/postinstall.js b/scripts/postinstall.js
index 8e1ff9b9..610947a2 100644
--- a/scripts/postinstall.js
+++ b/scripts/postinstall.js
@@ -1,7 +1,7 @@
#!/usr/bin/env node
/**
- * Claudeman postinstall verification script
+ * Codeman postinstall verification script
* Runs after `npm install` to check environment readiness
*/
@@ -94,7 +94,7 @@ function getTmuxInstallInstructions() {
// Main Checks
// ============================================================================
-console.log(colors.bold('Claudeman postinstall check...'));
+console.log(colors.bold('Codeman postinstall check...'));
console.log('');
let hasWarnings = false;
@@ -259,11 +259,11 @@ if (hasErrors) {
console.log(colors.bold('Next steps:'));
if (isGlobalInstall) {
- console.log(colors.dim(' 1. Start: ') + colors.cyan('claudeman web'));
+ console.log(colors.dim(' 1. Start: ') + colors.cyan('codeman web'));
console.log(colors.dim(' 2. Open: ') + colors.cyan('http://localhost:3000'));
} else {
console.log(colors.dim(' 1. Build: ') + colors.cyan('npm run build'));
- console.log(colors.dim(' 2. Start: ') + colors.cyan('claudeman web'));
+ console.log(colors.dim(' 2. Start: ') + colors.cyan('codeman web'));
console.log(colors.dim(' 3. Open: ') + colors.cyan('http://localhost:3000'));
}
diff --git a/scripts/ralph-wizard-demo.mjs b/scripts/ralph-wizard-demo.mjs
index e0477975..861b0eec 100644
--- a/scripts/ralph-wizard-demo.mjs
+++ b/scripts/ralph-wizard-demo.mjs
@@ -8,7 +8,7 @@ import { join } from 'node:path';
import { homedir } from 'node:os';
const BASE_URL = 'https://localhost:3000';
-const CASE_NAME = 'claudeman-ios';
+const CASE_NAME = 'codeman-ios';
async function main() {
console.log('🎬 Starting Ralph Loop Wizard demo...\n');
@@ -25,7 +25,7 @@ async function main() {
});
const page = await context.newPage();
- console.log('📱 Opening Claudeman web UI...');
+ console.log('📱 Opening Codeman web UI...');
await page.goto(BASE_URL);
await page.waitForLoadState('networkidle');
@@ -41,8 +41,8 @@ async function main() {
await page.selectOption('#ralphCaseSelect', CASE_NAME);
// Load initprompt.md if it exists
- const initPromptPath = join(homedir(), 'claudeman-cases', CASE_NAME, 'initprompt.md');
- let taskDescription = 'Build an awesome iOS app for Claudeman!';
+ const initPromptPath = join(homedir(), 'codeman-cases', CASE_NAME, 'initprompt.md');
+ let taskDescription = 'Build an awesome iOS app for Codeman!';
if (existsSync(initPromptPath)) {
taskDescription = readFileSync(initPromptPath, 'utf-8').trim();
console.log(`📝 Loaded initprompt.md (${taskDescription.length} chars)`);
diff --git a/scripts/ralph-wizard-prod.mjs b/scripts/ralph-wizard-prod.mjs
index 2069c97a..11b13553 100644
--- a/scripts/ralph-wizard-prod.mjs
+++ b/scripts/ralph-wizard-prod.mjs
@@ -10,8 +10,8 @@ import { join } from 'node:path';
import { homedir } from 'node:os';
const BASE_URL = 'https://localhost:3000';
-const CASE_NAME = 'claudeman-ios';
-const CASE_PATH = join(homedir(), 'claudeman-cases', CASE_NAME);
+const CASE_NAME = 'codeman-ios';
+const CASE_PATH = join(homedir(), 'codeman-cases', CASE_NAME);
async function main() {
// Read initprompt.md
@@ -49,7 +49,7 @@ async function main() {
page.on('pageerror', err => console.log(`[Browser Error] ${err.message}`));
try {
- console.log('[1/10] Navigating to Claudeman...');
+ console.log('[1/10] Navigating to Codeman...');
await page.goto(BASE_URL, { timeout: 10000 });
console.log('[2/10] Clicking Ralph Loop button (.btn-ralph)...');
@@ -122,7 +122,7 @@ async function main() {
});
session = sessions
- .filter(s => s.workingDir?.includes('claudeman-ios'))
+ .filter(s => s.workingDir?.includes('codeman-ios'))
.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt))[0];
if (session) {
@@ -151,7 +151,7 @@ async function main() {
console.log('SUCCESS! Ralph Loop started.');
console.log('========================================');
console.log(`Session ID: ${session?.id}`);
- console.log(`Screen: claudeman-${session?.id?.slice(0, 8)}`);
+ console.log(`Screen: codeman-${session?.id?.slice(0, 8)}`);
console.log(`Status: ${session?.status}`);
console.log('');
console.log('Session is now running. View at: https://localhost:3000');
diff --git a/scripts/ralph-wizard-start.mjs b/scripts/ralph-wizard-start.mjs
index 1a3e23be..5faad32b 100644
--- a/scripts/ralph-wizard-start.mjs
+++ b/scripts/ralph-wizard-start.mjs
@@ -8,7 +8,7 @@ import { join } from 'node:path';
import { homedir } from 'node:os';
const BASE_URL = 'https://localhost:3000';
-const CASE_NAME = 'claudeman-ios';
+const CASE_NAME = 'codeman-ios';
async function main() {
console.log('Starting Ralph Loop via wizard on production server...\n');
@@ -21,7 +21,7 @@ async function main() {
const context = await browser.newContext({ ignoreHTTPSErrors: true });
const page = await context.newPage();
- console.log('1. Opening Claudeman web UI...');
+ console.log('1. Opening Codeman web UI...');
await page.goto(BASE_URL);
await page.waitForLoadState('networkidle');
@@ -36,8 +36,8 @@ async function main() {
await page.selectOption('#ralphCaseSelect', CASE_NAME);
// Load initprompt.md
- const initPromptPath = join(homedir(), 'claudeman-cases', CASE_NAME, 'initprompt.md');
- let taskDescription = 'Build an awesome iOS app for Claudeman!';
+ const initPromptPath = join(homedir(), 'codeman-cases', CASE_NAME, 'initprompt.md');
+ let taskDescription = 'Build an awesome iOS app for Codeman!';
if (existsSync(initPromptPath)) {
taskDescription = readFileSync(initPromptPath, 'utf-8').trim();
console.log(`5. Loaded initprompt.md (${taskDescription.length} chars)`);
@@ -87,13 +87,13 @@ async function main() {
return res.json();
});
- const iosSession = sessions.find(s => s.workingDir?.includes('claudeman-ios'));
+ const iosSession = sessions.find(s => s.workingDir?.includes('codeman-ios'));
console.log('\n========================================');
console.log('SUCCESS! Ralph Loop started.');
console.log('========================================');
console.log(`Session ID: ${iosSession?.id}`);
- console.log(`Screen: claudeman-${iosSession?.id?.slice(0, 8)}`);
+ console.log(`Screen: codeman-${iosSession?.id?.slice(0, 8)}`);
console.log(`Working Dir: ${iosSession?.workingDir}`);
console.log('\nThe session is now running on your production server.');
console.log('View it at: https://localhost:3000');
diff --git a/scripts/test-links-browser.mjs b/scripts/test-links-browser.mjs
index 5f73262f..6477067f 100644
--- a/scripts/test-links-browser.mjs
+++ b/scripts/test-links-browser.mjs
@@ -1,6 +1,6 @@
#!/usr/bin/env node
/**
- * Browser test for clickable file links in Claudeman terminal
+ * Browser test for clickable file links in Codeman terminal
* Uses Playwright directly to ignore HTTPS errors
*/
@@ -33,8 +33,8 @@ async function main() {
const page = await context.newPage();
try {
- // Navigate to Claudeman
- console.log('Navigating to Claudeman...');
+ // Navigate to Codeman
+ console.log('Navigating to Codeman...');
await page.goto(BASE_URL, { waitUntil: 'networkidle', timeout: 30000 });
console.log('Page loaded: ' + await page.title());
@@ -63,9 +63,9 @@ async function main() {
await page.waitForTimeout(2000);
}
- // Get active session (use claudeman session if exists)
- const claudemanSession = sessions.find(s => s.workingDir?.includes('claudeman'));
- const sessionId = claudemanSession?.id || sessions[0]?.id;
+ // Get active session (use codeman session if exists)
+ const codemanSession = sessions.find(s => s.workingDir?.includes('codeman'));
+ const sessionId = codemanSession?.id || sessions[0]?.id;
console.log(`Using session: ${sessionId}\n`);
// Send a command that outputs file paths
@@ -81,8 +81,8 @@ async function main() {
await page.waitForTimeout(2000);
// Take screenshot
- await page.screenshot({ path: '/tmp/claudeman-link-test-1.png' });
- console.log('Screenshot saved: /tmp/claudeman-link-test-1.png\n');
+ await page.screenshot({ path: '/tmp/codeman-link-test-1.png' });
+ console.log('Screenshot saved: /tmp/codeman-link-test-1.png\n');
// Check if terminal contains our file path
const terminalContent = await page.evaluate(() => {
@@ -132,8 +132,8 @@ async function main() {
console.log('Log viewer windows:', logViewerCount);
// Take final screenshot
- await page.screenshot({ path: '/tmp/claudeman-link-test-2.png' });
- console.log('\nFinal screenshot: /tmp/claudeman-link-test-2.png');
+ await page.screenshot({ path: '/tmp/codeman-link-test-2.png' });
+ console.log('\nFinal screenshot: /tmp/codeman-link-test-2.png');
// Test the link provider registration
console.log('\n--- Link Provider Debug ---');
@@ -155,8 +155,8 @@ async function main() {
} catch (error) {
console.error('Error:', error.message);
- await page.screenshot({ path: '/tmp/claudeman-link-test-error.png' });
- console.log('Error screenshot saved to /tmp/claudeman-link-test-error.png');
+ await page.screenshot({ path: '/tmp/codeman-link-test-error.png' });
+ console.log('Error screenshot saved to /tmp/codeman-link-test-error.png');
} finally {
await browser.close();
console.log('\nBrowser closed');
diff --git a/scripts/test-tail-links.sh b/scripts/test-tail-links.sh
index fd0a399e..b6787122 100755
--- a/scripts/test-tail-links.sh
+++ b/scripts/test-tail-links.sh
@@ -1,8 +1,8 @@
#!/bin/bash
-# Test script for clickable file links in Claudeman terminal
+# Test script for clickable file links in Codeman terminal
# Creates a log file and continuously writes timestamped data
-LOGFILE="/tmp/claudeman-test-$(date +%s).log"
+LOGFILE="/tmp/codeman-test-$(date +%s).log"
echo "Created log file: $LOGFILE"
echo ""
diff --git a/scripts/tmux-chooser.sh b/scripts/tmux-chooser.sh
index 908e33ed..0aef49d5 100755
--- a/scripts/tmux-chooser.sh
+++ b/scripts/tmux-chooser.sh
@@ -1,6 +1,6 @@
#!/bin/bash
# ============================================================================
-# Claudeman Sessions - Mobile-friendly Tmux Session Chooser
+# Codeman Sessions - Mobile-friendly Tmux Session Chooser
# Optimized for iPhone/Termius (portrait ~45 chars, landscape ~95 chars)
# ============================================================================
#
@@ -8,7 +8,7 @@
# - Single-digit selection (1-9) for fast thumb typing
# - Compact display, no wasted space
# - Color-coded status for quick scanning
-# - Names pulled from Claudeman state.json
+# - Names pulled from Codeman state.json
# - Minimal keystrokes to attach
#
# Usage:
@@ -29,8 +29,8 @@ set -e
# Configuration
# ============================================================================
-CLAUDEMAN_STATE="$HOME/.claudeman/state.json"
-CLAUDEMAN_SESSIONS="$HOME/.claudeman/mux-sessions.json"
+CODEMAN_STATE="$HOME/.codeman/state.json"
+CODEMAN_SESSIONS="$HOME/.codeman/mux-sessions.json"
# iPhone 17 Pro portrait width (conservative)
@@ -106,22 +106,22 @@ truncate() {
find_full_session_id() {
local short_id="$1"
- if [ -f "$CLAUDEMAN_STATE" ]; then
+ if [ -f "$CODEMAN_STATE" ]; then
local full_id
full_id=$(jq -r --arg short "$short_id" '
.sessions | keys[] | select(startswith($short))
- ' "$CLAUDEMAN_STATE" 2>/dev/null | head -1)
+ ' "$CODEMAN_STATE" 2>/dev/null | head -1)
if [ -n "$full_id" ]; then
echo "$full_id"
return
fi
fi
- if [ -f "$CLAUDEMAN_SESSIONS" ]; then
+ if [ -f "$CODEMAN_SESSIONS" ]; then
local full_id
full_id=$(jq -r --arg short "$short_id" '
.[] | select(.sessionId | startswith($short)) | .sessionId
- ' "$CLAUDEMAN_SESSIONS" 2>/dev/null | head -1)
+ ' "$CODEMAN_SESSIONS" 2>/dev/null | head -1)
if [ -n "$full_id" ]; then
echo "$full_id"
return
@@ -136,22 +136,22 @@ get_session_name() {
local name=""
local workdir=""
- if [ -f "$CLAUDEMAN_SESSIONS" ]; then
+ if [ -f "$CODEMAN_SESSIONS" ]; then
local result
result=$(jq -r --arg id "$session_id" '
.[] | select(.sessionId | startswith($id)) | "\(.name // "")\t\(.workingDir // "")"
- ' "$CLAUDEMAN_SESSIONS" 2>/dev/null | head -1)
+ ' "$CODEMAN_SESSIONS" 2>/dev/null | head -1)
if [ -n "$result" ]; then
name="${result%% *}"
workdir="${result#* }"
fi
fi
- if [ -z "$name" ] && [ -f "$CLAUDEMAN_STATE" ]; then
+ if [ -z "$name" ] && [ -f "$CODEMAN_STATE" ]; then
local result
result=$(jq -r --arg id "$session_id" '
.sessions | to_entries[] | select(.key | startswith($id)) | "\(.value.name // "")\t\(.value.workingDir // "")"
- ' "$CLAUDEMAN_STATE" 2>/dev/null | head -1)
+ ' "$CODEMAN_STATE" 2>/dev/null | head -1)
if [ -n "$result" ]; then
name="${result%% *}"
[ -z "$workdir" ] && workdir="${result#* }"
@@ -174,22 +174,22 @@ get_session_name() {
get_working_dir() {
local session_id="$1"
- if [ -f "$CLAUDEMAN_SESSIONS" ]; then
+ if [ -f "$CODEMAN_SESSIONS" ]; then
local dir
dir=$(jq -r --arg id "$session_id" '
.[] | select(.sessionId | startswith($id)) | .workingDir // empty
- ' "$CLAUDEMAN_SESSIONS" 2>/dev/null | head -1)
+ ' "$CODEMAN_SESSIONS" 2>/dev/null | head -1)
if [ -n "$dir" ] && [ "$dir" != "null" ]; then
echo "${dir/#$HOME/~}"
return
fi
fi
- if [ -f "$CLAUDEMAN_STATE" ]; then
+ if [ -f "$CODEMAN_STATE" ]; then
local dir
dir=$(jq -r --arg id "$session_id" '
.sessions | to_entries[] | select(.key | startswith($id)) | .value.workingDir // empty
- ' "$CLAUDEMAN_STATE" 2>/dev/null | head -1)
+ ' "$CODEMAN_STATE" 2>/dev/null | head -1)
if [ -n "$dir" ] && [ "$dir" != "null" ]; then
echo "${dir/#$HOME/~}"
return
@@ -201,12 +201,12 @@ get_working_dir() {
get_tokens() {
local session_id="$1"
- if [ -f "$CLAUDEMAN_STATE" ]; then
+ if [ -f "$CODEMAN_STATE" ]; then
local tokens
tokens=$(jq -r --arg id "$session_id" '
.sessions | to_entries[] | select(.key | startswith($id)) |
((.value.inputTokens // 0) + (.value.outputTokens // 0))
- ' "$CLAUDEMAN_STATE" 2>/dev/null | head -1)
+ ' "$CODEMAN_STATE" 2>/dev/null | head -1)
if [ -n "$tokens" ] && [ "$tokens" != "null" ] && [ "$tokens" -gt 0 ] 2>/dev/null; then
if [ "$tokens" -gt 1000 ]; then
@@ -223,11 +223,11 @@ get_tokens() {
get_respawn_status() {
local session_id="$1"
- if [ -f "$CLAUDEMAN_SESSIONS" ]; then
+ if [ -f "$CODEMAN_SESSIONS" ]; then
local respawn_enabled
respawn_enabled=$(jq -r --arg id "$session_id" '
.[] | select(.sessionId | startswith($id)) | .respawnConfig.enabled // false
- ' "$CLAUDEMAN_SESSIONS" 2>/dev/null | head -1)
+ ' "$CODEMAN_SESSIONS" 2>/dev/null | head -1)
if [ "$respawn_enabled" = "true" ]; then
echo "R"
@@ -273,8 +273,8 @@ parse_sessions() {
while IFS= read -r line; do
local session_name="${line%%:*}"
- # Only show claudeman sessions
- if [[ "$session_name" != claudeman-* ]]; then
+ # Only show codeman sessions
+ if [[ "$session_name" != codeman-* ]]; then
continue
fi
@@ -292,9 +292,9 @@ parse_sessions() {
MUX_NAMES+=("$session_name")
SESSION_STATES+=("$state")
- # Extract session ID from claudeman session name
+ # Extract session ID from codeman session name
local session_id=""
- local cm_regex='^claudeman-(.+)$'
+ local cm_regex='^codeman-(.+)$'
if [[ "$session_name" =~ $cm_regex ]]; then
session_id="${BASH_REMATCH[1]}"
fi
@@ -327,7 +327,7 @@ clear_screen() {
print_header() {
local count=${#SESSION_PIDS[@]}
- echo -e "${B}${CYAN}Claudeman Sessions${R} ${D}($count)${R}"
+ echo -e "${B}${CYAN}Codeman Sessions${R} ${D}($count)${R}"
echo -e "${D}$(printf '%.0s─' {1..32})${R}"
}
@@ -395,13 +395,13 @@ print_footer() {
print_no_sessions() {
clear_screen
- echo -e "${B}${CYAN}Claudeman Sessions${R}"
+ echo -e "${B}${CYAN}Codeman Sessions${R}"
echo -e "${D}$(printf '%.0s─' {1..32})${R}"
echo ""
echo -e " ${YELLOW}No tmux sessions found${R}"
echo ""
echo -e " ${D}Start one with:${R}"
- echo -e " ${WHITE}claudeman web${R}"
+ echo -e " ${WHITE}codeman web${R}"
echo ""
echo -e "${D}$(printf '%.0s─' {1..32})${R}"
echo -e " ${GRAY}[${WHITE}r${GRAY}]efresh [${WHITE}q${GRAY}]uit${R}"
@@ -584,7 +584,7 @@ quick_attach() {
show_help() {
cat << 'EOF'
-Claudeman Sessions - Mobile-friendly Tmux Session Chooser
+Codeman Sessions - Mobile-friendly Tmux Session Chooser
USAGE:
sc Interactive chooser
@@ -607,7 +607,7 @@ INDICATORS:
TIPS:
- Detach from tmux: Ctrl+B D
- - Session names from Claudeman state
+ - Session names from Codeman state
- Optimized for Termius/iPhone
EOF
diff --git a/scripts/tmux-manager.sh b/scripts/tmux-manager.sh
index a5f25757..01de1847 100755
--- a/scripts/tmux-manager.sh
+++ b/scripts/tmux-manager.sh
@@ -1,8 +1,8 @@
#!/bin/bash
#
-# Claudeman Tmux Session Manager
+# Codeman Tmux Session Manager
# Interactive tool with arrow key navigation
-# Reads from ~/.claudeman/mux-sessions.json
+# Reads from ~/.codeman/mux-sessions.json
#
# Colors
@@ -17,8 +17,8 @@ DIM='\033[2m'
NC='\033[0m'
REVERSE='\033[7m'
-# Use the same path as claudeman (src/tmux-manager.ts)
-SESSIONS_FILE="${HOME}/.claudeman/mux-sessions.json"
+# Use the same path as codeman (src/tmux-manager.ts)
+SESSIONS_FILE="${HOME}/.codeman/mux-sessions.json"
# Cached data
@@ -133,7 +133,7 @@ kill_session() {
# Draw header (only once)
draw_header() {
echo -e "${BOLD}${CYAN}╔══════════════════════════════════════════════════════════╗${NC}"
- echo -e "${BOLD}${CYAN}║ Claudeman Tmux Session Manager ║${NC}"
+ echo -e "${BOLD}${CYAN}║ Codeman Tmux Session Manager ║${NC}"
echo -e "${BOLD}${CYAN}║ ${DIM}Press q or Esc to exit${CYAN} ║${NC}"
echo -e "${BOLD}${CYAN}╚══════════════════════════════════════════════════════════╝${NC}"
echo ""
@@ -401,11 +401,11 @@ quick_list() {
local now=$(date +%s)
if [[ $CACHED_COUNT -eq 0 ]]; then
- echo "No claudeman sessions found."
+ echo "No codeman sessions found."
exit 0
fi
- echo "Claudeman Sessions ($SESSIONS_FILE):"
+ echo "Codeman Sessions ($SESSIONS_FILE):"
echo ""
printf "%-4s %-22s %-14s %-10s %-8s\n" "#" "NAME" "RUNNING" "STATUS" "MODE"
echo "─────────────────────────────────────────────────────────────────"
@@ -432,7 +432,7 @@ quick_list() {
# Usage
usage() {
cat << EOF
-Claudeman Tmux Session Manager
+Codeman Tmux Session Manager
Reads from: $SESSIONS_FILE
diff --git a/src/ai-checker-base.ts b/src/ai-checker-base.ts
index f67f778d..dc9711c7 100644
--- a/src/ai-checker-base.ts
+++ b/src/ai-checker-base.ts
@@ -11,9 +11,9 @@
* - Event emission for state changes
*
* Subclasses implement:
- * - `muxNamePrefix`: Prefix for mux session names (e.g., 'claudeman-aicheck-')
+ * - `muxNamePrefix`: Prefix for mux session names (e.g., 'codeman-aicheck-')
* - `doneMarker`: Completion marker in output file (e.g., '__AICHECK_DONE__')
- * - `tempFilePrefix`: Prefix for temp files (e.g., 'claudeman-aicheck')
+ * - `tempFilePrefix`: Prefix for temp files (e.g., 'codeman-aicheck')
* - `logPrefix`: Prefix for log messages (e.g., '[AiIdleChecker]')
* - `buildPrompt()`: Build the prompt from terminal buffer
* - `parseVerdict()`: Parse the verdict from AI output
@@ -143,13 +143,13 @@ export abstract class AiCheckerBase<
// ========== Abstract Properties ==========
- /** Prefix for mux session names (e.g., 'claudeman-aicheck-') */
+ /** Prefix for mux session names (e.g., 'codeman-aicheck-') */
protected abstract readonly muxNamePrefix: string;
/** Marker written to temp file when check is complete */
protected abstract readonly doneMarker: string;
- /** Prefix for temp files (e.g., 'claudeman-aicheck') */
+ /** Prefix for temp files (e.g., 'codeman-aicheck') */
protected abstract readonly tempFilePrefix: string;
/** Prefix for log messages (e.g., '[AiIdleChecker]') */
diff --git a/src/ai-idle-checker.ts b/src/ai-idle-checker.ts
index 89aaf409..b5154602 100644
--- a/src/ai-idle-checker.ts
+++ b/src/ai-idle-checker.ts
@@ -8,7 +8,7 @@
* ## How It Works
*
* 1. Generate temp file path for output capture
- * 2. Spawn tmux: `tmux new-session -d -s claudeman-aicheck- bash -c 'claude -p ...'`
+ * 2. Spawn tmux: `tmux new-session -d -s codeman-aicheck- bash -c 'claude -p ...'`
* 3. Poll the temp file every 500ms for `__AICHECK_DONE__` marker
* 4. Parse the file content for IDLE/WORKING on the first word
* 5. Kill tmux session and delete temp file
@@ -129,9 +129,9 @@ export class AiIdleChecker extends AiCheckerBase<
AiCheckResult,
AiCheckState
> {
- protected readonly muxNamePrefix = 'claudeman-aicheck-';
+ protected readonly muxNamePrefix = 'codeman-aicheck-';
protected readonly doneMarker = '__AICHECK_DONE__';
- protected readonly tempFilePrefix = 'claudeman-aicheck';
+ protected readonly tempFilePrefix = 'codeman-aicheck';
protected readonly logPrefix = '[AiIdleChecker]';
protected readonly checkDescription = 'AI idle check';
diff --git a/src/ai-plan-checker.ts b/src/ai-plan-checker.ts
index eec922ef..f302f88f 100644
--- a/src/ai-plan-checker.ts
+++ b/src/ai-plan-checker.ts
@@ -8,7 +8,7 @@
* ## How It Works
*
* 1. Generate temp file path for output capture
- * 2. Spawn tmux: `tmux new-session -d -s claudeman-plancheck- bash -c 'claude -p ...'`
+ * 2. Spawn tmux: `tmux new-session -d -s codeman-plancheck- bash -c 'claude -p ...'`
* 3. Poll the temp file every 500ms for `__PLANCHECK_DONE__` marker
* 4. Parse the file content for PLAN_MODE/NOT_PLAN_MODE on the first line
* 5. Kill tmux session and delete temp file
@@ -91,9 +91,9 @@ export class AiPlanChecker extends AiCheckerBase<
AiPlanCheckResult,
AiPlanCheckState
> {
- protected readonly muxNamePrefix = 'claudeman-plancheck-';
+ protected readonly muxNamePrefix = 'codeman-plancheck-';
protected readonly doneMarker = '__PLANCHECK_DONE__';
- protected readonly tempFilePrefix = 'claudeman-plancheck';
+ protected readonly tempFilePrefix = 'codeman-plancheck';
protected readonly logPrefix = '[AiPlanChecker]';
protected readonly checkDescription = 'AI plan check';
diff --git a/src/cli.ts b/src/cli.ts
index ad4fca2e..425d6c03 100644
--- a/src/cli.ts
+++ b/src/cli.ts
@@ -1,5 +1,5 @@
/**
- * @fileoverview Claudeman CLI command definitions
+ * @fileoverview Codeman CLI command definitions
*
* Defines all CLI commands and subcommands for managing Claude sessions,
* tasks, Ralph loops, and the web server.
@@ -22,7 +22,7 @@ const pkg = require('../package.json') as { version: string };
const program = new Command();
program
- .name('claudeman')
+ .name('codeman')
.description('Claude Code session manager with autonomous Ralph Loop')
.version(pkg.version);
@@ -407,7 +407,7 @@ program
? sessions.filter((s) => s.isBusy()).length
: storedValues.filter((s) => s.status === 'busy').length;
- console.log(chalk.bold('\nClaudeman Status'));
+ console.log(chalk.bold('\nCodeman Status'));
console.log('─'.repeat(40));
console.log(chalk.bold('\nSessions:'));
@@ -504,7 +504,7 @@ program
const https = !!options.https;
const protocol = https ? 'https' : 'http';
- console.log(chalk.cyan(`Starting Claudeman web interface on port ${port}${https ? ' (HTTPS)' : ''}...`));
+ console.log(chalk.cyan(`Starting Codeman web interface on port ${port}${https ? ' (HTTPS)' : ''}...`));
try {
const server = await startWebServer(port, https);
diff --git a/src/config/buffer-limits.ts b/src/config/buffer-limits.ts
index 90b14eba..41f7bcd5 100644
--- a/src/config/buffer-limits.ts
+++ b/src/config/buffer-limits.ts
@@ -2,7 +2,7 @@
* @fileoverview Centralized buffer size limits for memory management.
*
* These constants define the maximum sizes for various buffers throughout
- * Claudeman. Consolidating them here ensures consistent limits and makes
+ * Codeman. Consolidating them here ensures consistent limits and makes
* it easy to tune memory usage.
*
* Memory Budget Rationale (for 20 concurrent sessions):
diff --git a/src/hooks-config.ts b/src/hooks-config.ts
index d00627ea..f9843c71 100644
--- a/src/hooks-config.ts
+++ b/src/hooks-config.ts
@@ -2,9 +2,9 @@
* @fileoverview Claude Code hooks configuration generator
*
* Generates .claude/settings.local.json with hook definitions that POST
- * to Claudeman's /api/hook-event endpoint when Claude Code fires
- * notification or stop hooks. Uses $CLAUDEMAN_API_URL and
- * $CLAUDEMAN_SESSION_ID env vars (set on every managed session) so the
+ * to Codeman's /api/hook-event endpoint when Claude Code fires
+ * notification or stop hooks. Uses $CODEMAN_API_URL and
+ * $CODEMAN_SESSION_ID env vars (set on every managed session) so the
* config is static per case directory.
*/
@@ -18,7 +18,7 @@ import type { HookEventType } from './types.js';
* Generates the hooks section for .claude/settings.local.json
*
* The hook commands read stdin JSON from Claude Code (contains tool_name,
- * tool_input, etc.) and forward it as the `data` field to Claudeman's API.
+ * tool_input, etc.) and forward it as the `data` field to Codeman's API.
* Env vars are resolved at runtime by the shell, so the config is static
* per case directory.
*/
@@ -27,9 +27,9 @@ export function generateHooksConfig(): { hooks: Record } {
// Falls back to empty object if stdin is unavailable or malformed.
const curlCmd = (event: HookEventType) =>
`HOOK_DATA=$(cat 2>/dev/null || echo '{}'); ` +
- `curl -s -X POST "$CLAUDEMAN_API_URL/api/hook-event" ` +
+ `curl -s -X POST "$CODEMAN_API_URL/api/hook-event" ` +
`-H 'Content-Type: application/json' ` +
- `-d "{\\"event\\":\\"${event}\\",\\"sessionId\\":\\"$CLAUDEMAN_SESSION_ID\\",\\"data\\":$HOOK_DATA}" ` +
+ `-d "{\\"event\\":\\"${event}\\",\\"sessionId\\":\\"$CODEMAN_SESSION_ID\\",\\"data\\":$HOOK_DATA}" ` +
`2>/dev/null || true`;
return {
diff --git a/src/image-watcher.ts b/src/image-watcher.ts
index eb5e4443..87c43dc1 100644
--- a/src/image-watcher.ts
+++ b/src/image-watcher.ts
@@ -137,7 +137,7 @@ export class ImageWatcher extends EventEmitter {
/**
* Start watching a session's working directory for new images.
*
- * @param sessionId - Claudeman session ID
+ * @param sessionId - Codeman session ID
* @param workingDir - Path to the session's working directory
*/
watchSession(sessionId: string, workingDir: string): void {
@@ -200,7 +200,7 @@ export class ImageWatcher extends EventEmitter {
/**
* Stop watching a session's working directory.
*
- * @param sessionId - Claudeman session ID to stop watching
+ * @param sessionId - Codeman session ID to stop watching
*/
unwatchSession(sessionId: string): void {
const watcher = this.sessionWatchers.get(sessionId);
diff --git a/src/index.ts b/src/index.ts
index de4c52e1..ea502157 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,8 +1,8 @@
#!/usr/bin/env node
/**
- * @fileoverview Claudeman CLI entry point
+ * @fileoverview Codeman CLI entry point
*
- * This is the main executable entry point for the Claudeman CLI.
+ * This is the main executable entry point for the Codeman CLI.
* It sets up global error handlers and invokes the CLI parser.
*
* @module index
diff --git a/src/mux-interface.ts b/src/mux-interface.ts
index fd475b5f..e3a91ecc 100644
--- a/src/mux-interface.ts
+++ b/src/mux-interface.ts
@@ -13,9 +13,9 @@ import type { ProcessStats, PersistedRespawnConfig, NiceConfig, ClaudeMode, Sess
* Multiplexer session metadata.
*/
export interface MuxSession {
- /** Claudeman session ID */
+ /** Codeman session ID */
sessionId: string;
- /** Multiplexer session name (e.g., "claudeman-abc12345") */
+ /** Multiplexer session name (e.g., "codeman-abc12345") */
muxName: string;
/** Process PID */
pid: number;
@@ -105,7 +105,7 @@ export interface TerminalMultiplexer extends EventEmitter {
/** Get all tracked sessions */
getSessions(): MuxSession[];
- /** Get a session by Claudeman session ID */
+ /** Get a session by Codeman session ID */
getSession(sessionId: string): MuxSession | undefined;
/** Get all sessions with process resource statistics */
diff --git a/src/run-summary.ts b/src/run-summary.ts
index cbb21981..7a9c0fae 100644
--- a/src/run-summary.ts
+++ b/src/run-summary.ts
@@ -1,5 +1,5 @@
/**
- * @fileoverview Run Summary Tracker for Claudeman sessions
+ * @fileoverview Run Summary Tracker for Codeman sessions
*
* Tracks significant events during a session's lifetime to provide users
* with a consolidated "what happened while I was away" view.
diff --git a/src/session-lifecycle-log.ts b/src/session-lifecycle-log.ts
index 4aa1262e..ddab9978 100644
--- a/src/session-lifecycle-log.ts
+++ b/src/session-lifecycle-log.ts
@@ -2,7 +2,7 @@
* @fileoverview Append-only JSONL audit log for session lifecycle events.
*
* Records every session creation, start, exit, deletion, recovery, and server
- * start/stop to ~/.claudeman/session-lifecycle.jsonl. Survives server restarts
+ * start/stop to ~/.codeman/session-lifecycle.jsonl. Survives server restarts
* (unlike RunSummary which is in-memory only).
*
* @module session-lifecycle-log
@@ -22,7 +22,7 @@ export class SessionLifecycleLog {
private writeQueue: Promise = Promise.resolve();
constructor(filePath?: string) {
- this.filePath = filePath || join(homedir(), '.claudeman', 'session-lifecycle.jsonl');
+ this.filePath = filePath || join(homedir(), '.codeman', 'session-lifecycle.jsonl');
const dir = dirname(this.filePath);
if (!existsSync(dir)) {
mkdirSync(dir, { recursive: true, mode: 0o700 });
diff --git a/src/session.ts b/src/session.ts
index 97f54059..8d64a404 100644
--- a/src/session.ts
+++ b/src/session.ts
@@ -400,8 +400,8 @@ export class Session extends EventEmitter {
this.mode = config.mode || 'claude';
this._name = config.name || '';
this._lastActivityAt = this.createdAt;
- // Set claudeSessionId immediately — Claudeman always passes --session-id ${this.id}
- // to Claude CLI, so the Claude session ID always matches the Claudeman session ID.
+ // Set claudeSessionId immediately — Codeman always passes --session-id ${this.id}
+ // to Claude CLI, so the Claude session ID always matches the Codeman session ID.
// This ensures subagent matching works even for recovered sessions (where
// startInteractive() hasn't been called yet).
this._claudeSessionId = this.id;
@@ -1041,7 +1041,7 @@ export class Session extends EventEmitter {
throw new Error('OpenCode sessions require tmux. Direct PTY fallback is not supported.');
}
try {
- // Pass --session-id to use the SAME ID as the Claudeman session
+ // Pass --session-id to use the SAME ID as the Codeman session
// This ensures subagents can be directly matched to the correct tab
const args = [...this._buildPermissionArgs(), '--session-id', this.id];
if (this._model) args.push('--model', this._model);
@@ -1058,10 +1058,10 @@ export class Session extends EventEmitter {
TERM: 'xterm-256color',
COLORTERM: undefined,
CLAUDECODE: undefined,
- // Inform Claude it's running within Claudeman (helps prevent self-termination)
- CLAUDEMAN_MUX: '1',
- CLAUDEMAN_SESSION_ID: this.id,
- CLAUDEMAN_API_URL: process.env.CLAUDEMAN_API_URL || 'http://localhost:3000',
+ // Inform Claude it's running within Codeman (helps prevent self-termination)
+ CODEMAN_MUX: '1',
+ CODEMAN_SESSION_ID: this.id,
+ CODEMAN_API_URL: process.env.CODEMAN_API_URL || 'http://localhost:3000',
},
});
} catch (spawnErr) {
@@ -1376,9 +1376,9 @@ export class Session extends EventEmitter {
LANG: 'en_US.UTF-8',
LC_ALL: 'en_US.UTF-8',
TERM: 'xterm-256color',
- CLAUDEMAN_MUX: '1',
- CLAUDEMAN_SESSION_ID: this.id,
- CLAUDEMAN_API_URL: process.env.CLAUDEMAN_API_URL || 'http://localhost:3000',
+ CODEMAN_MUX: '1',
+ CODEMAN_SESSION_ID: this.id,
+ CODEMAN_API_URL: process.env.CODEMAN_API_URL || 'http://localhost:3000',
},
});
} catch (spawnErr) {
@@ -1509,10 +1509,10 @@ export class Session extends EventEmitter {
TERM: 'xterm-256color',
COLORTERM: undefined,
CLAUDECODE: undefined,
- // Inform Claude it's running within Claudeman
- CLAUDEMAN_MUX: '1',
- CLAUDEMAN_SESSION_ID: this.id,
- CLAUDEMAN_API_URL: process.env.CLAUDEMAN_API_URL || 'http://localhost:3000',
+ // Inform Claude it's running within Codeman
+ CODEMAN_MUX: '1',
+ CODEMAN_SESSION_ID: this.id,
+ CODEMAN_API_URL: process.env.CODEMAN_API_URL || 'http://localhost:3000',
},
});
} catch (spawnErr) {
@@ -1867,7 +1867,7 @@ export class Session extends EventEmitter {
}
// Parse Claude Code CLI info from terminal startup output
- // Extracts version, model, and account type for display in Claudeman UI
+ // Extracts version, model, and account type for display in Codeman UI
// Note: Expects cleanData with ANSI codes already stripped by caller
private parseClaudeCodeInfo(cleanData: string): void {
// Only parse once per session (during startup)
diff --git a/src/state-store.ts b/src/state-store.ts
index 5d64f335..cd872b90 100644
--- a/src/state-store.ts
+++ b/src/state-store.ts
@@ -1,8 +1,8 @@
/**
- * @fileoverview Persistent JSON state storage for Claudeman.
+ * @fileoverview Persistent JSON state storage for Codeman.
*
* This module provides the StateStore class which persists application state
- * to `~/.claudeman/state.json` with debounced writes to prevent excessive disk I/O.
+ * to `~/.codeman/state.json` with debounced writes to prevent excessive disk I/O.
*
* State is split into two files:
* - `state.json`: Main app state (sessions, tasks, config)
@@ -68,7 +68,23 @@ export class StateStore {
private _saveInFlight: Promise | null = null;
constructor(filePath?: string) {
- this.filePath = filePath || join(homedir(), '.claudeman', 'state.json');
+ // Migrate legacy data directory (~/.claudeman → ~/.codeman)
+ if (!filePath) {
+ const legacyDir = join(homedir(), '.claudeman');
+ const newDir = join(homedir(), '.codeman');
+ if (existsSync(legacyDir) && !existsSync(newDir)) {
+ console.log(`[state-store] Migrating data directory: ${legacyDir} → ${newDir}`);
+ renameSync(legacyDir, newDir);
+ }
+ const legacyCasesDir = join(homedir(), 'claudeman-cases');
+ const newCasesDir = join(homedir(), 'codeman-cases');
+ if (existsSync(legacyCasesDir) && !existsSync(newCasesDir)) {
+ console.log(`[state-store] Migrating cases directory: ${legacyCasesDir} → ${newCasesDir}`);
+ renameSync(legacyCasesDir, newCasesDir);
+ }
+ }
+
+ this.filePath = filePath || join(homedir(), '.codeman', 'state.json');
this.ralphStatePath = this.filePath.replace('.json', '-inner.json');
this.state = this.load();
this.state.config.stateFilePath = this.filePath;
diff --git a/src/subagent-watcher.ts b/src/subagent-watcher.ts
index 7b725c86..e9008055 100644
--- a/src/subagent-watcher.ts
+++ b/src/subagent-watcher.ts
@@ -310,7 +310,7 @@ export class SubagentWatcher extends EventEmitter {
/**
* Run pgrep once and read /proc info for all Claude PIDs in parallel.
* Returns a Map of pid -> { environ, cmdline } for subagent processes only.
- * Excludes main Claudeman-managed Claude processes (CLAUDEMAN_MUX=1).
+ * Excludes main Codeman-managed Claude processes (CODEMAN_MUX=1).
* Also updates cached PIDs on tracked agents when a match is found.
*/
private async getClaudePids(): Promise