Token导航 LogoToken导航

Agent Skill · 研究检索

test-migration(测试迁移)

用于辅助测试设计、自动化测试、用例整理和回归验证。它适合让 Agent 编写单元测试、端到端测试、测试计划或根据失败日志定位问题。使用时需要确认项目测试框架、运行命令和夹具数据,避免为了通过测试而改坏真实逻辑;涉及浏览器或外部服务时,应区分本地模拟、测试环境和生产环境。

test-migration 是研究检索类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为接触敏感数据;许可证信息还不明确,第三方扫描已通过,按安装量在研究检索类的 73,674 个 Skill 里排第 65,084。

总安装 288周安装 12GitHub Stars 4下载 96核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
unknown

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:test-migration(测试迁移)
来源仓库:https://github.com/petrkindlmann/qa-skills
仓库路径:skills/test-migration
安装命令:
npx skills add https://github.com/petrkindlmann/qa-skills --skill test-migration
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/petrkindlmann/qa-skills --skill test-migration

这个 Skill 是做什么的

研究检索类 Skill 主要解决「找资料、核对事实、把来源整理清楚」的问题,通常会让助手先检索再总结。

用于辅助测试设计、自动化测试、用例整理和回归验证。适合编写单元测试、端到端测试或根据日志定位问题。需确认项目测试框架、运行命令和夹具数据后使用。test-migration 属于研究检索类 Skill,可作为该场景下的辅助能力补充。涉及浏览器或外部服务时应区分模拟环境与生产环境。

安装方式:通过 npx 从指定 GitHub 仓库添加。

来源仓库内路径:skills/test-migration

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/petrkindlmann/qa-skills --skill test-migration;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要接触敏感数据,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

test-migration 怎么安装?

在终端执行 npx skills add https://github.com/petrkindlmann/qa-skills --skill test-migration。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

test-migration 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

test-migration 需要什么权限?

权限级别是接触敏感数据。该 Skill 可能接触密钥、Token、环境变量或敏感配置,应进入高风险复核队列,默认不自动发布。

test-migration 是免费的吗?

公开资料没有标注明确许可证,收费和商用限制都无法确认。正式使用前请到来源仓库核对授权说明。

test-migration 用的人多吗?

公开数据是累计安装 288 次,近一周安装 12 次,下载 96 次,GitHub 4 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

test-migration 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 需要接触敏感数据,装到常用环境前要先评估影响面。
  • 许可证没有明确标注,能不能商用、能不能再分发都不确定。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理研究检索类任务、又不想每次都手写提示词的人。

不太适合

  • 环境里有大量密钥、凭证,不方便给第三方 Skill 读取的人。
  • 需要明确授权才能用到公司项目里的场景。
  • 需要厂商级技术支持和 SLA 的生产系统。

研究检索类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
find-skills

寻找技能 · Codex、Claude

31,199,81316,486操作浏览器MIT有提醒
self-improving-agent

自我改进 Agent · OpenClaw

16,464,0023,396接触敏感数据MIT-0通过
soultrace

灵魂追踪 · Codex、Claude

7,588,94412需要联网未明确有提醒
self-improving

自我完善 · OpenClaw

6,829,2841,046需要联网MIT-0通过
microsoft-foundry

微软代工厂 · Codex、Claude

6,614,144764调用外部服务未明确有提醒
test-migration

测试迁移 · 本页

2884接触敏感数据未明确通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文


Discovery Questions

Check .agents/qa-project-context.md first. If it exists, use it as context and skip questions already answered there.

Current state:

  • What framework are you migrating from? (Selenium, Cypress, Protractor, Jest, Mocha, Jasmine)
  • What framework are you migrating to? (Playwright, Vitest, Jest)
  • How many tests exist? (10, 100, 500, 1000+)
  • What is the current flakiness rate? (Migrating flaky tests reproduces flakiness)
  • What percentage of tests are disabled or skipped?

Test infrastructure:

  • What supporting infrastructure exists? (Page objects, utility libraries, custom commands, fixtures, data factories)
  • How are test accounts and test data managed?
  • What CI pipeline runs the tests? How long does it take?
  • Are there custom reporters, plugins, or integrations that need migration?

Parallel running:

  • Can both test frameworks run in CI simultaneously?
  • Is there budget for running both suites during migration? (Double CI cost temporarily)
  • What is the timeline pressure? (Urgent: framework EOL, or comfortable: modernization project)

Team:

  • How many engineers write and maintain tests?
  • What is the team's familiarity with the target framework?
  • Is there training budget or time for learning the new framework?

