Переглянути джерело

chore(deps): 更新 npm/cargo 依赖并对齐 Node 24 LTS

同步 semver 范围内依赖与 Cargo.lock,新增 .nvmrc,
将 @types/node 与 CI/build workflow 固定为 Node 24。

Co-authored-by: Cursor <cursoragent@cursor.com>
darknessomi 1 місяць тому
батько
коміт
02032745e6

+ 1 - 1
.github/workflows/build.yml

@@ -116,7 +116,7 @@ jobs:
       - name: Setup Node.js
         uses: actions/setup-node@v4
         with:
-          node-version: 20
+          node-version: 24
           cache: npm
 
       - name: Install frontend dependencies

+ 1 - 1
.github/workflows/ci.yml

@@ -66,7 +66,7 @@ jobs:
       - name: Setup Node.js
         uses: actions/setup-node@v4
         with:
-          node-version: 20
+          node-version: 24
 
       - name: Install frontend dependencies
         run: npm install

+ 1 - 0
.nvmrc

@@ -0,0 +1 @@
+24

+ 15 - 15
analytics-worker/package-lock.json

@@ -8,9 +8,9 @@
       "name": "qmai-analytics-worker",
       "version": "1.0.0",
       "devDependencies": {
-        "@cloudflare/workers-types": "^4.20241127.0",
-        "typescript": "^5.7.0",
-        "wrangler": "^3.99.0"
+        "@cloudflare/workers-types": "^4.20260702.1",
+        "typescript": "^5.9.3",
+        "wrangler": "^3.114.17"
       }
     },
     "node_modules/@cloudflare/kv-asset-handler": {
@@ -128,9 +128,9 @@
       }
     },
     "node_modules/@cloudflare/workers-types": {
-      "version": "4.20260531.1",
-      "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20260531.1.tgz",
-      "integrity": "sha512-7DybhbX12n+mVgJEDvm9W/jjqpaUIczg+RWj1Hua9nGEG+pNJnT+yZj1JKENrbdyuGWx3OFEgUCNFcGJN86Dvg==",
+      "version": "4.20260702.1",
+      "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20260702.1.tgz",
+      "integrity": "sha512-mOhf5TUEB1m2vPrxtqoIGfz0fUC9xyxRDx5gWHy5s+OCo6dcV+g7wI1R7gYCMFohhqF/2y2xeKVwMwCJjfn/WA==",
       "dev": true,
       "license": "MIT OR Apache-2.0"
     },
@@ -148,9 +148,9 @@
       }
     },
     "node_modules/@emnapi/runtime": {
-      "version": "1.10.0",
-      "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz",
-      "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==",
+      "version": "1.11.3",
+      "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.3.tgz",
+      "integrity": "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==",
       "dev": true,
       "license": "MIT",
       "optional": true,
@@ -1170,9 +1170,9 @@
       }
     },
     "node_modules/exsolve": {
-      "version": "1.0.8",
-      "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.8.tgz",
-      "integrity": "sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==",
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.1.1.tgz",
+      "integrity": "sha512-9U/jZUgjnSGyntRr6y5Muu1MJcwFl6kPu7k8qLF0IMNfLqvw0NZ4nnVDq0RVoZ0RvCyumib4Ez3KYrVfilrw+g==",
       "dev": true,
       "license": "MIT"
     },
@@ -1338,9 +1338,9 @@
       }
     },
     "node_modules/semver": {
-      "version": "7.8.1",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz",
-      "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==",
+      "version": "7.8.5",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz",
+      "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==",
       "dev": true,
       "license": "ISC",
       "optional": true,

+ 3 - 3
analytics-worker/package.json

@@ -9,8 +9,8 @@
     "db:migrate": "wrangler d1 execute qmai-analytics-db --remote --file=./schema.sql"
   },
   "devDependencies": {
-    "wrangler": "^3.99.0",
-    "@cloudflare/workers-types": "^4.20241127.0",
-    "typescript": "^5.7.0"
+    "@cloudflare/workers-types": "^4.20260702.1",
+    "typescript": "^5.9.3",
+    "wrangler": "^3.114.17"
   }
 }

Різницю між файлами не показано, бо вона завелика
+ 303 - 316
package-lock.json


+ 28 - 28
package.json

