Skip to content

fix(skill): surface per-platform install failures + handle UNKNOWN symlink errors (#93)#124

Merged
legeling merged 2 commits into
legeling:mainfrom
TuTouPower:fix/issue-93-symlink-install
May 10, 2026
Merged

fix(skill): surface per-platform install failures + handle UNKNOWN symlink errors (#93)#124
legeling merged 2 commits into
legeling:mainfrom
TuTouPower:fix/issue-93-symlink-install

Conversation

@TuTouPower
Copy link
Copy Markdown
Contributor

@TuTouPower TuTouPower commented May 9, 2026

Summary

Fixes #93. A user reported that installing a skill via Symlink mode silently produced no install. Investigation found two layered problems:

  1. Silent failures in the batch installer. `batchInstall` in `use-skill-platform.ts` caught individual per-platform install errors, logged them to the console, and then discarded them. The caller only ever saw `{ successCount, totalCount }`, so the green "Installation successful" toast still showed even when a platform had failed. The user had no way to know what went wrong.

  2. Windows symlink errors can be `UNKNOWN`, not `EPERM`. On Windows without Developer Mode / admin, `fs.symlink` can fail with code `UNKNOWN`. The existing fallback-to-copy path only handled `EPERM` / `EACCES` / `ENOTSUP`, so `UNKNOWN` escaped the fallback, propagated as an unexplained throw, and was then silently discarded by problem (1).

Changes

File What
`use-skill-platform.ts` `BatchInstallResult` now carries a `failures: BatchInstallFailure[]` list. Each caught error becomes a structured entry with the `platformId` and a localizable reason.
`SkillFullDetailPage.tsx` The `batchInstall` handler renders any failures as an explicit error toast, one platform per line, so the user can immediately see which platforms failed and why.
`skill-installer-platform.ts` `installSkillMdSymlink` also falls back to copy on code `UNKNOWN`. When no fallback applies, it throws an error message that includes the skill name, platform, error code, and original reason. Root cause attached via `.cause` for diagnostics.
`tests/unit/main/skill-installer-platform.test.ts` New regression tests cover both the `UNKNOWN` fallback path and the richer error thrown for non-fallback failures.
`src/renderer/i18n/locales/*.json` New `skill.installPartialFailure` key across all 7 locales.

Verification

  • `pnpm lint` → clean
  • `pnpm test -- --run tests/unit/main/skill-installer-platform.test.ts tests/unit/services/skill-platform-sync.test.ts` → 7/7 passing

Notes

  • No IPC contract change: the IPC boundary still passes the raw error message; the structured failure list is built client-side.
  • The symlink → copy fallback is still transparent when it succeeds (no toast for that case), matching prior behavior. Only explicit failures surface in the UI.

Summary by CodeRabbit

  • 新功能

    • 批量安装技能时,会在成功提示外显示按平台汇总的失败列表,并在安装未全部成功时保持安装对话框打开以便用户处理。
  • 错误修复

    • 提供更清晰的安装失败错误提示,包含技能与平台相关信息以便诊断。
    • 扩展了安装故障的回退处理,覆盖更多平台/权限相关的失败场景。
  • 国际化

    • 为安装失败详情添加多语言提示(英文、简体、繁体、日文、法文、德文、西班牙文)。

Review Change Stack

…mlink errors (legeling#93)

Users trying to install skills via Symlink reported that the skill
was 'not installed' without any error. Investigation showed two
problems layered on top of each other:

1. In `batchInstall` (use-skill-platform.ts), individual per-platform
   install failures were caught, console.error'd, and then silently
   dropped. The caller only got `{ successCount, totalCount }`, so a
   partial failure still produced a green 'installation successful'
   toast that did not mention which platforms failed or why.

2. On Windows without Developer Mode / admin rights, `fs.symlink`
   permission failures can surface as code 'UNKNOWN' rather than the
   expected 'EPERM'. The existing fallback-to-copy path only handled
   EPERM / EACCES / ENOTSUP, so 'UNKNOWN' escaped the fallback and
   propagated up as an unexplained throw — the user saw no install.

### Changes

- apps/desktop/src/renderer/components/skill/use-skill-platform.ts:
  `BatchInstallResult` now carries a `failures: BatchInstallFailure[]`
  list. Each caught error becomes a structured entry with the
  platformId and a localizable reason.
- apps/desktop/src/renderer/components/skill/SkillFullDetailPage.tsx:
  The `batchInstall` handler now renders any failures as an explicit
  error toast, one platform per line, so the user can tell immediately
  which platforms failed and what the underlying error was.
- apps/desktop/src/main/services/skill-installer-platform.ts:
  `installSkillMdSymlink` also falls back to copy on code 'UNKNOWN',
  and when no fallback applies it now throws an error message that
  includes the skill name, platform, error code, and original reason.
  The root cause is attached as `.cause` for diagnostics.
- apps/desktop/tests/unit/main/skill-installer-platform.test.ts:
  new regression tests cover both the UNKNOWN fallback path and the
  richer error thrown for non-fallback failures.
- i18n: new `skill.installPartialFailure` key across all 7 locales.

### Verification

- `pnpm lint` → clean
- `pnpm test -- --run tests/unit/main/skill-installer-platform.test.ts tests/unit/services/skill-platform-sync.test.ts` → 7/7 passing

Fixes legeling#93
@vercel
Copy link
Copy Markdown

vercel Bot commented May 9, 2026

@TuTouPower is attempting to deploy a commit to the legeling's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 9, 2026

📝 Walkthrough

通览

该 PR 增强了技能安装失败的错误处理和报告。后端现在支持 UNKNOWN 符号链接错误作为回退情况,并为所有非回退错误生成可操作的错误消息。前端批量安装功能现在跟踪每个平台的失败原因,在 UI 中显示失败摘要,并为 7 种语言添加了国际化支持。

变更

技能安装失败处理与报告

层级 / 文件 摘要
数据结构
apps/desktop/src/renderer/components/skill/use-skill-platform.ts
新增 BatchInstallFailure 接口和扩展 BatchInstallResult,添加 failures 数组以跟踪每个平台的失败 platformIdreason
符号链接错误处理
apps/desktop/src/main/services/skill-installer-platform.ts
installSkillMdSymlink 新增对 UNKNOWN 错误代码的支持作为回退情况;对非回退错误改为抛出格式化错误消息(包含技能名称、平台名称、原始消息和错误代码),并在 .cause 中保留原始错误。
批量安装函数
apps/desktop/src/renderer/components/skill/use-skill-platform.ts
batchInstall 函数初始化 failures 数组,在安装每个平台时捕获失败原因,返回包含 failures 的完整 BatchInstallResult(包括早返回路径)。
UI 失败展示
apps/desktop/src/renderer/components/skill/SkillFullDetailPage.tsx, apps/desktop/src/renderer/components/skill/SkillQuickInstall.tsx
检查 result.failures 后显示错误 toast,通过 availablePlatforms 获取平台显示名称,使用 i18n 键 skill.installPartialFailure 显示失败摘要;QuickInstall 在存在失败时不自动关闭模态窗。
国际化
apps/desktop/src/renderer/i18n/locales/{de,en,es,fr,ja,zh-TW,zh}.json
在 7 种语言中新增 skill.installPartialFailure 翻译键,用于报告批量安装中的部分平台失败;新增 skill.installFailureRow 用于每平台失败行。
测试
apps/desktop/tests/unit/main/skill-installer-platform.test.ts
新增两个单元测试:验证 fs.symlink 因 UNKNOWN 错误失败时回退到复制安装;验证因非回退错误失败时返回包含 "Symlink install failed for" 的可操作错误消息。

🎯 3 (中等) | ⏱️ ~25 分钟

Sequence Diagram

sequenceDiagram
  participant User
  participant UI
  participant batchInstall
  participant installer
  participant fs
  User->>UI: 发起批量安装
  UI->>batchInstall: 调用 batchInstall(platforms)
  loop 每个平台
    batchInstall->>installer: installSkill(platformId)
    installer->>fs: fs.symlink(...)
    alt symlink success
      fs-->>installer: success
    else symlink error (EPERM/EACCES/ENOTSUP/UNKNOWN)
      fs-->>installer: error
      installer->>installer: fallbackInstall -> writeFile SKILL.md
    else other symlink error
      fs-->>installer: error
      installer-->>batchInstall: throw formatted Error (.cause = original)
    end
    installer-->>batchInstall: result or error
  end
  batchInstall-->>UI: {successCount,totalCount,failures}
  alt failures.length > 0
    UI->>User: 显示 partial failure toast (skill.installPartialFailure)
  else
    UI->>User: 显示 success toast
  end
Loading

🐰 符号链接重重困难
我来支持 UNKNOWN 的名号
平台失败各显其理
错误消息更友好明了
多语并肩把信息带到手上

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 标题准确概括了PR的主要改动:修复技能安装时的每平台失败显示和处理UNKNOWN符号链接错误。
Linked Issues check ✅ Passed PR解决了#93的所有编码需求:处理UNKNOWN错误代码的符号链接失败 [#93],为用户显示每平台安装失败信息 [#93]。
Out of Scope Changes check ✅ Passed 所有改动都在#93的范围内,包括符号链接错误处理、失败信息展示、国际化支持和单元测试。

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@qodo-code-review
Copy link
Copy Markdown

Review Summary by Qodo

Surface per-platform install failures and handle UNKNOWN symlink errors

🐞 Bug fix

Grey Divider

Walkthroughs

Description
• Surface per-platform install failures in batch installer UI
• Handle Windows UNKNOWN symlink errors with copy fallback
• Add structured failure tracking to BatchInstallResult
• Display platform-specific error messages in error toast
• Add i18n key for partial installation failures
Diagram
flowchart LR
  A["Symlink install attempt"] -->|UNKNOWN error| B["Fallback to copy"]
  A -->|Other errors| C["Throw formatted error"]
  C --> D["BatchInstallFailure captured"]
  D --> E["Error toast with platform details"]
  B --> F["Silent success"]
Loading

Grey Divider

File Changes

1. apps/desktop/src/main/services/skill-installer-platform.ts 🐞 Bug fix +27/-2

Handle UNKNOWN symlink errors and improve error messages

apps/desktop/src/main/services/skill-installer-platform.ts


2. apps/desktop/src/renderer/components/skill/use-skill-platform.ts ✨ Enhancement +30/-3

Add failures list to BatchInstallResult interface

apps/desktop/src/renderer/components/skill/use-skill-platform.ts


3. apps/desktop/src/renderer/components/skill/SkillFullDetailPage.tsx 🐞 Bug fix +20/-0

Display per-platform failures in error toast

apps/desktop/src/renderer/components/skill/SkillFullDetailPage.tsx


View more (8)
4. apps/desktop/tests/unit/main/skill-installer-platform.test.ts 🧪 Tests +31/-0

Add regression tests for UNKNOWN error handling

apps/desktop/tests/unit/main/skill-installer-platform.test.ts


5. apps/desktop/src/renderer/i18n/locales/en.json 📝 Documentation +1/-0

Add installPartialFailure translation key

apps/desktop/src/renderer/i18n/locales/en.json


6. apps/desktop/src/renderer/i18n/locales/de.json 📝 Documentation +1/-0

Add installPartialFailure translation key

apps/desktop/src/renderer/i18n/locales/de.json


7. apps/desktop/src/renderer/i18n/locales/es.json 📝 Documentation +1/-0

Add installPartialFailure translation key

apps/desktop/src/renderer/i18n/locales/es.json


8. apps/desktop/src/renderer/i18n/locales/fr.json 📝 Documentation +1/-0

Add installPartialFailure translation key

apps/desktop/src/renderer/i18n/locales/fr.json


9. apps/desktop/src/renderer/i18n/locales/ja.json 📝 Documentation +1/-0

Add installPartialFailure translation key

apps/desktop/src/renderer/i18n/locales/ja.json


10. apps/desktop/src/renderer/i18n/locales/zh-TW.json 📝 Documentation +1/-0

Add installPartialFailure translation key

apps/desktop/src/renderer/i18n/locales/zh-TW.json


11. apps/desktop/src/renderer/i18n/locales/zh.json 📝 Documentation +1/-0

Add installPartialFailure translation key

apps/desktop/src/renderer/i18n/locales/zh.json


Grey Divider

Qodo Logo

@qodo-code-review
Copy link
Copy Markdown

qodo-code-review Bot commented May 9, 2026

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider


Action required

1. Chinese comments in TS files ✓ Resolved 📘 Rule violation ⚙ Maintainability
Description
Chinese characters were added in code comments outside the locale JSON files. This violates the
requirement to prohibit hardcoded Chinese outside src/renderer/i18n/locales/* and can create
inconsistent localization practices.
Code

apps/desktop/src/main/services/skill-installer-platform.ts[R399-401]

+    // Windows 需要 admin 或 Developer Mode 才能创建符号链接;macOS/Linux 在只读
+    // 文件系统上常见 EACCES。这些场景下回落到复制安装是合理的,并记录结构化
+    // 警告以便渲染端(#93)在"部分失败"提示中说明实际采用了复制。
Evidence
PR Compliance ID 2 prohibits hardcoded Chinese characters outside locale JSON files; the PR adds
Chinese comment text in multiple non-locale .ts/.tsx/.test.ts files.

AGENTS.md
apps/desktop/src/main/services/skill-installer-platform.ts[399-401]
apps/desktop/src/renderer/components/skill/SkillFullDetailPage.tsx[458-458]
apps/desktop/src/renderer/components/skill/use-skill-platform.ts[201-202]
apps/desktop/tests/unit/main/skill-installer-platform.test.ts[121-122]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Chinese characters were added in comments in non-locale source files, which violates the "no hardcoded Chinese outside locale JSON" requirement.
## Issue Context
This PR introduced bilingual comments in main, renderer, and test files.
## Fix Focus Areas
- apps/desktop/src/main/services/skill-installer-platform.ts[399-401]
- apps/desktop/src/renderer/components/skill/SkillFullDetailPage.tsx[458-458]
- apps/desktop/src/renderer/components/skill/use-skill-platform.ts[201-202]
- apps/desktop/tests/unit/main/skill-installer-platform.test.ts[121-122]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. installPartialFailure toast concatenated ✓ Resolved 📘 Rule violation ≡ Correctness
Description
The new partial-failure toast is assembled via template-literal concatenation and hardcoded
formatting (e.g., \n, : ) instead of i18n interpolation. This violates the requirement to avoid
concatenating translated strings and to use i18n interpolation for dynamic content.
Code

apps/desktop/src/renderer/components/skill/SkillFullDetailPage.tsx[R466-471]

+            return `${label}: ${failure.reason}`;
+          })
+          .join("\n");
+        showToast(
+          `${t("skill.installPartialFailure", "Some platforms could not be installed")}\n${summary}`,
+          "error",
Evidence
PR Compliance ID 4 requires i18n interpolation rather than concatenation; the toast message is built
by concatenating t("skill.installPartialFailure", ...) with \n and a manually formatted summary
line (${label}: ${failure.reason}).

AGENTS.md
apps/desktop/src/renderer/components/skill/SkillFullDetailPage.tsx[466-471]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The partial-failure toast uses string concatenation/template literals to combine translated text with dynamic details (and includes hardcoded formatting like `: ` and `\n`). This should be expressed via i18n keys with interpolation.
## Issue Context
Current code builds `summary` via `${label}: ${failure.reason}` and then does `${t("skill.installPartialFailure", ...)}\n${summary}`.
## Fix Focus Areas
- apps/desktop/src/renderer/components/skill/SkillFullDetailPage.tsx[460-472]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Quick install hides failures ✓ Resolved 🐞 Bug ≡ Correctness
Description
SkillQuickInstall.handleInstall ignores BatchInstallResult.failures, so per-platform install
errors remain silent in the quick-install flow. If at least one platform succeeds, the modal closes
even when other selected platforms failed to install.
Code

apps/desktop/src/renderer/components/skill/use-skill-platform.ts[R197-214]

      } catch (error) {
-          console.error(`Failed to install "${skill.name}" to ${platformId}:`, error);
+          // Surface per-platform failures to the caller so the UI can show
+          // the user exactly which platforms failed and why (#93). Still
+          // log for diagnostics.
+          // 把每个平台的错误上抛,让 UI 能准确告诉用户哪个平台出问题(#93),
+          // 同时保留日志方便诊断。
+          const reason = error instanceof Error ? error.message : String(error);
+          console.error(
+            `Failed to install "${skill.name}" to ${platformId}:`,
+            error,
+          );
+          failures.push({ platformId, reason });
      }
    }
    await refreshInstallStatus();
-      return { successCount, totalCount: platformIds.length };
+      return { successCount, totalCount: platformIds.length, failures };
  } finally {
Evidence
useSkillPlatform.batchInstall now collects per-platform exceptions into failures and returns
them to callers, but SkillQuickInstall only checks successCount and never displays/handles
failures, so the PR’s “surface per-platform failures” behavior is incomplete for this entrypoint.

apps/desktop/src/renderer/components/skill/use-skill-platform.ts[164-214]
apps/desktop/src/renderer/components/skill/SkillQuickInstall.tsx[45-59]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`SkillQuickInstall` does not surface `BatchInstallResult.failures`, so partial failures are still silent (and the modal may close after a partial success).
## Issue Context
`useSkillPlatform.batchInstall` now returns `{ successCount, totalCount, failures }`. `SkillFullDetailPage` renders failures, but `SkillQuickInstall` does not.
## Fix Focus Areas
- apps/desktop/src/renderer/components/skill/SkillQuickInstall.tsx[45-66]
- apps/desktop/src/renderer/components/skill/SkillFullDetailPage.tsx[441-473]
## Implementation notes
- After `const result = await batchInstall()`, add the same failure-toast behavior used in `SkillFullDetailPage` (map failures to platform labels, join, show an error toast).
- Avoid closing the modal when `result.failures.length > 0` (or close only if `failures.length === 0`), so users can immediately see and act on failures.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

4. Toast newlines collapse 🐞 Bug ≡ Correctness
Description
SkillFullDetailPage builds a newline-separated failure summary and passes it to showToast, but
the Toast message is rendered in a normal ` so \n` collapses to spaces. This makes the
per-platform failure list unreadable and not actually “one platform per line.”
Code

apps/desktop/src/renderer/components/skill/SkillFullDetailPage.tsx[R459-472]

+      if (result.failures.length > 0) {
+        const summary = result.failures
+          .map((failure) => {
+            const platform = availablePlatforms.find(
+              (entry) => entry.id === failure.platformId,
+            );
+            const label = platform?.name ?? failure.platformId;
+            return `${label}: ${failure.reason}`;
+          })
+          .join("\n");
+        showToast(
+          `${t("skill.installPartialFailure", "Some platforms could not be installed")}\n${summary}`,
+          "error",
+        );
Evidence
The failure toast string includes newline separators (.join("\n") and an additional "\n" before
the summary). The Toast component renders toast.message directly inside a ` with no white-space:
pre-line/pre-wrap`, so HTML whitespace collapsing will remove the intended line breaks.

apps/desktop/src/renderer/components/skill/SkillFullDetailPage.tsx[459-472]
apps/desktop/src/renderer/components/ui/Toast.tsx[87-99]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The partial-failure toast is constructed with `\n`-separated lines, but the Toast UI collapses newlines, so the per-platform list formatting is lost.
## Issue Context
`SkillFullDetailPage` intentionally joins failures with `"\n"` and prefixes another newline. The toast renderer currently uses a plain `<span>`.
## Fix Focus Areas
- apps/desktop/src/renderer/components/ui/Toast.tsx[87-99]
- apps/desktop/src/renderer/components/skill/SkillFullDetailPage.tsx[459-472]
## Implementation notes
- Update the toast message element to preserve newlines, e.g. add Tailwind `whitespace-pre-line` (or `whitespace-pre-wrap`) to the message span.
- Optionally add a max width / wrapping class to avoid extremely wide toasts when multiple failures are listed.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment thread apps/desktop/src/main/services/skill-installer-platform.ts Outdated
Comment thread apps/desktop/src/renderer/components/skill/SkillFullDetailPage.tsx Outdated
Comment thread apps/desktop/src/renderer/components/skill/use-skill-platform.ts
- Drop Chinese comment lines introduced by this PR (AGENTS.md rule)
- Replace hand-assembled 'Label: reason' + newline string in the
  partial-failure toast with i18n interpolation:
  * new key `skill.installFailureRow` ({{platform}}: {{reason}})
  * `skill.installPartialFailure` now takes {{details}}
  added to all 7 locales so translators can change the separator
- Fix silent partial failures in SkillQuickInstall:
  * handleInstall now reads result.failures and shows the same
    error toast as the main detail page
  * auto-close only when every selected platform succeeded; keep
    the modal open on partial failure so the user can retry
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/desktop/src/renderer/components/skill/SkillQuickInstall.tsx (1)

26-26: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

导出的组件函数缺少显式返回类型注解

该组件函数已导出但未声明返回类型。根据编码规范,所有导出的函数必须具有显式的返回类型注解。

🔧 建议的修复
-export function SkillQuickInstall({ skill, onClose }: SkillQuickInstallProps) {
+export function SkillQuickInstall({ skill, onClose }: SkillQuickInstallProps): JSX.Element {

根据编码规范:"All exported functions must have explicit return type annotations"

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/desktop/src/renderer/components/skill/SkillQuickInstall.tsx` at line 26,
The exported component function SkillQuickInstall lacks an explicit return type;
update its signature to include a TypeScript return annotation (e.g., :
JSX.Element or : React.ReactElement) on the SkillQuickInstall function
declaration so it conforms to the rule that all exported functions must have
explicit return types; adjust any imports if you choose React.ReactElement
(ensure React is imported) and keep the component implementation unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/desktop/src/renderer/components/skill/SkillQuickInstall.tsx`:
- Around line 60-82: The exported function SkillQuickInstall is missing an
explicit return type annotation; update its function signature (the exported
SkillQuickInstall declaration) to include a React return type such as
React.ReactElement or JSX.Element (import React if needed) so the export has a
clear type; you don't need to change the implementation that handles
result.failures or the platform?.name ?? failure.platformId expression—only add
the explicit return type to the SkillQuickInstall function signature.

---

Outside diff comments:
In `@apps/desktop/src/renderer/components/skill/SkillQuickInstall.tsx`:
- Line 26: The exported component function SkillQuickInstall lacks an explicit
return type; update its signature to include a TypeScript return annotation
(e.g., : JSX.Element or : React.ReactElement) on the SkillQuickInstall function
declaration so it conforms to the rule that all exported functions must have
explicit return types; adjust any imports if you choose React.ReactElement
(ensure React is imported) and keep the component implementation unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 016495aa-f9b6-4855-82c5-362e0b0329e0

📥 Commits

Reviewing files that changed from the base of the PR and between 8fb3c93 and 0feb283.

📒 Files selected for processing (12)
  • apps/desktop/src/main/services/skill-installer-platform.ts
  • apps/desktop/src/renderer/components/skill/SkillFullDetailPage.tsx
  • apps/desktop/src/renderer/components/skill/SkillQuickInstall.tsx
  • apps/desktop/src/renderer/components/skill/use-skill-platform.ts
  • apps/desktop/src/renderer/i18n/locales/de.json
  • apps/desktop/src/renderer/i18n/locales/en.json
  • apps/desktop/src/renderer/i18n/locales/es.json
  • apps/desktop/src/renderer/i18n/locales/fr.json
  • apps/desktop/src/renderer/i18n/locales/ja.json
  • apps/desktop/src/renderer/i18n/locales/zh-TW.json
  • apps/desktop/src/renderer/i18n/locales/zh.json
  • apps/desktop/tests/unit/main/skill-installer-platform.test.ts
✅ Files skipped from review due to trivial changes (6)
  • apps/desktop/src/renderer/i18n/locales/en.json
  • apps/desktop/src/renderer/i18n/locales/es.json
  • apps/desktop/src/renderer/i18n/locales/zh.json
  • apps/desktop/src/renderer/i18n/locales/zh-TW.json
  • apps/desktop/src/renderer/i18n/locales/ja.json
  • apps/desktop/tests/unit/main/skill-installer-platform.test.ts
🚧 Files skipped from review as they are similar to previous changes (5)
  • apps/desktop/src/renderer/i18n/locales/fr.json
  • apps/desktop/src/renderer/i18n/locales/de.json
  • apps/desktop/src/renderer/components/skill/SkillFullDetailPage.tsx
  • apps/desktop/src/main/services/skill-installer-platform.ts
  • apps/desktop/src/renderer/components/skill/use-skill-platform.ts

Comment on lines +60 to +82
if (result.failures.length > 0) {
const details = result.failures
.map((failure) => {
const platform = availablePlatforms.find(
(entry) => entry.id === failure.platformId,
);
const label = platform?.name ?? failure.platformId;
return t("skill.installFailureRow", {
platform: label,
reason: failure.reason,
defaultValue: "{{platform}}: {{reason}}",
});
})
.join("\n");
showToast(
t("skill.installPartialFailure", {
details,
defaultValue:
"Some platforms could not be installed\n{{details}}",
}),
"error",
);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# 描述: 验证 batchInstall 的返回类型定义,确认 failures 字段的契约

# 查找 batchInstall 函数的类型定义或实现
rg -nP --type=ts -A 10 'function\s+batchInstall|const\s+batchInstall.*=' apps/desktop/src/renderer/components/skill/use-skill-platform.ts

# 查找相关的类型定义(BatchInstallResult 或类似)
rg -nP --type=ts -A 5 'interface.*BatchInstall.*Result|type.*BatchInstall.*Result' apps/desktop/src/renderer/components/skill/

Repository: legeling/PromptHub

Length of output: 1112


🏁 Script executed:

# Get the complete BatchInstallResult interface definition
rg -nP --type=ts -A 15 'export interface BatchInstallResult' apps/desktop/src/renderer/components/skill/use-skill-platform.ts

Repository: legeling/PromptHub

Length of output: 661


🏁 Script executed:

# Check all exported functions in SkillQuickInstall.tsx for return type annotations
rg -nP --type=tsx 'export\s+(async\s+)?function|export\s+const.*=.*\(' apps/desktop/src/renderer/components/skill/SkillQuickInstall.tsx | head -20

Repository: legeling/PromptHub

Length of output: 90


🏁 Script executed:

# Get the full context of lines 60-82 in SkillQuickInstall.tsx to see function signature
sed -n '1,90p' apps/desktop/src/renderer/components/skill/SkillQuickInstall.tsx | head -90

Repository: legeling/PromptHub

Length of output: 2973


🏁 Script executed:

# Get the complete SkillQuickInstall function signature with return type if present
sed -n '23,40p' apps/desktop/src/renderer/components/skill/SkillQuickInstall.tsx

Repository: legeling/PromptHub

Length of output: 578


🏁 Script executed:

# Also check for any other exported functions in this file
rg -nP --type=ts 'export\s+(async\s+)?function' apps/desktop/src/renderer/components/skill/SkillQuickInstall.tsx

Repository: legeling/PromptHub

Length of output: 145


为导出函数添加显式返回类型注解

第 26 行的导出函数 SkillQuickInstall 缺少显式返回类型注解。根据编码规范,所有导出函数必须有明确的返回类型声明。应为该函数添加返回类型注解(如 React.ReactNodeJSX.Element)。

关于 result.failures 的处理:契约已保证 BatchInstallResult.failures 始终为数组类型,代码安全地假设其存在。第 73 行使用的可选链操作符与空值合并操作符 (platform?.name ?? failure.platformId) 正确地显式处理了 null/undefined 情况。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/desktop/src/renderer/components/skill/SkillQuickInstall.tsx` around
lines 60 - 82, The exported function SkillQuickInstall is missing an explicit
return type annotation; update its function signature (the exported
SkillQuickInstall declaration) to include a React return type such as
React.ReactElement or JSX.Element (import React if needed) so the export has a
clear type; you don't need to change the implementation that handles
result.failures or the platform?.name ?? failure.platformId expression—only add
the explicit return type to the SkillQuickInstall function signature.

@legeling legeling merged commit 55d7433 into legeling:main May 10, 2026
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Symlink not working

2 participants