Skip to content

chore: 提升最低 Node 到 22,兼容 pnpm 9/10/11,引入 vitest 单元测试#648

Open
sj817 wants to merge 6 commits into
mainfrom
chore/node22-pnpm-and-tests
Open

chore: 提升最低 Node 到 22,兼容 pnpm 9/10/11,引入 vitest 单元测试#648
sj817 wants to merge 6 commits into
mainfrom
chore/node22-pnpm-and-tests

Conversation

@sj817
Copy link
Copy Markdown
Member

@sj817 sj817 commented May 15, 2026

Summary

  • 引擎升级:所有 engines.node>=18 升至 >=22;新增 engines.pnpm: ">=9" 覆盖 9/10/11;根 package.json 添加 packageManager: "pnpm@10.14.0" 锁定可复现安装版本;@types/node 升到 ^22.10.0
  • CIpnpm/action-setup 全部升到 v4 并改用 pnpm@10,发布相关 workflow 增加 actions/setup-node@v4 与 pnpm 缓存;新增 .github/workflows/ci.yml,对 Node 22/24/26 × pnpm 10/11 跑 pnpm test 矩阵。
  • 单元测试:根目录新增 vitest.config.ts@ 别名映射 packages/core/src,覆盖率聚焦 utils/**);tests/setup.ts 注入 logger/debug 全局桩;packages/core/tests/108 个用例,覆盖 utils/common(number/sleep/string/uptime)utils/system(time/range)utils/fs(json/path)utils/iniutils/button/convert
  • WSL 验证脚本tests/run-matrix.sh(Node 22/24/26 × pnpm 10/11)、tests/verify-pnpm11.sh(临时摘掉 packageManager 钉子,验证 pnpm 11 自身真正能跑),tests/check-pnpm-version.sh(对比项目内外 pnpm 自版本切换)。

本地验证

在 WSL Ubuntu 24.04 下跑过 6 个组合,每组 108/108 全绿:

node22/pnpm10.14.0: PASS
node22/pnpm11.1.1:  PASS
node24/pnpm10.14.0: PASS
node24/pnpm11.1.1:  PASS
node26/pnpm10.14.0: PASS
node26/pnpm11.1.1:  PASS

另外 verify-pnpm11.sh 摘掉 packageManager 钉子后直接以 pnpm 11.1.1 跑,108/108 通过,确认 pnpm 11 本身能够真正驱动安装与测试。

已知遗留(未在本 PR 修复,仅由测试锁定当前行为)

  • packages/core/src/utils/system/time.tsformatTime
    • 清零正则 /0[天时分秒]/g 漏掉 0小时(因为 0 后面是 不是 ),10 位秒级时间戳会被错误地放大成天级负数。
    • 测试用 toBe('0小时钟5秒') 等断言锁定当前行为,留待单独的 fix PR 处理。

Test plan

  • CI 矩阵在 PR 上首次跑出 6 组绿
  • pnpm install 不再因 engines 报错
  • pnpm test 在 Node 22/24/26 上均 108 用例通过
  • release / beta-version / manual-publish-core 三个 workflow 在 Node 22 + pnpm 10 下仍能完成构建步骤

Summary by Sourcery

将最低支持的 Node.js 版本提升到 22,使项目与 pnpm 9+ 以及锁定的 pnpm 10 工具链保持一致,并为核心工具引入基于 vitest 的测试套件,同时更新 CI 以在现代 Node/pnpm 组合下运行测试。

New Features:

  • 添加 vitest 配置和测试初始化设置,将核心源代码通过别名 '@' 引入,并在测试中接入全局 logger/debug 的桩实现。
  • 为核心工具模块引入单元测试,包括按钮转换、文件系统 JSON 工具、INI 处理以及其他通用/系统辅助方法。
  • 添加辅助 shell 脚本,用于验证 Node/pnpm 版本矩阵以及 pnpm 11 在 WSL 下的行为。

Enhancements:

  • 提升所有 package 的 engines 要求,使其需要 Node.js >=22 和 pnpm >=9,并在各个包中将 @types/node 更新为 Node 22 的类型定义。
  • 将项目的 packageManager 固定为 pnpm@10.14.0,以确保本地和 CI 安装的可重现性。

CI:

  • 新增 CI 工作流,在 Node 22/24/26 和 pnpm 10/11(对 Node 26 使用精简配对)上运行测试套件。
  • 更新 release、beta-version 和 manual-publish-core 工作流,使其使用 pnpm/action-setup v4、pnpm 10、Node 22,以及支持 pnpm 的缓存机制。

Tests:

  • 为核心工具新增基于 vitest 的测试矩阵,覆盖 common、system、filesystem、INI 和按钮转换等辅助方法,扩大自动化回归测试覆盖范围。
Original summary in English

Summary by Sourcery

Raise the minimum supported Node.js version to 22, align the project with pnpm 9+ and a pinned pnpm 10 toolchain, and introduce a vitest-based test suite for core utilities, with CI updated to run the tests across modern Node/pnpm combinations.

New Features:

  • Add a vitest configuration and test setup that aliases core source under '@' and wires in global logger/debug stubs for tests.
  • Introduce unit tests for core utility modules, including button conversion, filesystem JSON utilities, INI handling, and other common/system helpers.
  • Add helper shell scripts to validate Node/pnpm version matrices and pnpm 11 behavior under WSL.

Enhancements:

  • Bump all package engines to require Node.js >=22 and pnpm >=9, and update @types/node to the Node 22 typings across packages.
  • Pin the project packageManager to pnpm@10.14.0 to ensure reproducible local and CI installations.

CI:

  • Add a new CI workflow that runs the test suite across Node 22/24/26 and pnpm 10/11 (with a reduced pair for Node 26).
  • Update release, beta-version, and manual-publish-core workflows to use pnpm/action-setup v4, pnpm 10, Node 22, and pnpm-aware caching.

Tests:

  • Add a vitest-based test matrix for core utilities covering common, system, filesystem, INI, and button conversion helpers, expanding automated regression coverage.

Summary by CodeRabbit

  • Chores

    • Raised minimum Node.js requirement to 22 and added pnpm >=9; set packageManager to pnpm@10.14.0
    • Updated project workflows to use newer Node and pnpm tooling and enabled pnpm caching
    • Expanded CI to run additional build and smoke-check steps against multiple Node/pnpm combinations
  • Tests

    • Added extensive Vitest suites covering many core utilities and filesystem/INI/path helpers
    • Added Vitest config and multiple test/verification scripts for cross-Node/pnpm validation

Review Change Stack

sj817 added 3 commits May 15, 2026 20:13
- 所有 package.json 的 engines.node 从 >=18 升级到 >=22
- 新增 engines.pnpm: ">=9" 以兼容 pnpm 9/10/11
- 根 package.json 添加 packageManager: "pnpm@10.14.0" 锁定可复现版本
- @types/node 升至 ^22.10.0
- beta-version/release/manual-publish-core 工作流统一切换到 pnpm@10、Node 22
  并启用 setup-node 的 pnpm 缓存
- 新增 ci.yml:Node 22/24/26 × pnpm 10/11 矩阵,PR 与 push 时执行 pnpm test
- 根目录新增 vitest.config.ts,@ 别名指向 packages/core/src,
  覆盖率聚焦 utils/**
- tests/setup.ts 注入 logger/debug 全局桩,避免触发 utils 之外的副作用
- packages/core/tests:为 common(number/sleep/string/uptime)、
  system(time/range)、fs(json/path)、ini、button/convert 共 108 个用例
- tests/run-matrix.sh:在 WSL 内跑 Node 22/24/26 × pnpm 10/11 矩阵
- tests/verify-pnpm11.sh:临时移除 packageManager 钉子以验证 pnpm 11 真正运行
- tests/check-pnpm-version.sh:对比项目内外 pnpm 自版本切换行为
Copilot AI review requested due to automatic review settings May 15, 2026 12:20
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 15, 2026

Warning

Rate limit exceeded

@sj817 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 20 minutes and 41 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 62006915-01ae-4da9-86e7-5e912fb64401

📥 Commits

Reviewing files that changed from the base of the PR and between ffb77ad and 29555ee.

📒 Files selected for processing (6)
  • .github/workflows/beta-version.yml
  • .github/workflows/ci.yml
  • .github/workflows/manual-publish-core.yml
  • .github/workflows/release.yml
  • package.json
  • tests/verify-pnpm9.sh
📝 Walkthrough

Walkthrough

Upgrades Node and pnpm toolchain declarations, updates GitHub Actions to Node 22 / pnpm 10 with an expanded CI matrix and smoke-build step, adds Vitest configuration and setup, introduces many utility test suites, and provides local test/run helper scripts.

Changes

Node 22 Upgrade and Testing Infrastructure

Layer / File(s) Summary
Toolchain version constraints
package.json, packages/cli-Internal/package.json, packages/cli/package.json, packages/core/package.json, packages/create-karin/package.json
Root and workspace package.json files declare Node >=22 and add pnpm engine constraints; packageManager updated to pnpm@10.14.0 and @types/node bumped to ^22.10.0.
GitHub Actions workflow updates
.github/workflows/beta-version.yml, .github/workflows/ci.yml, .github/workflows/manual-publish-core.yml, .github/workflows/release.yml
Workflows updated to use pnpm/action-setup@v4 (pnpm 10) and actions/setup-node@v4 (Node 22) with pnpm caching; CI matrix expanded to Node 22/24/25/26 and pnpm 10/11 with exclusions and added build + smoke-test steps for create-karin.
Vitest configuration and test setup
vitest.config.ts, tests/setup.ts
Adds vitest.config.ts with alias and coverage settings; tests/setup.ts defines LoggerLike, a stub logger, and initializes globalThis.logger/globalThis.debug for tests.
Utility function test coverage
packages/core/tests/utils/**/*.test.ts
New Vitest suites cover button conversion, numeric/string/sleep/uptime utilities, fs json/path helpers, INI parser, and system range/time utilities including edge cases and error paths.
Test execution helper scripts
tests/check-pnpm-version.sh, tests/run-matrix.sh, tests/verify-pnpm11.sh, tests/verify-create-karin*.sh
Shell scripts for validating pnpm versions, running tests across Node/pnpm matrices, and performing CLI smoke/deep checks against multiple Node versions.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • KarinJS/Karin#582: Similar changes to .github/workflows/release.yml updating Node/pnpm setup.

Poem

🐰 A rabbit hops through Node twenty-two,
Pnpm ten brings testing shiny and new,
Vitest config guides the way so clear,
Utility tests now holding cheer,
Workflows dance in CI's good light!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: upgrading Node to version 22, adding pnpm 9/10/11 compatibility, and introducing vitest unit tests. All three key themes directly correspond to substantial portions of the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/node22-pnpm-and-tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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.

@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai Bot commented May 15, 2026

Reviewer's Guide

将最低支持的 Node.js 版本提升到 22,要求 pnpm >=9(仓库中固定为 pnpm 10),现代化 GitHub Actions 工作流,引入基于 Vitest 的单元测试配置(为核心工具新增 100+ 个测试),并添加用于在 WSL 中验证 Node/pnpm 兼容矩阵的辅助脚本,同时不改变现有的运行时行为。

File-Level Changes

Change Details Files
升级运行时/工具链版本,并通过 engines 和 packageManager 元数据进行强制约束。
  • 在根目录中将 engines.node 设为 ">=22",engines.pnpm 设为 ">=9",并将 packageManager 固定为 pnpm@10.14.0,以保证可复现的安装。
  • 在 core、cli、cli-Internal 和 create-karin 等 package 中对齐 engines 配置,要求 Node >=22 且 pnpm >=9。
  • 将所有 @types/node 开发依赖升级到 ^22.10.0,以匹配新的 Node 基线版本。
  • 重新生成 pnpm-lock.yaml,以反映新的依赖图和 pnpm 版本。
package.json
packages/core/package.json
packages/cli/package.json
packages/cli-Internal/package.json
packages/create-karin/package.json
pnpm-lock.yaml
现代化 CI 和发布工作流,使其在 Node 22 和 pnpm 10 上运行并启用缓存,同时添加一个 Node 22/24/26 与 pnpm 10/11 的矩阵 CI 任务。
  • 将现有工作流从 pnpm/action-setup@v2+Node 20 切换为 pnpm/action-setup@v4+pnpm 10,以及 actions/setup-node@v4(node-version 22)并启用 pnpm 缓存。
  • 新增一个 ci 工作流,在 Node 22/24/26 和 pnpm 10/11 的矩阵上运行 pnpm test(其中 Node 26 仅与 pnpm 11 搭配),并关闭 fail-fast。
  • 确保工作流仍然使用启用缓存的 pnpm 执行依赖安装和构建/测试步骤。
.github/workflows/release.yml
.github/workflows/beta-version.yml
.github/workflows/manual-publish-core.yml
.github/workflows/ci.yml
引入基于 Vitest 的单元测试基础设施,聚焦核心工具,并提供全局 logger/debug stub。
  • 添加 vitest.config.ts,将 @ 别名指向 packages/core/src,在 packages/**/tests 下进行测试发现,并将覆盖率限制在核心工具上(排除 logger/debug 和 d.ts 文件)。
  • 添加 tests/setup.ts,提供在测试期间供核心工具使用的全局 logger 和 debug stub 函数。
  • 在根目录 package.json 中将 npm scripts(test、test:watch、test:coverage)接入 Vitest(原有脚本现由真实测试支撑)。
vitest.config.ts
tests/setup.ts
package.json
为核心工具模块添加全面的单元测试,在不改变实现行为的前提下,包括锁定当前时间格式化中的既有“怪癖”。
  • 为 utils/button/convert 添加测试,覆盖 karinToQQBot 和 qqbotToKarin 的行为,包括链接/回调/管理员权限、用户/角色列表以及 id 序列。
  • 为 utils/fs/json 和 utils/fs/path 添加测试,覆盖同步/异步读写行为、错误处理以及命名空间导出。
  • 为 utils/ini 添加测试,覆盖解析、带目录创建的写入以及 createINIParser 工厂行为。
  • 为 utils/common(number、sleep、string、uptime)和 utils/system(time、range)添加测试,覆盖边界情况,例如已知的 formatTime bug,这些 bug 会被显式断言并留待未来的修复 PR 处理。
packages/core/tests/utils/button/convert.test.ts
packages/core/tests/utils/fs/json.test.ts
packages/core/tests/utils/fs/path.test.ts
packages/core/tests/utils/ini/index.test.ts
packages/core/tests/utils/common/number.test.ts
packages/core/tests/utils/common/sleep.test.ts
packages/core/tests/utils/common/string.test.ts
packages/core/tests/utils/common/uptime.test.ts
packages/core/tests/utils/system/time.test.ts
packages/core/tests/utils/system/range.test.ts
添加本地 WSL 辅助脚本,用于跑 Node/pnpm 兼容性矩阵,并验证在有/无 packageManager 固定时 pnpm 11 的行为。
  • 添加 tests/run-matrix.sh,用于在 Node 22/24/26 与 pnpm 10.14.0/11.1.1 的组合上运行 pnpm test,并生成汇总报告。
  • 添加 tests/verify-pnpm11.sh,用于临时移除 packageManager 固定,在特定检出中使用 pnpm 11 运行测试,然后恢复 package.json。
  • 添加 tests/check-pnpm-version.sh,用于在存在 packageManager 固定时对比项目外部与项目内部看到的 pnpm 版本。
tests/run-matrix.sh
tests/verify-pnpm11.sh
tests/check-pnpm-version.sh

Tips and commands

Interacting with Sourcery

  • 触发新一轮 Review: 在 pull request 上评论 @sourcery-ai review
  • 继续讨论: 直接回复 Sourcery 的评论即可继续对话。
  • 从 Review 评论生成 GitHub Issue: 在某条 Review 评论下回复,请求 Sourcery 基于该评论创建 Issue。你也可以直接回复 @sourcery-ai issue 来基于该评论创建 Issue。
  • 生成 pull request 标题: 在 pull request 标题中任意位置写上 @sourcery-ai,即可随时生成标题。你也可以在 pull request 中评论 @sourcery-ai title 来(重新)生成标题。
  • 生成 pull request 摘要: 在 pull request 正文中任意位置写上 @sourcery-ai summary,即可在对应位置生成 PR 摘要。你也可以在 pull request 中评论 @sourcery-ai summary,在任意时间(重新)生成摘要。
  • 生成 Reviewer's Guide: 在 pull request 中评论 @sourcery-ai guide,即可在任意时间(重新)生成 reviewer's guide。
  • 一次性解决所有 Sourcery 评论: 在 pull request 中评论 @sourcery-ai resolve,即可将所有 Sourcery 评论标记为已解决。如果你已经处理完所有评论且不想再看到它们,这会很有用。
  • 一次性关闭所有 Sourcery Review: 在 pull request 中评论 @sourcery-ai dismiss,即可关闭所有现有的 Sourcery Review。特别适合想要从头开始新一轮 Review 的场景——别忘了再评论 @sourcery-ai review 来触发新的 Review!

Customizing Your Experience

访问你的 dashboard 来:

  • 启用或禁用诸如 Sourcery 生成的 pull request 摘要、reviewer's guide 等 Review 功能。
  • 修改 Review 语言。
  • 添加、移除或编辑自定义 Review 指南。
  • 调整其他 Review 设置。

Getting Help

Original review guide in English

Reviewer's Guide

Raises the minimum supported Node.js version to 22 with pnpm >=9 (pinned to pnpm 10 in the repo), modernizes GitHub Actions workflows, introduces a Vitest-based unit test setup with 100+ tests for core utils, and adds WSL helper scripts for validating Node/pnpm compatibility matrices without changing existing runtime behavior.

File-Level Changes

Change Details Files
Upgrade runtime/tooling versions and enforce them via engines and packageManager metadata.
  • Set root engines.node to ">=22" and engines.pnpm to ">=9" and pin packageManager to pnpm@10.14.0 for reproducible installs.
  • Align package-level engines in core, cli, cli-Internal, and create-karin to require Node >=22 and pnpm >=9.
  • Upgrade all @types/node devDependencies to ^22.10.0 to match the new Node baseline.
  • Regenerate pnpm-lock.yaml to reflect the new dependency graph and pnpm version.
package.json
packages/core/package.json
packages/cli/package.json
packages/cli-Internal/package.json
packages/create-karin/package.json
pnpm-lock.yaml
Modernize CI and release workflows to run on Node 22 and pnpm 10 with caching, plus add a matrix CI job for Node 22/24/26 and pnpm 10/11.
  • Switch existing workflows from pnpm/action-setup@v2+Node 20 to pnpm/action-setup@v4+pnpm 10 and actions/setup-node@v4 with node-version 22 and pnpm cache.
  • Add a new ci workflow running pnpm test on a matrix of Node 22/24/26 and pnpm 10/11 (with Node 26 only paired to pnpm 11) and disable fail-fast.
  • Ensure workflows still perform dependency installation and build/test steps using pnpm with cache enabled.
.github/workflows/release.yml
.github/workflows/beta-version.yml
.github/workflows/manual-publish-core.yml
.github/workflows/ci.yml
Introduce Vitest-based unit testing infrastructure focused on core utils with global logger/debug stubs.
  • Add vitest.config.ts with @ alias to packages/core/src, test discovery under packages/**/tests, and coverage restricted to core utils (excluding logger/debug and d.ts files).
  • Add tests/setup.ts to provide stubbed global logger and debug functions used by core utilities during tests.
  • Wire npm scripts (test, test:watch, test:coverage) to Vitest in the root package.json (pre-existing wiring now backed by real tests).
vitest.config.ts
tests/setup.ts
package.json
Add comprehensive unit tests for core utility modules without changing their implementation behavior, including locking in existing quirks in time formatting.
  • Add tests for utils/button/convert covering karinToQQBot and qqbotToKarin behavior including link/callback/admin permissions, user/role lists, and id sequencing.
  • Add tests for utils/fs/json and utils/fs/path covering sync/async read/write behavior, error handling, and namespace exports.
  • Add tests for utils/ini including parsing, writing with directory creation, and createINIParser factory behavior.
  • Add tests for utils/common (number, sleep, string, uptime) and utils/system (time, range) including edge cases such as known formatTime bugs which are explicitly asserted and left for a future fix PR.
packages/core/tests/utils/button/convert.test.ts
packages/core/tests/utils/fs/json.test.ts
packages/core/tests/utils/fs/path.test.ts
packages/core/tests/utils/ini/index.test.ts
packages/core/tests/utils/common/number.test.ts
packages/core/tests/utils/common/sleep.test.ts
packages/core/tests/utils/common/string.test.ts
packages/core/tests/utils/common/uptime.test.ts
packages/core/tests/utils/system/time.test.ts
packages/core/tests/utils/system/range.test.ts
Add local WSL helper scripts to exercise a Node/pnpm compatibility matrix and verify pnpm 11 behavior with and without packageManager pinning.
  • Add tests/run-matrix.sh to run pnpm test across Node 22/24/26 and pnpm 10.14.0/11.1.1 combinations and generate a summary report.
  • Add tests/verify-pnpm11.sh to temporarily remove the packageManager pin, run pnpm 11 tests in a specific checkout, and restore package.json afterward.
  • Add tests/check-pnpm-version.sh to compare the pnpm version seen outside vs. inside the project when a packageManager pin is present.
tests/run-matrix.sh
tests/verify-pnpm11.sh
tests/check-pnpm-version.sh

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request upgrades the project's environment requirements to Node.js 22 and pnpm 9, alongside updating related type definitions and lockfile dependencies. It introduces a comprehensive suite of unit tests for core utility modules and adds several shell scripts to verify the engine transition. Feedback focuses on improving the portability of the new test scripts by removing hardcoded absolute paths and enhancing error visibility. Additionally, it is recommended to use fake timers for time-sensitive tests to prevent CI flakiness and to avoid asserting known bugs or typos as expected behavior in the test suite.

Comment thread tests/run-matrix.sh
Comment on lines +8 to +15
["24"]="$HOME/node-versions/v24.15.0/bin/node"
["26"]="$HOME/node-versions/v26.1.0/bin/node"
)