@@ -18,23 +18,23 @@
     "build:github-release": "powershell -NoProfile -ExecutionPolicy Bypass -Command \"if (-not $env:TAURI_SIGNING_PRIVATE_KEY_PATH) { $env:TAURI_SIGNING_PRIVATE_KEY_PATH = Join-Path $env:USERPROFILE '.tauri\\qmai-updater.key' }; if (-not (Test-Path $env:TAURI_SIGNING_PRIVATE_KEY_PATH)) { throw '缺少 TAURI_SIGNING_PRIVATE_KEY_PATH 对应的签名私钥文件' }; if ($null -eq $env:TAURI_SIGNING_PRIVATE_KEY_PASSWORD) { $env:TAURI_SIGNING_PRIVATE_KEY_PASSWORD = '' }; $env:CARGO_PROFILE_RELEASE_LTO='false'; $env:CARGO_PROFILE_RELEASE_CODEGEN_UNITS='16'; $env:CARGO_PROFILE_RELEASE_OPT_LEVEL='1'; npx tauri build; if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }; node scripts/build-portable.mjs; if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }; node scripts/prepare-github-release.mjs\""
   },
   "dependencies": {
-    "@base-ui/react": "^1.6.0",
+    "@base-ui/react": "^1.7.0",
     "@dnd-kit/core": "^6.3.1",
     "@dnd-kit/sortable": "^8.0.0",
     "@dnd-kit/utilities": "^3.2.2",
-    "@fontsource-variable/geist": "^5.2.9",
-    "@milkdown/kit": "^7.20.0",
+    "@fontsource-variable/geist": "^5.3.0",
+    "@milkdown/kit": "^7.22.0",
     "@milkdown/plugin-math": "^7.5.9",
-    "@milkdown/react": "^7.21.2",
-    "@milkdown/theme-nord": "^7.21.2",
+    "@milkdown/react": "^7.22.0",
+    "@milkdown/theme-nord": "^7.22.0",
     "@react-sigma/core": "^5.0.6",
     "@sigma/edge-curve": "^3.1.0",
-    "@tailwindcss/vite": "^4.3.2",
+    "@tailwindcss/vite": "^4.3.3",
     "@tauri-apps/api": "^2.11.1",
-    "@tauri-apps/plugin-dialog": "^2.7.1",
+    "@tauri-apps/plugin-dialog": "^2.7.2",
     "@tauri-apps/plugin-http": "^2.5.9",
     "@tauri-apps/plugin-opener": "^2.5.4",
-    "@tauri-apps/plugin-store": "^2.4.3",
+    "@tauri-apps/plugin-store": "^2.4.4",
     "@tauri-apps/plugin-updater": "^2.10.1",
     "@types/js-yaml": "^4.0.9",
     "class-variance-authority": "^0.7.1",
@@ -42,40 +42,40 @@
     "graphology": "^0.26.0",
     "graphology-communities-louvain": "^2.0.2",
     "graphology-layout-forceatlas2": "^0.10.1",
-    "i18next": "^26.3.4",
-    "js-yaml": "^4.3.0",
+    "i18next": "^26.3.6",
+    "js-yaml": "^4.3.1",
     "jsonrepair": "^3.15.0",
     "katex": "^0.16.47",
-    "lucide-react": "^1.23.0",
-    "mermaid": "^11.16.0",
-    "opencc-js": "^1.4.0",
-    "pangu": "^9.0.0",
-    "pinyin-pro": "^3.28.1",
-    "react": "^19.2.7",
-    "react-dom": "^19.2.7",
-    "react-i18next": "^17.0.8",
+    "lucide-react": "^1.28.0",
+    "mermaid": "^11.16.1",
+    "opencc-js": "^1.4.1",
+    "pangu": "^9.1.0",
+    "pinyin-pro": "^3.28.2",
+    "react": "^19.2.8",
+    "react-dom": "^19.2.8",
+    "react-i18next": "^17.0.11",
     "react-markdown": "^10.1.0",
-    "react-resizable-panels": "^4.12.1",
+    "react-resizable-panels": "^4.12.2",
     "rehype-katex": "^7.0.1",
     "remark-gfm": "^4.0.1",
     "remark-math": "^6.0.0",
-    "shadcn": "^4.13.0",
+    "shadcn": "^4.16.1",
     "sigma": "^3.0.3",
     "tailwind-merge": "^3.6.0",
-    "tailwindcss": "^4.3.1",
+    "tailwindcss": "^4.3.3",
     "tw-animate-css": "^1.4.0",
     "zustand": "^5.0.14"
   },
   "devDependencies": {
     "@tauri-apps/cli": "^2.11.4",
-    "@types/node": "^25.9.4",
-    "@types/react": "^19.2.17",
-    "@types/react-dom": "^19.2.3",
-    "@vitejs/plugin-react": "^6.0.3",
-    "fast-check": "^4.8.0",
+    "@types/node": "^24.13.3",
+    "@types/react": "^19.2.18",
+    "@types/react-dom": "^19.2.4",
+    "@vitejs/plugin-react": "^6.0.5",
+    "fast-check": "^4.9.0",
     "jsdom": "^29.1.1",
     "typescript": "^5.9.3",
-    "vite": "^8.1.3",
-    "vitest": "^4.1.9"
+    "vite": "^8.2.0",
+    "vitest": "^4.1.10"
   }
 }

Різницю між файлами не показано, бо вона завелика
+ 196 - 159
src-tauri/Cargo.lock


+ 3 - 3
src-tauri/Cargo.toml

@@ -21,14 +21,14 @@ tauri-plugin-opener = "2"
 serde = { version = "1", features = ["derive"] }
 serde_json = "1"
 chrono = { version = "0.4", features = ["clock"] }
-tauri-plugin-dialog = "2.7.1"
+tauri-plugin-dialog = "2.7.2"
 tauri-plugin-updater = "2"
 pdfium-render = "0.9"
-tauri-plugin-store = "2.4.2"
+tauri-plugin-store = "2.4.4"
 tauri-plugin-http = { version = "2", features = ["unsafe-headers"] }
 zip = "2"
 calamine = "0.34.0"
