mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-04-10 03:13:29 +08:00
docs(zh-CN): sync Chinese docs with latest upstream changes
This commit is contained in:
29
docs/zh-CN/commands/context-budget.md
Normal file
29
docs/zh-CN/commands/context-budget.md
Normal file
@@ -0,0 +1,29 @@
|
||||
---
|
||||
description: 分析跨代理、技能、MCP服务器和规则的上下文窗口使用情况,以寻找优化机会。有助于减少令牌开销并避免性能警告。
|
||||
---
|
||||
|
||||
# 上下文预算优化器
|
||||
|
||||
分析您的 Claude Code 设置中的上下文窗口消耗,并提供可操作的建议以减少令牌开销。
|
||||
|
||||
## 使用方法
|
||||
|
||||
```
|
||||
/context-budget [--verbose]
|
||||
```
|
||||
|
||||
* 默认:提供摘要及主要建议
|
||||
* `--verbose`:按组件提供完整细分
|
||||
|
||||
$ARGUMENTS
|
||||
|
||||
## 操作步骤
|
||||
|
||||
运行 **context-budget** 技能(`skills/context-budget/SKILL.md`),并输入以下内容:
|
||||
|
||||
1. 如果 `$ARGUMENTS` 中存在 `--verbose` 标志,则传递该标志
|
||||
2. 除非用户另行指定,否则假设为 200K 上下文窗口(Claude Sonnet 默认值)
|
||||
3. 遵循技能的四个阶段:清单 → 分类 → 检测问题 → 报告
|
||||
4. 向用户输出格式化的上下文预算报告
|
||||
|
||||
该技能负责所有扫描逻辑、令牌估算、问题检测和报告格式化。
|
||||
177
docs/zh-CN/commands/cpp-build.md
Normal file
177
docs/zh-CN/commands/cpp-build.md
Normal file
@@ -0,0 +1,177 @@
|
||||
---
|
||||
description: 逐步修复C++构建错误、CMake问题和链接器问题。调用cpp-build-resolver代理进行最小化、精准的修复。
|
||||
---
|
||||
|
||||
# C++ 构建与修复
|
||||
|
||||
此命令调用 **cpp-build-resolver** 代理,以最小的更改逐步修复 C++ 构建错误。
|
||||
|
||||
## 此命令的作用
|
||||
|
||||
1. **运行诊断**:执行 `cmake --build`、`clang-tidy`、`cppcheck`
|
||||
2. **解析错误**:按文件分组并按严重性排序
|
||||
3. **逐步修复**:一次修复一个错误
|
||||
4. **验证每个修复**:每次更改后重新运行构建
|
||||
5. **报告摘要**:显示已修复的内容和剩余的问题
|
||||
|
||||
## 何时使用
|
||||
|
||||
在以下情况下使用 `/cpp-build`:
|
||||
|
||||
* `cmake --build build` 因错误而失败时
|
||||
* 链接器错误(未定义的引用,多重定义)
|
||||
* 模板实例化失败
|
||||
* 包含/依赖项问题
|
||||
* 拉取更改后导致构建失败时
|
||||
|
||||
## 运行的诊断命令
|
||||
|
||||
```bash
|
||||
# CMake configure
|
||||
cmake -B build -S .
|
||||
|
||||
# Build
|
||||
cmake --build build 2>&1 | head -100
|
||||
|
||||
# Static analysis (if available)
|
||||
clang-tidy src/*.cpp -- -std=c++17
|
||||
cppcheck --enable=all src/
|
||||
```
|
||||
|
||||
## 示例会话
|
||||
|
||||
````text
|
||||
User: /cpp-build
|
||||
|
||||
Agent:
|
||||
# C++ Build Resolution
|
||||
|
||||
## Initial Diagnostics
|
||||
|
||||
```bash
|
||||
$ cmake --build build
|
||||
src/service/user.cpp:25:15: error: use of undeclared identifier 'UserRepository'
|
||||
src/handler/api.cpp:42:9: error: no matching function for call to 'process'
|
||||
src/handler/api.cpp:58:1: error: non-void function does not return a value
|
||||
````
|
||||
|
||||
发现的错误:3
|
||||
|
||||
## 修复 1:未声明的标识符
|
||||
|
||||
文件:src/service/user.cpp:25
|
||||
错误:使用了未声明的标识符 'UserRepository'
|
||||
原因:缺少包含
|
||||
|
||||
```cpp
|
||||
// Added include
|
||||
#include "repository/user_repository.hpp"
|
||||
```
|
||||
|
||||
```bash
|
||||
$ cmake --build build
|
||||
# 2 errors remaining
|
||||
```
|
||||
|
||||
## 修复 2:无匹配函数
|
||||
|
||||
文件:src/handler/api.cpp:42
|
||||
错误:没有匹配的函数用于调用 'process'
|
||||
|
||||
```cpp
|
||||
// Changed
|
||||
process(params.get("count"));
|
||||
// To
|
||||
process(std::stoi(params.get("count")));
|
||||
```
|
||||
|
||||
```bash
|
||||
$ cmake --build build
|
||||
# 1 error remaining
|
||||
```
|
||||
|
||||
## 修复 3:缺少返回
|
||||
|
||||
文件:src/handler/api.cpp:58
|
||||
错误:非 void 函数未返回值
|
||||
|
||||
```cpp
|
||||
std::optional<User> getUser(const std::string& id) {
|
||||
if (id.empty()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
auto user = findUser(id);
|
||||
// Added missing return
|
||||
return user;
|
||||
}
|
||||
```
|
||||
|
||||
```bash
|
||||
$ cmake --build build
|
||||
# Build successful!
|
||||
```
|
||||
|
||||
## 最终验证
|
||||
|
||||
```bash
|
||||
$ ctest --test-dir build --output-on-failure
|
||||
Test project build
|
||||
1/5 Test #1: unit_tests ........ Passed 0.02 sec
|
||||
2/5 Test #2: integration_tests Passed 0.15 sec
|
||||
All tests passed.
|
||||
```
|
||||
|
||||
## 摘要
|
||||
|
||||
| 指标 | 数量 |
|
||||
|--------|-------|
|
||||
| 已修复的构建错误 | 3 |
|
||||
| 已修复的链接器错误 | 0 |
|
||||
| 已修改的文件 | 2 |
|
||||
| 剩余问题 | 0 |
|
||||
|
||||
构建状态:✅ 成功
|
||||
|
||||
```
|
||||
|
||||
## Common Errors Fixed
|
||||
|
||||
| Error | Typical Fix |
|
||||
|-------|-------------|
|
||||
| `undeclared identifier` | Add `#include` or fix typo |
|
||||
| `no matching function` | Fix argument types or add overload |
|
||||
| `undefined reference` | Link library or add implementation |
|
||||
| `multiple definition` | Use `inline` or move to .cpp |
|
||||
| `incomplete type` | Replace forward decl with `#include` |
|
||||
| `no member named X` | Fix member name or include |
|
||||
| `cannot convert X to Y` | Add appropriate cast |
|
||||
| `CMake Error` | Fix CMakeLists.txt configuration |
|
||||
|
||||
## Fix Strategy
|
||||
|
||||
1. **Compilation errors first** - Code must compile
|
||||
2. **Linker errors second** - Resolve undefined references
|
||||
3. **Warnings third** - Fix with `-Wall -Wextra`
|
||||
4. **One fix at a time** - Verify each change
|
||||
5. **Minimal changes** - Don't refactor, just fix
|
||||
|
||||
## Stop Conditions
|
||||
|
||||
The agent will stop and report if:
|
||||
- Same error persists after 3 attempts
|
||||
- Fix introduces more errors
|
||||
- Requires architectural changes
|
||||
- Missing external dependencies
|
||||
|
||||
## Related Commands
|
||||
|
||||
- `/cpp-test` - Run tests after build succeeds
|
||||
- `/cpp-review` - Review code quality
|
||||
- `/verify` - Full verification loop
|
||||
|
||||
## Related
|
||||
|
||||
- Agent: `agents/cpp-build-resolver.md`
|
||||
- Skill: `skills/cpp-coding-standards/`
|
||||
|
||||
```
|
||||
145
docs/zh-CN/commands/cpp-review.md
Normal file
145
docs/zh-CN/commands/cpp-review.md
Normal file
@@ -0,0 +1,145 @@
|
||||
---
|
||||
description: 全面的 C++ 代码审查,涵盖内存安全、现代 C++ 惯用法、并发性和安全性。调用 cpp-reviewer 代理。
|
||||
---
|
||||
|
||||
# C++ 代码审查
|
||||
|
||||
此命令调用 **cpp-reviewer** 代理进行全面的 C++ 特定代码审查。
|
||||
|
||||
## 此命令的作用
|
||||
|
||||
1. **识别 C++ 变更**:通过 `git diff` 查找已修改的 `.cpp`、`.hpp`、`.cc`、`.h` 文件
|
||||
2. **运行静态分析**:执行 `clang-tidy` 和 `cppcheck`
|
||||
3. **内存安全检查**:检查原始 new/delete、缓冲区溢出、释放后使用
|
||||
4. **并发审查**:分析线程安全性、互斥锁使用情况、数据竞争
|
||||
5. **现代 C++ 检查**:验证代码是否遵循 C++17/20 约定和最佳实践
|
||||
6. **生成报告**:按严重程度对问题进行分类
|
||||
|
||||
## 使用时机
|
||||
|
||||
在以下情况下使用 `/cpp-review`:
|
||||
|
||||
* 编写或修改 C++ 代码后
|
||||
* 提交 C++ 变更前
|
||||
* 审查包含 C++ 代码的拉取请求时
|
||||
* 接手新的 C++ 代码库时
|
||||
* 检查内存安全问题
|
||||
|
||||
## 审查类别
|
||||
|
||||
### 严重(必须修复)
|
||||
|
||||
* 未使用 RAII 的原始 `new`/`delete`
|
||||
* 缓冲区溢出和释放后使用
|
||||
* 无同步的数据竞争
|
||||
* 通过 `system()` 进行命令注入
|
||||
* 未初始化的变量读取
|
||||
* 空指针解引用
|
||||
|
||||
### 高(应该修复)
|
||||
|
||||
* 五法则违规
|
||||
* 缺少 `std::lock_guard` / `std::scoped_lock`
|
||||
* 分离的线程没有正确的生命周期管理
|
||||
* 使用 C 风格强制转换而非 `static_cast`/`dynamic_cast`
|
||||
* 缺少 `const` 正确性
|
||||
|
||||
### 中(考虑)
|
||||
|
||||
* 不必要的拷贝(按值传递而非 `const&`)
|
||||
* 已知大小的容器上缺少 `reserve()`
|
||||
* 头文件中的 `using namespace std;`
|
||||
* 重要返回值上缺少 `[[nodiscard]]`
|
||||
* 过于复杂的模板元编程
|
||||
|
||||
## 运行的自动化检查
|
||||
|
||||
```bash
|
||||
# Static analysis
|
||||
clang-tidy --checks='*,-llvmlibc-*' src/*.cpp -- -std=c++17
|
||||
|
||||
# Additional analysis
|
||||
cppcheck --enable=all --suppress=missingIncludeSystem src/
|
||||
|
||||
# Build with warnings
|
||||
cmake --build build -- -Wall -Wextra -Wpedantic
|
||||
```
|
||||
|
||||
## 使用示例
|
||||
|
||||
````text
|
||||
User: /cpp-review
|
||||
|
||||
Agent:
|
||||
# C++ Code Review Report
|
||||
|
||||
## Files Reviewed
|
||||
- src/handler/user.cpp (modified)
|
||||
- src/service/auth.cpp (modified)
|
||||
|
||||
## Static Analysis Results
|
||||
✓ clang-tidy: 2 warnings
|
||||
✓ cppcheck: No issues
|
||||
|
||||
## Issues Found
|
||||
|
||||
[CRITICAL] Memory Leak
|
||||
File: src/service/auth.cpp:45
|
||||
Issue: Raw `new` without matching `delete`
|
||||
```cpp
|
||||
auto* session = new Session(userId); // Memory leak!
|
||||
cache[userId] = session;
|
||||
````
|
||||
|
||||
修复:使用 `std::unique_ptr`
|
||||
|
||||
```cpp
|
||||
auto session = std::make_unique<Session>(userId);
|
||||
cache[userId] = std::move(session);
|
||||
```
|
||||
|
||||
\[高] 缺少常量引用
|
||||
文件:src/handler/user.cpp:28
|
||||
问题:大对象按值传递
|
||||
|
||||
```cpp
|
||||
void processUser(User user) { // Unnecessary copy
|
||||
```
|
||||
|
||||
修复:通过常量引用传递
|
||||
|
||||
```cpp
|
||||
void processUser(const User& user) {
|
||||
```
|
||||
|
||||
## 摘要
|
||||
|
||||
* 严重:1
|
||||
* 高:1
|
||||
* 中:0
|
||||
|
||||
建议:❌ 在严重问题修复前阻止合并
|
||||
|
||||
```
|
||||
|
||||
## Approval Criteria
|
||||
|
||||
| Status | Condition |
|
||||
|--------|-----------|
|
||||
| ✅ Approve | No CRITICAL or HIGH issues |
|
||||
| ⚠️ Warning | Only MEDIUM issues (merge with caution) |
|
||||
| ❌ Block | CRITICAL or HIGH issues found |
|
||||
|
||||
## Integration with Other Commands
|
||||
|
||||
- Use `/cpp-test` first to ensure tests pass
|
||||
- Use `/cpp-build` if build errors occur
|
||||
- Use `/cpp-review` before committing
|
||||
- Use `/code-review` for non-C++ specific concerns
|
||||
|
||||
## Related
|
||||
|
||||
- Agent: `agents/cpp-reviewer.md`
|
||||
- Skills: `skills/cpp-coding-standards/`, `skills/cpp-testing/`
|
||||
|
||||
```
|
||||
257
docs/zh-CN/commands/cpp-test.md
Normal file
257
docs/zh-CN/commands/cpp-test.md
Normal file
@@ -0,0 +1,257 @@
|
||||
---
|
||||
description: 为 C++ 强制执行 TDD 工作流程。先编写 GoogleTest 测试,然后实现。使用 gcov/lcov 验证覆盖率。
|
||||
---
|
||||
|
||||
# C++ TDD 命令
|
||||
|
||||
此命令使用 GoogleTest/GoogleMock 与 CMake/CTest,为 C++ 代码强制执行测试驱动开发方法。
|
||||
|
||||
## 此命令的作用
|
||||
|
||||
1. **定义接口**:首先搭建类/函数签名
|
||||
2. **编写测试**:创建全面的 GoogleTest 测试用例(RED 阶段)
|
||||
3. **运行测试**:验证测试因正确原因失败
|
||||
4. **实现代码**:编写最少代码以通过测试(GREEN 阶段)
|
||||
5. **重构**:在保持测试通过的同时改进代码
|
||||
6. **检查覆盖率**:确保覆盖率在 80% 以上
|
||||
|
||||
## 何时使用
|
||||
|
||||
在以下情况使用 `/cpp-test`:
|
||||
|
||||
* 实现新的 C++ 函数或类时
|
||||
* 为现有代码增加测试覆盖率时
|
||||
* 修复错误时(先编写失败的测试)
|
||||
* 构建关键业务逻辑时
|
||||
* 学习 C++ 中的 TDD 工作流时
|
||||
|
||||
## TDD 循环
|
||||
|
||||
```
|
||||
RED → Write failing GoogleTest test
|
||||
GREEN → Implement minimal code to pass
|
||||
REFACTOR → Improve code, tests stay green
|
||||
REPEAT → Next test case
|
||||
```
|
||||
|
||||
## 示例会话
|
||||
|
||||
````
|
||||
User: /cpp-test I need a function to validate email addresses
|
||||
|
||||
Agent:
|
||||
# TDD Session: Email Validator
|
||||
|
||||
## Step 1: Define Interface
|
||||
|
||||
```cpp
|
||||
// validator/email.hpp
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <expected>
|
||||
|
||||
enum class EmailError {
|
||||
Empty,
|
||||
InvalidFormat
|
||||
};
|
||||
|
||||
std::expected<void, EmailError> validate_email(const std::string& email);
|
||||
```
|
||||
|
||||
## Step 2: Write Tests (RED)
|
||||
|
||||
```cpp
|
||||
// validator/email_test.cpp
|
||||
#include <gtest/gtest.h>
|
||||
#include "email.hpp"
|
||||
|
||||
TEST(ValidateEmail, AcceptsSimpleEmail) {
|
||||
auto result = validate_email("user@example.com");
|
||||
EXPECT_TRUE(result.has_value());
|
||||
}
|
||||
|
||||
TEST(ValidateEmail, AcceptsSubdomain) {
|
||||
EXPECT_TRUE(validate_email("user@mail.example.com").has_value());
|
||||
}
|
||||
|
||||
TEST(ValidateEmail, AcceptsPlus) {
|
||||
EXPECT_TRUE(validate_email("user+tag@example.com").has_value());
|
||||
}
|
||||
|
||||
TEST(ValidateEmail, RejectsEmpty) {
|
||||
auto result = validate_email("");
|
||||
ASSERT_FALSE(result.has_value());
|
||||
EXPECT_EQ(result.error(), EmailError::Empty);
|
||||
}
|
||||
|
||||
TEST(ValidateEmail, RejectsNoAtSign) {
|
||||
EXPECT_FALSE(validate_email("userexample.com").has_value());
|
||||
}
|
||||
|
||||
TEST(ValidateEmail, RejectsNoDomain) {
|
||||
EXPECT_FALSE(validate_email("user@").has_value());
|
||||
}
|
||||
|
||||
TEST(ValidateEmail, RejectsNoLocalPart) {
|
||||
EXPECT_FALSE(validate_email("@example.com").has_value());
|
||||
}
|
||||
```
|
||||
|
||||
## Step 3: Run Tests - Verify FAIL
|
||||
|
||||
```bash
|
||||
$ cmake --build build && ctest --test-dir build --output-on-failure
|
||||
|
||||
1/1 Test #1: email_validator_test .....***Failed
|
||||
--- undefined reference to `validate_email`
|
||||
|
||||
FAIL
|
||||
```
|
||||
|
||||
✓ Tests fail as expected (unimplemented).
|
||||
|
||||
## Step 4: Implement Minimal Code (GREEN)
|
||||
|
||||
```cpp
|
||||
// validator/email.cpp
|
||||
#include "email.hpp"
|
||||
#include <regex>
|
||||
|
||||
std::expected<void, EmailError> validate_email(const std::string& email) {
|
||||
if (email.empty()) {
|
||||
return std::unexpected(EmailError::Empty);
|
||||
}
|
||||
static const std::regex pattern(R"([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})");
|
||||
if (!std::regex_match(email, pattern)) {
|
||||
return std::unexpected(EmailError::InvalidFormat);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
```
|
||||
|
||||
## Step 5: Run Tests - Verify PASS
|
||||
|
||||
```bash
|
||||
$ cmake --build build && ctest --test-dir build --output-on-failure
|
||||
|
||||
1/1 Test #1: email_validator_test ..... Passed 0.01 sec
|
||||
|
||||
100% tests passed.
|
||||
```
|
||||
|
||||
✓ All tests passing!
|
||||
|
||||
## Step 6: Check Coverage
|
||||
|
||||
```bash
|
||||
$ cmake -DCMAKE_CXX_FLAGS="--coverage" -B build && cmake --build build
|
||||
$ ctest --test-dir build
|
||||
$ lcov --capture --directory build --output-file coverage.info
|
||||
$ lcov --list coverage.info
|
||||
|
||||
validator/email.cpp | 100%
|
||||
```
|
||||
|
||||
✓ Coverage: 100%
|
||||
|
||||
## TDD Complete!
|
||||
````
|
||||
|
||||
## 测试模式
|
||||
|
||||
### 基础测试
|
||||
|
||||
```cpp
|
||||
TEST(SuiteName, TestName) {
|
||||
EXPECT_EQ(add(2, 3), 5);
|
||||
EXPECT_NE(result, nullptr);
|
||||
EXPECT_TRUE(is_valid);
|
||||
EXPECT_THROW(func(), std::invalid_argument);
|
||||
}
|
||||
```
|
||||
|
||||
### 测试夹具
|
||||
|
||||
```cpp
|
||||
class DatabaseTest : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override { db_ = create_test_db(); }
|
||||
void TearDown() override { db_.reset(); }
|
||||
std::unique_ptr<Database> db_;
|
||||
};
|
||||
|
||||
TEST_F(DatabaseTest, InsertsRecord) {
|
||||
db_->insert("key", "value");
|
||||
EXPECT_EQ(db_->get("key"), "value");
|
||||
}
|
||||
```
|
||||
|
||||
### 参数化测试
|
||||
|
||||
```cpp
|
||||
class PrimeTest : public ::testing::TestWithParam<std::pair<int, bool>> {};
|
||||
|
||||
TEST_P(PrimeTest, ChecksPrimality) {
|
||||
auto [input, expected] = GetParam();
|
||||
EXPECT_EQ(is_prime(input), expected);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(Primes, PrimeTest, ::testing::Values(
|
||||
std::make_pair(2, true),
|
||||
std::make_pair(4, false),
|
||||
std::make_pair(7, true)
|
||||
));
|
||||
```
|
||||
|
||||
## 覆盖率命令
|
||||
|
||||
```bash
|
||||
# Build with coverage
|
||||
cmake -DCMAKE_CXX_FLAGS="--coverage" -DCMAKE_EXE_LINKER_FLAGS="--coverage" -B build
|
||||
|
||||
# Run tests
|
||||
cmake --build build && ctest --test-dir build
|
||||
|
||||
# Generate coverage report
|
||||
lcov --capture --directory build --output-file coverage.info
|
||||
lcov --remove coverage.info '/usr/*' --output-file coverage.info
|
||||
genhtml coverage.info --output-directory coverage_html
|
||||
```
|
||||
|
||||
## 覆盖率目标
|
||||
|
||||
| 代码类型 | 目标 |
|
||||
|-----------|--------|
|
||||
| 关键业务逻辑 | 100% |
|
||||
| 公共 API | 90%+ |
|
||||
| 通用代码 | 80%+ |
|
||||
| 生成的代码 | 排除 |
|
||||
|
||||
## TDD 最佳实践
|
||||
|
||||
**应做:**
|
||||
|
||||
* 先编写测试,再进行任何实现
|
||||
* 每次更改后运行测试
|
||||
* 在适当时使用 `EXPECT_*`(继续)而非 `ASSERT_*`(停止)
|
||||
* 测试行为,而非实现细节
|
||||
* 包含边界情况(空值、null、最大值、边界条件)
|
||||
|
||||
**不应做:**
|
||||
|
||||
* 在编写测试之前实现代码
|
||||
* 跳过 RED 阶段
|
||||
* 直接测试私有方法(通过公共 API 进行测试)
|
||||
* 在测试中使用 `sleep`
|
||||
* 忽略不稳定的测试
|
||||
|
||||
## 相关命令
|
||||
|
||||
* `/cpp-build` - 修复构建错误
|
||||
* `/cpp-review` - 在实现后审查代码
|
||||
* `/verify` - 运行完整的验证循环
|
||||
|
||||
## 相关
|
||||
|
||||
* 技能:`skills/cpp-testing/`
|
||||
* 技能:`skills/tdd-workflow/`
|
||||
93
docs/zh-CN/commands/devfleet.md
Normal file
93
docs/zh-CN/commands/devfleet.md
Normal file
@@ -0,0 +1,93 @@
|
||||
---
|
||||
description: 通过Claude DevFleet协调并行Claude Code代理——从自然语言规划项目,在隔离的工作树中调度代理,监控进度,并读取结构化报告。
|
||||
---
|
||||
|
||||
# DevFleet — 多智能体编排
|
||||
|
||||
通过 Claude DevFleet 编排并行的 Claude Code 智能体。每个智能体在隔离的 git worktree 中运行,并配备完整的工具链。
|
||||
|
||||
需要 DevFleet MCP 服务器:`claude mcp add devfleet --transport http http://localhost:18801/mcp`
|
||||
|
||||
## 流程
|
||||
|
||||
```
|
||||
User describes project
|
||||
→ plan_project(prompt) → mission DAG with dependencies
|
||||
→ Show plan, get approval
|
||||
→ dispatch_mission(M1) → Agent spawns in worktree
|
||||
→ M1 completes → auto-merge → M2 auto-dispatches (depends_on M1)
|
||||
→ M2 completes → auto-merge
|
||||
→ get_report(M2) → files_changed, what_done, errors, next_steps
|
||||
→ Report summary to user
|
||||
```
|
||||
|
||||
## 工作流
|
||||
|
||||
1. **根据用户描述规划项目**:
|
||||
|
||||
```
|
||||
mcp__devfleet__plan_project(prompt="<user's description>")
|
||||
```
|
||||
|
||||
这将返回一个包含链式任务的项目。向用户展示:
|
||||
|
||||
* 项目名称和 ID
|
||||
* 每个任务:标题、类型、依赖项
|
||||
* 依赖关系 DAG(哪些任务阻塞了哪些任务)
|
||||
|
||||
2. **在派发前等待用户批准**。清晰展示计划。
|
||||
|
||||
3. **派发第一个任务**(`depends_on` 为空的任务):
|
||||
|
||||
```
|
||||
mcp__devfleet__dispatch_mission(mission_id="<first_mission_id>")
|
||||
```
|
||||
|
||||
剩余的任务会在其依赖项完成时自动派发(因为 `plan_project` 创建它们时使用了 `auto_dispatch=true`)。当使用 `create_mission` 手动创建任务时,您必须显式设置 `auto_dispatch=true` 才能启用此行为。
|
||||
|
||||
4. **监控进度** — 检查正在运行的内容:
|
||||
|
||||
```
|
||||
mcp__devfleet__get_dashboard()
|
||||
```
|
||||
|
||||
或检查特定任务:
|
||||
|
||||
```
|
||||
mcp__devfleet__get_mission_status(mission_id="<id>")
|
||||
```
|
||||
|
||||
对于长时间运行的任务,优先使用 `get_mission_status` 轮询,而不是 `wait_for_mission`,以便用户能看到进度更新。
|
||||
|
||||
5. **读取每个已完成任务的报告**:
|
||||
|
||||
```
|
||||
mcp__devfleet__get_report(mission_id="<mission_id>")
|
||||
```
|
||||
|
||||
对每个达到终止状态的任务调用此工具。报告包含:files\_changed, what\_done, what\_open, what\_tested, what\_untested, next\_steps, errors\_encountered。
|
||||
|
||||
## 所有可用工具
|
||||
|
||||
| 工具 | 用途 |
|
||||
|------|---------|
|
||||
| `plan_project(prompt)` | AI 将描述分解为具有 `auto_dispatch=true` 的链式任务 |
|
||||
| `create_project(name, path?, description?)` | 手动创建项目,返回 `project_id` |
|
||||
| `create_mission(project_id, title, prompt, depends_on?, auto_dispatch?)` | 添加任务。`depends_on` 是任务 ID 字符串列表。 |
|
||||
| `dispatch_mission(mission_id, model?, max_turns?)` | 启动一个智能体 |
|
||||
| `cancel_mission(mission_id)` | 停止一个正在运行的智能体 |
|
||||
| `wait_for_mission(mission_id, timeout_seconds?)` | 阻塞直到完成(对于长任务,优先使用轮询) |
|
||||
| `get_mission_status(mission_id)` | 非阻塞地检查进度 |
|
||||
| `get_report(mission_id)` | 读取结构化报告 |
|
||||
| `get_dashboard()` | 系统概览 |
|
||||
| `list_projects()` | 浏览项目 |
|
||||
| `list_missions(project_id, status?)` | 列出任务 |
|
||||
|
||||
## 指南
|
||||
|
||||
* 除非用户明确说"开始吧",否则派发前始终确认计划
|
||||
* 报告状态时包含任务标题和 ID
|
||||
* 如果任务失败,在重试前先读取其报告以了解错误
|
||||
* 智能体并发数是可配置的(默认:3)。超额的任务会排队,并在有空闲槽位时自动派发。检查 `get_dashboard()` 以了解槽位可用性。
|
||||
* 依赖关系形成一个 DAG — 切勿创建循环依赖
|
||||
* 每个智能体在完成时自动合并其 worktree。如果发生合并冲突,更改将保留在 worktree 分支上,以供手动解决。
|
||||
32
docs/zh-CN/commands/docs.md
Normal file
32
docs/zh-CN/commands/docs.md
Normal file
@@ -0,0 +1,32 @@
|
||||
---
|
||||
description: 通过 Context7 查找库或主题的当前文档。
|
||||
---
|
||||
|
||||
# /docs
|
||||
|
||||
## 目的
|
||||
|
||||
查找库、框架或 API 的最新文档,并返回包含相关代码片段的摘要答案。使用 Context7 MCP(resolve-library-id 和 query-docs),因此答案反映的是当前文档,而非训练数据。
|
||||
|
||||
## 用法
|
||||
|
||||
```
|
||||
/docs [library name] [question]
|
||||
```
|
||||
|
||||
对于多单词参数,使用引号以便它们被解析为单个标记。示例:`/docs "Next.js" "How do I configure middleware?"`
|
||||
|
||||
如果省略了库或问题,则提示用户输入:
|
||||
|
||||
1. 库或产品名称(例如 Next.js、Prisma、Supabase)。
|
||||
2. 具体问题或任务(例如“如何设置中间件?”、“认证方法”)。
|
||||
|
||||
## 工作流程
|
||||
|
||||
1. **解析库 ID** — 调用 Context7 工具 `resolve-library-id`,传入库名称和用户问题,以获取 Context7 兼容的库 ID(例如 `/vercel/next.js`)。
|
||||
2. **查询文档** — 使用该库 ID 和用户问题调用 `query-docs`。
|
||||
3. **总结** — 返回简洁的答案,并包含从获取的文档中提取的相关代码示例。提及库(如果相关,包括版本)。
|
||||
|
||||
## 输出
|
||||
|
||||
用户收到一个简短、准确的答案,该答案基于当前文档,并附带任何有帮助的代码片段。如果 Context7 不可用,则说明情况,并根据训练数据回答问题,并注明文档可能已过时。
|
||||
@@ -1,6 +1,6 @@
|
||||
# 工具链审计命令
|
||||
|
||||
审计当前代码库的智能体工具链设置并返回一份优先级评分卡。
|
||||
运行确定性仓库框架审计并返回优先级评分卡。
|
||||
|
||||
## 使用方式
|
||||
|
||||
@@ -9,9 +9,19 @@
|
||||
* `scope` (可选): `repo` (默认), `hooks`, `skills`, `commands`, `agents`
|
||||
* `--format`: 输出样式 (`text` 默认, `json` 用于自动化)
|
||||
|
||||
## 评估内容
|
||||
## 确定性引擎
|
||||
|
||||
将每个类别从 `0` 到 `10` 进行评分:
|
||||
始终运行:
|
||||
|
||||
```bash
|
||||
node scripts/harness-audit.js <scope> --format <text|json>
|
||||
```
|
||||
|
||||
此脚本是评分和检查的单一事实来源。不要发明额外的维度或临时添加评分点。
|
||||
|
||||
评分标准版本:`2026-03-16`。
|
||||
|
||||
该脚本计算 7 个固定类别(每个类别标准化为 `0-10`):
|
||||
|
||||
1. 工具覆盖度
|
||||
2. 上下文效率
|
||||
@@ -21,34 +31,37 @@
|
||||
6. 安全护栏
|
||||
7. 成本效率
|
||||
|
||||
分数源自显式的文件/规则检查,并且对于同一提交是可复现的。
|
||||
|
||||
## 输出约定
|
||||
|
||||
返回:
|
||||
|
||||
1. `overall_score` (满分 70)
|
||||
2. 类别得分和具体发现
|
||||
3. 前 3 项待办事项及其确切文件路径
|
||||
4. 建议接下来应用的 ECC 技能
|
||||
1. `overall_score` 分(满分 `max_score` 分;`repo` 为 70 分;范围限定审计则分数更小)
|
||||
2. 类别分数及具体发现项
|
||||
3. 失败的检查及其确切的文件路径
|
||||
4. 确定性输出的前 3 项行动(`top_actions`)
|
||||
5. 建议接下来应用的 ECC 技能
|
||||
|
||||
## 检查清单
|
||||
|
||||
* 检查 `hooks/hooks.json`, `scripts/hooks/` 以及钩子测试。
|
||||
* 检查 `skills/`、命令覆盖度和智能体覆盖度。
|
||||
* 验证 `.cursor/`, `.opencode/`, `.codex/` 在跨工具链间的一致性。
|
||||
* 标记已损坏或过时的引用。
|
||||
* 直接使用脚本输出;不要手动重新评分。
|
||||
* 如果请求 `--format json`,则原样返回脚本的 JSON 输出。
|
||||
* 如果请求文本输出,则总结失败的检查和首要行动。
|
||||
* 包含来自 `checks[]` 和 `top_actions[]` 的确切文件路径。
|
||||
|
||||
## 结果示例
|
||||
|
||||
```text
|
||||
Harness Audit (repo): 52/70
|
||||
- Quality Gates: 9/10
|
||||
- Eval Coverage: 6/10
|
||||
- Cost Efficiency: 4/10
|
||||
Harness Audit (repo): 66/70
|
||||
- Tool Coverage: 10/10 (10/10 pts)
|
||||
- Context Efficiency: 9/10 (9/10 pts)
|
||||
- Quality Gates: 10/10 (10/10 pts)
|
||||
|
||||
Top 3 Actions:
|
||||
1) Add cost tracking hook in scripts/hooks/cost-tracker.js
|
||||
2) Add pass@k docs and templates in skills/eval-harness/SKILL.md
|
||||
3) Add command parity for /harness-audit in .opencode/commands/
|
||||
1) [Security Guardrails] Add prompt/tool preflight security guards in hooks/hooks.json. (hooks/hooks.json)
|
||||
2) [Tool Coverage] Sync commands/harness-audit.md and .opencode/commands/harness-audit.md. (.opencode/commands/harness-audit.md)
|
||||
3) [Eval Coverage] Increase automated test coverage across scripts/hooks/lib. (tests/)
|
||||
```
|
||||
|
||||
## 参数
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
---
|
||||
description: 针对多智能体工作流程的顺序和tmux/worktree编排指南。
|
||||
---
|
||||
|
||||
# 编排命令
|
||||
|
||||
用于复杂任务的顺序代理工作流。
|
||||
|
||||
@@ -315,6 +315,6 @@ result = "".join(str(item) for item in items)
|
||||
| 海象运算符 (`:=`) | 3.8+ |
|
||||
| 仅限位置参数 | 3.8+ |
|
||||
| Match 语句 | 3.10+ |
|
||||
| 类型联合 (`x \| None`) | 3.10+ |
|
||||
| 类型联合 (\`x | None\`) | 3.10+ |
|
||||
|
||||
确保你的项目 `pyproject.toml` 或 `setup.py` 指定了正确的最低 Python 版本。
|
||||
|
||||
11
docs/zh-CN/commands/rules-distill.md
Normal file
11
docs/zh-CN/commands/rules-distill.md
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
description: "扫描技能以提取跨领域原则并将其提炼为规则"
|
||||
---
|
||||
|
||||
# /rules-distill — 从技能中提炼原则为规则
|
||||
|
||||
扫描已安装的技能,提取跨领域原则,并将其提炼为规则。
|
||||
|
||||
## 流程
|
||||
|
||||
遵循 `rules-distill` 技能中定义的完整工作流程。
|
||||
189
docs/zh-CN/commands/rust-build.md
Normal file
189
docs/zh-CN/commands/rust-build.md
Normal file
@@ -0,0 +1,189 @@
|
||||
---
|
||||
description: 逐步修复 Rust 构建错误、借用检查器问题和依赖问题。调用 rust-build-resolver 代理以进行最小化、精确的修复。
|
||||
---
|
||||
|
||||
# Rust 构建与修复
|
||||
|
||||
此命令调用 **rust-build-resolver** 代理,以最小改动逐步修复 Rust 构建错误。
|
||||
|
||||
## 此命令的作用
|
||||
|
||||
1. **运行诊断**:执行 `cargo check`、`cargo clippy`、`cargo fmt --check`
|
||||
2. **解析错误**:识别错误代码和受影响的文件
|
||||
3. **逐步修复**:一次修复一个错误
|
||||
4. **验证每次修复**:每次更改后重新运行 `cargo check`
|
||||
5. **报告摘要**:显示已修复的内容和剩余问题
|
||||
|
||||
## 使用时机
|
||||
|
||||
在以下情况下使用 `/rust-build`:
|
||||
|
||||
* `cargo build` 或 `cargo check` 因错误而失败时
|
||||
* `cargo clippy` 报告警告时
|
||||
* 借用检查器或生命周期错误阻碍编译时
|
||||
* Cargo 依赖项解析失败时
|
||||
* 拉取导致构建破坏的更改后
|
||||
|
||||
## 运行的诊断命令
|
||||
|
||||
```bash
|
||||
# Primary build check
|
||||
cargo check 2>&1
|
||||
|
||||
# Lints and suggestions
|
||||
cargo clippy -- -D warnings 2>&1
|
||||
|
||||
# Formatting check
|
||||
cargo fmt --check 2>&1
|
||||
|
||||
# Dependency issues
|
||||
cargo tree --duplicates
|
||||
|
||||
# Security audit (if available)
|
||||
if command -v cargo-audit >/dev/null; then cargo audit; else echo "cargo-audit not installed"; fi
|
||||
```
|
||||
|
||||
## 示例会话
|
||||
|
||||
````text
|
||||
User: /rust-build
|
||||
|
||||
Agent:
|
||||
# Rust Build Resolution
|
||||
|
||||
## Initial Diagnostics
|
||||
|
||||
```bash
|
||||
$ cargo check
|
||||
error[E0502]: cannot borrow `map` as mutable because it is also borrowed as immutable
|
||||
--> src/service/cache.rs:25:5
|
||||
error[E0308]: mismatched types
|
||||
--> src/handler/api.rs:42:12
|
||||
error[E0425]: cannot find value `db` in this scope
|
||||
--> src/handler/api.rs:58:9
|
||||
```
|
||||
|
||||
Errors found: 3
|
||||
|
||||
## Fix 1: Borrow Checker Error
|
||||
|
||||
File: src/service/cache.rs:25
|
||||
Error: E0502 — cannot borrow `map` as mutable because also borrowed as immutable
|
||||
Cause: Immutable borrow still active during mutable insert
|
||||
|
||||
```rust
|
||||
// Changed: restructured to end immutable borrow before mutable access
|
||||
if !map.contains_key("key") {
|
||||
map.insert("key".into(), default);
|
||||
}
|
||||
```
|
||||
|
||||
```bash
|
||||
$ cargo check
|
||||
# 2 errors remaining
|
||||
```
|
||||
|
||||
## Fix 2: Type Mismatch
|
||||
|
||||
File: src/handler/api.rs:42
|
||||
Error: E0308 — mismatched types: expected `usize`, found `&str`
|
||||
|
||||
```rust
|
||||
// Changed
|
||||
let count = params.get("count");
|
||||
// To
|
||||
let count: usize = params.get("count")
|
||||
.and_then(|s| s.parse().ok())
|
||||
.unwrap_or(0);
|
||||
```
|
||||
|
||||
```bash
|
||||
$ cargo check
|
||||
# 1 error remaining
|
||||
```
|
||||
|
||||
## Fix 3: Unresolved Name
|
||||
|
||||
File: src/handler/api.rs:58
|
||||
Error: E0425 — cannot find value `db` in this scope
|
||||
Cause: Missing import
|
||||
|
||||
```rust
|
||||
// Added
|
||||
use crate::db;
|
||||
```
|
||||
|
||||
```bash
|
||||
$ cargo check
|
||||
# Build successful!
|
||||
```
|
||||
|
||||
## Final Verification
|
||||
|
||||
```bash
|
||||
$ cargo clippy -- -D warnings
|
||||
# No warnings
|
||||
|
||||
$ cargo test
|
||||
running 6 tests
|
||||
test service::cache::tests::test_insert ... ok
|
||||
test service::cache::tests::test_get ... ok
|
||||
test handler::api::tests::test_parse_count ... ok
|
||||
test handler::api::tests::test_missing_count ... ok
|
||||
test handler::api::tests::test_db_import ... ok
|
||||
test handler::api::tests::test_response ... ok
|
||||
|
||||
test result: ok. 6 passed; 0 failed; 0 ignored
|
||||
```
|
||||
|
||||
## Summary
|
||||
|
||||
| Metric | Count |
|
||||
|--------|-------|
|
||||
| Build errors fixed | 3 |
|
||||
| Clippy warnings fixed | 0 |
|
||||
| Files modified | 2 |
|
||||
| Remaining issues | 0 |
|
||||
|
||||
Build Status: SUCCESS
|
||||
````
|
||||
|
||||
## 修复的常见错误
|
||||
|
||||
| 错误 | 典型修复方法 |
|
||||
|-------|-------------|
|
||||
| `cannot borrow as mutable` | 重构以先结束不可变借用;仅在合理情况下克隆 |
|
||||
| `does not live long enough` | 使用拥有所有权的类型或添加生命周期注解 |
|
||||
| `cannot move out of` | 重构以获取所有权;仅作为最后手段进行克隆 |
|
||||
| `mismatched types` | 添加 `.into()`、`as` 或显式转换 |
|
||||
| `trait X not implemented` | 添加 `#[derive(Trait)]` 或手动实现 |
|
||||
| `unresolved import` | 添加到 Cargo.toml 或修复 `use` 路径 |
|
||||
| `cannot find value` | 添加导入或修复路径 |
|
||||
|
||||
## 修复策略
|
||||
|
||||
1. **首先解决构建错误** - 代码必须能够编译
|
||||
2. **其次解决 Clippy 警告** - 修复可疑的构造
|
||||
3. **第三处理格式化** - 符合 `cargo fmt` 标准
|
||||
4. **一次修复一个** - 验证每次更改
|
||||
5. **最小化改动** - 不进行重构,仅修复问题
|
||||
|
||||
## 停止条件
|
||||
|
||||
代理将在以下情况下停止并报告:
|
||||
|
||||
* 同一错误尝试 3 次后仍然存在
|
||||
* 修复引入了更多错误
|
||||
* 需要架构性更改
|
||||
* 借用检查器错误需要重新设计数据所有权
|
||||
|
||||
## 相关命令
|
||||
|
||||
* `/rust-test` - 构建成功后运行测试
|
||||
* `/rust-review` - 审查代码质量
|
||||
* `/verify` - 完整验证循环
|
||||
|
||||
## 相关
|
||||
|
||||
* 代理:`agents/rust-build-resolver.md`
|
||||
* 技能:`skills/rust-patterns/`
|
||||
146
docs/zh-CN/commands/rust-review.md
Normal file
146
docs/zh-CN/commands/rust-review.md
Normal file
@@ -0,0 +1,146 @@
|
||||
---
|
||||
description: 全面的Rust代码审查,涵盖所有权、生命周期、错误处理、不安全代码使用以及惯用模式。调用rust-reviewer代理。
|
||||
---
|
||||
|
||||
# Rust 代码审查
|
||||
|
||||
此命令调用 **rust-reviewer** 代理进行全面的 Rust 专项代码审查。
|
||||
|
||||
## 此命令的作用
|
||||
|
||||
1. **验证自动化检查**:运行 `cargo check`、`cargo clippy -- -D warnings`、`cargo fmt --check` 和 `cargo test` —— 任何一项失败则停止
|
||||
2. **识别 Rust 变更**:通过 `git diff HEAD~1`(或针对 PR 使用 `git diff main...HEAD`)查找修改过的 `.rs` 文件
|
||||
3. **运行安全审计**:如果可用,则执行 `cargo audit`
|
||||
4. **安全扫描**:检查不安全使用、命令注入、硬编码密钥
|
||||
5. **所有权审查**:分析不必要的克隆、生命周期问题、借用模式
|
||||
6. **生成报告**:按严重性对问题进行分类
|
||||
|
||||
## 何时使用
|
||||
|
||||
在以下情况下使用 `/rust-review`:
|
||||
|
||||
* 编写或修改 Rust 代码之后
|
||||
* 提交 Rust 变更之前
|
||||
* 审查包含 Rust 代码的拉取请求时
|
||||
* 接手新的 Rust 代码库时
|
||||
* 学习惯用的 Rust 模式时
|
||||
|
||||
## 审查类别
|
||||
|
||||
### 关键(必须修复)
|
||||
|
||||
* 生产代码路径中未经检查的 `unwrap()`/`expect()`
|
||||
* 没有 `// SAFETY:` 注释记录不变量的 `unsafe`
|
||||
* 查询中通过字符串插值导致的 SQL 注入
|
||||
* 在 `std::process::Command` 中通过未经验证的输入导致的命令注入
|
||||
* 硬编码凭据
|
||||
* 通过原始指针导致的释放后使用
|
||||
|
||||
### 高(应该修复)
|
||||
|
||||
* 为满足借用检查器而进行的不必要的 `.clone()`
|
||||
* 参数为 `String`,而 `&str` 或 `impl AsRef<str>` 即可满足
|
||||
* 在异步上下文中的阻塞操作(`std::thread::sleep`、`std::fs`)
|
||||
* 共享类型上缺少 `Send`/`Sync` 约束
|
||||
* 对业务关键枚举使用通配符 `_ =>` 匹配
|
||||
* 大型函数(>50 行)
|
||||
|
||||
### 中(考虑)
|
||||
|
||||
* 在热点路径中不必要的分配
|
||||
* 已知大小时缺少 `with_capacity`
|
||||
* 未说明理由就抑制 clippy 警告
|
||||
* 公共 API 缺少 `///` 文档
|
||||
* 对于忽略返回值很可能是错误的非 `must_use` 返回类型,考虑使用 `#[must_use]`
|
||||
|
||||
## 运行的自动化检查
|
||||
|
||||
```bash
|
||||
# Build gate (must pass before review)
|
||||
cargo check
|
||||
|
||||
# Lints and suggestions
|
||||
cargo clippy -- -D warnings
|
||||
|
||||
# Formatting
|
||||
cargo fmt --check
|
||||
|
||||
# Tests
|
||||
cargo test
|
||||
|
||||
# Security audit (if available)
|
||||
if command -v cargo-audit >/dev/null; then cargo audit; else echo "cargo-audit not installed"; fi
|
||||
```
|
||||
|
||||
## 使用示例
|
||||
|
||||
````text
|
||||
User: /rust-review
|
||||
|
||||
Agent:
|
||||
# Rust Code Review Report
|
||||
|
||||
## Files Reviewed
|
||||
- src/service/user.rs (modified)
|
||||
- src/handler/api.rs (modified)
|
||||
|
||||
## Static Analysis Results
|
||||
- Build: Successful
|
||||
- Clippy: No warnings
|
||||
- Formatting: Passed
|
||||
- Tests: All passing
|
||||
|
||||
## Issues Found
|
||||
|
||||
[CRITICAL] Unchecked unwrap in Production Path
|
||||
File: src/service/user.rs:28
|
||||
Issue: Using `.unwrap()` on database query result
|
||||
```rust
|
||||
let user = db.find_by_id(id).unwrap(); // Panics on missing user
|
||||
```
|
||||
Fix: Propagate error with context
|
||||
```rust
|
||||
let user = db.find_by_id(id)
|
||||
.context("failed to fetch user")?;
|
||||
```
|
||||
|
||||
[HIGH] Unnecessary Clone
|
||||
File: src/handler/api.rs:45
|
||||
Issue: Cloning String to satisfy borrow checker
|
||||
```rust
|
||||
let name = user.name.clone();
|
||||
process(&user, &name);
|
||||
```
|
||||
Fix: Restructure to avoid clone
|
||||
```rust
|
||||
let result = process_name(&user.name);
|
||||
use_user(&user, result);
|
||||
```
|
||||
|
||||
## Summary
|
||||
- CRITICAL: 1
|
||||
- HIGH: 1
|
||||
- MEDIUM: 0
|
||||
|
||||
Recommendation: Block merge until CRITICAL issue is fixed
|
||||
````
|
||||
|
||||
## 批准标准
|
||||
|
||||
| 状态 | 条件 |
|
||||
|--------|-----------|
|
||||
| 批准 | 无关键或高优先级问题 |
|
||||
| 警告 | 仅存在中优先级问题(谨慎合并) |
|
||||
| 阻止 | 发现关键或高优先级问题 |
|
||||
|
||||
## 与其他命令的集成
|
||||
|
||||
* 首先使用 `/rust-test` 确保测试通过
|
||||
* 如果出现构建错误,使用 `/rust-build`
|
||||
* 提交前使用 `/rust-review`
|
||||
* 对于非 Rust 专项问题,使用 `/code-review`
|
||||
|
||||
## 相关
|
||||
|
||||
* 代理:`agents/rust-reviewer.md`
|
||||
* 技能:`skills/rust-patterns/`、`skills/rust-testing/`
|
||||
311
docs/zh-CN/commands/rust-test.md
Normal file
311
docs/zh-CN/commands/rust-test.md
Normal file
@@ -0,0 +1,311 @@
|
||||
---
|
||||
description: 为Rust强制执行TDD工作流。先写测试,然后实现。使用cargo-llvm-cov验证80%以上的覆盖率。
|
||||
---
|
||||
|
||||
# Rust TDD 命令
|
||||
|
||||
该命令使用 `#[test]`、rstest、proptest 和 mockall 来强制执行 Rust 代码的测试驱动开发方法。
|
||||
|
||||
## 该命令的作用
|
||||
|
||||
1. **定义类型/特征**:使用 `todo!()` 搭建函数签名
|
||||
2. **编写测试**:创建全面的测试模块(RED)
|
||||
3. **运行测试**:验证测试因正确的原因而失败
|
||||
4. **实现代码**:编写通过测试所需的最少代码(GREEN)
|
||||
5. **重构**:在保持测试通过的前提下进行改进
|
||||
6. **检查覆盖率**:使用 cargo-llvm-cov 确保 80%+ 的覆盖率
|
||||
|
||||
## 何时使用
|
||||
|
||||
在以下情况使用 `/rust-test`:
|
||||
|
||||
* 实现新的 Rust 函数、方法或特征时
|
||||
* 为现有 Rust 代码添加测试覆盖时
|
||||
* 修复错误时(首先编写失败的测试)
|
||||
* 构建关键业务逻辑时
|
||||
* 学习 Rust 中的 TDD 工作流程时
|
||||
|
||||
## TDD 循环
|
||||
|
||||
```
|
||||
RED -> Write failing test first
|
||||
GREEN -> Implement minimal code to pass
|
||||
REFACTOR -> Improve code, tests stay green
|
||||
REPEAT -> Next test case
|
||||
```
|
||||
|
||||
## 示例会话
|
||||
|
||||
````text
|
||||
User: /rust-test I need a function to validate user registration
|
||||
|
||||
Agent:
|
||||
# TDD Session: Registration Validator
|
||||
|
||||
## Step 1: Define Interface
|
||||
|
||||
```rust
|
||||
// src/validator.rs
|
||||
pub struct RegistrationRequest {
|
||||
pub name: String,
|
||||
pub email: String,
|
||||
pub password: String,
|
||||
}
|
||||
|
||||
pub enum ValidationResult {
|
||||
Valid,
|
||||
Invalid(Vec<String>),
|
||||
}
|
||||
|
||||
pub fn validate_registration(request: &RegistrationRequest) -> ValidationResult {
|
||||
todo!()
|
||||
}
|
||||
```
|
||||
|
||||
## Step 2: Write Tests (RED)
|
||||
|
||||
```rust
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn valid_registration_returns_valid() {
|
||||
let request = RegistrationRequest {
|
||||
name: "Alice".into(),
|
||||
email: "alice@example.com".into(),
|
||||
password: "SecureP@ss1".into(),
|
||||
};
|
||||
assert!(matches!(validate_registration(&request), ValidationResult::Valid));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn blank_name_returns_invalid() {
|
||||
let request = RegistrationRequest {
|
||||
name: "".into(),
|
||||
email: "alice@example.com".into(),
|
||||
password: "SecureP@ss1".into(),
|
||||
};
|
||||
match validate_registration(&request) {
|
||||
ValidationResult::Invalid(errors) => {
|
||||
assert!(errors.contains(&"Name is required".to_string()));
|
||||
}
|
||||
ValidationResult::Valid => panic!("expected Invalid"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_email_returns_invalid() {
|
||||
let request = RegistrationRequest {
|
||||
name: "Alice".into(),
|
||||
email: "not-an-email".into(),
|
||||
password: "SecureP@ss1".into(),
|
||||
};
|
||||
assert!(matches!(
|
||||
validate_registration(&request),
|
||||
ValidationResult::Invalid(_)
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn short_password_returns_invalid() {
|
||||
let request = RegistrationRequest {
|
||||
name: "Alice".into(),
|
||||
email: "alice@example.com".into(),
|
||||
password: "short".into(),
|
||||
};
|
||||
assert!(matches!(
|
||||
validate_registration(&request),
|
||||
ValidationResult::Invalid(_)
|
||||
));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Step 3: Run Tests — Verify FAIL
|
||||
|
||||
```bash
|
||||
$ cargo test
|
||||
running 4 tests
|
||||
test tests::valid_registration_returns_valid ... FAILED (not yet implemented)
|
||||
test tests::blank_name_returns_invalid ... FAILED
|
||||
test tests::invalid_email_returns_invalid ... FAILED
|
||||
test tests::short_password_returns_invalid ... FAILED
|
||||
```
|
||||
|
||||
Tests fail as expected (todo! panic).
|
||||
|
||||
## Step 4: Implement Minimal Code (GREEN)
|
||||
|
||||
```rust
|
||||
pub fn validate_registration(request: &RegistrationRequest) -> ValidationResult {
|
||||
let mut errors = Vec::new();
|
||||
|
||||
if request.name.trim().is_empty() {
|
||||
errors.push("Name is required".into());
|
||||
}
|
||||
if !request.email.contains('@') {
|
||||
errors.push("Invalid email format".into());
|
||||
}
|
||||
if request.password.len() < 8 {
|
||||
errors.push("Password must be at least 8 characters".into());
|
||||
}
|
||||
|
||||
if errors.is_empty() {
|
||||
ValidationResult::Valid
|
||||
} else {
|
||||
ValidationResult::Invalid(errors)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Step 5: Run Tests — Verify PASS
|
||||
|
||||
```bash
|
||||
$ cargo test
|
||||
running 4 tests
|
||||
test tests::valid_registration_returns_valid ... ok
|
||||
test tests::blank_name_returns_invalid ... ok
|
||||
test tests::invalid_email_returns_invalid ... ok
|
||||
test tests::short_password_returns_invalid ... ok
|
||||
|
||||
test result: ok. 4 passed; 0 failed
|
||||
```
|
||||
|
||||
All tests passing!
|
||||
|
||||
## Step 6: Check Coverage
|
||||
|
||||
```bash
|
||||
$ cargo llvm-cov
|
||||
Coverage: 100.0% of lines
|
||||
```
|
||||
|
||||
Coverage: 100%
|
||||
|
||||
## TDD Complete!
|
||||
````
|
||||
|
||||
## 测试模式
|
||||
|
||||
### 单元测试
|
||||
|
||||
```rust
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn adds_two_numbers() {
|
||||
assert_eq!(add(2, 3), 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn handles_error() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let result = parse_config(r#"port = 8080"#)?;
|
||||
assert_eq!(result.port, 8080);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 使用 rstest 进行参数化测试
|
||||
|
||||
```rust
|
||||
use rstest::{rstest, fixture};
|
||||
|
||||
#[rstest]
|
||||
#[case("hello", 5)]
|
||||
#[case("", 0)]
|
||||
#[case("rust", 4)]
|
||||
fn test_string_length(#[case] input: &str, #[case] expected: usize) {
|
||||
assert_eq!(input.len(), expected);
|
||||
}
|
||||
```
|
||||
|
||||
### 异步测试
|
||||
|
||||
```rust
|
||||
#[tokio::test]
|
||||
async fn fetches_data_successfully() {
|
||||
let client = TestClient::new().await;
|
||||
let result = client.get("/data").await;
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
```
|
||||
|
||||
### 基于属性的测试
|
||||
|
||||
```rust
|
||||
use proptest::prelude::*;
|
||||
|
||||
proptest! {
|
||||
#[test]
|
||||
fn encode_decode_roundtrip(input in ".*") {
|
||||
let encoded = encode(&input);
|
||||
let decoded = decode(&encoded).unwrap();
|
||||
assert_eq!(input, decoded);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 覆盖率命令
|
||||
|
||||
```bash
|
||||
# Summary report
|
||||
cargo llvm-cov
|
||||
|
||||
# HTML report
|
||||
cargo llvm-cov --html
|
||||
|
||||
# Fail if below threshold
|
||||
cargo llvm-cov --fail-under-lines 80
|
||||
|
||||
# Run specific test
|
||||
cargo test test_name
|
||||
|
||||
# Run with output
|
||||
cargo test -- --nocapture
|
||||
|
||||
# Run without stopping on first failure
|
||||
cargo test --no-fail-fast
|
||||
```
|
||||
|
||||
## 覆盖率目标
|
||||
|
||||
| 代码类型 | 目标 |
|
||||
|-----------|--------|
|
||||
| 关键业务逻辑 | 100% |
|
||||
| 公共 API | 90%+ |
|
||||
| 通用代码 | 80%+ |
|
||||
| 生成的 / FFI 绑定 | 排除 |
|
||||
|
||||
## TDD 最佳实践
|
||||
|
||||
**应做:**
|
||||
|
||||
* **首先**编写测试,在任何实现之前
|
||||
* 每次更改后运行测试
|
||||
* 使用 `assert_eq!` 而非 `assert!` 以获得更好的错误信息
|
||||
* 在返回 `Result` 的测试中使用 `?` 以获得更清晰的输出
|
||||
* 测试行为,而非实现
|
||||
* 包含边界情况(空值、边界值、错误路径)
|
||||
|
||||
**不应做:**
|
||||
|
||||
* 在测试之前编写实现
|
||||
* 跳过 RED 阶段
|
||||
* 在 `Result::is_err()` 可用时使用 `#[should_panic]`
|
||||
* 在测试中使用 `sleep()` — 应使用通道或 `tokio::time::pause()`
|
||||
* 模拟一切 — 在可行时优先使用集成测试
|
||||
|
||||
## 相关命令
|
||||
|
||||
* `/rust-build` - 修复构建错误
|
||||
* `/rust-review` - 在实现后审查代码
|
||||
* `/verify` - 运行完整的验证循环
|
||||
|
||||
## 相关
|
||||
|
||||
* 技能:`skills/rust-testing/`
|
||||
* 技能:`skills/rust-patterns/`
|
||||
@@ -1,3 +1,7 @@
|
||||
---
|
||||
description: 管理Claude Code会话历史、别名和会话元数据。
|
||||
---
|
||||
|
||||
# Sessions 命令
|
||||
|
||||
管理 Claude Code 会话历史 - 列出、加载、设置别名和编辑存储在 `~/.claude/sessions/` 中的会话。
|
||||
@@ -26,8 +30,8 @@
|
||||
|
||||
```bash
|
||||
node -e "
|
||||
const sm = require((process.env.CLAUDE_PLUGIN_ROOT||require('path').join(require('os').homedir(),'.claude'))+'/scripts/lib/session-manager');
|
||||
const aa = require((process.env.CLAUDE_PLUGIN_ROOT||require('path').join(require('os').homedir(),'.claude'))+'/scripts/lib/session-aliases');
|
||||
const sm = require((()=>{var e=process.env.CLAUDE_PLUGIN_ROOT;if(e&&e.trim())return e.trim();var p=require('path'),f=require('fs'),h=require('os').homedir(),d=p.join(h,'.claude'),q=p.join('scripts','lib','utils.js');if(f.existsSync(p.join(d,q)))return d;try{var b=p.join(d,'plugins','cache','everything-claude-code');for(var o of f.readdirSync(b))for(var v of f.readdirSync(p.join(b,o))){var c=p.join(b,o,v);if(f.existsSync(p.join(c,q)))return c}}catch(x){}return d})()+'/scripts/lib/session-manager');
|
||||
const aa = require((()=>{var e=process.env.CLAUDE_PLUGIN_ROOT;if(e&&e.trim())return e.trim();var p=require('path'),f=require('fs'),h=require('os').homedir(),d=p.join(h,'.claude'),q=p.join('scripts','lib','utils.js');if(f.existsSync(p.join(d,q)))return d;try{var b=p.join(d,'plugins','cache','everything-claude-code');for(var o of f.readdirSync(b))for(var v of f.readdirSync(p.join(b,o))){var c=p.join(b,o,v);if(f.existsSync(p.join(c,q)))return c}}catch(x){}return d})()+'/scripts/lib/session-aliases');
|
||||
const path = require('path');
|
||||
|
||||
const result = sm.getAllSessions({ limit: 20 });
|
||||
@@ -68,8 +72,8 @@ for (const s of result.sessions) {
|
||||
|
||||
```bash
|
||||
node -e "
|
||||
const sm = require((process.env.CLAUDE_PLUGIN_ROOT||require('path').join(require('os').homedir(),'.claude'))+'/scripts/lib/session-manager');
|
||||
const aa = require((process.env.CLAUDE_PLUGIN_ROOT||require('path').join(require('os').homedir(),'.claude'))+'/scripts/lib/session-aliases');
|
||||
const sm = require((()=>{var e=process.env.CLAUDE_PLUGIN_ROOT;if(e&&e.trim())return e.trim();var p=require('path'),f=require('fs'),h=require('os').homedir(),d=p.join(h,'.claude'),q=p.join('scripts','lib','utils.js');if(f.existsSync(p.join(d,q)))return d;try{var b=p.join(d,'plugins','cache','everything-claude-code');for(var o of f.readdirSync(b))for(var v of f.readdirSync(p.join(b,o))){var c=p.join(b,o,v);if(f.existsSync(p.join(c,q)))return c}}catch(x){}return d})()+'/scripts/lib/session-manager');
|
||||
const aa = require((()=>{var e=process.env.CLAUDE_PLUGIN_ROOT;if(e&&e.trim())return e.trim();var p=require('path'),f=require('fs'),h=require('os').homedir(),d=p.join(h,'.claude'),q=p.join('scripts','lib','utils.js');if(f.existsSync(p.join(d,q)))return d;try{var b=p.join(d,'plugins','cache','everything-claude-code');for(var o of f.readdirSync(b))for(var v of f.readdirSync(p.join(b,o))){var c=p.join(b,o,v);if(f.existsSync(p.join(c,q)))return c}}catch(x){}return d})()+'/scripts/lib/session-aliases');
|
||||
const id = process.argv[1];
|
||||
|
||||
// First try to resolve as alias
|
||||
@@ -142,8 +146,8 @@ if (session.metadata.worktree) {
|
||||
|
||||
```bash
|
||||
node -e "
|
||||
const sm = require((process.env.CLAUDE_PLUGIN_ROOT||require('path').join(require('os').homedir(),'.claude'))+'/scripts/lib/session-manager');
|
||||
const aa = require((process.env.CLAUDE_PLUGIN_ROOT||require('path').join(require('os').homedir(),'.claude'))+'/scripts/lib/session-aliases');
|
||||
const sm = require((()=>{var e=process.env.CLAUDE_PLUGIN_ROOT;if(e&&e.trim())return e.trim();var p=require('path'),f=require('fs'),h=require('os').homedir(),d=p.join(h,'.claude'),q=p.join('scripts','lib','utils.js');if(f.existsSync(p.join(d,q)))return d;try{var b=p.join(d,'plugins','cache','everything-claude-code');for(var o of f.readdirSync(b))for(var v of f.readdirSync(p.join(b,o))){var c=p.join(b,o,v);if(f.existsSync(p.join(c,q)))return c}}catch(x){}return d})()+'/scripts/lib/session-manager');
|
||||
const aa = require((()=>{var e=process.env.CLAUDE_PLUGIN_ROOT;if(e&&e.trim())return e.trim();var p=require('path'),f=require('fs'),h=require('os').homedir(),d=p.join(h,'.claude'),q=p.join('scripts','lib','utils.js');if(f.existsSync(p.join(d,q)))return d;try{var b=p.join(d,'plugins','cache','everything-claude-code');for(var o of f.readdirSync(b))for(var v of f.readdirSync(p.join(b,o))){var c=p.join(b,o,v);if(f.existsSync(p.join(c,q)))return c}}catch(x){}return d})()+'/scripts/lib/session-aliases');
|
||||
|
||||
const sessionId = process.argv[1];
|
||||
const aliasName = process.argv[2];
|
||||
@@ -183,7 +187,7 @@ if (result.success) {
|
||||
|
||||
```bash
|
||||
node -e "
|
||||
const aa = require((process.env.CLAUDE_PLUGIN_ROOT||require('path').join(require('os').homedir(),'.claude'))+'/scripts/lib/session-aliases');
|
||||
const aa = require((()=>{var e=process.env.CLAUDE_PLUGIN_ROOT;if(e&&e.trim())return e.trim();var p=require('path'),f=require('fs'),h=require('os').homedir(),d=p.join(h,'.claude'),q=p.join('scripts','lib','utils.js');if(f.existsSync(p.join(d,q)))return d;try{var b=p.join(d,'plugins','cache','everything-claude-code');for(var o of f.readdirSync(b))for(var v of f.readdirSync(p.join(b,o))){var c=p.join(b,o,v);if(f.existsSync(p.join(c,q)))return c}}catch(x){}return d})()+'/scripts/lib/session-aliases');
|
||||
|
||||
const aliasName = process.argv[1];
|
||||
if (!aliasName) {
|
||||
@@ -213,8 +217,8 @@ if (result.success) {
|
||||
|
||||
```bash
|
||||
node -e "
|
||||
const sm = require((process.env.CLAUDE_PLUGIN_ROOT||require('path').join(require('os').homedir(),'.claude'))+'/scripts/lib/session-manager');
|
||||
const aa = require((process.env.CLAUDE_PLUGIN_ROOT||require('path').join(require('os').homedir(),'.claude'))+'/scripts/lib/session-aliases');
|
||||
const sm = require((()=>{var e=process.env.CLAUDE_PLUGIN_ROOT;if(e&&e.trim())return e.trim();var p=require('path'),f=require('fs'),h=require('os').homedir(),d=p.join(h,'.claude'),q=p.join('scripts','lib','utils.js');if(f.existsSync(p.join(d,q)))return d;try{var b=p.join(d,'plugins','cache','everything-claude-code');for(var o of f.readdirSync(b))for(var v of f.readdirSync(p.join(b,o))){var c=p.join(b,o,v);if(f.existsSync(p.join(c,q)))return c}}catch(x){}return d})()+'/scripts/lib/session-manager');
|
||||
const aa = require((()=>{var e=process.env.CLAUDE_PLUGIN_ROOT;if(e&&e.trim())return e.trim();var p=require('path'),f=require('fs'),h=require('os').homedir(),d=p.join(h,'.claude'),q=p.join('scripts','lib','utils.js');if(f.existsSync(p.join(d,q)))return d;try{var b=p.join(d,'plugins','cache','everything-claude-code');for(var o of f.readdirSync(b))for(var v of f.readdirSync(p.join(b,o))){var c=p.join(b,o,v);if(f.existsSync(p.join(c,q)))return c}}catch(x){}return d})()+'/scripts/lib/session-aliases');
|
||||
|
||||
const id = process.argv[1];
|
||||
const resolved = aa.resolveAlias(id);
|
||||
@@ -260,16 +264,11 @@ if (aliases.length > 0) {
|
||||
/sessions aliases # List all aliases
|
||||
```
|
||||
|
||||
## 操作员笔记
|
||||
|
||||
* 会话文件在头部持久化 `Project`、`Branch` 和 `Worktree`,以便 `/sessions info` 可以区分并行 tmux/工作树运行。
|
||||
* 对于指挥中心式监控,请结合使用 `/sessions info`、`git diff --stat` 以及由 `scripts/hooks/cost-tracker.js` 发出的成本指标。
|
||||
|
||||
**脚本:**
|
||||
|
||||
```bash
|
||||
node -e "
|
||||
const aa = require((process.env.CLAUDE_PLUGIN_ROOT||require('path').join(require('os').homedir(),'.claude'))+'/scripts/lib/session-aliases');
|
||||
const aa = require((()=>{var e=process.env.CLAUDE_PLUGIN_ROOT;if(e&&e.trim())return e.trim();var p=require('path'),f=require('fs'),h=require('os').homedir(),d=p.join(h,'.claude'),q=p.join('scripts','lib','utils.js');if(f.existsSync(p.join(d,q)))return d;try{var b=p.join(d,'plugins','cache','everything-claude-code');for(var o of f.readdirSync(b))for(var v of f.readdirSync(p.join(b,o))){var c=p.join(b,o,v);if(f.existsSync(p.join(c,q)))return c}}catch(x){}return d})()+'/scripts/lib/session-aliases');
|
||||
|
||||
const aliases = aa.listAliases();
|
||||
console.log('Session Aliases (' + aliases.length + '):');
|
||||
@@ -290,6 +289,11 @@ if (aliases.length === 0) {
|
||||
"
|
||||
```
|
||||
|
||||
## 操作员笔记
|
||||
|
||||
* 会话文件在头部持久化 `Project`、`Branch` 和 `Worktree`,以便 `/sessions info` 可以区分并行 tmux/工作树运行。
|
||||
* 对于指挥中心式监控,请结合使用 `/sessions info`、`git diff --stat` 以及由 `scripts/hooks/cost-tracker.js` 发出的成本指标。
|
||||
|
||||
## 参数
|
||||
|
||||
$ARGUMENTS:
|
||||
|
||||
54
docs/zh-CN/commands/skill-health.md
Normal file
54
docs/zh-CN/commands/skill-health.md
Normal file
@@ -0,0 +1,54 @@
|
||||
---
|
||||
name: skill-health
|
||||
description: 显示技能组合健康仪表板,包含图表和分析
|
||||
command: true
|
||||
---
|
||||
|
||||
# 技能健康仪表盘
|
||||
|
||||
展示投资组合中所有技能的综合健康仪表盘,包含成功率走势图、故障模式聚类、待处理修订和版本历史。
|
||||
|
||||
## 实现
|
||||
|
||||
在仪表盘模式下运行技能健康 CLI:
|
||||
|
||||
```bash
|
||||
ECC_ROOT="${CLAUDE_PLUGIN_ROOT:-$(node -e "var p=require('path'),f=require('fs'),h=require('os').homedir(),d=p.join(h,'.claude'),q=p.join('scripts','lib','utils.js');if(!f.existsSync(p.join(d,q))){try{var b=p.join(d,'plugins','cache','everything-claude-code');for(var o of f.readdirSync(b))for(var v of f.readdirSync(p.join(b,o))){var c=p.join(b,o,v);if(f.existsSync(p.join(c,q))){d=c;break}}}catch(x){}}console.log(d)")}"
|
||||
node "$ECC_ROOT/scripts/skills-health.js" --dashboard
|
||||
```
|
||||
|
||||
仅针对特定面板:
|
||||
|
||||
```bash
|
||||
ECC_ROOT="${CLAUDE_PLUGIN_ROOT:-$(node -e "var p=require('path'),f=require('fs'),h=require('os').homedir(),d=p.join(h,'.claude'),q=p.join('scripts','lib','utils.js');if(!f.existsSync(p.join(d,q))){try{var b=p.join(d,'plugins','cache','everything-claude-code');for(var o of f.readdirSync(b))for(var v of f.readdirSync(p.join(b,o))){var c=p.join(b,o,v);if(f.existsSync(p.join(c,q))){d=c;break}}}catch(x){}}console.log(d)")}"
|
||||
node "$ECC_ROOT/scripts/skills-health.js" --dashboard --panel failures
|
||||
```
|
||||
|
||||
获取机器可读输出:
|
||||
|
||||
```bash
|
||||
ECC_ROOT="${CLAUDE_PLUGIN_ROOT:-$(node -e "var p=require('path'),f=require('fs'),h=require('os').homedir(),d=p.join(h,'.claude'),q=p.join('scripts','lib','utils.js');if(!f.existsSync(p.join(d,q))){try{var b=p.join(d,'plugins','cache','everything-claude-code');for(var o of f.readdirSync(b))for(var v of f.readdirSync(p.join(b,o))){var c=p.join(b,o,v);if(f.existsSync(p.join(c,q))){d=c;break}}}catch(x){}}console.log(d)")}"
|
||||
node "$ECC_ROOT/scripts/skills-health.js" --dashboard --json
|
||||
```
|
||||
|
||||
## 使用方法
|
||||
|
||||
```
|
||||
/skill-health # Full dashboard view
|
||||
/skill-health --panel failures # Only failure clustering panel
|
||||
/skill-health --json # Machine-readable JSON output
|
||||
```
|
||||
|
||||
## 操作步骤
|
||||
|
||||
1. 使用 --dashboard 标志运行 skills-health.js 脚本
|
||||
2. 向用户显示输出
|
||||
3. 如果有任何技能出现衰退,高亮显示并建议运行 /evolve
|
||||
4. 如果有待处理修订,建议进行审查
|
||||
|
||||
## 面板
|
||||
|
||||
* **成功率 (30天)** — 显示每个技能每日成功率的走势图
|
||||
* **故障模式** — 聚类故障原因并显示水平条形图
|
||||
* **待处理修订** — 等待审查的修订提案
|
||||
* **版本历史** — 每个技能的版本快照时间线
|
||||
Reference in New Issue
Block a user