Core Principles

1. Incremental over big bang

A big-bang migration -- rewriting all tests at once -- is the highest-risk approach. It stops all test development for weeks, introduces a large batch of unproven tests, and removes the proven safety net of the existing suite. Always migrate incrementally: one test at a time, one module at a time.

2. Parallel run until parity

Run both the old and new test suites in CI until the new suite provides at least the same coverage as the old one. The old suite is your safety net. Do not decommission it until the new suite has proven itself over multiple sprints.

3. Migrate highest-value tests first

Start with tests that are most valuable: critical user journeys, frequently failing tests (which benefit most from a better framework), and tests covering high-risk areas. Save low-value tests for last -- some may not be worth migrating at all.

4. Modernize patterns during migration, don't just translate

Translating a bad Selenium test into a bad Playwright test wastes the migration opportunity. When migrating each test, ask: "How would I write this test from scratch in the target framework?" Use modern patterns, user-facing locators, auto-waiting, and fixtures.


Migration Workflow

Phase 1: Audit existing suite (Week 1)

Before migrating a single test, understand what you have.

Audit checklist:
  [ ] Total test count: ___
  [ ] Tests by category: unit ___, integration ___, E2E ___
  [ ] Disabled/skipped tests: ___ (percentage: ___%)
  [ ] Flaky tests: ___ (percentage: ___%)
  [ ] Code coverage: ___% (if measured)
  [ ] Test runtime: ___
  [ ] Page objects / utilities: ___ files
  [ ] Custom plugins / commands: ___ (list)
  [ ] CI pipeline stages: ___

Priority categorization:
  Critical (migrate first): Tests covering revenue-impacting flows
  High: Tests covering core user journeys
  Medium: Tests covering secondary features
  Low: Tests covering admin, edge cases, rarely-used features
  Skip: Disabled tests, duplicate tests, obsolete feature tests

Phase 2: Set up target framework (Week 1-2)

Install and configure the new framework alongside the old one.

Setup checklist:
  [ ] Install target framework and dependencies
  [ ] Create configuration file (playwright.config.ts, vitest.config.ts)
  [ ] Configure test directory structure (separate from old tests)
  [ ] Set up CI pipeline stage for new framework (non-blocking)
  [ ] Create a single smoke test to verify the setup works
  [ ] Configure reporters to match existing reporting format
  [ ] Set up shared environment variables and secrets

Phase 3: Migrate shared infrastructure (Week 2-3)

Migrate page objects, utilities, data factories, and helper functions before migrating tests. Tests depend on infrastructure.

Infrastructure migration order:
  1. Base page object / test base class
  2. Authentication helpers (login, session management)
  3. API client helpers (data setup, cleanup)
  4. Common page objects (navigation, header, footer)
  5. Data factories (user creation, test data generation)
  6. Custom assertions / matchers
  7. Feature-specific page objects (migrate with their tests)

Phase 4: Migrate tests by priority (Week 3-8+)

Migrate tests in priority order. Each migrated test follows the same pattern.

Per-test migration pattern:
  1. Read the old test — understand what it actually verifies
  2. Write the new test from scratch using modern patterns
     (do not line-by-line translate)
  3. Run the new test locally — verify it passes
  4. Run the new test in CI — verify it passes in CI
  5. Mark the old test as "migrated" (tag, not delete)
  6. After 1 sprint of parallel passing, delete the old test

Phase 5: Parallel run in CI (Throughout)

Both suites run in every CI pipeline during the migration.

# GitHub Actions: parallel suite execution
jobs:
  old-suite:
    name: "E2E Tests (Cypress) [Legacy]"
    runs-on: ubuntu-latest
    # Non-blocking during migration — failures are informational
    continue-on-error: true
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npx cypress run

  new-suite:
    name: "E2E Tests (Playwright) [Migration]"
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npx playwright install --with-deps
      - run: npx playwright test

Phase 6: Decommission old framework (Final)

Only after the new suite has reached parity and proven stability.

Decommission checklist:
  [ ] All critical and high-priority tests migrated
  [ ] New suite has been green in CI for 2+ consecutive sprints
  [ ] New suite flakiness rate is at or below old suite
  [ ] Coverage comparison shows no regression
  [ ] Team has been writing new tests in the new framework for 2+ sprints
  [ ] Old framework dependencies removed from package.json
  [ ] Old test files deleted (not just disabled)
  [ ] CI pipeline updated to run only the new suite
  [ ] Documentation updated to reference new framework

Translation Patterns

Locator mapping

