mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-02-24 09:37:38 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4f6ff9260d | ||
|
|
49061bc7a3 | ||
|
|
50e097d4ac | ||
|
|
f986004319 | ||
|
|
f488a346ef | ||
|
|
82efac4704 | ||
|
|
81697d0e73 |
13
CHANGELOG.md
13
CHANGELOG.md
@@ -3,6 +3,19 @@
|
||||
All notable changes to CloudCLI UI will be documented in this file.
|
||||
|
||||
|
||||
## [1.20.1](https://github.com/siteboon/claudecodeui/compare/v1.19.1...v1.20.1) (2026-02-23)
|
||||
|
||||
### New Features
|
||||
|
||||
* implement install mode detection and update commands in version upgrade process ([f986004](https://github.com/siteboon/claudecodeui/commit/f986004319207b068431f9f6adf338a8ce8decfc))
|
||||
* migrate legacy database to new location and improve last login update handling ([50e097d](https://github.com/siteboon/claudecodeui/commit/50e097d4ac498aa9f1803ef3564843721833dc19))
|
||||
|
||||
## [1.19.1](https://github.com/siteboon/claudecodeui/compare/v1.19.0...v1.19.1) (2026-02-23)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* add prepublishOnly script to build before publishing ([82efac4](https://github.com/siteboon/claudecodeui/commit/82efac4704cab11ed8d1a05fe84f41312140b223))
|
||||
|
||||
## [1.19.0](https://github.com/siteboon/claudecodeui/compare/v1.18.2...v1.19.0) (2026-02-23)
|
||||
|
||||
### New Features
|
||||
|
||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@siteboon/claude-code-ui",
|
||||
"version": "1.19.0",
|
||||
"version": "1.20.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@siteboon/claude-code-ui",
|
||||
"version": "1.19.0",
|
||||
"version": "1.20.1",
|
||||
"hasInstallScript": true,
|
||||
"license": "GPL-3.0",
|
||||
"dependencies": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@siteboon/claude-code-ui",
|
||||
"version": "1.19.0",
|
||||
"version": "1.20.1",
|
||||
"description": "A web-based UI for Claude Code CLI",
|
||||
"type": "module",
|
||||
"main": "server/index.js",
|
||||
@@ -32,6 +32,7 @@
|
||||
"typecheck": "tsc --noEmit -p tsconfig.json",
|
||||
"start": "npm run build && npm run server",
|
||||
"release": "./release.sh",
|
||||
"prepublishOnly": "npm run build",
|
||||
"postinstall": "node scripts/fix-node-pty.js"
|
||||
},
|
||||
"keywords": [
|
||||
|
||||
@@ -40,6 +40,22 @@ if (process.env.DATABASE_PATH) {
|
||||
}
|
||||
}
|
||||
|
||||
// As part of 1.19.2 we are introducing a new location for auth.db. The below handles exisitng moving legacy database from install directory to new location
|
||||
const LEGACY_DB_PATH = path.join(__dirname, 'auth.db');
|
||||
if (DB_PATH !== LEGACY_DB_PATH && !fs.existsSync(DB_PATH) && fs.existsSync(LEGACY_DB_PATH)) {
|
||||
try {
|
||||
fs.copyFileSync(LEGACY_DB_PATH, DB_PATH);
|
||||
console.log(`[MIGRATION] Copied database from ${LEGACY_DB_PATH} to ${DB_PATH}`);
|
||||
for (const suffix of ['-wal', '-shm']) {
|
||||
if (fs.existsSync(LEGACY_DB_PATH + suffix)) {
|
||||
fs.copyFileSync(LEGACY_DB_PATH + suffix, DB_PATH + suffix);
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn(`[MIGRATION] Could not copy legacy database: ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Create database connection
|
||||
const db = new Database(DB_PATH);
|
||||
|
||||
@@ -128,12 +144,12 @@ const userDb = {
|
||||
}
|
||||
},
|
||||
|
||||
// Update last login time
|
||||
// Update last login time (non-fatal — logged but not thrown)
|
||||
updateLastLogin: (userId) => {
|
||||
try {
|
||||
db.prepare('UPDATE users SET last_login = CURRENT_TIMESTAMP WHERE id = ?').run(userId);
|
||||
} catch (err) {
|
||||
throw err;
|
||||
console.warn('Failed to update last login:', err.message);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@ import { dirname } from 'path';
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
|
||||
const installMode = fs.existsSync(path.join(__dirname, '..', '.git')) ? 'git' : 'npm';
|
||||
|
||||
// ANSI color codes for terminal output
|
||||
const colors = {
|
||||
reset: '\x1b[0m',
|
||||
@@ -333,7 +335,8 @@ app.use(express.urlencoded({ limit: '50mb', extended: true }));
|
||||
app.get('/health', (req, res) => {
|
||||
res.json({
|
||||
status: 'ok',
|
||||
timestamp: new Date().toISOString()
|
||||
timestamp: new Date().toISOString(),
|
||||
installMode
|
||||
});
|
||||
});
|
||||
|
||||
@@ -410,11 +413,13 @@ app.post('/api/system/update', authenticateToken, async (req, res) => {
|
||||
|
||||
console.log('Starting system update from directory:', projectRoot);
|
||||
|
||||
// Run the update command
|
||||
const updateCommand = 'git checkout main && git pull && npm install';
|
||||
// Run the update command based on install mode
|
||||
const updateCommand = installMode === 'git'
|
||||
? 'git checkout main && git pull && npm install'
|
||||
: 'npm install -g @siteboon/claude-code-ui@latest';
|
||||
|
||||
const child = spawn('sh', ['-c', updateCommand], {
|
||||
cwd: projectRoot,
|
||||
cwd: installMode === 'git' ? projectRoot : os.homedir(),
|
||||
env: process.env
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// Load environment variables from .env before other imports execute.
|
||||
import fs from 'fs';
|
||||
import os from 'os';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { dirname } from 'path';
|
||||
@@ -22,3 +23,7 @@ try {
|
||||
} catch (e) {
|
||||
console.log('No .env file found or error reading it:', e.message);
|
||||
}
|
||||
|
||||
if (!process.env.DATABASE_PATH) {
|
||||
process.env.DATABASE_PATH = path.join(os.homedir(), '.cloudcli', 'auth.db');
|
||||
}
|
||||
|
||||
@@ -53,11 +53,11 @@ router.post('/register', async (req, res) => {
|
||||
// Generate token
|
||||
const token = generateToken(user);
|
||||
|
||||
// Update last login
|
||||
db.prepare('COMMIT').run();
|
||||
|
||||
// Update last login (non-fatal, outside transaction)
|
||||
userDb.updateLastLogin(user.id);
|
||||
|
||||
db.prepare('COMMIT').run();
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
user: { id: user.id, username: user.username },
|
||||
|
||||
@@ -63,5 +63,5 @@ export const CODEX_MODELS = {
|
||||
{ value: 'o4-mini', label: 'O4-mini' }
|
||||
],
|
||||
|
||||
DEFAULT: 'gpt-5.2'
|
||||
DEFAULT: 'gpt-5.3-codex'
|
||||
};
|
||||
|
||||
@@ -2,6 +2,7 @@ import { useCallback, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { authenticatedFetch } from "../../utils/api";
|
||||
import { ReleaseInfo } from "../../types/sharedTypes";
|
||||
import type { InstallMode } from "../../hooks/useVersionCheck";
|
||||
|
||||
interface VersionUpgradeModalProps {
|
||||
isOpen: boolean;
|
||||
@@ -9,6 +10,7 @@ interface VersionUpgradeModalProps {
|
||||
releaseInfo: ReleaseInfo | null;
|
||||
currentVersion: string;
|
||||
latestVersion: string | null;
|
||||
installMode: InstallMode;
|
||||
}
|
||||
|
||||
export default function VersionUpgradeModal({
|
||||
@@ -16,9 +18,13 @@ export default function VersionUpgradeModal({
|
||||
onClose,
|
||||
releaseInfo,
|
||||
currentVersion,
|
||||
latestVersion
|
||||
latestVersion,
|
||||
installMode
|
||||
}: VersionUpgradeModalProps) {
|
||||
const { t } = useTranslation('common');
|
||||
const upgradeCommand = installMode === 'npm'
|
||||
? t('versionUpdate.npmUpgradeCommand')
|
||||
: 'git checkout main && git pull && npm install';
|
||||
const [isUpdating, setIsUpdating] = useState(false);
|
||||
const [updateOutput, setUpdateOutput] = useState('');
|
||||
const [updateError, setUpdateError] = useState('');
|
||||
@@ -150,7 +156,7 @@ export default function VersionUpgradeModal({
|
||||
<h3 className="text-sm font-medium text-gray-900 dark:text-white">{t('versionUpdate.manualUpgrade')}</h3>
|
||||
<div className="bg-gray-100 dark:bg-gray-800 rounded-lg p-3 border">
|
||||
<code className="text-sm text-gray-800 dark:text-gray-200 font-mono">
|
||||
git checkout main && git pull && npm install
|
||||
{upgradeCommand}
|
||||
</code>
|
||||
</div>
|
||||
<p className="text-xs text-gray-600 dark:text-gray-400">
|
||||
@@ -171,7 +177,7 @@ export default function VersionUpgradeModal({
|
||||
<>
|
||||
<button
|
||||
onClick={() => {
|
||||
navigator.clipboard.writeText('git checkout main && git pull && npm install');
|
||||
navigator.clipboard.writeText(upgradeCommand);
|
||||
}}
|
||||
className="flex-1 px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 bg-gray-100 dark:bg-gray-700 hover:bg-gray-200 dark:hover:bg-gray-600 rounded-md transition-colors"
|
||||
>
|
||||
|
||||
@@ -38,7 +38,7 @@ function Sidebar({
|
||||
}: SidebarProps) {
|
||||
const { t } = useTranslation(['sidebar', 'common']);
|
||||
const { isPWA } = useDeviceSettings({ trackMobile: false });
|
||||
const { updateAvailable, latestVersion, currentVersion, releaseInfo } = useVersionCheck(
|
||||
const { updateAvailable, latestVersion, currentVersion, releaseInfo, installMode } = useVersionCheck(
|
||||
'siteboon',
|
||||
'claudecodeui',
|
||||
);
|
||||
@@ -200,6 +200,7 @@ function Sidebar({
|
||||
releaseInfo={releaseInfo}
|
||||
currentVersion={currentVersion}
|
||||
latestVersion={latestVersion}
|
||||
installMode={installMode}
|
||||
t={t}
|
||||
/>
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import Settings from '../../../Settings';
|
||||
import VersionUpgradeModal from '../../../modals/VersionUpgradeModal';
|
||||
import type { Project } from '../../../../types/app';
|
||||
import type { ReleaseInfo } from '../../../../types/sharedTypes';
|
||||
import type { InstallMode } from '../../../../hooks/useVersionCheck';
|
||||
import { normalizeProjectForSettings } from '../../utils/utils';
|
||||
import type { DeleteProjectConfirmation, SessionDeleteConfirmation, SettingsProject } from '../../types/types';
|
||||
|
||||
@@ -30,6 +31,7 @@ type SidebarModalsProps = {
|
||||
releaseInfo: ReleaseInfo | null;
|
||||
currentVersion: string;
|
||||
latestVersion: string | null;
|
||||
installMode: InstallMode;
|
||||
t: TFunction;
|
||||
};
|
||||
|
||||
@@ -65,6 +67,7 @@ export default function SidebarModals({
|
||||
releaseInfo,
|
||||
currentVersion,
|
||||
latestVersion,
|
||||
installMode,
|
||||
t,
|
||||
}: SidebarModalsProps) {
|
||||
// Settings expects project identity/path fields to be present for dropdown labels and local-scope MCP config.
|
||||
@@ -199,6 +202,7 @@ export default function SidebarModals({
|
||||
releaseInfo={releaseInfo}
|
||||
currentVersion={currentVersion}
|
||||
latestVersion={latestVersion}
|
||||
installMode={installMode}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -21,10 +21,28 @@ const compareVersions = (v1: string, v2: string) => {
|
||||
return 0;
|
||||
};
|
||||
|
||||
export type InstallMode = 'git' | 'npm';
|
||||
|
||||
export const useVersionCheck = (owner: string, repo: string) => {
|
||||
const [updateAvailable, setUpdateAvailable] = useState(false);
|
||||
const [latestVersion, setLatestVersion] = useState<string | null>(null);
|
||||
const [releaseInfo, setReleaseInfo] = useState<ReleaseInfo | null>(null);
|
||||
const [installMode, setInstallMode] = useState<InstallMode>('git');
|
||||
|
||||
useEffect(() => {
|
||||
const fetchInstallMode = async () => {
|
||||
try {
|
||||
const response = await fetch('/health');
|
||||
const data = await response.json();
|
||||
if (data.installMode === 'npm' || data.installMode === 'git') {
|
||||
setInstallMode(data.installMode);
|
||||
}
|
||||
} catch {
|
||||
// Default to git on error
|
||||
}
|
||||
};
|
||||
fetchInstallMode();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const checkVersion = async () => {
|
||||
@@ -66,5 +84,5 @@ export const useVersionCheck = (owner: string, repo: string) => {
|
||||
return () => clearInterval(interval);
|
||||
}, [owner, repo]);
|
||||
|
||||
return { updateAvailable, latestVersion, currentVersion: version, releaseInfo };
|
||||
return { updateAvailable, latestVersion, currentVersion: version, releaseInfo, installMode };
|
||||
};
|
||||
@@ -200,6 +200,7 @@
|
||||
"viewFullRelease": "View full release",
|
||||
"updateProgress": "Update Progress:",
|
||||
"manualUpgrade": "Manual upgrade:",
|
||||
"npmUpgradeCommand": "npm install -g @siteboon/claude-code-ui@latest",
|
||||
"manualUpgradeHint": "Or click \"Update Now\" to run the update automatically.",
|
||||
"updateCompleted": "Update completed successfully!",
|
||||
"restartServer": "Please restart the server to apply changes.",
|
||||
|
||||
@@ -200,6 +200,7 @@
|
||||
"viewFullRelease": "リリース全文を見る",
|
||||
"updateProgress": "アップデートの進捗:",
|
||||
"manualUpgrade": "手動アップグレード:",
|
||||
"npmUpgradeCommand": "npm install -g @siteboon/claude-code-ui@latest",
|
||||
"manualUpgradeHint": "または「今すぐ更新」をクリックして自動的にアップデートを実行できます。",
|
||||
"updateCompleted": "アップデートが完了しました!",
|
||||
"restartServer": "変更を適用するにはサーバーを再起動してください。",
|
||||
|
||||
@@ -200,6 +200,7 @@
|
||||
"viewFullRelease": "전체 릴리스 보기",
|
||||
"updateProgress": "업데이트 진행 상황:",
|
||||
"manualUpgrade": "수동 업그레이드:",
|
||||
"npmUpgradeCommand": "npm install -g @siteboon/claude-code-ui@latest",
|
||||
"manualUpgradeHint": "또는 \"지금 업데이트\"를 클릭하여 자동으로 업데이트합니다.",
|
||||
"updateCompleted": "업데이트가 완료되었습니다!",
|
||||
"restartServer": "변경사항을 적용하려면 서버를 재시작하세요.",
|
||||
|
||||
@@ -200,6 +200,7 @@
|
||||
"viewFullRelease": "查看完整发布",
|
||||
"updateProgress": "更新进度:",
|
||||
"manualUpgrade": "手动升级:",
|
||||
"npmUpgradeCommand": "npm install -g @siteboon/claude-code-ui@latest",
|
||||
"manualUpgradeHint": "或点击'立即更新'以自动运行更新。",
|
||||
"updateCompleted": "更新成功完成!",
|
||||
"restartServer": "请重启服务器以应用更改。",
|
||||
|
||||
Reference in New Issue
Block a user