mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-02-24 17:47:37 +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.
|
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)
|
## [1.19.0](https://github.com/siteboon/claudecodeui/compare/v1.18.2...v1.19.0) (2026-02-23)
|
||||||
|
|
||||||
### New Features
|
### New Features
|
||||||
|
|||||||
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.19.0",
|
"version": "1.20.1",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@siteboon/claude-code-ui",
|
"name": "@siteboon/claude-code-ui",
|
||||||
"version": "1.19.0",
|
"version": "1.20.1",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@siteboon/claude-code-ui",
|
"name": "@siteboon/claude-code-ui",
|
||||||
"version": "1.19.0",
|
"version": "1.20.1",
|
||||||
"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",
|
||||||
@@ -32,6 +32,7 @@
|
|||||||
"typecheck": "tsc --noEmit -p tsconfig.json",
|
"typecheck": "tsc --noEmit -p tsconfig.json",
|
||||||
"start": "npm run build && npm run server",
|
"start": "npm run build && npm run server",
|
||||||
"release": "./release.sh",
|
"release": "./release.sh",
|
||||||
|
"prepublishOnly": "npm run build",
|
||||||
"postinstall": "node scripts/fix-node-pty.js"
|
"postinstall": "node scripts/fix-node-pty.js"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"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
|
// Create database connection
|
||||||
const db = new Database(DB_PATH);
|
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) => {
|
updateLastLogin: (userId) => {
|
||||||
try {
|
try {
|
||||||
db.prepare('UPDATE users SET last_login = CURRENT_TIMESTAMP WHERE id = ?').run(userId);
|
db.prepare('UPDATE users SET last_login = CURRENT_TIMESTAMP WHERE id = ?').run(userId);
|
||||||
} catch (err) {
|
} 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 __filename = fileURLToPath(import.meta.url);
|
||||||
const __dirname = dirname(__filename);
|
const __dirname = dirname(__filename);
|
||||||
|
|
||||||
|
const installMode = fs.existsSync(path.join(__dirname, '..', '.git')) ? 'git' : 'npm';
|
||||||
|
|
||||||
// ANSI color codes for terminal output
|
// ANSI color codes for terminal output
|
||||||
const colors = {
|
const colors = {
|
||||||
reset: '\x1b[0m',
|
reset: '\x1b[0m',
|
||||||
@@ -333,7 +335,8 @@ app.use(express.urlencoded({ limit: '50mb', extended: true }));
|
|||||||
app.get('/health', (req, res) => {
|
app.get('/health', (req, res) => {
|
||||||
res.json({
|
res.json({
|
||||||
status: 'ok',
|
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);
|
console.log('Starting system update from directory:', projectRoot);
|
||||||
|
|
||||||
// Run the update command
|
// Run the update command based on install mode
|
||||||
const updateCommand = 'git checkout main && git pull && npm install';
|
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], {
|
const child = spawn('sh', ['-c', updateCommand], {
|
||||||
cwd: projectRoot,
|
cwd: installMode === 'git' ? projectRoot : os.homedir(),
|
||||||
env: process.env
|
env: process.env
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
// Load environment variables from .env before other imports execute.
|
// Load environment variables from .env before other imports execute.
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
|
import os from 'os';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { fileURLToPath } from 'url';
|
import { fileURLToPath } from 'url';
|
||||||
import { dirname } from 'path';
|
import { dirname } from 'path';
|
||||||
@@ -22,3 +23,7 @@ try {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log('No .env file found or error reading it:', e.message);
|
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
|
// Generate token
|
||||||
const token = generateToken(user);
|
const token = generateToken(user);
|
||||||
|
|
||||||
// Update last login
|
db.prepare('COMMIT').run();
|
||||||
|
|
||||||
|
// Update last login (non-fatal, outside transaction)
|
||||||
userDb.updateLastLogin(user.id);
|
userDb.updateLastLogin(user.id);
|
||||||
|
|
||||||
db.prepare('COMMIT').run();
|
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
success: true,
|
success: true,
|
||||||
user: { id: user.id, username: user.username },
|
user: { id: user.id, username: user.username },
|
||||||
|
|||||||
@@ -63,5 +63,5 @@ export const CODEX_MODELS = {
|
|||||||
{ value: 'o4-mini', label: 'O4-mini' }
|
{ 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 { useTranslation } from "react-i18next";
|
||||||
import { authenticatedFetch } from "../../utils/api";
|
import { authenticatedFetch } from "../../utils/api";
|
||||||
import { ReleaseInfo } from "../../types/sharedTypes";
|
import { ReleaseInfo } from "../../types/sharedTypes";
|
||||||
|
import type { InstallMode } from "../../hooks/useVersionCheck";
|
||||||
|
|
||||||
interface VersionUpgradeModalProps {
|
interface VersionUpgradeModalProps {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
@@ -9,6 +10,7 @@ interface VersionUpgradeModalProps {
|
|||||||
releaseInfo: ReleaseInfo | null;
|
releaseInfo: ReleaseInfo | null;
|
||||||
currentVersion: string;
|
currentVersion: string;
|
||||||
latestVersion: string | null;
|
latestVersion: string | null;
|
||||||
|
installMode: InstallMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function VersionUpgradeModal({
|
export default function VersionUpgradeModal({
|
||||||
@@ -16,9 +18,13 @@ export default function VersionUpgradeModal({
|
|||||||
onClose,
|
onClose,
|
||||||
releaseInfo,
|
releaseInfo,
|
||||||
currentVersion,
|
currentVersion,
|
||||||
latestVersion
|
latestVersion,
|
||||||
|
installMode
|
||||||
}: VersionUpgradeModalProps) {
|
}: VersionUpgradeModalProps) {
|
||||||
const { t } = useTranslation('common');
|
const { t } = useTranslation('common');
|
||||||
|
const upgradeCommand = installMode === 'npm'
|
||||||
|
? t('versionUpdate.npmUpgradeCommand')
|
||||||
|
: 'git checkout main && git pull && npm install';
|
||||||
const [isUpdating, setIsUpdating] = useState(false);
|
const [isUpdating, setIsUpdating] = useState(false);
|
||||||
const [updateOutput, setUpdateOutput] = useState('');
|
const [updateOutput, setUpdateOutput] = useState('');
|
||||||
const [updateError, setUpdateError] = 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>
|
<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">
|
<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">
|
<code className="text-sm text-gray-800 dark:text-gray-200 font-mono">
|
||||||
git checkout main && git pull && npm install
|
{upgradeCommand}
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
<p className="text-xs text-gray-600 dark:text-gray-400">
|
<p className="text-xs text-gray-600 dark:text-gray-400">
|
||||||
@@ -171,7 +177,7 @@ export default function VersionUpgradeModal({
|
|||||||
<>
|
<>
|
||||||
<button
|
<button
|
||||||
onClick={() => {
|
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"
|
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) {
|
}: SidebarProps) {
|
||||||
const { t } = useTranslation(['sidebar', 'common']);
|
const { t } = useTranslation(['sidebar', 'common']);
|
||||||
const { isPWA } = useDeviceSettings({ trackMobile: false });
|
const { isPWA } = useDeviceSettings({ trackMobile: false });
|
||||||
const { updateAvailable, latestVersion, currentVersion, releaseInfo } = useVersionCheck(
|
const { updateAvailable, latestVersion, currentVersion, releaseInfo, installMode } = useVersionCheck(
|
||||||
'siteboon',
|
'siteboon',
|
||||||
'claudecodeui',
|
'claudecodeui',
|
||||||
);
|
);
|
||||||
@@ -200,6 +200,7 @@ function Sidebar({
|
|||||||
releaseInfo={releaseInfo}
|
releaseInfo={releaseInfo}
|
||||||
currentVersion={currentVersion}
|
currentVersion={currentVersion}
|
||||||
latestVersion={latestVersion}
|
latestVersion={latestVersion}
|
||||||
|
installMode={installMode}
|
||||||
t={t}
|
t={t}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import Settings from '../../../Settings';
|
|||||||
import VersionUpgradeModal from '../../../modals/VersionUpgradeModal';
|
import VersionUpgradeModal from '../../../modals/VersionUpgradeModal';
|
||||||
import type { Project } from '../../../../types/app';
|
import type { Project } from '../../../../types/app';
|
||||||
import type { ReleaseInfo } from '../../../../types/sharedTypes';
|
import type { ReleaseInfo } from '../../../../types/sharedTypes';
|
||||||
|
import type { InstallMode } from '../../../../hooks/useVersionCheck';
|
||||||
import { normalizeProjectForSettings } from '../../utils/utils';
|
import { normalizeProjectForSettings } from '../../utils/utils';
|
||||||
import type { DeleteProjectConfirmation, SessionDeleteConfirmation, SettingsProject } from '../../types/types';
|
import type { DeleteProjectConfirmation, SessionDeleteConfirmation, SettingsProject } from '../../types/types';
|
||||||
|
|
||||||
@@ -30,6 +31,7 @@ type SidebarModalsProps = {
|
|||||||
releaseInfo: ReleaseInfo | null;
|
releaseInfo: ReleaseInfo | null;
|
||||||
currentVersion: string;
|
currentVersion: string;
|
||||||
latestVersion: string | null;
|
latestVersion: string | null;
|
||||||
|
installMode: InstallMode;
|
||||||
t: TFunction;
|
t: TFunction;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -65,6 +67,7 @@ export default function SidebarModals({
|
|||||||
releaseInfo,
|
releaseInfo,
|
||||||
currentVersion,
|
currentVersion,
|
||||||
latestVersion,
|
latestVersion,
|
||||||
|
installMode,
|
||||||
t,
|
t,
|
||||||
}: SidebarModalsProps) {
|
}: SidebarModalsProps) {
|
||||||
// Settings expects project identity/path fields to be present for dropdown labels and local-scope MCP config.
|
// 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}
|
releaseInfo={releaseInfo}
|
||||||
currentVersion={currentVersion}
|
currentVersion={currentVersion}
|
||||||
latestVersion={latestVersion}
|
latestVersion={latestVersion}
|
||||||
|
installMode={installMode}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -21,10 +21,28 @@ const compareVersions = (v1: string, v2: string) => {
|
|||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type InstallMode = 'git' | 'npm';
|
||||||
|
|
||||||
export const useVersionCheck = (owner: string, repo: string) => {
|
export const useVersionCheck = (owner: string, repo: string) => {
|
||||||
const [updateAvailable, setUpdateAvailable] = useState(false);
|
const [updateAvailable, setUpdateAvailable] = useState(false);
|
||||||
const [latestVersion, setLatestVersion] = useState<string | null>(null);
|
const [latestVersion, setLatestVersion] = useState<string | null>(null);
|
||||||
const [releaseInfo, setReleaseInfo] = useState<ReleaseInfo | 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(() => {
|
useEffect(() => {
|
||||||
const checkVersion = async () => {
|
const checkVersion = async () => {
|
||||||
@@ -66,5 +84,5 @@ export const useVersionCheck = (owner: string, repo: string) => {
|
|||||||
return () => clearInterval(interval);
|
return () => clearInterval(interval);
|
||||||
}, [owner, repo]);
|
}, [owner, repo]);
|
||||||
|
|
||||||
return { updateAvailable, latestVersion, currentVersion: version, releaseInfo };
|
return { updateAvailable, latestVersion, currentVersion: version, releaseInfo, installMode };
|
||||||
};
|
};
|
||||||
@@ -200,6 +200,7 @@
|
|||||||
"viewFullRelease": "View full release",
|
"viewFullRelease": "View full release",
|
||||||
"updateProgress": "Update Progress:",
|
"updateProgress": "Update Progress:",
|
||||||
"manualUpgrade": "Manual upgrade:",
|
"manualUpgrade": "Manual upgrade:",
|
||||||
|
"npmUpgradeCommand": "npm install -g @siteboon/claude-code-ui@latest",
|
||||||
"manualUpgradeHint": "Or click \"Update Now\" to run the update automatically.",
|
"manualUpgradeHint": "Or click \"Update Now\" to run the update automatically.",
|
||||||
"updateCompleted": "Update completed successfully!",
|
"updateCompleted": "Update completed successfully!",
|
||||||
"restartServer": "Please restart the server to apply changes.",
|
"restartServer": "Please restart the server to apply changes.",
|
||||||
|
|||||||
@@ -200,6 +200,7 @@
|
|||||||
"viewFullRelease": "リリース全文を見る",
|
"viewFullRelease": "リリース全文を見る",
|
||||||
"updateProgress": "アップデートの進捗:",
|
"updateProgress": "アップデートの進捗:",
|
||||||
"manualUpgrade": "手動アップグレード:",
|
"manualUpgrade": "手動アップグレード:",
|
||||||
|
"npmUpgradeCommand": "npm install -g @siteboon/claude-code-ui@latest",
|
||||||
"manualUpgradeHint": "または「今すぐ更新」をクリックして自動的にアップデートを実行できます。",
|
"manualUpgradeHint": "または「今すぐ更新」をクリックして自動的にアップデートを実行できます。",
|
||||||
"updateCompleted": "アップデートが完了しました!",
|
"updateCompleted": "アップデートが完了しました!",
|
||||||
"restartServer": "変更を適用するにはサーバーを再起動してください。",
|
"restartServer": "変更を適用するにはサーバーを再起動してください。",
|
||||||
|
|||||||
@@ -200,6 +200,7 @@
|
|||||||
"viewFullRelease": "전체 릴리스 보기",
|
"viewFullRelease": "전체 릴리스 보기",
|
||||||
"updateProgress": "업데이트 진행 상황:",
|
"updateProgress": "업데이트 진행 상황:",
|
||||||
"manualUpgrade": "수동 업그레이드:",
|
"manualUpgrade": "수동 업그레이드:",
|
||||||
|
"npmUpgradeCommand": "npm install -g @siteboon/claude-code-ui@latest",
|
||||||
"manualUpgradeHint": "또는 \"지금 업데이트\"를 클릭하여 자동으로 업데이트합니다.",
|
"manualUpgradeHint": "또는 \"지금 업데이트\"를 클릭하여 자동으로 업데이트합니다.",
|
||||||
"updateCompleted": "업데이트가 완료되었습니다!",
|
"updateCompleted": "업데이트가 완료되었습니다!",
|
||||||
"restartServer": "변경사항을 적용하려면 서버를 재시작하세요.",
|
"restartServer": "변경사항을 적용하려면 서버를 재시작하세요.",
|
||||||
|
|||||||
@@ -200,6 +200,7 @@
|
|||||||
"viewFullRelease": "查看完整发布",
|
"viewFullRelease": "查看完整发布",
|
||||||
"updateProgress": "更新进度:",
|
"updateProgress": "更新进度:",
|
||||||
"manualUpgrade": "手动升级:",
|
"manualUpgrade": "手动升级:",
|
||||||
|
"npmUpgradeCommand": "npm install -g @siteboon/claude-code-ui@latest",
|
||||||
"manualUpgradeHint": "或点击'立即更新'以自动运行更新。",
|
"manualUpgradeHint": "或点击'立即更新'以自动运行更新。",
|
||||||
"updateCompleted": "更新成功完成!",
|
"updateCompleted": "更新成功完成!",
|
||||||
"restartServer": "请重启服务器以应用更改。",
|
"restartServer": "请重启服务器以应用更改。",
|
||||||
|
|||||||
Reference in New Issue
Block a user