Conversation
Add system prompt configuration to enable CLAUDE.md loading from project, user config, and local directories. This allows Claude Code to use custom instructions defined in CLAUDE.md files. Fix scroll position management during message streaming to prevent conflicting with user's manual scroll actions. Remove automatic scroll state reset in scrollToBottom function and let scroll event handler manage the state naturally. Also remove debug logging for session ID capture.
Update .env.example with comprehensive CLI command documentation and clearer DATABASE_PATH configuration comments. Enhance README.md with restructured installation guide featuring new cloudcli commands, detailed PM2 background service setup instructions, and improved organization of global installation benefits and restart procedures. Add CLI command reference showing cloudcli start, status, help, and version commands. Expand PM2 section with separate subsections for installation, service startup, and auto-start configuration.
|
Caution Review failedThe pull request is closed. WalkthroughNew CLI interface added with start, status, help, and version commands. Package.json bin entries updated to reference Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 inconclusive)
✅ Passed checks (2 passed)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
server/claude-sdk.js (1)
386-407: Session ID property name: add fallback for camelCaseSome SDKs emit sessionId (camelCase). Add a fallback to avoid missing new-session handling.
- if (message.session_id && !capturedSessionId) { + const sid = message.session_id || message.sessionId; + if (sid && !capturedSessionId) { - capturedSessionId = message.session_id; + capturedSessionId = sid;README.md (1)
336-341: License mismatch with package.json (MIT vs GPLv3)package.json declares MIT, README states GPLv3. Align to a single license to avoid compliance risk.
- Update README to MIT or change package.json to GPLv3, and ensure LICENSE file matches.
🧹 Nitpick comments (14)
server/claude-sdk.js (4)
412-415: Guard WebSocket sendsAvoid exceptions on closed sockets; check readyState before send.
- ws.send(JSON.stringify({ + if (ws && ws.readyState === 1) ws.send(JSON.stringify({ type: 'claude-response', data: transformedMessage - })); + })); @@ - ws.send(JSON.stringify({ + if (ws && ws.readyState === 1) ws.send(JSON.stringify({ type: 'token-budget', data: tokenBudget - })); + })); @@ - ws.send(JSON.stringify({ + if (ws && ws.readyState === 1) ws.send(JSON.stringify({ type: 'claude-error', error: error.message - })); + }));Also applies to: 422-425, 460-463
182-186: parseInt without radixUse radix to avoid subtle parsing issues and default correctly.
- const contextWindow = parseInt(process.env.CONTEXT_WINDOW) || 160000; + const contextWindow = Number.parseInt(process.env.CONTEXT_WINDOW, 10) || 160000;
509-512: Ensure boolean returnReturn a strict boolean from isClaudeSDKSessionActive.
- return session && session.status === 'active'; + return !!(session && session.status === 'active');
82-91: Apply suggested refactor to respect caller-provided systemPrompt and settingSources overridesThe SDK options are valid for v0.1.29 as confirmed in the docs. However, the code currently hardcodes
systemPromptandsettingSourceswithout checking theoptionsparameter, which is inconsistent with howmodelis handled on line 80 (options.model || 'sonnet'). Apply the suggested refactor to allow callers to override these values while maintaining sensible defaults:- sdkOptions.systemPrompt = { - type: 'preset', - preset: 'claude_code' // Required to use CLAUDE.md - }; + sdkOptions.systemPrompt = options.systemPrompt ?? { + type: 'preset', + preset: 'claude_code' // default to CLAUDE.md preset + }; - sdkOptions.settingSources = ['project', 'user', 'local']; + sdkOptions.settingSources = options.settingSources ?? ['project', 'user', 'local'];package.json (1)
34-34: Minor typo in keywords"claude coode" → "claude code".
- "claude coode", + "claude code",src/components/ChatInterface.jsx (1)
3541-3546: Session switch scroll: timing looks fine; add null guardAdd a lightweight guard to avoid rare NPEs if container unmounts during the 200ms delay.
- setTimeout(() => { - scrollToBottom(); - // After scrolling, the scroll event handler will naturally set isUserScrolledUp based on position - }, 200); // Delay to ensure full rendering + setTimeout(() => { + if (scrollContainerRef.current) { + scrollToBottom(); + } + }, 200);Ensure no double-scroll occurs when isLoadingSessionRef flips within this 200ms window.
server/database/db.js (2)
29-41: Harden DB directory permissionsCreate the DB directory with restrictive perms (0700) when using a custom DATABASE_PATH.
- fs.mkdirSync(dbDir, { recursive: true }); + fs.mkdirSync(dbDir, { recursive: true, mode: 0o700 });
59-68: initializeDatabase marked async but uses sync I/OEither remove async or switch to fs.promises for consistency.
-const initializeDatabase = async () => { +const initializeDatabase = () => { try { const initSQL = fs.readFileSync(INIT_SQL_PATH, 'utf8'); db.exec(initSQL); console.log('Database initialized successfully'); } catch (error) { console.error('Error initializing database:', error.message); throw error; } };.env.example (1)
32-36: Add a concrete DATABASE_PATH exampleHelps users discover correct absolute paths; matches db.js behavior that creates the directory.
# To use a custom location: -# DATABASE_PATH=/path/to/your/custom/auth.db +# DATABASE_PATH=/absolute/path/to/your/custom/auth.db +# e.g. on Linux/Mac: +# DATABASE_PATH=$HOME/.claude-code-ui/auth/auth.db +# e.g. on Windows (PowerShell): +# DATABASE_PATH=C:\Users\YourUser\AppData\Local\ClaudeCodeUI\auth\auth.dbREADME.md (1)
90-110: Specify languages on fenced code blocksSeveral code blocks lack a language marker (MD040). Use bash for CLI examples.
-``` +```bash npx @siteboon/claude-code-uiApply similarly for other shell snippets (cloudcli, pm2, etc.). </blockquote></details> <details> <summary>server/index.js (3)</summary><blockquote> `47-47`: **Use standardized logging format for consistency.** This debug log doesn't follow the new standardized logging format introduced in this PR. Apply this diff: ```diff -console.log('PORT from env:', process.env.PORT); +console.log(`${c.info('[DEBUG]')} PORT from env: ${c.dim(process.env.PORT)}`);
774-774: Complete the logging standardization by converting remaining emoji logs.These WebSocket-related logs still use emoji prefixes (🔌, 🐚, 🔴), which is inconsistent with the standardized logging format introduced throughout the rest of the file.
Apply this diff for consistency:
- ws.on('close', () => { - console.log('🔌 Chat client disconnected'); + ws.on('close', () => { + console.log(`${c.info('[INFO]')} Chat client disconnected`); -function handleShellConnection(ws) { - console.log('🐚 Shell client connected'); +function handleShellConnection(ws) { + console.log(`${c.info('[INFO]')} Shell client connected`); - ws.on('close', () => { - console.log('🔌 Shell client disconnected'); - if (shellProcess && shellProcess.kill) { - console.log('🔴 Killing shell process:', shellProcess.pid); + ws.on('close', () => { + console.log(`${c.info('[INFO]')} Shell client disconnected`); + if (shellProcess && shellProcess.kill) { + console.log(`${c.info('[INFO]')} Killing shell process: ${shellProcess.pid}`);Also applies to: 782-782, 985-987
687-698: Standardize logging within this code block.This section mixes the new
[DEBUG]prefix format with emoji-based logs, creating visual inconsistency.Consider standardizing all logs in this block:
- console.log('[DEBUG] User message:', data.command || '[Continue/Resume]'); - console.log('📁 Project:', data.options?.projectPath || 'Unknown'); - console.log('🔄 Session:', data.options?.sessionId ? 'Resume' : 'New'); + console.log(`${c.info('[DEBUG]')} User message: ${c.dim(data.command || '[Continue/Resume]')}`); + console.log(`${c.info('[DEBUG]')} Project: ${c.dim(data.options?.projectPath || 'Unknown')}`); + console.log(`${c.info('[DEBUG]')} Session: ${c.dim(data.options?.sessionId ? 'Resume' : 'New')}`);Similar changes can be applied to lines 694-698 and 801-804.
server/cli.js (1)
44-44: Consider using red color for errors to distinguish from warnings.Both
errorandwarnhelpers use yellow color, making them visually indistinguishable. Conventionally, errors should be red and warnings yellow.Apply this diff:
const colors = { reset: '\x1b[0m', bright: '\x1b[1m', dim: '\x1b[2m', // Foreground colors cyan: '\x1b[36m', green: '\x1b[32m', yellow: '\x1b[33m', + red: '\x1b[31m', blue: '\x1b[34m', magenta: '\x1b[35m', white: '\x1b[37m', gray: '\x1b[90m', }; const c = { info: (text) => `${colors.cyan}${text}${colors.reset}`, ok: (text) => `${colors.green}${text}${colors.reset}`, warn: (text) => `${colors.yellow}${text}${colors.reset}`, - error: (text) => `${colors.yellow}${text}${colors.reset}`, + error: (text) => `${colors.red}${text}${colors.reset}`, tip: (text) => `${colors.blue}${text}${colors.reset}`,Note: If you extract the color helpers to a shared module (as suggested for server/index.js), apply this change there as well.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
.env.example(2 hunks)README.md(2 hunks)package.json(1 hunks)server/claude-sdk.js(2 hunks)server/cli.js(1 hunks)server/database/db.js(2 hunks)server/index.js(19 hunks)src/components/ChatInterface.jsx(3 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
server/database/db.js (2)
server/cli.js (2)
colors(24-37)c(40-48)server/index.js (2)
colors(12-20)c(22-29)
server/index.js (2)
server/cli.js (3)
colors(24-37)c(40-48)__dirname(21-21)server/database/db.js (4)
colors(12-17)c(19-23)appInstallPath(47-47)__dirname(9-9)
🪛 markdownlint-cli2 (0.18.1)
README.md
116-116: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🔇 Additional comments (6)
src/components/ChatInterface.jsx (2)
2606-2608: Leaving isUserScrolledUp to the scroll handler is correctPrevents tug-of-war during streaming. LGTM.
3526-3531: Preserving visual position when auto-scroll is offGood UX; preserves context on new inserts. LGTM.
package.json (1)
8-9: Bin configuration verified and correctly implementedThe server/cli.js file has the required
#!/usr/bin/env nodeshebang and executable permissions (-rwxr-xr-x) are properly set. Both bin entries reference the correct executable, and the "files" field in package.json includes the server directory, ensuring the executable is published to the tarball with permissions preserved.server/index.js (1)
1440-1458: LGTM! Enhanced startup banner improves UX.The colorized startup banner with clear server URL, installation path, and helpful tips significantly improves the developer experience. The reference to the new
cloudcli statuscommand provides good discoverability.server/cli.js (2)
85-137: LGTM! Comprehensive status command aids troubleshooting.The status command provides excellent diagnostic information including version, paths, existence checks, and configuration details. The helpful tips at the end improve discoverability. Good use of color coding to distinguish OK/WARN states.
192-219: LGTM! Well-structured CLI with good command handling.The CLI implementation is clean and user-friendly:
- Clear command routing with switch statement
- Dynamic import for
startcommand avoids unnecessary server initialization- Helpful error message for unknown commands
- Good use of aliases (status/info, help/-h/--help, version/-v/--version)
| // ANSI color codes for terminal output | ||
| const colors = { | ||
| reset: '\x1b[0m', | ||
| bright: '\x1b[1m', | ||
| cyan: '\x1b[36m', | ||
| green: '\x1b[32m', | ||
| yellow: '\x1b[33m', | ||
| blue: '\x1b[34m', | ||
| dim: '\x1b[2m', | ||
| }; | ||
|
|
||
| const c = { | ||
| info: (text) => `${colors.cyan}${text}${colors.reset}`, | ||
| ok: (text) => `${colors.green}${text}${colors.reset}`, | ||
| warn: (text) => `${colors.yellow}${text}${colors.reset}`, | ||
| tip: (text) => `${colors.blue}${text}${colors.reset}`, | ||
| bright: (text) => `${colors.bright}${text}${colors.reset}`, | ||
| dim: (text) => `${colors.dim}${text}${colors.reset}`, | ||
| }; |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
Extract color helpers to a shared module to eliminate duplication.
The colors object and c helper functions are duplicated identically in both server/index.js and server/cli.js. This violates the DRY principle and makes maintenance harder.
Consider creating a shared utility module:
Create a new file server/utils/logger.js:
// ANSI color codes for terminal output
export const colors = {
reset: '\x1b[0m',
bright: '\x1b[1m',
cyan: '\x1b[36m',
green: '\x1b[32m',
yellow: '\x1b[33m',
blue: '\x1b[34m',
dim: '\x1b[2m',
};
export const c = {
info: (text) => `${colors.cyan}${text}${colors.reset}`,
ok: (text) => `${colors.green}${text}${colors.reset}`,
warn: (text) => `${colors.yellow}${text}${colors.reset}`,
tip: (text) => `${colors.blue}${text}${colors.reset}`,
bright: (text) => `${colors.bright}${text}${colors.reset}`,
dim: (text) => `${colors.dim}${text}${colors.reset}`,
};Then import in both files:
-const colors = { ... };
-const c = { ... };
+import { colors, c } from './utils/logger.js';🤖 Prompt for AI Agents
In server/index.js around lines 11 to 29 the ANSI color definitions and helper
functions are duplicated; extract them into a shared module (e.g.,
server/utils/logger.js) that exports the colors object and the c helpers, then
replace the local definitions in server/index.js with an import/require of that
module; also update server/cli.js to import the same module so both files use
the shared implementation and the duplicate code is removed.
Feature/cli commands
Summary by CodeRabbit
New Features
Documentation
Style