Old PatternNew Pattern (Playwright)Notes
By.id('submit-btn')page.getByRole('button', {name: 'Submit'})Prefer role-based
By.css('.nav-item.active')page.getByRole('link', {name: 'Dashboard'})Use user-visible text
By.xpath('//div[@class="modal"]')page.getByRole('dialog')ARIA roles are more stable
By.css('[data-testid="user-menu"]')page.getByTestId('user-menu')testid as fallback
cy.get('.product-card').first()page.getByRole('article').first()Semantic elements preferred
cy.contains('Add to cart')page.getByRole('button', {name: 'Add to cart'})Specific role is better
element(by.model('username'))page.getByLabel('Username')Angular model → label

Wait strategy mapping

Old PatternNew Pattern (Playwright)Notes
Thread.sleep(3000)*(remove entirely)*Playwright auto-waits
WebDriverWait(driver, 10).until(visible)*(remove entirely)*Auto-wait on actions
cy.wait(2000)*(remove entirely)*Auto-wait on assertions
cy.wait('@apiCall')page.waitForResponse('**/api/data')Explicit network wait
browser.wait(EC.presenceOf(...))await expect(locator).toBeVisible()Web-first assertion
implicitlyWait(10, SECONDS)*(remove entirely — configure in config)*Use actionTimeout in config
FluentWait with pollingawait expect(locator).toHaveText('Done')Web-first assertions retry

Assertion mapping

Old PatternNew Pattern (Playwright)Notes
assert element.is_displayed()await expect(locator).toBeVisible()Auto-retrying
cy.get('.msg').should('have.text', 'Done')await expect(locator).toHaveText('Done')Auto-retrying
expect(element.getText()).toBe('Done')await expect(locator).toHaveText('Done')Auto-retrying
cy.url().should('include', '/dashboard')await expect(page).toHaveURL(/dashboard/)Auto-retrying
assert len(elements) == 5await expect(locator).toHaveCount(5)Auto-retrying

Config mapping

Old (Cypress)New (Playwright)
baseUrl in cypress.config.tsuse.baseURL in playwright.config.ts
defaultCommandTimeout: 10000use.actionTimeout: 10000
pageLoadTimeout: 30000use.navigationTimeout: 30000
retries: {runMode: 2}retries: 2
video: trueuse.video: 'on'
screenshotOnRunFailure: trueuse.screenshot: 'only-on-failure'

Specific Migration Guides

Selenium to Playwright

Key differences:

  • Selenium uses the WebDriver protocol; Playwright uses the Chrome DevTools Protocol (CDP) and browser-specific protocols. Playwright is faster because it bypasses the HTTP-based WebDriver layer.
  • Selenium requires explicit waits everywhere; Playwright auto-waits on every action and assertion.
  • Selenium locators are strings; Playwright locators are objects with built-in filtering and chaining.
# Selenium (Python)
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver.get("https://example.com/login")
wait = WebDriverWait(driver, 10)
email_input = wait.until(EC.visibility_of_element_located((By.ID, "email")))
email_input.send_keys("user@example.com")
driver.find_element(By.ID, "password").send_keys("pass123")
driver.find_element(By.CSS_SELECTOR, "button[type='submit']").click()
wait.until(EC.url_contains("/dashboard"))
// Playwright (TypeScript)
await page.goto('https://example.com/login');
await page.getByLabel('Email').fill('user@example.com');
await page.getByLabel('Password').fill('pass123');
await page.getByRole('button', { name: 'Sign in' }).click();
await expect(page).toHaveURL(/dashboard/);

Migration notes:

  • Remove all explicit waits (WebDriverWait, implicitly_wait). Playwright auto-waits.
  • Replace find_element(By.ID/CSS/XPATH) with getByRole, getByLabel, getByTestId.
  • Replace send_keys with fill (clears the field first, which is usually what you want).
  • Replace assert statements with expect (auto-retrying web-first assertions).
  • Replace WebDriver session management with Playwright's BrowserContext (lighter, faster).

Jest to Vitest

Key differences:

  • Vitest is API-compatible with Jest for most use cases. Many tests work unchanged.
  • Vitest uses vi instead of jest for mock/spy/timer utilities.
  • Vitest uses Vite's transform pipeline (esbuild), which is significantly faster.
  • Vitest supports ESM natively without transformation.
// Jest
import { jest } from '@jest/globals';
jest.mock('./database');
jest.useFakeTimers();
const spy = jest.spyOn(service, 'fetch');
jest.advanceTimersByTime(1000);