declare -A NODE_DIRS=(
["22"]="$(dirname "$(which node)")"
["24"]="$HOME/node-versions/v24.15.0/bin"
["26"]="$HOME/node-versions/v26.1.0/bin"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

脚本中包含硬编码的绝对路径(如 $HOME/node-versions/...),这使得脚本在其他开发者的环境或不同的 CI 环境中无法运行。建议使用环境变量或在 PATH 中搜索二进制文件,以提高脚本的可移植性。

Comment thread tests/run-matrix.sh
PNPM_BIN="$PREFIX/node_modules/.bin"

PATH="$PNPM_BIN:$SAFE_PATH" pnpm --version
PATH="$PNPM_BIN:$SAFE_PATH" pnpm test 2>&1 | tail -6
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

使用 tail -6 可能会隐藏测试失败时的详细错误信息。建议移除它或增加显示的行数,以便在测试失败时能看到完整的错误堆栈。

Suggested change
PATH="$PNPM_BIN:$SAFE_PATH" pnpm test 2>&1 | tail -6
PATH="$PNPM_BIN:$SAFE_PATH" pnpm test 2>&1

Comment thread tests/verify-pnpm11.sh
# stays at v11 (instead of self-downgrading to the pinned version) and
# verify install + tests still work.
set -uo pipefail
cd /mnt/d/Github/Karin-test-build
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

硬编码路径 /mnt/d/Github/Karin-test-build 是特定于本地机器的目录结构。建议使用相对路径以提高脚本的可移植性。

Suggested change
cd /mnt/d/Github/Karin-test-build
cd "$(dirname "$0")/.."

~/node-versions/_pnpm-cache/22/node_modules/.bin/pnpm --version
echo
echo "Inside project (with packageManager pin), pnpm 11 binary:"
cd /mnt/d/Github/Karin-test-build
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

硬编码路径 /mnt/d/Github/Karin-test-build 是特定于本地机器的目录结构。建议使用相对路径。

Suggested change
cd /mnt/d/Github/Karin-test-build
cd "$(dirname "$0")/.."

Comment on lines +36 to +40
it('drops zero day/min/sec but keeps a quirky "0小时钟" segment for zero hour', () => {
const t1 = 1_700_000_000_000
const t2 = t1 + 5_000 // 5 seconds
expect(formatTime(t1, t2)).toBe('0小时钟5秒')
})
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

该测试用例断言了一个已知的 bug(0小时钟5秒)。在测试套件中将错误行为(包括拼写错误 "小时钟")固化下来通常是不推荐的,因为这可能会在以后被误认为是预期的功能。建议将此测试标记为 it.todoit.skip 并说明 bug 原因,而不是将错误的输出断言为预期结果。

Comment on lines +5 to +12
it('resolves after at least the requested duration', async () => {
const start = Date.now()
await sleep(50)
const elapsed = Date.now() - start
// generous lower bound: timers can fire 5-10ms early on busy CI
expect(elapsed).toBeGreaterThanOrEqual(40)
expect(elapsed).toBeLessThan(500)
})
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

使用真实延迟测试与时间相关的代码可能会在 CI 环境中导致不稳定性(flakiness)。此外,对于 50ms 的 sleep,40ms 的阈值也过于宽松。建议使用 Vitest 的模拟计时器(vi.useFakeTimers())来测试逻辑,这样更可靠且运行速度更快。

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey - 我发现了 1 个问题,并给出了一些整体性的反馈:

  • tests/ 目录下的辅助脚本(例如 run-matrix.shverify-pnpm11.shcheck-pnpm-version.sh)中包含硬编码的绝对路径和用户特定目录(/mnt/d/Github/Karin-test-build~/node-versions/...),这会导致其他贡献者无法直接使用;建议通过环境变量对这些路径进行参数化,或者通过动态方式推导项目根目录(例如 git rev-parse --show-toplevel)。
  • verify-pnpm11.shrun-matrix.sh 中你修改了 PATH,并依赖特定的本地 Node/npm 布局;如果能在必需的二进制缺失时增加更清晰的前置检查和错误信息,会让失败原因更容易理解,也能让这些脚本在稍有差异的环境中运行得更安全。
  • CI workflow 在安装 Node 之前安装了 pnpm(ci.yml),而其他 workflows 则是先安装 Node;如果能统一顺序(先 Node 设置 → 再 pnpm 设置),可以减少困惑,并在后续步骤依赖 actions/setup-node 中的 node-version 时,确保运行时环境的一致性。
供 AI Agents 使用的提示
Please address the comments from this code review:

## Overall Comments
- `tests/` 目录下的辅助脚本(例如 `run-matrix.sh``verify-pnpm11.sh``check-pnpm-version.sh`)中包含硬编码的绝对路径和用户特定目录(`/mnt/d/Github/Karin-test-build``~/node-versions/...`),这会导致其他贡献者无法直接使用;建议通过环境变量对这些路径进行参数化,或者通过动态方式推导项目根目录(例如 `git rev-parse --show-toplevel`)。
-`verify-pnpm11.sh``run-matrix.sh` 中你修改了 `PATH`,并依赖特定的本地 Node/npm 布局;如果能在必需的二进制缺失时增加更清晰的前置检查和错误信息,会让失败原因更容易理解,也能让这些脚本在稍有差异的环境中运行得更安全。
- CI workflow 在安装 Node 之前安装了 pnpm(`ci.yml`),而其他 workflows 则是先安装 Node;如果能统一顺序(先 Node 设置 → 再 pnpm 设置),可以减少困惑,并在后续步骤依赖 `actions/setup-node` 中的 `node-version` 时,确保运行时环境的一致性。

## Individual Comments

### Comment 1
<location path="packages/core/tests/utils/fs/json.test.ts" line_range="48-62" />
<code_context>
+  })
+})
+
+describe('utils/fs/json — async', () => {
+  it('writes and reads JSON', async () => {
+    const file = path.join(tmpDir, 'async.json')
+    expect(await writeJson(file, { x: [1, 2, 3] })).toBe(true)
+    await expect(readJson(file)).resolves.toEqual({ x: [1, 2, 3] })
+  })
+
+  it('returns null when missing without throwing', async () => {
+    await expect(readJson(path.join(tmpDir, 'missing-async.json'))).resolves.toBeNull()
+  })
+
+  it('throws when isThrow=true on missing file', async () => {
+    await expect(readJson(path.join(tmpDir, 'missing-async.json'), true)).rejects.toBeDefined()
+  })
</code_context>
<issue_to_address>
**suggestion (testing):** Add async write failure tests to mirror the sync error-path coverage

异步 helper 目前只覆盖了 “文件缺失” 的情况,而同步 helper 同时覆盖了读/写失败,并区分是否传入 `isThrow`。为了对齐行为并防止回归,请补充异步测试,以覆盖以下场景:

-`tmpDir` 为目录的情况下调用 `writeJson(tmpDir, { ... })`,并断言其返回的 Promise 解析为 `false`(或预期的不抛错失败值)。
- 在相同场景下调用 `writeJson(tmpDir, { ... }, true)`,并断言其返回的 Promise 被拒绝(reject)。

```suggestion
describe('utils/fs/json — async', () => {
  it('writes and reads JSON', async () => {
    const file = path.join(tmpDir, 'async.json')
    expect(await writeJson(file, { x: [1, 2, 3] })).toBe(true)
    await expect(readJson(file)).resolves.toEqual({ x: [1, 2, 3] })
  })

  it('returns null when missing without throwing', async () => {
    await expect(readJson(path.join(tmpDir, 'missing-async.json'))).resolves.toBeNull()
  })

  it('throws when isThrow=true on missing file', async () => {
    await expect(readJson(path.join(tmpDir, 'missing-async.json'), true)).rejects.toBeDefined()
  })

  it('returns false on write failure (invalid target) without throwing', async () => {
    // A directory cannot be written to as a file
    await expect(writeJson(tmpDir, { foo: 'bar' })).resolves.toBe(false)
  })

  it('rejects on write failure when isThrow=true', async () => {
    // A directory cannot be written to as a file
    await expect(writeJson(tmpDir, { foo: 'bar' }, true)).rejects.toBeDefined()
  })
})
```
</issue_to_address>

Sourcery 对开源项目是免费的 —— 如果你觉得这些评审有帮助,欢迎分享给更多人 ✨
帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据你的反馈改进后续评审。
Original comment in English

Hey - I've found 1 issue, and left some high level feedback:

  • The helper scripts under tests/ (e.g. run-matrix.sh, verify-pnpm11.sh, check-pnpm-version.sh) contain hard-coded absolute paths and user-specific directories (/mnt/d/Github/Karin-test-build, ~/node-versions/...), which makes them unusable for other contributors; consider parameterizing these paths via environment variables or deriving the project root dynamically (e.g. git rev-parse --show-toplevel).
  • In verify-pnpm11.sh and run-matrix.sh you mutate PATH and rely on specific local Node/npm layouts; adding clearer guard checks and error messages when required binaries are missing would make failures easier to understand and the scripts safer to run in slightly different environments.
  • The CI workflow installs pnpm before Node (ci.yml), while other workflows install Node first; aligning the order (Node setup → pnpm setup) across workflows can reduce confusion and ensure a consistent runtime environment if future steps depend on node-version in actions/setup-node.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The helper scripts under `tests/` (e.g. `run-matrix.sh`, `verify-pnpm11.sh`, `check-pnpm-version.sh`) contain hard-coded absolute paths and user-specific directories (`/mnt/d/Github/Karin-test-build`, `~/node-versions/...`), which makes them unusable for other contributors; consider parameterizing these paths via environment variables or deriving the project root dynamically (e.g. `git rev-parse --show-toplevel`).
- In `verify-pnpm11.sh` and `run-matrix.sh` you mutate `PATH` and rely on specific local Node/npm layouts; adding clearer guard checks and error messages when required binaries are missing would make failures easier to understand and the scripts safer to run in slightly different environments.
- The CI workflow installs pnpm before Node (`ci.yml`), while other workflows install Node first; aligning the order (Node setup → pnpm setup) across workflows can reduce confusion and ensure a consistent runtime environment if future steps depend on `node-version` in `actions/setup-node`.

## Individual Comments

### Comment 1
<location path="packages/core/tests/utils/fs/json.test.ts" line_range="48-62" />
<code_context>
+  })
+})
+
+describe('utils/fs/json — async', () => {
+  it('writes and reads JSON', async () => {
+    const file = path.join(tmpDir, 'async.json')
+    expect(await writeJson(file, { x: [1, 2, 3] })).toBe(true)
+    await expect(readJson(file)).resolves.toEqual({ x: [1, 2, 3] })
+  })
+
+  it('returns null when missing without throwing', async () => {
+    await expect(readJson(path.join(tmpDir, 'missing-async.json'))).resolves.toBeNull()
+  })
+
+  it('throws when isThrow=true on missing file', async () => {
+    await expect(readJson(path.join(tmpDir, 'missing-async.json'), true)).rejects.toBeDefined()
+  })
</code_context>
<issue_to_address>
**suggestion (testing):** Add async write failure tests to mirror the sync error-path coverage

The async helpers only cover the missing-file case, whereas the sync helpers cover both read/write failures with and without `isThrow`. To match that behavior and guard against regressions, please add async tests that:

- Call `writeJson(tmpDir, { ... })` where `tmpDir` is a directory and assert it resolves to `false` (or the expected non-throwing failure value).
- Call `writeJson(tmpDir, { ... }, true)` in the same scenario and assert it rejects.

```suggestion
describe('utils/fs/json — async', () => {
  it('writes and reads JSON', async () => {
    const file = path.join(tmpDir, 'async.json')
    expect(await writeJson(file, { x: [1, 2, 3] })).toBe(true)
    await expect(readJson(file)).resolves.toEqual({ x: [1, 2, 3] })
  })

  it('returns null when missing without throwing', async () => {
    await expect(readJson(path.join(tmpDir, 'missing-async.json'))).resolves.toBeNull()
  })

  it('throws when isThrow=true on missing file', async () => {
    await expect(readJson(path.join(tmpDir, 'missing-async.json'), true)).rejects.toBeDefined()
  })

  it('returns false on write failure (invalid target) without throwing', async () => {
    // A directory cannot be written to as a file
    await expect(writeJson(tmpDir, { foo: 'bar' })).resolves.toBe(false)
  })

  it('rejects on write failure when isThrow=true', async () => {
    // A directory cannot be written to as a file
    await expect(writeJson(tmpDir, { foo: 'bar' }, true)).rejects.toBeDefined()
  })
})
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +48 to +62
describe('utils/fs/json — async', () => {
it('writes and reads JSON', async () => {
const file = path.join(tmpDir, 'async.json')
expect(await writeJson(file, { x: [1, 2, 3] })).toBe(true)
await expect(readJson(file)).resolves.toEqual({ x: [1, 2, 3] })
})

it('returns null when missing without throwing', async () => {
await expect(readJson(path.join(tmpDir, 'missing-async.json'))).resolves.toBeNull()
})

it('throws when isThrow=true on missing file', async () => {
await expect(readJson(path.join(tmpDir, 'missing-async.json'), true)).rejects.toBeDefined()
})
})
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

suggestion (testing): Add async write failure tests to mirror the sync error-path coverage

异步 helper 目前只覆盖了 “文件缺失” 的情况,而同步 helper 同时覆盖了读/写失败,并区分是否传入 isThrow。为了对齐行为并防止回归,请补充异步测试,以覆盖以下场景:

  • tmpDir 为目录的情况下调用 writeJson(tmpDir, { ... }),并断言其返回的 Promise 解析为 false(或预期的不抛错失败值)。
  • 在相同场景下调用 writeJson(tmpDir, { ... }, true),并断言其返回的 Promise 被拒绝(reject)。
Suggested change
describe('utils/fs/json — async', () => {
it('writes and reads JSON', async () => {
const file = path.join(tmpDir, 'async.json')
expect(await writeJson(file, { x: [1, 2, 3] })).toBe(true)
await expect(readJson(file)).resolves.toEqual({ x: [1, 2, 3] })
})
it('returns null when missing without throwing', async () => {
await expect(readJson(path.join(tmpDir, 'missing-async.json'))).resolves.toBeNull()
})
it('throws when isThrow=true on missing file', async () => {
await expect(readJson(path.join(tmpDir, 'missing-async.json'), true)).rejects.toBeDefined()
})
})
describe('utils/fs/json — async', () => {
it('writes and reads JSON', async () => {
const file = path.join(tmpDir, 'async.json')
expect(await writeJson(file, { x: [1, 2, 3] })).toBe(true)
await expect(readJson(file)).resolves.toEqual({ x: [1, 2, 3] })
})
it('returns null when missing without throwing', async () => {
await expect(readJson(path.join(tmpDir, 'missing-async.json'))).resolves.toBeNull()
})
it('throws when isThrow=true on missing file', async () => {
await expect(readJson(path.join(tmpDir, 'missing-async.json'), true)).rejects.toBeDefined()
})
it('returns false on write failure (invalid target) without throwing', async () => {
// A directory cannot be written to as a file
await expect(writeJson(tmpDir, { foo: 'bar' })).resolves.toBe(false)
})
it('rejects on write failure when isThrow=true', async () => {
// A directory cannot be written to as a file
await expect(writeJson(tmpDir, { foo: 'bar' }, true)).rejects.toBeDefined()
})
})
Original comment in English

suggestion (testing): Add async write failure tests to mirror the sync error-path coverage

The async helpers only cover the missing-file case, whereas the sync helpers cover both read/write failures with and without isThrow. To match that behavior and guard against regressions, please add async tests that:

  • Call writeJson(tmpDir, { ... }) where tmpDir is a directory and assert it resolves to false (or the expected non-throwing failure value).
  • Call writeJson(tmpDir, { ... }, true) in the same scenario and assert it rejects.
Suggested change
describe('utils/fs/json — async', () => {
it('writes and reads JSON', async () => {
const file = path.join(tmpDir, 'async.json')
expect(await writeJson(file, { x: [1, 2, 3] })).toBe(true)
await expect(readJson(file)).resolves.toEqual({ x: [1, 2, 3] })
})
it('returns null when missing without throwing', async () => {
await expect(readJson(path.join(tmpDir, 'missing-async.json'))).resolves.toBeNull()
})
it('throws when isThrow=true on missing file', async () => {
await expect(readJson(path.join(tmpDir, 'missing-async.json'), true)).rejects.toBeDefined()
})
})
describe('utils/fs/json — async', () => {
it('writes and reads JSON', async () => {
const file = path.join(tmpDir, 'async.json')
expect(await writeJson(file, { x: [1, 2, 3] })).toBe(true)
await expect(readJson(file)).resolves.toEqual({ x: [1, 2, 3] })
})
it('returns null when missing without throwing', async () => {
await expect(readJson(path.join(tmpDir, 'missing-async.json'))).resolves.toBeNull()
})
it('throws when isThrow=true on missing file', async () => {
await expect(readJson(path.join(tmpDir, 'missing-async.json'), true)).rejects.toBeDefined()
})
it('returns false on write failure (invalid target) without throwing', async () => {
// A directory cannot be written to as a file
await expect(writeJson(tmpDir, { foo: 'bar' })).resolves.toBe(false)
})
it('rejects on write failure when isThrow=true', async () => {
// A directory cannot be written to as a file
await expect(writeJson(tmpDir, { foo: 'bar' }, true)).rejects.toBeDefined()
})
})

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

该 PR 主要围绕工程化升级:将全仓最低 Node 版本提升到 22、声明 pnpm 引擎范围并引入 Vitest 单元测试,同时新增 CI 矩阵验证在多 Node / pnpm 组合下的可用性。

Changes:

  • 将根与各 package 的 engines.node 提升到 >=22,并新增 engines.pnpm: ">=9",同时根 package.json 增加 packageManager 钉子与升级 @types/node
  • 引入 Vitest(配置、测试初始化),并在 packages/core 增加覆盖多个 utils/** 模块的单测。
  • CI/发布相关 workflow 升级 pnpm action 到 v4、切换到 Node 22,并新增 ci.yml 测试矩阵;额外加入 WSL 本地验证脚本。

Reviewed changes

Copilot reviewed 24 out of 25 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
vitest.config.ts 新增 Vitest 配置(别名、覆盖率范围、setupFiles)。
tests/setup.ts 为测试注入全局 logger/debug 的桩,避免运行时依赖。
tests/run-matrix.sh 新增 WSL 本地矩阵脚本,用于多 Node/pnpm 组合自测。
tests/verify-pnpm11.sh 新增验证脚本:临时移除 packageManager 钉子以测试 pnpm 11。
tests/check-pnpm-version.sh 新增脚本用于对比项目内外 pnpm 版本表现。
package.json 提升引擎约束、添加 packageManager 钉子、升级 @types/node,并增加/启用测试脚本。
pnpm-lock.yaml 锁文件随 @types/node 等依赖升级更新。
packages/core/package.json engines 升级到 Node>=22 并新增 pnpm 引擎。
packages/cli/package.json engines 升级到 Node>=22 并新增 pnpm 引擎。
packages/cli-Internal/package.json engines 升级到 Node>=22 并新增 pnpm 引擎。
packages/create-karin/package.json 升级 @types/node 并更新 engines
packages/core/tests/utils/common/number.test.ts 新增 number 工具函数单测。
packages/core/tests/utils/common/sleep.test.ts 新增 sleep 工具函数单测。
packages/core/tests/utils/common/string.test.ts 新增 string 工具函数单测。
packages/core/tests/utils/common/uptime.test.ts 新增 common/uptime 单测。
packages/core/tests/utils/system/time.test.ts 新增 system/time(含已知遗留行为锁定)单测。
packages/core/tests/utils/system/range.test.ts 新增 range 工具函数单测。
packages/core/tests/utils/fs/json.test.ts 新增 JSON 读写工具函数单测。
packages/core/tests/utils/fs/path.test.ts 新增 path 工具函数单测。
packages/core/tests/utils/ini/index.test.ts 新增 ini 读写与 parser 工厂单测。
packages/core/tests/utils/button/convert.test.ts 新增按钮转换工具单测。
.github/workflows/ci.yml 新增 CI 测试矩阵(Node 22/24/26 × pnpm 10/11)。
.github/workflows/release.yml 发布 workflow 调整为 Node 22 + pnpm action v4,并启用 pnpm cache。
.github/workflows/beta-version.yml beta workflow 升级 pnpm action v4 / Node 22 / pnpm cache(但当前步骤顺序存在问题)。
.github/workflows/manual-publish-core.yml 手动发布 workflow 升级 pnpm action v4 / Node 22 / pnpm cache(但当前步骤顺序存在问题)。
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported
Comments suppressed due to low confidence (1)

.github/workflows/beta-version.yml:37

  • run_install: true runs pnpm install during the pnpm setup step, which occurs before actions/setup-node. With engines.node >=22, the install will run under the runner’s default Node (currently 20) and can fail the workflow or install with the wrong Node version. Move actions/setup-node before pnpm installation, or remove run_install and add an explicit pnpm install step after Node 22 is set.
      - name: 安装pnpm
        uses: pnpm/action-setup@v4
        with:
          version: 10
          run_install: true

      - name: 安装Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: pnpm


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 19 to +37
- name: 拉取代码
uses: actions/checkout@v4
with:
fetch-depth: 0 # 获取完整历史记录,用于生成版本号
ref: ${{ github.event.pull_request.head.ref || github.ref_name }}
repository: ${{ github.event.pull_request.head.repo.full_name || '' }}

- name: 安装pnpm
uses: pnpm/action-setup@v2
uses: pnpm/action-setup@v4
with:
version: 9
version: 10
run_install: true

- name: 安装Node.js
uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm

Comment on lines +23 to +35
# 安装pnpm
- name: 配置pnpm
uses: pnpm/action-setup@v2
uses: pnpm/action-setup@v4
with:
version: 9
version: 10
run_install: true

- name: 安装Node.js
uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm

Comment thread tests/verify-pnpm11.sh
Comment on lines +5 to +10
set -uo pipefail
cd /mnt/d/Github/Karin-test-build

NODE_BIN="$HOME/node-versions/v22.22.2/bin"
[ -x "$NODE_BIN/node" ] || NODE_BIN="$(dirname "$(which node)")"
export PATH="$HOME/node-versions/_pnpm-cache/22/node_modules/.bin:$NODE_BIN:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
Comment thread tests/verify-pnpm11.sh
Comment on lines +12 to +25
cp package.json package.json.bak
node -e "
const fs = require('fs');
const pkg = JSON.parse(fs.readFileSync('package.json','utf8'));
delete pkg.packageManager;
fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');
"

echo "pnpm version (no packageManager pin): $(pnpm --version)"
pnpm test 2>&1 | tail -10
RC=$?

mv package.json.bak package.json
exit $RC
~/node-versions/_pnpm-cache/22/node_modules/.bin/pnpm --version
echo
echo "Inside project (with packageManager pin), pnpm 11 binary:"
cd /mnt/d/Github/Karin-test-build
Comment thread tests/run-matrix.sh
Comment on lines +6 to +18
declare -A NODE_PATHS=(
["22"]="$(which node)"
["24"]="$HOME/node-versions/v24.15.0/bin/node"
["26"]="$HOME/node-versions/v26.1.0/bin/node"
)

declare -A NODE_DIRS=(
["22"]="$(dirname "$(which node)")"
["24"]="$HOME/node-versions/v24.15.0/bin"
["26"]="$HOME/node-versions/v26.1.0/bin"
)

PNPM_VERSIONS=("10.14.0" "11.1.1")
Comment thread .github/workflows/ci.yml Outdated
cache: pnpm

- name: 安装依赖
run: pnpm install --frozen-lockfile=false
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: 4

🧹 Nitpick comments (4)
tests/run-matrix.sh (2)

6-10: ⚡ Quick win

Remove unused NODE_PATHS variable.

The NODE_PATHS associative array is declared but never referenced in the script. Only NODE_DIRS is used (lines 25, 42, 45).

♻️ Proposed fix
-declare -A NODE_PATHS=(
-  ["22"]="$(which node)"
-  ["24"]="$HOME/node-versions/v24.15.0/bin/node"
-  ["26"]="$HOME/node-versions/v26.1.0/bin/node"
-)
-
 declare -A NODE_DIRS=(
   ["22"]="$(dirname "$(which node)")"
   ["24"]="$HOME/node-versions/v24.15.0/bin"
   ["26"]="$HOME/node-versions/v26.1.0/bin"
 )
🤖 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 `@tests/run-matrix.sh` around lines 6 - 10, Remove the dead associative array
declaration NODE_PATHS from the script (the declare -A NODE_PATHS=(...) block)
since it is never used; keep and use the existing NODE_DIRS variable as intended
(no other code changes required), and run the script to ensure no references to
NODE_PATHS remain.

48-48: 💤 Low value

Consider capturing more test output for debugging.

The test output is truncated to the last 6 lines via tail -6. If tests fail, important error context from earlier in the output may be lost, making debugging more difficult.

Consider increasing the tail line count or conditionally showing full output on failure.

🤖 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 `@tests/run-matrix.sh` at line 48, The test runner currently pipes the pnpm
test output through "tail -6" which truncates logs and loses valuable context;
modify the invocation around the PATH="$PNPM_BIN:$SAFE_PATH" pnpm test call to
preserve more output by either increasing the tail window (e.g., tail -100) or
capturing the full output to a temporary file (using tee) and only tailing the
end for success while printing the entire file on failure (check the pnpm test
exit status and cat the saved log if non-zero).
tests/verify-pnpm11.sh (1)

6-6: ⚡ Quick win

Add error handling for directory change.

The cd command lacks error handling. If the directory change fails, the script will modify the wrong package.json file, potentially corrupting an unrelated project.

🛡️ Proposed fix
-cd /mnt/d/Github/Karin-test-build
+cd /mnt/d/Github/Karin-test-build || exit 1
🤖 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 `@tests/verify-pnpm11.sh` at line 6, The script's lone cd command ("cd
/mnt/d/Github/Karin-test-build") has no error handling so a failed directory
change could cause subsequent operations to run in the wrong folder; update
tests/verify-pnpm11.sh to check the exit status of the cd (e.g., perform the cd
and if it fails print a clear error to stderr and exit non‑zero) before
continuing, ensuring any subsequent package.json modifications only run after a
successful chdir.
tests/check-pnpm-version.sh (1)

3-3: ⚡ Quick win

Add error handling for directory changes.

The cd commands at lines 3 and 8 lack error handling. If the directory change fails, the script will continue executing in the wrong directory.

🛡️ Proposed fix
-cd /tmp
+cd /tmp || exit 1

Apply the same pattern to line 8.

🤖 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 `@tests/check-pnpm-version.sh` at line 3, The script's cd commands (the
existing "cd /tmp" at start and the other cd at line 8) lack error handling;
update both cd invocations to check their exit status and abort on failure
(e.g., append a conditional exit or add a short error message then exit) so the
script does not continue running in the wrong directory; apply this pattern to
the "cd /tmp" occurrences and ensure any subsequent cd uses follow the same
guard.
🤖 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 @.github/workflows/ci.yml:
- Line 43: The pnpm install step currently uses "pnpm install
--frozen-lockfile=false" without explanation; either add an inline comment above
that run step clarifying that the lockfile is intentionally allowed to float to
exercise compatibility across the pnpm (10/11) and Node (22/24/26) matrix, or
change the command to "pnpm install --frozen-lockfile" and update/commit the
lockfile for reproducible CI (or adopt a strategy to regenerate
per-tool-version); update only the run step referencing "pnpm install
--frozen-lockfile=false" and its surrounding comment to reflect the chosen
approach.

In `@package.json`:
- Line 30: Remove the packageManager field ("packageManager": "pnpm@10.14.0")
from package.json so CI matrix jobs can control pnpm versions, and rely on the
existing engines.pnpm constraint (e.g., "engines": { "pnpm": ">=9" }) for
compatibility; alternatively, if you must keep packageManager for local
reproducibility, update CI workflows that call pnpm/action-setup to remove their
explicit version inputs so they don't conflict with the pinned packageManager
value—ensure you modify either the packageManager entry or the CI job inputs,
not both.

In `@packages/core/tests/utils/fs/path.test.ts`:
- Around line 62-72: The tests in packages/core/tests/utils/fs/path.test.ts use
toBeTruthy()/toBeFalsy() which can mask non-boolean return values from
isSubPath; update the three assertions that reference isSubPath (the cases
"returns truthy for paths under the root", "returns falsy for paths outside the
root", and "returns falsy when target equals root") to assert strict booleans by
using toBe(true) for the positive case and toBe(false) for the two negative
cases so the tests fail if isSubPath returns a non-boolean (the function
referenced isSubPath).

In `@tests/setup.ts`:
- Line 25: The stub assignment currently sets g.debug to a function that returns
noop instead of the no-op itself; change the assignment so g.debug = noop (use
the existing noop function) instead of g.debug = () => noop to ensure calls to
g.debug execute the no-op rather than returning it; update the code referencing
g.debug if any assumptions about its return value exist (use the noop symbol and
the g.debug identifier to locate the line).

---

Nitpick comments:
In `@tests/check-pnpm-version.sh`:
- Line 3: The script's cd commands (the existing "cd /tmp" at start and the
other cd at line 8) lack error handling; update both cd invocations to check
their exit status and abort on failure (e.g., append a conditional exit or add a
short error message then exit) so the script does not continue running in the
wrong directory; apply this pattern to the "cd /tmp" occurrences and ensure any
subsequent cd uses follow the same guard.

In `@tests/run-matrix.sh`:
- Around line 6-10: Remove the dead associative array declaration NODE_PATHS
from the script (the declare -A NODE_PATHS=(...) block) since it is never used;
keep and use the existing NODE_DIRS variable as intended (no other code changes
required), and run the script to ensure no references to NODE_PATHS remain.
- Line 48: The test runner currently pipes the pnpm test output through "tail
-6" which truncates logs and loses valuable context; modify the invocation
around the PATH="$PNPM_BIN:$SAFE_PATH" pnpm test call to preserve more output by
either increasing the tail window (e.g., tail -100) or capturing the full output
to a temporary file (using tee) and only tailing the end for success while
printing the entire file on failure (check the pnpm test exit status and cat the
saved log if non-zero).

In `@tests/verify-pnpm11.sh`:
- Line 6: The script's lone cd command ("cd /mnt/d/Github/Karin-test-build") has
no error handling so a failed directory change could cause subsequent operations
to run in the wrong folder; update tests/verify-pnpm11.sh to check the exit
status of the cd (e.g., perform the cd and if it fails print a clear error to
stderr and exit non‑zero) before continuing, ensuring any subsequent
package.json modifications only run after a successful chdir.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 15e1ced1-a0fe-45bf-a477-9322961f99fc

📥 Commits

Reviewing files that changed from the base of the PR and between b2eef43 and da9166d.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (24)
  • .github/workflows/beta-version.yml
  • .github/workflows/ci.yml
  • .github/workflows/manual-publish-core.yml
  • .github/workflows/release.yml
  • package.json
  • packages/cli-Internal/package.json
  • packages/cli/package.json
  • packages/core/package.json
  • packages/core/tests/utils/button/convert.test.ts
  • packages/core/tests/utils/common/number.test.ts
  • packages/core/tests/utils/common/sleep.test.ts
  • packages/core/tests/utils/common/string.test.ts
  • packages/core/tests/utils/common/uptime.test.ts
  • packages/core/tests/utils/fs/json.test.ts
  • packages/core/tests/utils/fs/path.test.ts
  • packages/core/tests/utils/ini/index.test.ts
  • packages/core/tests/utils/system/range.test.ts
  • packages/core/tests/utils/system/time.test.ts
  • packages/create-karin/package.json
  • tests/check-pnpm-version.sh
  • tests/run-matrix.sh
  • tests/setup.ts
  • tests/verify-pnpm11.sh
  • vitest.config.ts

Comment thread .github/workflows/ci.yml Outdated
Comment thread package.json Outdated
Comment on lines +62 to +72
it('returns truthy for paths under the root', () => {
expect(isSubPath(process.cwd(), path.join(process.cwd(), 'a', 'b'))).toBeTruthy()
})

it('returns falsy for paths outside the root', () => {
expect(isSubPath(path.join(process.cwd(), 'a'), path.join(process.cwd(), 'b'))).toBeFalsy()
})

it('returns falsy when target equals root (relative is empty)', () => {
expect(isSubPath(process.cwd(), process.cwd())).toBeFalsy()
})
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 | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify whether isSubPath is typed/implemented as a strict boolean predicate.
# Expected: declaration/signature or implementation should indicate boolean return semantics.

rg -nP -C3 '\bisSubPath\b'

Repository: KarinJS/Karin

Length of output: 2904


🏁 Script executed:

cat -n packages/core/src/utils/fs/path.ts | sed -n '105,130p'

Repository: KarinJS/Karin

Length of output: 885


Replace toBeTruthy/toBeFalsy with strict boolean assertions.

The isSubPath function returns relative && !relative.startsWith('..') && !path.isAbsolute(relative) (line 119), which can return an empty string instead of the strict boolean false. Using toBeTruthy()/toBeFalsy() at lines 63, 67, and 71 masks this behavior; replace with toBe(true)/toBe(false) to enforce strict boolean semantics.

Suggested fix
   it('returns truthy for paths under the root', () => {
-    expect(isSubPath(process.cwd(), path.join(process.cwd(), 'a', 'b'))).toBeTruthy()
+    expect(isSubPath(process.cwd(), path.join(process.cwd(), 'a', 'b'))).toBe(true)
   })

   it('returns falsy for paths outside the root', () => {
-    expect(isSubPath(path.join(process.cwd(), 'a'), path.join(process.cwd(), 'b'))).toBeFalsy()
+    expect(isSubPath(path.join(process.cwd(), 'a'), path.join(process.cwd(), 'b'))).toBe(false)
   })

   it('returns falsy when target equals root (relative is empty)', () => {
-    expect(isSubPath(process.cwd(), process.cwd())).toBeFalsy()
+    expect(isSubPath(process.cwd(), process.cwd())).toBe(false)
   })
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
it('returns truthy for paths under the root', () => {
expect(isSubPath(process.cwd(), path.join(process.cwd(), 'a', 'b'))).toBeTruthy()
})
it('returns falsy for paths outside the root', () => {
expect(isSubPath(path.join(process.cwd(), 'a'), path.join(process.cwd(), 'b'))).toBeFalsy()
})
it('returns falsy when target equals root (relative is empty)', () => {
expect(isSubPath(process.cwd(), process.cwd())).toBeFalsy()
})
it('returns truthy for paths under the root', () => {
expect(isSubPath(process.cwd(), path.join(process.cwd(), 'a', 'b'))).toBe(true)
})
it('returns falsy for paths outside the root', () => {
expect(isSubPath(path.join(process.cwd(), 'a'), path.join(process.cwd(), 'b'))).toBe(false)
})
it('returns falsy when target equals root (relative is empty)', () => {
expect(isSubPath(process.cwd(), process.cwd())).toBe(false)
})
🤖 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 `@packages/core/tests/utils/fs/path.test.ts` around lines 62 - 72, The tests in
packages/core/tests/utils/fs/path.test.ts use toBeTruthy()/toBeFalsy() which can
mask non-boolean return values from isSubPath; update the three assertions that
reference isSubPath (the cases "returns truthy for paths under the root",
"returns falsy for paths outside the root", and "returns falsy when target
equals root") to assert strict booleans by using toBe(true) for the positive
case and toBe(false) for the two negative cases so the tests fail if isSubPath
returns a non-boolean (the function referenced isSubPath).

Comment thread tests/setup.ts

const g = globalThis as Record<string, unknown>
if (!g.logger) g.logger = stubLogger
if (!g.debug) g.debug = () => noop
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 | 🟡 Minor | ⚡ Quick win

Fix debug stub assignment to a direct no-op function.

Line 25 currently sets debug to a function that returns noop, not to noop itself.

Proposed fix
-if (!g.debug) g.debug = () => noop
+if (!g.debug) g.debug = noop
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (!g.debug) g.debug = () => noop
if (!g.debug) g.debug = noop
🤖 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 `@tests/setup.ts` at line 25, The stub assignment currently sets g.debug to a
function that returns noop instead of the no-op itself; change the assignment so
g.debug = noop (use the existing noop function) instead of g.debug = () => noop
to ensure calls to g.debug execute the no-op rather than returning it; update
the code referencing g.debug if any assumptions about its return value exist
(use the noop symbol and the g.debug identifier to locate the line).

- ci.yml 矩阵从 22/24/26 扩到 22/24/25/26,非 LTS 版本只配对 pnpm 11 控规模
- 新增构建步:pnpm --filter create-karin build
- 新增烟测步:node packages/create-karin/dist/index.mjs --help
  捕获 import 级 Node 兼容性回归(ora/prompts/kolorist 等)
- 配套本地校验脚本:
  - tests/verify-create-karin.sh:跑本地 dist 的 --help + 环境探测
  - tests/verify-create-karin-published.sh:跑发布版 pnpm create karin
  - tests/verify-create-karin-deep.sh:跑完整 -y 静默建项目流程
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: 2

🤖 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 `@tests/verify-create-karin-deep.sh`:
- Around line 8-9: The script uses a hardcoded WSL path in the cd command and
then builds CLI="$(pwd)/packages/create-karin/dist/index.mjs", which will fail
on other machines; change the cd + CLI setup to detect the repository root
dynamically (e.g. use git rev-parse --show-toplevel or resolve the script's
directory) and then set CLI relative to that root (keep the CLI variable name
and the call that points to packages/create-karin/dist/index.mjs so other logic
remains unchanged).

In `@tests/verify-create-karin.sh`:
- Around line 10-11: The script uses a hardcoded absolute path in the cd command
which breaks on other machines; replace that with portable repo-root detection
by computing the script directory or git repo root (e.g., via dirname "$0" or
git rev-parse --show-toplevel) and cd to that computed path instead; also set
CLI=packages/create-karin/dist/index.mjs relative to the computed root so both
the cd and CLI assignment use the repository root resolution (refer to the cd
command and the CLI variable in the script).
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 735ceb48-85e8-45bd-b629-aa63df13ada5

📥 Commits

Reviewing files that changed from the base of the PR and between da9166d and ffb77ad.

📒 Files selected for processing (4)
  • .github/workflows/ci.yml
  • tests/verify-create-karin-deep.sh
  • tests/verify-create-karin-published.sh
  • tests/verify-create-karin.sh

Comment on lines +8 to +9
cd /mnt/d/Github/Karin-test-build
CLI="$(pwd)/packages/create-karin/dist/index.mjs"
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 | ⚡ Quick win

Replace hardcoded WSL path with portable repository root detection.

The absolute path /mnt/d/Github/Karin-test-build is specific to your WSL environment and will break for any other developer or CI system. Use relative paths or detect the repository root dynamically.

🔧 Proposed fix using git to find repo root
-cd /mnt/d/Github/Karin-test-build
-CLI="$(pwd)/packages/create-karin/dist/index.mjs"
+REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
+cd "$REPO_ROOT"
+CLI="$REPO_ROOT/packages/create-karin/dist/index.mjs"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
cd /mnt/d/Github/Karin-test-build
CLI="$(pwd)/packages/create-karin/dist/index.mjs"
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
cd "$REPO_ROOT"
CLI="$REPO_ROOT/packages/create-karin/dist/index.mjs"
🤖 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 `@tests/verify-create-karin-deep.sh` around lines 8 - 9, The script uses a
hardcoded WSL path in the cd command and then builds
CLI="$(pwd)/packages/create-karin/dist/index.mjs", which will fail on other
machines; change the cd + CLI setup to detect the repository root dynamically
(e.g. use git rev-parse --show-toplevel or resolve the script's directory) and
then set CLI relative to that root (keep the CLI variable name and the call that
points to packages/create-karin/dist/index.mjs so other logic remains
unchanged).

Comment on lines +10 to +11
cd /mnt/d/Github/Karin-test-build
CLI=packages/create-karin/dist/index.mjs
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 | ⚡ Quick win

Replace hardcoded WSL path with portable repository root detection.

The absolute path /mnt/d/Github/Karin-test-build is specific to your WSL environment and will break for any other developer. Use relative path resolution instead.

🔧 Proposed fix using relative path from script location
-cd /mnt/d/Github/Karin-test-build
-CLI=packages/create-karin/dist/index.mjs
+REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
+CLI="$REPO_ROOT/packages/create-karin/dist/index.mjs"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
cd /mnt/d/Github/Karin-test-build
CLI=packages/create-karin/dist/index.mjs
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
CLI="$REPO_ROOT/packages/create-karin/dist/index.mjs"
🤖 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 `@tests/verify-create-karin.sh` around lines 10 - 11, The script uses a
hardcoded absolute path in the cd command which breaks on other machines;
replace that with portable repo-root detection by computing the script directory
or git repo root (e.g., via dirname "$0" or git rev-parse --show-toplevel) and
cd to that computed path instead; also set
CLI=packages/create-karin/dist/index.mjs relative to the computed root so both
the cd and CLI assignment use the repository root resolution (refer to the cd
command and the CLI variable in the script).

sj817 added 2 commits May 15, 2026 22:07
- 删 package.json 里的 packageManager: pnpm@10.14.0:和 pnpm/action-setup
  的 version 输入冲突 (ERR_PNPM_BAD_PM_VERSION),且本地用着也烦
- beta-version / release / manual-publish-core 三个发布相关 workflow
  统一回退到 pnpm 9,setup-node 步骤提前到 pnpm install 之前
- ci.yml 矩阵新增 pnpm 9 作为 baseline (22×9、24×9),
  --frozen-lockfile=false 改成更稳的 --no-frozen-lockfile
- 新增 tests/verify-pnpm9.sh:本地复现 CI 的 pnpm 9 安装 + 测试路径
pnpm 11 把 onlyBuiltDependencies 的语义收紧了:列在白名单里的依赖也得通过
'pnpm approve-builds' 显式批准,否则装包后直接以 exit 1 报错。
单测/构建-create-karin 路径用不到 native 模块(sqlite3/node-pty/parcel-watcher
等),直接 --ignore-scripts 跳过 postinstall,跨 pnpm 9/10/11 行为一致。

本地用 pnpm 11.1.1 全量复现:install → pnpm test (108 passed) → build
create-karin → --help 烟测,全通过。
@github-actions
Copy link
Copy Markdown
Contributor

你可以通过以下命令安装该版本:

pnpm add https://pkg.pr.new/node-karin@29555ee -w

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.

2 participants