mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-08 16:39:42 +02:00
chore: rename Claudeman to Codeman
Full product rename across 109 files (~834 occurrences): - Env vars: CLAUDEMAN_* → CODEMAN_* - Data dirs: ~/.claudeman/ → ~/.codeman/, ~/claudeman-cases/ → ~/codeman-cases/ - tmux prefix: claudeman- → codeman- - localStorage: claudeman-* → codeman-* - Package/CLI: claudeman → codeman - GitHub repo: Ark0N/Claudeman → Ark0N/Codeman - systemd service: claudeman-web → codeman-web - Class: ClaudemanApp → CodemanApp Migration infrastructure for seamless transition: - state-store.ts: auto-migrates data directories on startup - tmux-manager.ts: dual-prefix detection (legacy claudeman- sessions) - app.js: localStorage key migration (preserves old keys) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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 `<span class="settings-status" id="notifPer
|
||||
|
||||
The settings UI shows a hint (index.html line 996):
|
||||
```
|
||||
For remote access, HTTPS is required. Start with: claudeman web --https
|
||||
For remote access, HTTPS is required. Start with: codeman web --https
|
||||
```
|
||||
|
||||
Browser Notification API requires a secure context (HTTPS or localhost). This hint warns users who access Claudeman remotely over HTTP.
|
||||
Browser Notification API requires a secure context (HTTPS or localhost). This hint warns users who access Codeman remotely over HTTP.
|
||||
|
||||
---
|
||||
|
||||
@@ -579,7 +579,7 @@ On mobile devices:
|
||||
|
||||
### Mobile Storage Key (lines 952-956)
|
||||
|
||||
Mobile uses a separate localStorage key (`claudeman-notification-prefs-mobile`) so that enabling notifications on desktop does not accidentally enable them on a mobile device viewing the same Claudeman instance.
|
||||
Mobile uses a separate localStorage key (`codeman-notification-prefs-mobile`) so that enabling notifications on desktop does not accidentally enable them on a mobile device viewing the same Codeman instance.
|
||||
|
||||
### Mobile Drawer Styling (mobile.css lines 1049-1058)
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ The App Settings modal has tabs: Display, Claude CLI, Models, Paths, **Notificat
|
||||
|
||||
The Browser row includes an "Ask" button that calls `requestPermission()` and a status badge showing the current `Notification.permission` state.
|
||||
|
||||
There is also a hint: _"For remote access, HTTPS is required. Start with: `claudeman web --https`"_
|
||||
There is also a hint: _"For remote access, HTTPS is required. Start with: `codeman web --https`"_
|
||||
|
||||
#### Alerts Section
|
||||
| Setting | Element ID | Type | Default |
|
||||
@@ -54,16 +54,16 @@ Notification preferences are stored in **two places simultaneously**:
|
||||
|
||||
#### Layer 1: localStorage (primary, device-specific)
|
||||
|
||||
- **Storage key**: `claudeman-notification-prefs` (desktop) or `claudeman-notification-prefs-mobile` (mobile)
|
||||
- **Storage key**: `codeman-notification-prefs` (desktop) or `codeman-notification-prefs-mobile` (mobile)
|
||||
- Determined by `NotificationManager.getStorageKey()` at line 953, which calls `MobileDetection.getDeviceType()`
|
||||
- Device type is based on `window.innerWidth`: `<430` = mobile, `430-768` = tablet, `>=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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user