Token导航 LogoToken导航

Agent Skill · 前端设计

test-writer(测试编写者)

用于辅助前端页面、组件、样式和交互逻辑的开发与维护。它适合让 Agent 生成或审查 React、Next.js、Vue、Tailwind、CSS 等相关代码,整理组件结构,或定位布局和性能问题。使用时需要结合项目现有设计系统、路由和构建方式,避免只生成孤立片段;涉及页面改动时,应配合本地预览和构建检查确认视觉效果。

test-writer 是前端设计类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为操作浏览器;许可证为 MIT,第三方扫描已通过,按安装量在前端设计类的 10,216 个 Skill 里排第 1,186。

总安装 7,056周安装 294GitHub Stars 66,321下载 2,352核验 2026-05-01

安装说明

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

安装方式

通过对话安装

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

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

命令行安装

复制命令到本机终端执行。不同来源提供的安装方式可能略有差异;本站展示可直接复制的安装命令,安装前请核对来源页面。

skills.shnpx skills
npx skills add https://github.com/leonardomso/33-js-concepts --skill test-writer

这个 Skill 是做什么的

前端设计类 Skill 关注页面结构、视觉规范和组件写法,输出通常是可运行的界面代码。

test-writer 专为 JavaScript 概念页面编写自动化测试而设计。适用于从文档中提取代码示例并生成对应单元测试用例。通过 GitHub 安装并使用 npx skills add 命令添加该技能。需确认项目已配置相应测试框架(如 Jest、Mocha 等)方可正常运行。

建议定期检查测试覆盖率报告以确保文档准确性。

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

上手步骤

4 步
  1. 1

    确认自己的宿主工具

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

  2. 2

    拿到安装命令

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

  3. 3

    安装后重启宿主

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

  4. 4

    按最小权限试用

    它需要操作浏览器,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

test-writer 怎么安装?

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

test-writer 支持哪些 AI 工具?

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

test-writer 需要什么权限?

权限级别是操作浏览器。该 Skill 可能涉及浏览器控制能力,使用时可能读取或操作网页内容,需要在受控环境中确认权限边界。

test-writer 是免费的吗?

来源标注的许可证是 MIT。本站不代收任何费用,也不托管安装包;能否商用、要不要署名,以许可证原文为准。

test-writer 用的人多吗?

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

test-writer 安全吗?

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

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

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 3 个目录同时收录,说明这个 Skill 流传比较广。
  • 许可证明确为 MIT,商用和分发边界好判断。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理前端设计类任务、又不想每次都手写提示词的人。
  • 需要许可证清楚、并且有第三方扫描结果的团队项目。

不太适合

  • 需要厂商级技术支持和 SLA 的生产系统。

前端设计类 Skill 对比

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

前端设计 · Codex、Claude

8,823,360126,072只读MIT通过
vercel-composition-patterns

Vercel 组合模式 · Codex、Claude

3,858,81625,893需要联网MIT通过
vercel-react-native-skills

Vercel React native skills 前端 · Codex、Claude

2,468,66425,878只读MIT通过
adapt

adapt 搜索 · Codex、Claude

2,027,04023,125操作浏览器未明确通过
bolder

bolder 分析 · Codex、Claude

2,004,28823,130只读未明确通过
test-writer

测试编写者 · 本页

7,05666,321操作浏览器MIT通过

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

SKILL.md 原文

Skill: Test Writer for Concept Pages

Use this skill to generate comprehensive Vitest tests for all code examples in a concept documentation page. Tests verify that code examples in the documentation are accurate and work as described.

When to Use

  • After writing a new concept page
  • When adding new code examples to existing pages
  • When updating existing code examples
  • To verify documentation accuracy through automated tests
  • Before publishing to ensure all examples work correctly

Test Writing Methodology

Follow these four phases to create comprehensive tests for a concept page.

Phase 1: Code Example Extraction

Scan the concept page for all code examples and categorize them:

CategoryCharacteristicsAction
TestableHas console.log with output comments, returns valuesWrite tests
DOM-specificUses document, window, DOM APIs, event handlersWrite DOM tests (separate file)
Error examplesIntentionally throws errors, demonstrates failuresWrite tests with toThrow
ConceptualASCII diagrams, pseudo-code, incomplete snippetsSkip (document why)
Browser-onlyUses browser APIs not available in jsdomSkip or mock

Phase 2: Determine Test File Structure

tests/
├── fundamentals/              # Concepts 1-6
├── functions-execution/       # Concepts 7-8
├── web-platform/             # Concepts 9-10
├── object-oriented/          # Concepts 11-15
├── functional-programming/   # Concepts 16-19
├── async-javascript/         # Concepts 20-22
├── advanced-topics/          # Concepts 23-31
└── beyond/                   # Extended concepts
    └── {subcategory}/