// Vitest
import { vi } from 'vitest';
vi.mock('./database');
vi.useFakeTimers();
const spy = vi.spyOn(service, 'fetch');
vi.advanceTimersByTime(1000);

Migration notes:

  • Replace jest. with vi. in mock/spy/timer calls.
  • Update jest.config.js to vitest.config.ts (Vite-based config).
  • Replace @jest/globals imports with vitest imports.
  • Remove Babel/ts-jest transform config (Vitest uses esbuild natively).
  • jest.fn() becomes vi.fn(). APIs are otherwise identical.
  • moduleNameMapper in Jest config becomes resolve.alias in Vitest config.
  • Speed improvement: expect 2-10x faster test execution.
// vitest.config.ts (replacing jest.config.js)
import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    globals: true,            // Optional: use describe/it/expect without imports
    environment: 'jsdom',     // Replaces jest-environment-jsdom
    setupFiles: ['./test/setup.ts'],
    coverage: {
      provider: 'v8',         // Replaces jest --coverage (istanbul)
      reporter: ['text', 'json', 'html'],
    },
  },
  resolve: {
    alias: {
      '@': '/src',            // Replaces moduleNameMapper
    },
  },
});

Cypress to Playwright

Key differences:

  • Cypress uses a command queue (chaining); Playwright uses async/await. This is the biggest mental model shift.
  • Cypress runs inside the browser; Playwright runs outside and controls it. This affects how you think about context and scope.
  • Cypress cy.intercept() becomes page.route(). Similar capability, different API.
  • Cypress custom commands become Playwright fixtures.
// Cypress
cy.visit('/products');
cy.get('[data-testid="search"]').type('widget');
cy.intercept('GET', '/api/products*', { fixture: 'products.json' }).as('search');
cy.wait('@search');
cy.get('.product-card').should('have.length', 3);
cy.get('.product-card').first().find('.price').should('contain', '$29.99');
// Playwright
await page.route('**/api/products*', route =>
  route.fulfill({ json: { items: [/*...*/] } }),
);
await page.goto('/products');
await page.getByTestId('search').fill('widget');
await expect(page.locator('.product-card')).toHaveCount(3);
await expect(page.locator('.product-card').first().locator('.price')).toContainText('$29.99');

Migration notes:

  • Replace cy.visit() with await page.goto().
  • Replace cy.get().type() with await locator.fill() (fill clears first, which is almost always correct).
  • Replace cy.intercept() + cy.wait() with page.route() + page.waitForResponse().
  • Replace .should() chain assertions with await expect() auto-retrying assertions.
  • Replace custom commands with fixtures (composable, typed, auto-teardown).
  • Remove cy.wrap(), cy.then() patterns -- async/await replaces the command queue.

Protractor to Playwright

Protractor reached end-of-life in 2023. This migration is urgent if not already completed.

Key differences:

  • Protractor was built for AngularJS with automatic waitForAngular. Playwright has no Angular-specific handling (and does not need it with modern Angular).
  • Protractor's element(by.model()), element(by.binding()) have no direct equivalent. Use getByLabel, getByRole, or getByTestId.
  • Protractor's browser.get() becomes page.goto().
// Protractor
browser.get('/login');
element(by.model('username')).sendKeys('admin');
element(by.model('password')).sendKeys('secret');
element(by.css('button[type="submit"]')).click();
browser.wait(EC.urlContains('/dashboard'), 10000);
expect(element(by.binding('user.name')).getText()).toEqual('Admin');
// Playwright
await page.goto('/login');
await page.getByLabel('Username').fill('admin');
await page.getByLabel('Password').fill('secret');
await page.getByRole('button', { name: 'Sign in' }).click();
await expect(page).toHaveURL(/dashboard/);
await expect(page.getByText('Admin')).toBeVisible();

Migration notes:

  • Remove all browser.waitForAngular() calls (unnecessary with modern frameworks).
  • Replace element(by.model('x')) with page.getByLabel('X') (map model name to its label).
  • Replace element(by.binding('x')) with page.getByText() or page.getByTestId().
  • Replace browser.wait(EC.*) with Playwright's auto-wait or expect assertions.
  • Replace Jasmine assertions with Playwright's expect (auto-retrying).
  • Protractor's onPrepare becomes Playwright's globalSetup.

Parallel Running Strategy

Coverage comparison during migration

Track coverage parity between old and new suites to ensure nothing is lost.

Coverage tracking spreadsheet:

Feature Area     | Old Suite Tests | New Suite Tests | Parity | Notes
Login/Auth       | 8               | 8               | 100%   | Complete
Dashboard        | 12              | 7               | 58%    | In progress
Search           | 6               | 0               | 0%     | Not started
Checkout         | 15              | 15              | 100%   | Complete
User Settings    | 4               | 4               | 100%   | Complete
Admin Panel      | 20              | 0               | 0%     | Low priority
---              | ---             | ---             | ---    |
Total            | 65              | 34              | 52%    | On track for Q2

Gradual cutover timeline

For a 200-test suite, plan 10 sprints: setup + infrastructure (Sprint 1-2), critical path migration (Sprint 3-5, ~50 tests), bulk migration (Sprint 6-8), cleanup and decommission (Sprint 9-10). The old suite starts as blocking and becomes non-blocking as parity approaches. New tests are written exclusively in the new framework from Sprint 3 onward.

When to delete old tests

Tag old tests as "migrated" rather than deleting immediately. Delete only after the new equivalent has been passing in CI for 2+ weeks and a manual review confirms no unique assertions are lost. If the old test catches a regression the new test misses, enhance the new test first.


Anti-Patterns

Big bang migration

Stopping all development for 3 months to rewrite every test at once. The team cannot ship new tests during the rewrite, coverage freezes, and the new suite is untested in CI until it lands all at once.

Fix: Incremental migration with parallel running. Migrate one module per sprint. Both suites run in CI throughout. New tests are written in the new framework from day one.

Translating without modernizing

Line-by-line translation of Selenium tests into Playwright tests, preserving explicit waits, CSS selectors, and fragile patterns. The tests are in a new framework but have all the old problems.

Fix: Rewrite each test using the target framework's best practices. Replace CSS selectors with getByRole. Remove explicit waits. Use fixtures instead of beforeEach. The migration is an opportunity to improve every test.

No parallel running

Decommissioning the old suite before the new suite is proven. A regression slips through because the new suite was missing a test that existed in the old suite.

Fix: Run both suites in CI for at least 2 sprints after reaching coverage parity. The old suite is cheap insurance. Only decommission when the new suite has proven it catches regressions on its own.

Losing coverage during migration

Twenty tests in the old suite become fifteen in the new suite because "some were redundant." But nobody verified whether the deleted tests were truly redundant or covered unique scenarios.

Fix: Map each old test to its new equivalent explicitly. Track coverage parity in a spreadsheet. If an old test is intentionally not migrated, document why and verify that its coverage is provided by other tests.

Migrating flaky tests as-is

A test that is flaky in Selenium will be flaky in Playwright if the root cause is in the test design (shared state, timing assumptions, non-deterministic data). Migrating it faithfully reproduces the flakiness.

Fix: When migrating a flaky test, diagnose the flakiness first. Fix the root cause, then write the new test with the fix incorporated. The migration is the best time to fix flakiness because you are rewriting the test anyway.

No team training

Migrating to Playwright while the team has never used Playwright means the migration champions write everything, and the rest of the team cannot maintain the new tests.

Fix: Run a 2-hour workshop before starting the migration. Pair-program on the first 10 migrated tests (migration champion + team member). Create a team-specific style guide for the new framework. Require at least 2 team members to review each migrated test.


Done When

  • Migration scope is defined: which tests move first (critical paths), which move last (low priority), and which are intentionally not migrated (with documented rationale)
  • Coverage parity is verified before decommissioning the old framework, with an explicit feature-area comparison showing no regression in test count or critical scenario coverage
  • Parallel run period is completed with both frameworks passing in CI for at least 2 consecutive sprints
  • Migration retrospective has been conducted with lessons captured (flakiness root causes, pattern improvements, team training gaps)
  • Old framework is fully removed: dependencies deleted from package.json, old test files deleted (not just disabled), and CI config updated to run only the new suite

Related Skills

SkillRelationship
playwright-automationTarget framework best practices for Selenium/Cypress/Protractor migrations
unit-testingJest-to-Vitest migration patterns and best practices
ci-cd-integrationParallel CI configuration for running both suites during migration
test-reliabilityFix flaky tests during migration rather than translating flakiness
qa-metricsTrack migration progress: test count parity, flakiness comparison, coverage delta
test-strategyMigration decisions should align with the overall test strategy

平台分布

Codex

32.88%
按下载量换算32

Claude

31.14%
按下载量换算30

Cursor

21.42%
按下载量换算21

Gemini CLI

10.41%
按下载量换算10

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

接触敏感数据

该 Skill 可能接触密钥、Token、环境变量或敏感配置,应进入高风险复核队列,默认不自动发布。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills