mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-01-23 18:07:34 +00:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
104e4260a7 | ||
|
|
8af982e706 | ||
|
|
ea19bd9a00 | ||
|
|
6d4e5017d0 | ||
|
|
9b217ada0d | ||
|
|
04efaa41f6 | ||
|
|
5aef9c683a | ||
|
|
724cb5bb5c | ||
|
|
4e163c8c10 | ||
|
|
b315360f8a | ||
|
|
04821b8ad5 | ||
|
|
19bb741af0 |
48
README.md
48
README.md
@@ -1,6 +1,6 @@
|
|||||||
<div align="center">
|
<div align="center">
|
||||||
<img src="public/logo.svg" alt="Claude Code UI" width="64" height="64">
|
<img src="public/logo.svg" alt="Claude Code UI" width="64" height="64">
|
||||||
<h1>Claude Code UI</h1>
|
<h1>Cloud CLI (aka Claude Code UI)</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
@@ -88,32 +88,31 @@ claude-code-ui
|
|||||||
|
|
||||||
**To restart**: Stop with Ctrl+C and run `claude-code-ui` again.
|
**To restart**: Stop with Ctrl+C and run `claude-code-ui` again.
|
||||||
|
|
||||||
### CLI Commands
|
**To update**:
|
||||||
|
```bash
|
||||||
|
cloudcli update
|
||||||
|
```
|
||||||
|
|
||||||
|
### CLI Usage
|
||||||
|
|
||||||
After global installation, you have access to both `claude-code-ui` and `cloudcli` commands:
|
After global installation, you have access to both `claude-code-ui` and `cloudcli` commands:
|
||||||
|
|
||||||
|
| Command / Option | Short | Description |
|
||||||
|
|------------------|-------|-------------|
|
||||||
|
| `cloudcli` or `claude-code-ui` | | Start the server (default) |
|
||||||
|
| `cloudcli start` | | Start the server explicitly |
|
||||||
|
| `cloudcli status` | | Show configuration and data locations |
|
||||||
|
| `cloudcli update` | | Update to the latest version |
|
||||||
|
| `cloudcli help` | | Show help information |
|
||||||
|
| `cloudcli version` | | Show version information |
|
||||||
|
| `--port <port>` | `-p` | Set server port (default: 3001) |
|
||||||
|
| `--database-path <path>` | | Set custom database location |
|
||||||
|
|
||||||
|
**Examples:**
|
||||||
```bash
|
```bash
|
||||||
# Start the server (default command)
|
cloudcli # Start with defaults
|
||||||
claude-code-ui
|
cloudcli -p 8080 # Start on custom port
|
||||||
cloudcli start
|
cloudcli status # Show current configuration
|
||||||
|
|
||||||
# Show configuration and data locations
|
|
||||||
cloudcli status
|
|
||||||
|
|
||||||
# Show help information
|
|
||||||
cloudcli help
|
|
||||||
|
|
||||||
# Show version
|
|
||||||
cloudcli version
|
|
||||||
```
|
|
||||||
|
|
||||||
**The `cloudcli status` command shows you:**
|
|
||||||
- Installation directory location
|
|
||||||
- Database location (where credentials are stored)
|
|
||||||
- Current configuration (PORT, DATABASE_PATH, etc.)
|
|
||||||
- Claude projects folder location
|
|
||||||
- Configuration file location
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Run as Background Service (Recommended for Production)
|
### Run as Background Service (Recommended for Production)
|
||||||
@@ -134,6 +133,9 @@ pm2 start claude-code-ui --name "claude-code-ui"
|
|||||||
|
|
||||||
# Or using the shorter alias
|
# Or using the shorter alias
|
||||||
pm2 start cloudcli --name "claude-code-ui"
|
pm2 start cloudcli --name "claude-code-ui"
|
||||||
|
|
||||||
|
# Start on a custom port
|
||||||
|
pm2 start cloudcli --name "claude-code-ui" -- --port 8080
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "@siteboon/claude-code-ui",
|
"name": "@siteboon/claude-code-ui",
|
||||||
"version": "1.13.1",
|
"version": "1.13.6",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@siteboon/claude-code-ui",
|
"name": "@siteboon/claude-code-ui",
|
||||||
"version": "1.13.1",
|
"version": "1.13.6",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@anthropic-ai/claude-agent-sdk": "^0.1.29",
|
"@anthropic-ai/claude-agent-sdk": "^0.1.29",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@siteboon/claude-code-ui",
|
"name": "@siteboon/claude-code-ui",
|
||||||
"version": "1.13.1",
|
"version": "1.13.6",
|
||||||
"description": "A web-based UI for Claude Code CLI",
|
"description": "A web-based UI for Claude Code CLI",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "server/index.js",
|
"main": "server/index.js",
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"server/",
|
"server/",
|
||||||
|
"shared/",
|
||||||
"dist/",
|
"dist/",
|
||||||
"README.md"
|
"README.md"
|
||||||
],
|
],
|
||||||
|
|||||||
134
server/cli.js
134
server/cli.js
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
import os from 'os';
|
||||||
import { fileURLToPath } from 'url';
|
import { fileURLToPath } from 'url';
|
||||||
import { dirname } from 'path';
|
import { dirname } from 'path';
|
||||||
|
|
||||||
@@ -115,7 +116,7 @@ function showStatus() {
|
|||||||
console.log(` CONTEXT_WINDOW: ${c.dim(process.env.CONTEXT_WINDOW || '160000 (default)')}`);
|
console.log(` CONTEXT_WINDOW: ${c.dim(process.env.CONTEXT_WINDOW || '160000 (default)')}`);
|
||||||
|
|
||||||
// Claude projects folder
|
// Claude projects folder
|
||||||
const claudeProjectsPath = path.join(process.env.HOME, '.claude', 'projects');
|
const claudeProjectsPath = path.join(os.homedir(), '.claude', 'projects');
|
||||||
const projectsExists = fs.existsSync(claudeProjectsPath);
|
const projectsExists = fs.existsSync(claudeProjectsPath);
|
||||||
console.log(`\n${c.info('[INFO]')} Claude Projects Folder:`);
|
console.log(`\n${c.info('[INFO]')} Claude Projects Folder:`);
|
||||||
console.log(` ${c.dim(claudeProjectsPath)}`);
|
console.log(` ${c.dim(claudeProjectsPath)}`);
|
||||||
@@ -130,10 +131,10 @@ function showStatus() {
|
|||||||
|
|
||||||
console.log('\n' + c.dim('═'.repeat(60)));
|
console.log('\n' + c.dim('═'.repeat(60)));
|
||||||
console.log(`\n${c.tip('[TIP]')} Hints:`);
|
console.log(`\n${c.tip('[TIP]')} Hints:`);
|
||||||
console.log(` ${c.dim('>')} Set DATABASE_PATH env variable to use a custom database location`);
|
console.log(` ${c.dim('>')} Use ${c.bright('cloudcli --port 8080')} to run on a custom port`);
|
||||||
console.log(` ${c.dim('>')} Create .env file in installation directory for persistent config`);
|
console.log(` ${c.dim('>')} Use ${c.bright('cloudcli --database-path /path/to/db')} for custom database`);
|
||||||
console.log(` ${c.dim('>')} Run "claude-code-ui" or "cloudcli start" to start the server`);
|
console.log(` ${c.dim('>')} Run ${c.bright('cloudcli help')} for all options`);
|
||||||
console.log(` ${c.dim('>')} Access the UI at http://localhost:3001 (or custom PORT)\n`);
|
console.log(` ${c.dim('>')} Access the UI at http://localhost:${process.env.PORT || '3001'}\n`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show help
|
// Show help
|
||||||
@@ -144,19 +145,28 @@ function showHelp() {
|
|||||||
╚═══════════════════════════════════════════════════════════════╝
|
╚═══════════════════════════════════════════════════════════════╝
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
claude-code-ui [command]
|
claude-code-ui [command] [options]
|
||||||
cloudcli [command]
|
cloudcli [command] [options]
|
||||||
|
|
||||||
Commands:
|
Commands:
|
||||||
start Start the Claude Code UI server (default)
|
start Start the Claude Code UI server (default)
|
||||||
status Show configuration and data locations
|
status Show configuration and data locations
|
||||||
|
update Update to the latest version
|
||||||
help Show this help information
|
help Show this help information
|
||||||
version Show version information
|
version Show version information
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-p, --port <port> Set server port (default: 3001)
|
||||||
|
--database-path <path> Set custom database location
|
||||||
|
-h, --help Show this help information
|
||||||
|
-v, --version Show version information
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
$ claude-code-ui # Start the server
|
$ cloudcli # Start with defaults
|
||||||
$ cloudcli status # Show configuration
|
$ cloudcli --port 8080 # Start on port 8080
|
||||||
$ cloudcli help # Show help
|
$ cloudcli -p 3000 # Short form for port
|
||||||
|
$ cloudcli start --port 4000 # Explicit start command
|
||||||
|
$ cloudcli status # Show configuration
|
||||||
|
|
||||||
Environment Variables:
|
Environment Variables:
|
||||||
PORT Set server port (default: 3001)
|
PORT Set server port (default: 3001)
|
||||||
@@ -164,11 +174,6 @@ Environment Variables:
|
|||||||
CLAUDE_CLI_PATH Set custom Claude CLI path
|
CLAUDE_CLI_PATH Set custom Claude CLI path
|
||||||
CONTEXT_WINDOW Set context window size (default: 160000)
|
CONTEXT_WINDOW Set context window size (default: 160000)
|
||||||
|
|
||||||
Configuration:
|
|
||||||
Create a .env file in the installation directory to set
|
|
||||||
persistent environment variables. Use 'cloudcli status' to
|
|
||||||
see the installation directory path.
|
|
||||||
|
|
||||||
Documentation:
|
Documentation:
|
||||||
${packageJson.homepage || 'https://github.com/siteboon/claudecodeui'}
|
${packageJson.homepage || 'https://github.com/siteboon/claudecodeui'}
|
||||||
|
|
||||||
@@ -182,16 +187,110 @@ function showVersion() {
|
|||||||
console.log(`${packageJson.version}`);
|
console.log(`${packageJson.version}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compare semver versions, returns true if v1 > v2
|
||||||
|
function isNewerVersion(v1, v2) {
|
||||||
|
const parts1 = v1.split('.').map(Number);
|
||||||
|
const parts2 = v2.split('.').map(Number);
|
||||||
|
for (let i = 0; i < 3; i++) {
|
||||||
|
if (parts1[i] > parts2[i]) return true;
|
||||||
|
if (parts1[i] < parts2[i]) return false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for updates
|
||||||
|
async function checkForUpdates(silent = false) {
|
||||||
|
try {
|
||||||
|
const { execSync } = await import('child_process');
|
||||||
|
const latestVersion = execSync('npm show @siteboon/claude-code-ui version', { encoding: 'utf8' }).trim();
|
||||||
|
const currentVersion = packageJson.version;
|
||||||
|
|
||||||
|
if (isNewerVersion(latestVersion, currentVersion)) {
|
||||||
|
console.log(`\n${c.warn('[UPDATE]')} New version available: ${c.bright(latestVersion)} (current: ${currentVersion})`);
|
||||||
|
console.log(` Run ${c.bright('cloudcli update')} to update\n`);
|
||||||
|
return { hasUpdate: true, latestVersion, currentVersion };
|
||||||
|
} else if (!silent) {
|
||||||
|
console.log(`${c.ok('[OK]')} You are on the latest version (${currentVersion})`);
|
||||||
|
}
|
||||||
|
return { hasUpdate: false, latestVersion, currentVersion };
|
||||||
|
} catch (e) {
|
||||||
|
if (!silent) {
|
||||||
|
console.log(`${c.warn('[WARN]')} Could not check for updates`);
|
||||||
|
}
|
||||||
|
return { hasUpdate: false, error: e.message };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the package
|
||||||
|
async function updatePackage() {
|
||||||
|
try {
|
||||||
|
const { execSync } = await import('child_process');
|
||||||
|
console.log(`${c.info('[INFO]')} Checking for updates...`);
|
||||||
|
|
||||||
|
const { hasUpdate, latestVersion, currentVersion } = await checkForUpdates(true);
|
||||||
|
|
||||||
|
if (!hasUpdate) {
|
||||||
|
console.log(`${c.ok('[OK]')} Already on the latest version (${currentVersion})`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`${c.info('[INFO]')} Updating from ${currentVersion} to ${latestVersion}...`);
|
||||||
|
execSync('npm update -g @siteboon/claude-code-ui', { stdio: 'inherit' });
|
||||||
|
console.log(`${c.ok('[OK]')} Update complete! Restart cloudcli to use the new version.`);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(`${c.error('[ERROR]')} Update failed: ${e.message}`);
|
||||||
|
console.log(`${c.tip('[TIP]')} Try running manually: npm update -g @siteboon/claude-code-ui`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Start the server
|
// Start the server
|
||||||
async function startServer() {
|
async function startServer() {
|
||||||
|
// Check for updates silently on startup
|
||||||
|
checkForUpdates(true);
|
||||||
|
|
||||||
// Import and run the server
|
// Import and run the server
|
||||||
await import('./index.js');
|
await import('./index.js');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parse CLI arguments
|
||||||
|
function parseArgs(args) {
|
||||||
|
const parsed = { command: 'start', options: {} };
|
||||||
|
|
||||||
|
for (let i = 0; i < args.length; i++) {
|
||||||
|
const arg = args[i];
|
||||||
|
|
||||||
|
if (arg === '--port' || arg === '-p') {
|
||||||
|
parsed.options.port = args[++i];
|
||||||
|
} else if (arg.startsWith('--port=')) {
|
||||||
|
parsed.options.port = arg.split('=')[1];
|
||||||
|
} else if (arg === '--database-path') {
|
||||||
|
parsed.options.databasePath = args[++i];
|
||||||
|
} else if (arg.startsWith('--database-path=')) {
|
||||||
|
parsed.options.databasePath = arg.split('=')[1];
|
||||||
|
} else if (arg === '--help' || arg === '-h') {
|
||||||
|
parsed.command = 'help';
|
||||||
|
} else if (arg === '--version' || arg === '-v') {
|
||||||
|
parsed.command = 'version';
|
||||||
|
} else if (!arg.startsWith('-')) {
|
||||||
|
parsed.command = arg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return parsed;
|
||||||
|
}
|
||||||
|
|
||||||
// Main CLI handler
|
// Main CLI handler
|
||||||
async function main() {
|
async function main() {
|
||||||
const args = process.argv.slice(2);
|
const args = process.argv.slice(2);
|
||||||
const command = args[0] || 'start';
|
const { command, options } = parseArgs(args);
|
||||||
|
|
||||||
|
// Apply CLI options to environment variables
|
||||||
|
if (options.port) {
|
||||||
|
process.env.PORT = options.port;
|
||||||
|
}
|
||||||
|
if (options.databasePath) {
|
||||||
|
process.env.DATABASE_PATH = options.databasePath;
|
||||||
|
}
|
||||||
|
|
||||||
switch (command) {
|
switch (command) {
|
||||||
case 'start':
|
case 'start':
|
||||||
@@ -211,6 +310,9 @@ async function main() {
|
|||||||
case '--version':
|
case '--version':
|
||||||
showVersion();
|
showVersion();
|
||||||
break;
|
break;
|
||||||
|
case 'update':
|
||||||
|
await updatePackage();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
console.error(`\n❌ Unknown command: ${command}`);
|
console.error(`\n❌ Unknown command: ${command}`);
|
||||||
console.log(' Run "cloudcli help" for usage information.\n');
|
console.log(' Run "cloudcli help" for usage information.\n');
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ const connectedClients = new Set();
|
|||||||
// Setup file system watcher for Claude projects folder using chokidar
|
// Setup file system watcher for Claude projects folder using chokidar
|
||||||
async function setupProjectsWatcher() {
|
async function setupProjectsWatcher() {
|
||||||
const chokidar = (await import('chokidar')).default;
|
const chokidar = (await import('chokidar')).default;
|
||||||
const claudeProjectsPath = path.join(process.env.HOME, '.claude', 'projects');
|
const claudeProjectsPath = path.join(os.homedir(), '.claude', 'projects');
|
||||||
|
|
||||||
if (projectsWatcher) {
|
if (projectsWatcher) {
|
||||||
projectsWatcher.close();
|
projectsWatcher.close();
|
||||||
@@ -462,7 +462,7 @@ app.post('/api/projects/create', authenticateToken, async (req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Browse filesystem endpoint for project suggestions - uses existing getFileTree
|
// Browse filesystem endpoint for project suggestions - uses existing getFileTree
|
||||||
app.get('/api/browse-filesystem', authenticateToken, async (req, res) => {
|
app.get('/api/browse-filesystem', authenticateToken, async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const { path: dirPath } = req.query;
|
const { path: dirPath } = req.query;
|
||||||
|
|
||||||
@@ -510,9 +510,9 @@ app.get('/api/browse-filesystem', authenticateToken, async (req, res) => {
|
|||||||
suggestions.push(...directories);
|
suggestions.push(...directories);
|
||||||
}
|
}
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
path: targetPath,
|
path: targetPath,
|
||||||
suggestions: suggestions
|
suggestions: suggestions
|
||||||
});
|
});
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -1015,7 +1015,7 @@ function handleShellConnection(ws) {
|
|||||||
name: 'xterm-256color',
|
name: 'xterm-256color',
|
||||||
cols: termCols,
|
cols: termCols,
|
||||||
rows: termRows,
|
rows: termRows,
|
||||||
cwd: process.env.HOME || (os.platform() === 'win32' ? process.env.USERPROFILE : '/'),
|
cwd: os.homedir(),
|
||||||
env: {
|
env: {
|
||||||
...process.env,
|
...process.env,
|
||||||
TERM: 'xterm-256color',
|
TERM: 'xterm-256color',
|
||||||
|
|||||||
@@ -204,7 +204,7 @@ function clearProjectDirectoryCache() {
|
|||||||
|
|
||||||
// Load project configuration file
|
// Load project configuration file
|
||||||
async function loadProjectConfig() {
|
async function loadProjectConfig() {
|
||||||
const configPath = path.join(process.env.HOME, '.claude', 'project-config.json');
|
const configPath = path.join(os.homedir(), '.claude', 'project-config.json');
|
||||||
try {
|
try {
|
||||||
const configData = await fs.readFile(configPath, 'utf8');
|
const configData = await fs.readFile(configPath, 'utf8');
|
||||||
return JSON.parse(configData);
|
return JSON.parse(configData);
|
||||||
@@ -216,7 +216,7 @@ async function loadProjectConfig() {
|
|||||||
|
|
||||||
// Save project configuration file
|
// Save project configuration file
|
||||||
async function saveProjectConfig(config) {
|
async function saveProjectConfig(config) {
|
||||||
const claudeDir = path.join(process.env.HOME, '.claude');
|
const claudeDir = path.join(os.homedir(), '.claude');
|
||||||
const configPath = path.join(claudeDir, 'project-config.json');
|
const configPath = path.join(claudeDir, 'project-config.json');
|
||||||
|
|
||||||
// Ensure the .claude directory exists
|
// Ensure the .claude directory exists
|
||||||
@@ -276,7 +276,7 @@ async function extractProjectDirectory(projectName) {
|
|||||||
return originalPath;
|
return originalPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
const projectDir = path.join(process.env.HOME, '.claude', 'projects', projectName);
|
const projectDir = path.join(os.homedir(), '.claude', 'projects', projectName);
|
||||||
const cwdCounts = new Map();
|
const cwdCounts = new Map();
|
||||||
let latestTimestamp = 0;
|
let latestTimestamp = 0;
|
||||||
let latestCwd = null;
|
let latestCwd = null;
|
||||||
@@ -380,7 +380,7 @@ async function extractProjectDirectory(projectName) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function getProjects() {
|
async function getProjects() {
|
||||||
const claudeDir = path.join(process.env.HOME, '.claude', 'projects');
|
const claudeDir = path.join(os.homedir(), '.claude', 'projects');
|
||||||
const config = await loadProjectConfig();
|
const config = await loadProjectConfig();
|
||||||
const projects = [];
|
const projects = [];
|
||||||
const existingProjects = new Set();
|
const existingProjects = new Set();
|
||||||
@@ -546,7 +546,7 @@ async function getProjects() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function getSessions(projectName, limit = 5, offset = 0) {
|
async function getSessions(projectName, limit = 5, offset = 0) {
|
||||||
const projectDir = path.join(process.env.HOME, '.claude', 'projects', projectName);
|
const projectDir = path.join(os.homedir(), '.claude', 'projects', projectName);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const files = await fs.readdir(projectDir);
|
const files = await fs.readdir(projectDir);
|
||||||
@@ -828,7 +828,7 @@ async function parseJsonlSessions(filePath) {
|
|||||||
|
|
||||||
// Get messages for a specific session with pagination support
|
// Get messages for a specific session with pagination support
|
||||||
async function getSessionMessages(projectName, sessionId, limit = null, offset = 0) {
|
async function getSessionMessages(projectName, sessionId, limit = null, offset = 0) {
|
||||||
const projectDir = path.join(process.env.HOME, '.claude', 'projects', projectName);
|
const projectDir = path.join(os.homedir(), '.claude', 'projects', projectName);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const files = await fs.readdir(projectDir);
|
const files = await fs.readdir(projectDir);
|
||||||
@@ -917,7 +917,7 @@ async function renameProject(projectName, newDisplayName) {
|
|||||||
|
|
||||||
// Delete a session from a project
|
// Delete a session from a project
|
||||||
async function deleteSession(projectName, sessionId) {
|
async function deleteSession(projectName, sessionId) {
|
||||||
const projectDir = path.join(process.env.HOME, '.claude', 'projects', projectName);
|
const projectDir = path.join(os.homedir(), '.claude', 'projects', projectName);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const files = await fs.readdir(projectDir);
|
const files = await fs.readdir(projectDir);
|
||||||
@@ -980,7 +980,7 @@ async function isProjectEmpty(projectName) {
|
|||||||
|
|
||||||
// Delete an empty project
|
// Delete an empty project
|
||||||
async function deleteProject(projectName) {
|
async function deleteProject(projectName) {
|
||||||
const projectDir = path.join(process.env.HOME, '.claude', 'projects', projectName);
|
const projectDir = path.join(os.homedir(), '.claude', 'projects', projectName);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// First check if the project is empty
|
// First check if the project is empty
|
||||||
@@ -1020,7 +1020,7 @@ async function addProjectManually(projectPath, displayName = null) {
|
|||||||
|
|
||||||
// Check if project already exists in config
|
// Check if project already exists in config
|
||||||
const config = await loadProjectConfig();
|
const config = await loadProjectConfig();
|
||||||
const projectDir = path.join(process.env.HOME, '.claude', 'projects', projectName);
|
const projectDir = path.join(os.homedir(), '.claude', 'projects', projectName);
|
||||||
|
|
||||||
if (config[projectName]) {
|
if (config[projectName]) {
|
||||||
throw new Error(`Project already configured for path: ${absolutePath}`);
|
throw new Error(`Project already configured for path: ${absolutePath}`);
|
||||||
|
|||||||
Reference in New Issue
Block a user