File naming:

  • Standard tests: {concept-name}.test.js
  • DOM tests: {concept-name}.dom.test.js

Phase 3: Convert Examples to Tests

For each testable code example:

  1. Identify the expected output (from console.log comments or documented behavior)
  2. Convert to expect assertions
  3. Add source line reference in comments
  4. Group related tests in describe blocks matching documentation sections

Phase 4: Handle Special Cases

CaseSolution
Browser-only APIsUse jsdom environment or skip with note
Timing-dependent codeUse vi.useFakeTimers() or test the logic, not timing
Side effectsCapture output or test mutations
Intentional errorsUse expect(() => {...}).toThrow()
Async codeUse async/await with proper assertions

Project Test Conventions

Import Pattern

import { describe, it, expect } from 'vitest'

For DOM tests or tests needing mocks:

import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'

DOM Test File Header

/**
 * @vitest-environment jsdom
 */
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'

Describe Block Organization

Match the structure of the documentation:

describe('Concept Name', () => {
  describe('Section from Documentation', () => {
    describe('Subsection if needed', () => {
      it('should [specific behavior]', () => {
        // Test
      })
    })
  })
})

Test Naming Convention

  • Start with "should"
  • Be descriptive and specific
  • Match the documented behavior
// Good
it('should return "object" for typeof null', () => {})
it('should throw TypeError when accessing property of undefined', () => {})
it('should resolve promises in order they were created', () => {})

// Bad
it('test typeof', () => {})
it('works correctly', () => {})
it('null test', () => {})

Source Line References

Always reference the documentation source:

// ============================================================
// SECTION NAME FROM DOCUMENTATION
// From {concept}.mdx lines XX-YY
// ============================================================

describe('Section Name', () => {
  // From lines 45-52: Basic typeof examples
  it('should return correct type strings', () => {
    // Test
  })
})

Test Patterns Reference

Pattern 1: Basic Value Assertion

Documentation:

console.log(typeof "hello")  // "string"
console.log(typeof 42)       // "number"

Test:

// From lines XX-YY: typeof examples
it('should return correct type for primitives', () => {
  expect(typeof "hello").toBe("string")
  expect(typeof 42).toBe("number")
})

Pattern 2: Multiple Related Assertions

Documentation:

let a = "hello"
let b = "hello"
console.log(a === b)  // true

let obj1 = { x: 1 }
let obj2 = { x: 1 }
console.log(obj1 === obj2)  // false

Test:

// From lines XX-YY: Primitive vs object comparison
it('should compare primitives by value', () => {
  let a = "hello"
  let b = "hello"
  expect(a === b).toBe(true)
})

it('should compare objects by reference', () => {
  let obj1 = { x: 1 }
  let obj2 = { x: 1 }
  expect(obj1 === obj2).toBe(false)
})

Pattern 3: Function Return Values

Documentation:

function greet(name) {
  return "Hello, " + name + "!"
}

console.log(greet("Alice"))  // "Hello, Alice!"

Test:

// From lines XX-YY: greet function example
it('should return greeting with name', () => {
  function greet(name) {
    return "Hello, " + name + "!"
  }

  expect(greet("Alice")).toBe("Hello, Alice!")
})

Pattern 4: Error Testing

Documentation:

// This throws an error!
const obj = null
console.log(obj.property)  // TypeError: Cannot read property of null

Test:

// From lines XX-YY: Accessing property of null
it('should throw TypeError when accessing property of null', () => {
  const obj = null

  expect(() => {
    obj.property
  }).toThrow(TypeError)
})

Pattern 5: Specific Error Messages

Documentation:

function divide(a, b) {
  if (b === 0) throw new Error("Cannot divide by zero")
  return a / b
}

Test:

// From lines XX-YY: divide function with error
it('should throw error when dividing by zero', () => {
  function divide(a, b) {
    if (b === 0) throw new Error("Cannot divide by zero")
    return a / b
  }

  expect(() => divide(10, 0)).toThrow("Cannot divide by zero")
  expect(divide(10, 2)).toBe(5)
})

Pattern 6: Async/Await Testing

Documentation:

async function fetchUser(id) {
  const response = await fetch(`/api/users/${id}`)
  return response.json()
}

Test:

// From lines XX-YY: async fetchUser function
it('should fetch user data asynchronously', async () => {
  // Mock fetch for testing
  global.fetch = vi.fn(() =>
    Promise.resolve({
      json: () => Promise.resolve({ id: 1, name: 'Alice' })
    })
  )

  async function fetchUser(id) {
    const response = await fetch(`/api/users/${id}`)
    return response.json()
  }

  const user = await fetchUser(1)
  expect(user).toEqual({ id: 1, name: 'Alice' })
})

Pattern 7: Promise Testing

Documentation:

const promise = new Promise((resolve) => {
  resolve("done")
})

promise.then(result => console.log(result))  // "done"

Test:

// From lines XX-YY: Basic Promise resolution
it('should resolve with correct value', async () => {
  const promise = new Promise((resolve) => {
    resolve("done")
  })

  await expect(promise).resolves.toBe("done")
})

Pattern 8: Promise Rejection

Documentation:

const promise = new Promise((resolve, reject) => {
  reject(new Error("Something went wrong"))
})

Test:

// From lines XX-YY: Promise rejection
it('should reject with error', async () => {
  const promise = new Promise((resolve, reject) => {
    reject(new Error("Something went wrong"))
  })

  await expect(promise).rejects.toThrow("Something went wrong")
})

Pattern 9: Floating Point Comparison

Documentation:

console.log(0.1 + 0.2)         // 0.30000000000000004
console.log(0.1 + 0.2 === 0.3) // false

Test:

// From lines XX-YY: Floating point precision
it('should demonstrate floating point imprecision', () => {
  expect(0.1 + 0.2).not.toBe(0.3)
  expect(0.1 + 0.2).toBeCloseTo(0.3)
  expect(0.1 + 0.2 === 0.3).toBe(false)
})

Pattern 10: Array Method Testing

Documentation:

const numbers = [1, 2, 3, 4, 5]
const doubled = numbers.map(n => n * 2)
console.log(doubled)  // [2, 4, 6, 8, 10]

Test:

// From lines XX-YY: Array map example
it('should double all numbers in array', () => {
  const numbers = [1, 2, 3, 4, 5]
  const doubled = numbers.map(n => n * 2)

  expect(doubled).toEqual([2, 4, 6, 8, 10])
  expect(numbers).toEqual([1, 2, 3, 4, 5]) // Original unchanged
})

Pattern 11: Object Mutation Testing

Documentation:

const obj = { a: 1 }
obj.b = 2
console.log(obj)  // { a: 1, b: 2 }

Test:

// From lines XX-YY: Object mutation
it('should allow adding properties to objects', () => {
  const obj = { a: 1 }
  obj.b = 2

  expect(obj).toEqual({ a: 1, b: 2 })
})

Pattern 12: Closure Testing

Documentation:

function counter() {
  let count = 0
  return function() {
    count++
    return count
  }
}

const increment = counter()
console.log(increment())  // 1
console.log(increment())  // 2
console.log(increment())  // 3

Test:

// From lines XX-YY: Closure counter example
it('should maintain state across calls via closure', () => {
  function counter() {
    let count = 0
    return function() {
      count++
      return count
    }
  }

  const increment = counter()
  expect(increment()).toBe(1)
  expect(increment()).toBe(2)
  expect(increment()).toBe(3)
})

it('should create independent counters', () => {
  function counter() {
    let count = 0
    return function() {
      count++
      return count
    }
  }

  const counter1 = counter()
  const counter2 = counter()

  expect(counter1()).toBe(1)
  expect(counter1()).toBe(2)
  expect(counter2()).toBe(1) // Independent
})

Pattern 13: DOM Event Testing

Documentation:

const button = document.getElementById('myButton')
button.addEventListener('click', function(event) {
  console.log('Button clicked!')
  console.log(event.type)  // "click"
})

Test (in.dom.test.js file):

/**
 * @vitest-environment jsdom
 */
import { describe, it, expect, beforeEach, afterEach } from 'vitest'

describe('DOM Event Handlers', () => {
  let button

  beforeEach(() => {
    button = document.createElement('button')
    button.id = 'myButton'
    document.body.appendChild(button)
  })

  afterEach(() => {
    document.body.innerHTML = ''
  })

  // From lines XX-YY: Button click event
  it('should fire click event handler', () => {
    const output = []

    button.addEventListener('click', function(event) {
      output.push('Button clicked!')
      output.push(event.type)
    })

    button.click()

    expect(output).toEqual(['Button clicked!', 'click'])
  })
})

Pattern 14: DOM Manipulation Testing

Documentation:

const div = document.createElement('div')
div.textContent = 'Hello'
div.classList.add('greeting')
document.body.appendChild(div)

Test:

// From lines XX-YY: Creating and appending elements
it('should create element with text and class', () => {
  const div = document.createElement('div')
  div.textContent = 'Hello'
  div.classList.add('greeting')
  document.body.appendChild(div)

  const element = document.querySelector('.greeting')
  expect(element).not.toBeNull()
  expect(element.textContent).toBe('Hello')
  expect(element.classList.contains('greeting')).toBe(true)
})

Pattern 15: Timer Testing

Documentation:

console.log('First')
setTimeout(() => console.log('Second'), 0)
console.log('Third')
// Output: First, Third, Second

Test:

// From lines XX-YY: setTimeout execution order
it('should execute setTimeout callback after synchronous code', async () => {
  const output = []

  output.push('First')
  setTimeout(() => output.push('Second'), 0)
  output.push('Third')

  // Wait for setTimeout to execute
  await new Promise(resolve => setTimeout(resolve, 10))

  expect(output).toEqual(['First', 'Third', 'Second'])
})

Pattern 16: Strict Mode Behavior

Documentation:

// In strict mode, this throws
"use strict"
x = 10  // ReferenceError: x is not defined

Test:

// From lines XX-YY: Strict mode variable declaration
it('should throw ReferenceError in strict mode for undeclared variables', () => {
  // Vitest runs in strict mode by default
  expect(() => {
    // Using eval to test strict mode behavior
    "use strict"
    eval('undeclaredVar = 10')
  }).toThrow()
})

Complete Test File Template

import { describe, it, expect } from 'vitest'

describe('[Concept Name]', () => {
  // ============================================================
  // [FIRST SECTION NAME FROM DOCUMENTATION]
  // From [concept].mdx lines XX-YY
  // ============================================================

  describe('[First Section]', () => {
    // From lines XX-YY: [Brief description of example]
    it('should [expected behavior]', () => {
      // Code from documentation

      expect(result).toBe(expected)
    })

    // From lines XX-YY: [Brief description of next example]
    it('should [another expected behavior]', () => {
      // Code from documentation

      expect(result).toEqual(expected)
    })
  })

  // ============================================================
  // [SECOND SECTION NAME FROM DOCUMENTATION]
  // From [concept].mdx lines XX-YY
  // ============================================================

  describe('[Second Section]', () => {
    // From lines XX-YY: [Description]
    it('should [behavior]', () => {
      // Test
    })
  })

  // ============================================================
  // EDGE CASES AND COMMON MISTAKES
  // From [concept].mdx lines XX-YY
  // ============================================================

  describe('Edge Cases', () => {
    // From lines XX-YY: [Edge case description]
    it('should handle [edge case]', () => {
      // Test
    })
  })

  describe('Common Mistakes', () => {
    // From lines XX-YY: Wrong way example
    it('should demonstrate the incorrect behavior', () => {
      // Test showing why the "wrong" way fails
    })

    // From lines XX-YY: Correct way example
    it('should demonstrate the correct behavior', () => {
      // Test showing the right approach
    })
  })
})

Complete DOM Test File Template

/**
 * @vitest-environment jsdom
 */
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'

// ============================================================
// DOM EXAMPLES FROM [CONCEPT NAME]
// From [concept].mdx lines XX-YY
// ============================================================

describe('[Concept Name] - DOM', () => {
  // Shared setup
  let container

  beforeEach(() => {
    // Create a fresh container for each test
    container = document.createElement('div')
    container.id = 'test-container'
    document.body.appendChild(container)
  })

  afterEach(() => {
    // Clean up after each test
    document.body.innerHTML = ''
    vi.restoreAllMocks()
  })

  // ============================================================
  // [SECTION NAME]
  // From lines XX-YY
  // ============================================================

  describe('[Section Name]', () => {
    // From lines XX-YY: [Example description]
    it('should [expected DOM behavior]', () => {
      // Setup
      const element = document.createElement('div')
      container.appendChild(element)

      // Action
      element.textContent = 'Hello'

      // Assert
      expect(element.textContent).toBe('Hello')
    })
  })

  // ============================================================
  // EVENT HANDLING
  // From lines XX-YY
  // ============================================================

  describe('Event Handling', () => {
    // From lines XX-YY: Click event example
    it('should handle click events', () => {
      const button = document.createElement('button')
      container.appendChild(button)

      let clicked = false
      button.addEventListener('click', () => {
        clicked = true
      })

      button.click()

      expect(clicked).toBe(true)
    })
  })
})

Running Tests

# Run all tests
npm test

# Run tests for specific concept
npm test -- tests/fundamentals/primitive-types/

# Run tests for specific file
npm test -- tests/fundamentals/primitive-types/primitive-types.test.js

# Run DOM tests only
npm test -- tests/fundamentals/primitive-types/primitive-types.dom.test.js

# Run with watch mode
npm run test:watch

# Run with coverage
npm run test:coverage

# Run with verbose output
npm test -- --reporter=verbose

Quality Checklist

Completeness

  • All testable code examples have corresponding tests
  • Tests organized by documentation sections
  • Source line references included in comments (From lines XX-YY)
  • DOM tests in separate .dom.test.js file
  • Edge cases and error examples tested

Correctness

  • Tests verify the actual documented behavior
  • Output comments in docs match test expectations
  • Async tests properly use async/await
  • Error tests use correct toThrow pattern
  • Floating point comparisons use toBeCloseTo
  • Object comparisons use toEqual (not toBe)

Convention

  • Uses explicit imports from vitest
  • Follows describe/it nesting pattern
  • Test names start with "should"
  • Proper file naming ({concept}.test.js)
  • DOM tests have jsdom environment directive

Verification

  • All tests pass: npm test -- tests/{category}/{concept}/
  • No skipped tests without documented reason
  • No false positives (tests that pass for wrong reasons)

Test Report Template

Use this template to document test coverage for a concept page.

# Test Coverage Report: [Concept Name]

**Concept Page:** `/docs/concepts/[slug].mdx`
**Test File:** `/tests/{category}/{concept}/{concept}.test.js`
**DOM Test File:** `/tests/{category}/{concept}/{concept}.dom.test.js` (if applicable)
**Date:** YYYY-MM-DD
**Author:** [Name/Claude]

## Summary

| Metric | Count |
|--------|-------|
| Total Code Examples in Doc | XX |
| Testable Examples | XX |
| Tests Written | XX |
| DOM Tests Written | XX |
| Skipped (with reason) | XX |

## Tests by Section

| Section | Line Range | Examples | Tests | Status |
|---------|------------|----------|-------|--------|
| [Section 1] | XX-YY | X | X | ✅ |
| [Section 2] | XX-YY | X | X | ✅ |
| [Section 3] | XX-YY | X | X | ⚠️ (1 skipped) |

## Skipped Examples

| Line | Example Description | Reason |
|------|---------------------|--------|
| XX | ASCII diagram of call stack | Conceptual, not executable |
| YY | Browser fetch example | Requires network, mocked instead |

## Test Execution

npm test -- tests/{category}/{concept}/


**Result:** ✅ XX passing | ❌ X failing | ⏭️ X skipped

## Notes

[Any special considerations, mock requirements, or issues encountered]

Common Issues and Solutions

Issue: Test passes but shouldn't

Problem: Test expectations don't match documentation output

Solution: Double-check the expected value matches the console.log comment exactly

// Documentation says: console.log(result)  // [1, 2, 3]
// Make sure test uses:
expect(result).toEqual([1, 2, 3])  // NOT toBe for arrays

Issue: Async test times out

Problem: Async test never resolves

Solution: Ensure all promises are awaited and async function is marked

// Bad
it('should fetch data', () => {
  const data = fetchData()  // Missing await!
  expect(data).toBeDefined()
})

// Good
it('should fetch data', async () => {
  const data = await fetchData()
  expect(data).toBeDefined()
})

Issue: DOM test fails with "document is not defined"

Problem: Missing jsdom environment

Solution: Add environment directive at top of file

/**
 * @vitest-environment jsdom
 */

Issue: Test isolation problems

Problem: Tests affect each other

Solution: Use beforeEach/afterEach for cleanup

afterEach(() => {
  document.body.innerHTML = ''
  vi.restoreAllMocks()
})

Summary

When writing tests for a concept page:

  1. Extract all code examples from the documentation
  2. Categorize as testable, DOM, error, or conceptual
  3. Create test file in correct location with proper naming
  4. Convert each example to test using appropriate pattern
  5. Reference source lines in comments for traceability
  6. Run tests to verify all pass
  7. Document coverage using the report template

Remember: Tests serve two purposes:

  1. Verify documentation is accurate
  2. Catch regressions if code examples are updated

Every testable code example in the documentation should have a corresponding test. If an example can't be tested, document why.

平台分布

Claude Code

25.71%
按下载量换算605

goose

23.27%
按下载量换算547

OpenCode

19.43%
按下载量换算457

Antigravity

11.52%
按下载量换算271

Gemini CLI

8.06%
按下载量换算190

Cursor

3.69%
按下载量换算87

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

操作浏览器

该 Skill 可能涉及浏览器控制能力,使用时可能读取或操作网页内容,需要在受控环境中确认权限边界。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。

继续浏览同类 Skills