Skip to content

Feature/cli commands#223

Merged
viper151 merged 3 commits intomainfrom
feature/cli-commands
Nov 2, 2025
Merged

Feature/cli commands#223
viper151 merged 3 commits intomainfrom
feature/cli-commands

Conversation

@viper151
Copy link
Contributor

@viper151 viper151 commented Nov 2, 2025

Summary by CodeRabbit

  • New Features

    • Added CLI with commands: start, status, help, and version for server management
    • New cloudcli command available after global installation
    • Status command displays installation path, database path, and configuration details
  • Documentation

    • Expanded setup guide with production deployment using PM2
    • Added comprehensive CLI commands reference
    • Enhanced local development installation instructions
  • Style

    • Improved terminal output with standardized, color-coded messages

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.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 2, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

New CLI interface added with start, status, help, and version commands. Package.json bin entries updated to reference server/cli.js for both claude-code-ui and new cloudcli commands. Logging standardized across server components using color-coded output. Environment configuration documentation improved in .env.example. README expanded with CLI usage and operational workflows.

Changes

Cohort / File(s) Summary
Configuration & Documentation
\.env.example, README.md, package.json
Updated .env.example with improved DATABASE_PATH documentation and new CONTEXT_WINDOW setting. README expanded with CLI commands section, production workflow guidance (PM2), and development setup instructions. package.json bin entries updated to reference server/cli.js for both claude-code-ui and new cloudcli commands.
CLI Implementation
server/cli.js
New Node.js CLI module with start, status/info, help, and version commands. Includes environment handling, database/configuration path checking, and colorized console output.
Logging & Output Standardization
server/database/db.js, server/index.js
Standardized logging with ANSI color codes and tagged output ([INFO], [WARN], [ERROR], [DEBUG]). Replaced emoji-based prefixes with consistent formatting. Added environment-aware directory creation in database initialization.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • server/cli.js: Review command handling logic, environment variable parsing, file/directory existence checks, and error handling paths.
  • Logging refactoring: Verify consistent application of new color-coded logging across multiple touch points in server/index.js and server/database/db.js; ensure no information loss from emoji-based messages.
  • bin entry changes: Confirm correct path references and that both claude-code-ui and cloudcli commands properly resolve to the new CLI entry point.

Possibly related PRs

Poem

🐰 A CLI bundled in joy, with commands so neat,
Colors paint logs in hues crisp and sweet,
Status and help at your paw's gentle touch,
Installation whispers—we configure much! 🌟

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title Check ❓ Inconclusive The PR title "Feature/cli commands" does reference a real and significant component of the changeset—a new CLI interface for the tool is indeed the primary change, evident from the new server/cli.js file, package.json bin mappings, and README documentation. However, the title has notable issues: it uses a branch naming convention format ("Feature/") rather than a direct PR title, and "cli commands" is somewhat vague about what specifically was added or changed. A teammate scanning the PR history would understand that CLI-related changes were made, but the title doesn't clearly convey the scope—whether this is purely documentation, a new tool, a restructuring, or all of the above. Consider revising the title to be more descriptive and direct, such as "Add CLI interface for server management and cloudcli command" or "Implement CLI commands for Claude Code UI". This would provide greater clarity about what was added while maintaining conciseness, making it easier for reviewers and future developers to understand the primary purpose of this changeset.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1c95c59 and 18ea4a1.

📒 Files selected for processing (1)
  • package.json (1 hunks)

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 camelCase

Some 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 sends

Avoid 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 radix

Use 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 return

Return 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 overrides

The SDK options are valid for v0.1.29 as confirmed in the docs. However, the code currently hardcodes systemPrompt and settingSources without checking the options parameter, which is inconsistent with how model is 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 guard

Add 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 permissions

Create 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/O

Either 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 example

Helps 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.db
README.md (1)

90-110: Specify languages on fenced code blocks

Several code blocks lack a language marker (MD040). Use bash for CLI examples.

-```
+```bash
 npx @siteboon/claude-code-ui
Apply 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 error and warn helpers 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

📥 Commits

Reviewing files that changed from the base of the PR and between 72e97c4 and 1c95c59.

📒 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 correct

Prevents tug-of-war during streaming. LGTM.


3526-3531: Preserving visual position when auto-scroll is off

Good UX; preserves context on new inserts. LGTM.

package.json (1)

8-9: Bin configuration verified and correctly implemented

The server/cli.js file has the required #!/usr/bin/env node shebang 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 status command 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 start command avoids unnecessary server initialization
  • Helpful error message for unknown commands
  • Good use of aliases (status/info, help/-h/--help, version/-v/--version)

Comment on lines +11 to +29
// 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}`,
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ 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.

@viper151 viper151 merged commit a5813e6 into main Nov 2, 2025
1 check was pending
@viper151 viper151 deleted the feature/cli-commands branch November 2, 2025 07:59
DumoeDss pushed a commit to atelierai/claudecodeui that referenced this pull request Nov 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant