chore: update CI to use pnpm and minor fixes

- Update GitHub Actions release workflow to use pnpm instead of npm
- Add pnpm/action-setup@v4 for pnpm installation
- Use pnpm install --frozen-lockfile for CI builds

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
coso
2026-01-12 08:20:14 +08:00
co-authored by Claude Opus 4.5
parent 862ce44172
commit 4b2a9e0873
3 changed files with 47 additions and 12 deletions
+6 -1
View File
@@ -52,6 +52,11 @@ jobs:
with:
node-version: '20'
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 9
- name: Install Linux dependencies
if: matrix.platform == 'ubuntu-22.04'
run: |
@@ -72,7 +77,7 @@ jobs:
cache-all-crates: true
- name: Install frontend dependencies
run: npm ci
run: pnpm install --frozen-lockfile
- name: Build Tauri app
uses: tauri-apps/tauri-action@v0
+11 -5
View File
@@ -172,7 +172,14 @@ export function TerminalPanel({
return true;
}, []);
// 使用 ref 存储回调,避免回调变化导致终端重建
const onStatusChangeRef = useRef(onStatusChange);
useEffect(() => {
onStatusChangeRef.current = onStatusChange;
}, [onStatusChange]);
// 当 sessionId 变化时,创建 TermWrap
// 注意:只依赖 sessionId 和 handleTerminalKeydown,避免回调变化导致终端重建
useEffect(() => {
const container = connectElemRef.current;
if (!container || !sessionId) {
@@ -183,10 +190,9 @@ export function TerminalPanel({
return;
}
// 销毁旧的 TermWrap
// 如果已有 TermWrap 且 sessionId 相同,不重建
if (termWrapRef.current) {
termWrapRef.current.dispose();
termWrapRef.current = null;
return;
}
// 清空容器
@@ -194,7 +200,7 @@ export function TerminalPanel({
// 创建新的 TermWrap
const termWrap = new TermWrap(sessionId, container, {
onStatusChange: (status) => onStatusChange?.(status),
onStatusChange: (status) => onStatusChangeRef.current?.(status),
themeName: loadThemePreference(),
fontSize: loadFontSizePreference(),
keydownHandler: handleTerminalKeydown,
@@ -218,7 +224,7 @@ export function TerminalPanel({
termWrap.dispose();
rszObs.disconnect();
};
}, [sessionId, handleTerminalKeydown, onStatusChange]);
}, [sessionId, handleTerminalKeydown]);
// 组件卸载时关闭会话
useEffect(() => {
+30 -6
View File
@@ -59,6 +59,7 @@ import {
type ThemeName,
loadThemePreference,
loadFontSizePreference,
getTheme,
} from "@/lib/terminal/themes";
import "./terminal.css";
@@ -170,6 +171,13 @@ export const TerminalView: React.FC<TerminalViewProps> = ({
// Refs
const connectElemRef = useRef<HTMLDivElement>(null);
const termWrapRef = useRef<TermWrap | null>(null);
// 使用 ref 存储回调,避免回调变化导致终端重建
const onStatusChangeRef = useRef(onStatusChange);
// 更新回调 ref
useEffect(() => {
onStatusChangeRef.current = onStatusChange;
}, [onStatusChange]);
// 初始化主题和字体大小
useEffect(() => {
@@ -299,16 +307,16 @@ export const TerminalView: React.FC<TerminalViewProps> = ({
// ============================================================================
// TermWrap 生命周期管理
// 注意:只依赖 blockId,避免主题/字体/回调变化导致终端重建
// ============================================================================
useEffect(() => {
const container = connectElemRef.current;
if (!container) return;
// 销毁旧的 TermWrap
// 如果已有 TermWrap,不重建
if (termWrapRef.current) {
termWrapRef.current.dispose();
termWrapRef.current = null;
return;
}
// 清空容器
@@ -317,7 +325,7 @@ export const TerminalView: React.FC<TerminalViewProps> = ({
// 创建新的 TermWrap
const termWrap = new TermWrap(blockId, container, {
onStatusChange: (status) => {
onStatusChange?.(status);
onStatusChangeRef.current?.(status);
},
themeName: themeName as ThemeName,
fontSize: fontSize,
@@ -340,11 +348,27 @@ export const TerminalView: React.FC<TerminalViewProps> = ({
return () => {
termWrap.dispose();
termWrapRef.current = null;
rszObs.disconnect();
};
// 注意:handleTerminalKeydown 使用 useCallback 且无依赖,不会导致重新创建
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [blockId, themeName, fontSize, onStatusChange]);
}, [blockId]);
// 主题变化时更新终端(不重建)
useEffect(() => {
if (termWrapRef.current?.terminal) {
const themeConfig = getTheme(themeName as ThemeName);
termWrapRef.current.terminal.options.theme = themeConfig;
}
}, [themeName]);
// 字体大小变化时更新终端(不重建)
useEffect(() => {
if (termWrapRef.current?.terminal) {
termWrapRef.current.terminal.options.fontSize = fontSize;
termWrapRef.current.handleResize_debounced();
}
}, [fontSize]);
// 清理 TermViewModel
useEffect(() => {