-docx-rs = "0.4.20"
+docx-rs = "0.4.22"
 cfb = "0.7.3"
 encoding_rs = "0.8.35"
 lancedb = "0.27.2"

+ 5 - 8
src/components/sources/outline-chat-panel.tsx

@@ -90,7 +90,6 @@ import {
 } from "@/lib/novel/character-save-extractor";
 import {
   buildCharacterAgentSystemPrompt,
-  buildCharacterAgentUserPrompt,
   buildCharacterAgentPlans,
   buildCharacterPlannerSystemPrompt,
   buildCharacterPlannerUserPrompt,
@@ -187,7 +186,6 @@ import {
   buildIntentAnalysisPrompt,
   parseIntentClarity,
   shouldAutoFollowUpGeneration,
-  stripStructuredMarkers,
   type IntentClarityResult,
 } from "@/lib/novel/outline-intent-clarity";
 import {
@@ -206,8 +204,6 @@ import {
 } from "@/lib/conversation-create-guard";
 import { outlineConversationRunRegistry } from "@/lib/conversation-run-registry";
 import { toast } from "@/lib/toast";
-import { finalizeStructuredMarkdownMessage } from "@/lib/novel/markdown-quality-finalizer";
-import { repairMarkdownFormatWithAi } from "@/lib/novel/markdown-quality-ai-repair";
 import {
   type OutlineWorkflowStage,
   canTransitionOutlineWorkflow,
@@ -1611,7 +1607,7 @@ export function OutlineChatPanel({ onClose }: { onClose: () => void }) {
   );
 
   const handleAutoSaveOutlineRequests = useCallback(
-    async (conversationId: string, assistantContent: string, canApply: () => boolean) => {
+    async (_conversationId: string, assistantContent: string, canApply: () => boolean) => {
       if (!project || !canApply()) return;
       const parsed = parseOutlineSaveRequests(assistantContent);
       if (parsed.requests.length === 0) {
@@ -2035,7 +2031,7 @@ export function OutlineChatPanel({ onClose }: { onClose: () => void }) {
           );
           let runText = "";
           let runReasoningContent = "";
-          let agentError: Error | null = null;
+          const agentErrorBox: { current: Error | null } = { current: null };
           if (optionsForRun.statusText) {
             if (isCurrentRun()) setStreamingContent(capturedConvId, optionsForRun.statusText);
           }
@@ -2065,7 +2061,7 @@ export function OutlineChatPanel({ onClose }: { onClose: () => void }) {
               onToolResult: () => {},
               onToolError: () => {},
               onToolEvent: (event) => {
-                if (!isCurrentRun()) return { started: true, sent: false };
+                if (!isCurrentRun()) return;
                 if (!historyPlan.showToolProcess) {
                   hiddenToolCalls = applyAgentToolEvent(hiddenToolCalls, event);
                   return;
@@ -2080,13 +2076,14 @@ export function OutlineChatPanel({ onClose }: { onClose: () => void }) {
               },
               onDone: () => {},
               onError: (error) => {
-                agentError = error;
+                agentErrorBox.current = error;
               },
             },
             controller.signal,
           );
           providerUsage = addLlmUsage(providerUsage, record.usage);
           allToolCalls.push(...record.toolCalls);
+          const agentError = agentErrorBox.current;
           const errMsg = agentError?.message ?? "";
           const isLengthTruncated = errMsg.includes("输出被截断") || errMsg.includes("最大输出 token");
           if (agentError && !isLengthTruncated) throw agentError;

+ 1 - 1
src/lib/foreshadowing-cleanup-runner.ts

@@ -457,7 +457,7 @@ export async function listInvalidSnapshots(
 }
 
 export async function deleteInvalidSnapshots(
-  projectPath: string,
+  _projectPath: string,
   paths: string[],
   options: { onLog?: CleanupLogFn } = {},
 ): Promise<number> {

+ 2 - 2
src/lib/outline-save.ts

@@ -188,7 +188,7 @@ function detectOutlineContentType(content: string): "chapter-outline" | "charact
   return "outline"
 }
 
-function extractChapterOutlineTitle(content: string, lines: string[]): string | null {
+function extractChapterOutlineTitle(content: string, _lines: string[]): string | null {
   const chapterMatch = content.match(/第\s*(\d{1,4}|[一二三四五六七八九十百千万]+)\s*章\s*([^\n#::,,。.]*)/)
   if (chapterMatch) {
     const chapterNum = chapterMatch[1]
@@ -227,7 +227,7 @@ function extractCharacterTitle(content: string, lines: string[]): string | null
   return null
 }
 
-function extractVolumeOutlineTitle(content: string, lines: string[]): string | null {
+function extractVolumeOutlineTitle(content: string, _lines: string[]): string | null {
   const volumeMatch = content.match(/第\s*(\d+|[一二三四五六七八九十百千万]+)\s*卷\s*([^\n#::,,。.]*)/)
   if (volumeMatch) {
     const volumeNum = volumeMatch[1]

Деякі файли не було показано, через те що забагато файлів було змінено