mirror of
https://github.com/sweetwisdom/everything-claude-code-zh.git
synced 2026-03-22 14:40:14 +00:00
chore: sync with upstream ae2c063 + update zh translations
This commit is contained in:
@@ -1,22 +1,22 @@
|
|||||||
# 插件清单模式(Manifest Schema)注意事项
|
# 插件清单模式(Plugin Manifest Schema)说明
|
||||||
|
|
||||||
本文档记录了 Claude Code 插件清单校验器中**未见于文档但强制执行的约束**。
|
本文档记录了 Claude Code 插件清单校验器(Validator)中**未公开但强制执行的约束条件**。
|
||||||
|
|
||||||
这些规则基于真实的安装失败案例、校验器行为以及与已知可用插件的对比。
|
这些规则基于真实的安装失败案例、校验器行为分析以及与已知可用插件的对比。
|
||||||
设置这些规则是为了防止隐性故障和重复的回归问题。
|
它们的存在是为了防止隐性破坏(silent breakage)和重复出现的回归(regressions)问题。
|
||||||
|
|
||||||
如果你编辑 `.claude-plugin/plugin.json`,请先阅读本文。
|
如果你需要编辑 `.claude-plugin/plugin.json`,请务必先阅读本文。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 摘要(优先阅读)
|
## 摘要(优先阅读)
|
||||||
|
|
||||||
Claude 插件清单校验器**极其严格且具有主观性**。
|
Claude 插件清单校验器非常**严格且具有确定性**。
|
||||||
它执行了一些在公开模式(Schema)参考文档中未完全说明的规则。
|
它强制执行了一些在公共模式(Schema)引用中未完全记录的规则。
|
||||||
|
|
||||||
最常见的失败模式是:
|
最常见的失败模式是:
|
||||||
|
|
||||||
> 清单看起来很合理,但校验器以模糊的错误拒绝它,例如:
|
> 清单看起来很合理,但校验器拒绝了它,并给出模糊的错误提示,例如
|
||||||
> `agents: Invalid input`
|
> `agents: Invalid input`
|
||||||
|
|
||||||
本文档将解释其原因。
|
本文档将解释其原因。
|
||||||
@@ -25,11 +25,11 @@ Claude 插件清单校验器**极其严格且具有主观性**。
|
|||||||
|
|
||||||
## 必填字段
|
## 必填字段
|
||||||
|
|
||||||
### `version`(强制性)
|
### `version`(强制要求)
|
||||||
|
|
||||||
即便在某些示例中被省略,校验器也要求必须包含 `version` 字段。
|
校验器要求必须包含 `version` 字段,即使在某些示例中省略了它。
|
||||||
|
|
||||||
如果缺失,在应用市场安装或 CLI 校验期间可能会失败。
|
如果缺失该字段,在应用市场安装或 CLI 校验期间可能会失败。
|
||||||
|
|
||||||
示例:
|
示例:
|
||||||
|
|
||||||
@@ -50,9 +50,9 @@ Claude 插件清单校验器**极其严格且具有主观性**。
|
|||||||
* `skills`
|
* `skills`
|
||||||
* `hooks`(如果存在)
|
* `hooks`(如果存在)
|
||||||
|
|
||||||
即便只有一个条目,**也不接受字符串(Strings)**。
|
即使只有一个条目,**也不接受字符串(Strings)类型**。
|
||||||
|
|
||||||
### 错误写法(Invalid)
|
### 错误示例(Invalid)
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -60,7 +60,7 @@ Claude 插件清单校验器**极其严格且具有主观性**。
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 正确写法(Valid)
|
### 正确示例(Valid)
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -68,17 +68,17 @@ Claude 插件清单校验器**极其严格且具有主观性**。
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
这适用于所有组件路径字段。
|
这一规则一致适用于所有组件路径字段。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 路径解析规则(至关重要)
|
## 路径解析规则(关键)
|
||||||
|
|
||||||
### Agents 必须使用显式文件路径
|
### Agents 必须使用显式文件路径
|
||||||
|
|
||||||
校验器**不接受 `agents` 使用目录路径**。
|
校验器**不接受 `agents` 字段使用目录路径**。
|
||||||
|
|
||||||
即便如下写法也会失败:
|
即使是以下写法也会失败:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -86,7 +86,7 @@ Claude 插件清单校验器**极其严格且具有主观性**。
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
相反,你必须显式列举智能体(Agent)文件:
|
相反,你必须显式枚举智能体(Agent)文件:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -100,21 +100,58 @@ Claude 插件清单校验器**极其严格且具有主观性**。
|
|||||||
|
|
||||||
这是校验错误最常见的来源。
|
这是校验错误最常见的来源。
|
||||||
|
|
||||||
### Commands 和 Skills
|
### 命令(Commands)与技能(Skills)
|
||||||
|
|
||||||
* `commands` 和 `skills` 仅在**包裹在数组中**时才接受目录路径。
|
* `commands` 和 `skills` **仅在包裹在数组中时**接受目录路径。
|
||||||
* 使用显式文件路径是最安全且面向未来的做法。
|
* 显式文件路径是最安全且最能兼容未来的做法。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 校验器行为备注
|
## 校验器行为注意事项
|
||||||
|
|
||||||
* `claude plugin validate` 比某些应用市场预览更严格。
|
* `claude plugin validate` 比某些应用市场预览(marketplace previews)更严格。
|
||||||
* 校验可能在本地通过,但如果路径含义模糊,则在安装时可能会失败。
|
* 校验可能在本地通过,但如果路径含义模糊,在安装时可能会失败。
|
||||||
* 错误通常很笼统(`Invalid input`),且不指示根本原因。
|
* 错误提示通常很通用(`Invalid input`),且不会指出根本原因。
|
||||||
* 跨平台安装(尤其是 Windows)对路径假设的容忍度较低。
|
* 跨平台安装(尤其是 Windows)对路径假设的容忍度较低。
|
||||||
|
|
||||||
请假设校验器是“带有敌意的”且完全字面化的。
|
请假设校验器是严苛且完全按字面意思理解的。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## `hooks` 字段:请勿添加
|
||||||
|
|
||||||
|
> ⚠️ **关键(CRITICAL):** 请勿在 `plugin.json` 中添加 `"hooks"` 字段。这是一个回归测试强制要求的规则。
|
||||||
|
|
||||||
|
### 为什么这很重要
|
||||||
|
|
||||||
|
按照约定,Claude Code v2.1+ 会**自动加载**任何已安装插件中的 `hooks/hooks.json`。如果你在 `plugin.json` 中也声明了它,你会得到:
|
||||||
|
|
||||||
|
```
|
||||||
|
Duplicate hooks file detected: ./hooks/hooks.json resolves to already-loaded file.
|
||||||
|
The standard hooks/hooks.json is loaded automatically, so manifest.hooks should
|
||||||
|
only reference additional hook files.
|
||||||
|
```
|
||||||
|
|
||||||
|
### 反复变更的历史
|
||||||
|
|
||||||
|
这曾导致此仓库中出现多次“修复/回滚”循环:
|
||||||
|
|
||||||
|
| 提交 | 动作 | 触发原因 |
|
||||||
|
|--------|--------|---------|
|
||||||
|
| `22ad036` | 添加(ADD)hooks | 用户报告“钩子未加载” |
|
||||||
|
| `a7bc5f2` | 移除(REMOVE)hooks | 用户报告“重复钩子错误” (#52) |
|
||||||
|
| `779085e` | 添加(ADD)hooks | 用户报告“智能体未加载” (#88) |
|
||||||
|
| `e3a1306` | 移除(REMOVE)hooks | 用户报告“重复钩子错误” (#103) |
|
||||||
|
|
||||||
|
**根本原因:** Claude Code CLI 在不同版本间更改了行为:
|
||||||
|
- v2.1 之前:需要显式声明 `hooks`。
|
||||||
|
- v2.1+:按约定自动加载,显式声明会导致重复错误。
|
||||||
|
|
||||||
|
### 当前规则(由测试强制执行)
|
||||||
|
|
||||||
|
`tests/hooks/hooks.test.js` 中的测试 `plugin.json does NOT have explicit hooks declaration` 会阻止重新引入此声明。
|
||||||
|
|
||||||
|
**如果你要添加额外的钩子文件**(非 `hooks/hooks.json`),可以声明它们。但标准路径 `hooks/hooks.json` **绝不能**被声明。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -123,16 +160,17 @@ Claude 插件清单校验器**极其严格且具有主观性**。
|
|||||||
这些看起来正确但会被拒绝:
|
这些看起来正确但会被拒绝:
|
||||||
|
|
||||||
* 使用字符串值而非数组
|
* 使用字符串值而非数组
|
||||||
* 为 `agents` 提供目录数组
|
* 在 `agents` 中使用目录数组
|
||||||
* 缺失 `version`
|
* 缺失 `version`
|
||||||
* 依赖推断路径
|
* 依赖推断路径
|
||||||
* 假设应用市场的行为与本地校验一致
|
* 假设应用市场行为与本地校验一致
|
||||||
|
* **添加 `"hooks": "./hooks/hooks.json"`** —— 按约定自动加载,会导致重复错误
|
||||||
|
|
||||||
不要耍小聪明。请保持显式。
|
不要尝试“取巧”,请保持显式声明。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 最小已知有效示例
|
## 最小已知可用示例
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -146,35 +184,37 @@ Claude 插件清单校验器**极其严格且具有主观性**。
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
该结构已通过 Claude 插件校验器的验证。
|
此结构已通过 Claude 插件校验器的验证。
|
||||||
|
|
||||||
|
**重要提示:** 请注意这里**没有** `"hooks"` 字段。`hooks/hooks.json` 文件会按约定自动加载。显式添加它会导致重复错误。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 对贡献者的建议
|
## 贡献者建议
|
||||||
|
|
||||||
在提交涉及 `plugin.json` 的更改之前:
|
在提交涉及 `plugin.json` 的更改前:
|
||||||
|
|
||||||
1. 为 agents 使用显式文件路径
|
1. 为智能体(Agents)使用显式文件路径
|
||||||
2. 确保所有组件字段均为数组
|
2. 确保所有组件字段均为数组
|
||||||
3. 包含 `version`
|
3. 包含 `version` 字段
|
||||||
4. 运行:
|
4. 运行以下命令:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
claude plugin validate .claude-plugin/plugin.json
|
claude plugin validate .claude-plugin/plugin.json
|
||||||
```
|
```
|
||||||
|
|
||||||
如有疑问,宁可繁琐也不要追求便利。
|
如有疑问,宁可繁琐也不要为了方便而导致解析失败。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 为什么存在此文件
|
## 为什么存在此文件
|
||||||
|
|
||||||
此仓库被广泛 fork 并用作参考实现。
|
此仓库被广泛 Fork 并作为参考实现。
|
||||||
|
|
||||||
在此记录校验器的特性:
|
在此记录校验器的奇特行为(quirks)是为了:
|
||||||
|
|
||||||
* 防止重复出现的问题
|
* 防止重复出现的问题
|
||||||
* 减少贡献者的挫败感
|
* 减少贡献者的挫败感
|
||||||
* 随着生态系统的演进保持插件的稳定性
|
* 随着生态系统的演进保持插件的稳定性
|
||||||
|
|
||||||
如果校验器发生变化,请首先更新本文档。
|
如果校验器规则发生变化,请首先更新此文档。
|
||||||
|
|||||||
5
.claude-plugin/README.md
Normal file
5
.claude-plugin/README.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
### 插件清单注意事项(Plugin Manifest Gotchas)
|
||||||
|
|
||||||
|
如果你计划编辑 `.claude-plugin/plugin.json`,请注意 Claude 插件验证器(plugin validator)强制执行了一些**未公开但严格的约束**,这些约束可能导致安装失败并显示模糊的错误(例如,`agents: Invalid input`)。特别是,组件字段必须是数组(arrays),`agents` 必须使用明确的文件路径而非目录,且为了实现可靠的验证和安装,必须包含 `version` 字段。
|
||||||
|
|
||||||
|
这些约束在公开示例中并不明显,且在过去曾多次导致安装失败。它们在 `.claude-plugin/PLUGIN_SCHEMA_NOTES.md` 中有详细记录,在对插件清单(plugin manifest)进行任何更改之前,应仔细阅读该文档。
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "everything-claude-code",
|
"name": "everything-claude-code",
|
||||||
"version": "1.0.0",
|
"version": "1.2.0",
|
||||||
"description": "Complete collection of battle-tested Claude Code configs from an Anthropic hackathon winner - agents, skills, hooks, commands, and rules evolved over 10+ months of intensive daily use",
|
"description": "Complete collection of battle-tested Claude Code configs from an Anthropic hackathon winner - agents, skills, hooks, and rules evolved over 10+ months of intensive daily use",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Affaan Mustafa",
|
"name": "Affaan Mustafa",
|
||||||
"url": "https://x.com/affaanmustafa"
|
"url": "https://x.com/affaanmustafa"
|
||||||
@@ -14,7 +14,6 @@
|
|||||||
"agents",
|
"agents",
|
||||||
"skills",
|
"skills",
|
||||||
"hooks",
|
"hooks",
|
||||||
"commands",
|
|
||||||
"rules",
|
"rules",
|
||||||
"tdd",
|
"tdd",
|
||||||
"code-review",
|
"code-review",
|
||||||
@@ -23,8 +22,7 @@
|
|||||||
"automation",
|
"automation",
|
||||||
"best-practices"
|
"best-practices"
|
||||||
],
|
],
|
||||||
"commands": ["./commands/"],
|
"skills": ["./skills/", "./commands/"],
|
||||||
"skills": ["./skills/"],
|
|
||||||
"agents": [
|
"agents": [
|
||||||
"./agents/architect.md",
|
"./agents/architect.md",
|
||||||
"./agents/build-error-resolver.md",
|
"./agents/build-error-resolver.md",
|
||||||
@@ -38,6 +36,5 @@
|
|||||||
"./agents/refactor-cleaner.md",
|
"./agents/refactor-cleaner.md",
|
||||||
"./agents/security-reviewer.md",
|
"./agents/security-reviewer.md",
|
||||||
"./agents/tdd-guide.md"
|
"./agents/tdd-guide.md"
|
||||||
],
|
]
|
||||||
"hooks": "./hooks/hooks.json"
|
|
||||||
}
|
}
|
||||||
|
|||||||
17
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
17
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
## Description
|
||||||
|
<!-- Brief description of changes -->
|
||||||
|
|
||||||
|
## Type of Change
|
||||||
|
- [ ] `fix:` Bug fix
|
||||||
|
- [ ] `feat:` New feature
|
||||||
|
- [ ] `refactor:` Code refactoring
|
||||||
|
- [ ] `docs:` Documentation
|
||||||
|
- [ ] `test:` Tests
|
||||||
|
- [ ] `chore:` Maintenance/tooling
|
||||||
|
- [ ] `ci:` CI/CD changes
|
||||||
|
|
||||||
|
## Checklist
|
||||||
|
- [ ] Tests pass locally (`node tests/run-all.js`)
|
||||||
|
- [ ] Validation scripts pass
|
||||||
|
- [ ] Follows conventional commits format
|
||||||
|
- [ ] Updated relevant documentation
|
||||||
218
.github/workflows/ci.yml
vendored
Normal file
218
.github/workflows/ci.yml
vendored
Normal file
@@ -0,0 +1,218 @@
|
|||||||
|
name: CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
pull_request:
|
||||||
|
branches: [main]
|
||||||
|
|
||||||
|
# Prevent duplicate runs
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
# Minimal permissions
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
name: Test (${{ matrix.os }}, Node ${{ matrix.node }}, ${{ matrix.pm }})
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
timeout-minutes: 10
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||||
|
node: ['18.x', '20.x', '22.x']
|
||||||
|
pm: [npm, pnpm, yarn, bun]
|
||||||
|
exclude:
|
||||||
|
# Bun has limited Windows support
|
||||||
|
- os: windows-latest
|
||||||
|
pm: bun
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Node.js ${{ matrix.node }}
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node }}
|
||||||
|
|
||||||
|
# Package manager setup
|
||||||
|
- name: Setup pnpm
|
||||||
|
if: matrix.pm == 'pnpm'
|
||||||
|
uses: pnpm/action-setup@v4
|
||||||
|
with:
|
||||||
|
version: latest
|
||||||
|
|
||||||
|
- name: Setup Bun
|
||||||
|
if: matrix.pm == 'bun'
|
||||||
|
uses: oven-sh/setup-bun@v2
|
||||||
|
|
||||||
|
# Cache configuration
|
||||||
|
- name: Get npm cache directory
|
||||||
|
if: matrix.pm == 'npm'
|
||||||
|
id: npm-cache-dir
|
||||||
|
shell: bash
|
||||||
|
run: echo "dir=$(npm config get cache)" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Cache npm
|
||||||
|
if: matrix.pm == 'npm'
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: ${{ steps.npm-cache-dir.outputs.dir }}
|
||||||
|
key: ${{ runner.os }}-node-${{ matrix.node }}-npm-${{ hashFiles('**/package-lock.json') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-node-${{ matrix.node }}-npm-
|
||||||
|
|
||||||
|
- name: Get pnpm store directory
|
||||||
|
if: matrix.pm == 'pnpm'
|
||||||
|
id: pnpm-cache-dir
|
||||||
|
shell: bash
|
||||||
|
run: echo "dir=$(pnpm store path)" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Cache pnpm
|
||||||
|
if: matrix.pm == 'pnpm'
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: ${{ steps.pnpm-cache-dir.outputs.dir }}
|
||||||
|
key: ${{ runner.os }}-node-${{ matrix.node }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-node-${{ matrix.node }}-pnpm-
|
||||||
|
|
||||||
|
- name: Get yarn cache directory
|
||||||
|
if: matrix.pm == 'yarn'
|
||||||
|
id: yarn-cache-dir
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
# Try Yarn Berry first, fall back to Yarn v1
|
||||||
|
if yarn config get cacheFolder >/dev/null 2>&1; then
|
||||||
|
echo "dir=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Cache yarn
|
||||||
|
if: matrix.pm == 'yarn'
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: ${{ steps.yarn-cache-dir.outputs.dir }}
|
||||||
|
key: ${{ runner.os }}-node-${{ matrix.node }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-node-${{ matrix.node }}-yarn-
|
||||||
|
|
||||||
|
- name: Cache bun
|
||||||
|
if: matrix.pm == 'bun'
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: ~/.bun/install/cache
|
||||||
|
key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-bun-
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
- name: Install dependencies
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
case "${{ matrix.pm }}" in
|
||||||
|
npm) npm ci ;;
|
||||||
|
pnpm) pnpm install ;;
|
||||||
|
# --ignore-engines required for Node 18 compat with some devDependencies (e.g., markdownlint-cli)
|
||||||
|
yarn) yarn install --ignore-engines ;;
|
||||||
|
bun) bun install ;;
|
||||||
|
*) echo "Unsupported package manager: ${{ matrix.pm }}" && exit 1 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Run tests
|
||||||
|
- name: Run tests
|
||||||
|
run: node tests/run-all.js
|
||||||
|
env:
|
||||||
|
CLAUDE_CODE_PACKAGE_MANAGER: ${{ matrix.pm }}
|
||||||
|
|
||||||
|
# Upload test artifacts on failure
|
||||||
|
- name: Upload test artifacts
|
||||||
|
if: failure()
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: test-results-${{ matrix.os }}-node${{ matrix.node }}-${{ matrix.pm }}
|
||||||
|
path: |
|
||||||
|
tests/
|
||||||
|
!tests/node_modules/
|
||||||
|
|
||||||
|
validate:
|
||||||
|
name: Validate Components
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 5
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: '20.x'
|
||||||
|
|
||||||
|
- name: Validate agents
|
||||||
|
run: node scripts/ci/validate-agents.js
|
||||||
|
continue-on-error: false
|
||||||
|
|
||||||
|
- name: Validate hooks
|
||||||
|
run: node scripts/ci/validate-hooks.js
|
||||||
|
continue-on-error: false
|
||||||
|
|
||||||
|
- name: Validate commands
|
||||||
|
run: node scripts/ci/validate-commands.js
|
||||||
|
continue-on-error: false
|
||||||
|
|
||||||
|
- name: Validate skills
|
||||||
|
run: node scripts/ci/validate-skills.js
|
||||||
|
continue-on-error: false
|
||||||
|
|
||||||
|
- name: Validate rules
|
||||||
|
run: node scripts/ci/validate-rules.js
|
||||||
|
continue-on-error: false
|
||||||
|
|
||||||
|
security:
|
||||||
|
name: Security Scan
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 5
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: '20.x'
|
||||||
|
|
||||||
|
- name: Run npm audit
|
||||||
|
run: npm audit --audit-level=high
|
||||||
|
continue-on-error: true # Allows PR to proceed, but marks job as failed if vulnerabilities found
|
||||||
|
|
||||||
|
lint:
|
||||||
|
name: Lint
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 5
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: '20.x'
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm ci
|
||||||
|
|
||||||
|
- name: Run ESLint
|
||||||
|
run: npx eslint scripts/**/*.js tests/**/*.js
|
||||||
|
|
||||||
|
- name: Run markdownlint
|
||||||
|
run: npx markdownlint "agents/**/*.md" "skills/**/*.md" "commands/**/*.md" "rules/**/*.md"
|
||||||
51
.github/workflows/maintenance.yml
vendored
Normal file
51
.github/workflows/maintenance.yml
vendored
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
name: Scheduled Maintenance
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 9 * * 1' # Weekly Monday 9am UTC
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
issues: write
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
dependency-check:
|
||||||
|
name: Check Dependencies
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: '20.x'
|
||||||
|
- name: Check for outdated packages
|
||||||
|
run: npm outdated || true
|
||||||
|
|
||||||
|
security-audit:
|
||||||
|
name: Security Audit
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: '20.x'
|
||||||
|
- name: Run security audit
|
||||||
|
run: |
|
||||||
|
if [ -f package-lock.json ]; then
|
||||||
|
npm ci
|
||||||
|
npm audit --audit-level=high
|
||||||
|
else
|
||||||
|
echo "No package-lock.json found; skipping npm audit"
|
||||||
|
fi
|
||||||
|
|
||||||
|
stale:
|
||||||
|
name: Stale Issues/PRs
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/stale@v9
|
||||||
|
with:
|
||||||
|
stale-issue-message: 'This issue is stale due to inactivity.'
|
||||||
|
stale-pr-message: 'This PR is stale due to inactivity.'
|
||||||
|
days-before-stale: 30
|
||||||
|
days-before-close: 7
|
||||||
47
.github/workflows/release.yml
vendored
Normal file
47
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
name: Release
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags: ['v*']
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release:
|
||||||
|
name: Create Release
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Validate version tag
|
||||||
|
run: |
|
||||||
|
if ! [[ "${{ github.ref_name }}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||||
|
echo "Invalid version tag format. Expected vX.Y.Z"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Generate changelog
|
||||||
|
id: changelog
|
||||||
|
run: |
|
||||||
|
PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
|
||||||
|
if [ -z "$PREV_TAG" ]; then
|
||||||
|
COMMITS=$(git log --pretty=format:"- %s" HEAD)
|
||||||
|
else
|
||||||
|
COMMITS=$(git log --pretty=format:"- %s" ${PREV_TAG}..HEAD)
|
||||||
|
fi
|
||||||
|
echo "commits<<EOF" >> $GITHUB_OUTPUT
|
||||||
|
echo "$COMMITS" >> $GITHUB_OUTPUT
|
||||||
|
echo "EOF" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Create GitHub Release
|
||||||
|
uses: softprops/action-gh-release@v2
|
||||||
|
with:
|
||||||
|
body: |
|
||||||
|
## Changes
|
||||||
|
${{ steps.changelog.outputs.commits }}
|
||||||
|
generate_release_notes: false
|
||||||
59
.github/workflows/reusable-release.yml
vendored
Normal file
59
.github/workflows/reusable-release.yml
vendored
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
name: Reusable Release Workflow
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
inputs:
|
||||||
|
tag:
|
||||||
|
description: 'Version tag (e.g., v1.0.0)'
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
generate-notes:
|
||||||
|
description: 'Auto-generate release notes'
|
||||||
|
required: false
|
||||||
|
type: boolean
|
||||||
|
default: true
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release:
|
||||||
|
name: Create Release
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Validate version tag
|
||||||
|
run: |
|
||||||
|
if ! [[ "${{ inputs.tag }}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||||
|
echo "Invalid version tag format. Expected vX.Y.Z"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Generate changelog
|
||||||
|
id: changelog
|
||||||
|
run: |
|
||||||
|
PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
|
||||||
|
if [ -z "$PREV_TAG" ]; then
|
||||||
|
COMMITS=$(git log --pretty=format:"- %s" HEAD)
|
||||||
|
else
|
||||||
|
COMMITS=$(git log --pretty=format:"- %s" ${PREV_TAG}..HEAD)
|
||||||
|
fi
|
||||||
|
# Use unique delimiter to prevent truncation if commit messages contain EOF
|
||||||
|
DELIMITER="COMMITS_END_$(date +%s)"
|
||||||
|
echo "commits<<${DELIMITER}" >> $GITHUB_OUTPUT
|
||||||
|
echo "$COMMITS" >> $GITHUB_OUTPUT
|
||||||
|
echo "${DELIMITER}" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Create GitHub Release
|
||||||
|
uses: softprops/action-gh-release@v2
|
||||||
|
with:
|
||||||
|
tag_name: ${{ inputs.tag }}
|
||||||
|
body: |
|
||||||
|
## Changes
|
||||||
|
${{ steps.changelog.outputs.commits }}
|
||||||
|
generate_release_notes: ${{ inputs.generate-notes }}
|
||||||
130
.github/workflows/reusable-test.yml
vendored
Normal file
130
.github/workflows/reusable-test.yml
vendored
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
name: Reusable Test Workflow
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
inputs:
|
||||||
|
os:
|
||||||
|
description: 'Operating system'
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
default: 'ubuntu-latest'
|
||||||
|
node-version:
|
||||||
|
description: 'Node.js version'
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
default: '20.x'
|
||||||
|
package-manager:
|
||||||
|
description: 'Package manager to use'
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
default: 'npm'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
name: Test
|
||||||
|
runs-on: ${{ inputs.os }}
|
||||||
|
timeout-minutes: 10
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: ${{ inputs.node-version }}
|
||||||
|
|
||||||
|
- name: Setup pnpm
|
||||||
|
if: inputs.package-manager == 'pnpm'
|
||||||
|
uses: pnpm/action-setup@v4
|
||||||
|
with:
|
||||||
|
version: latest
|
||||||
|
|
||||||
|
- name: Setup Bun
|
||||||
|
if: inputs.package-manager == 'bun'
|
||||||
|
uses: oven-sh/setup-bun@v2
|
||||||
|
|
||||||
|
- name: Get npm cache directory
|
||||||
|
if: inputs.package-manager == 'npm'
|
||||||
|
id: npm-cache-dir
|
||||||
|
shell: bash
|
||||||
|
run: echo "dir=$(npm config get cache)" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Cache npm
|
||||||
|
if: inputs.package-manager == 'npm'
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: ${{ steps.npm-cache-dir.outputs.dir }}
|
||||||
|
key: ${{ runner.os }}-node-${{ inputs.node-version }}-npm-${{ hashFiles('**/package-lock.json') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-node-${{ inputs.node-version }}-npm-
|
||||||
|
|
||||||
|
- name: Get pnpm store directory
|
||||||
|
if: inputs.package-manager == 'pnpm'
|
||||||
|
id: pnpm-cache-dir
|
||||||
|
shell: bash
|
||||||
|
run: echo "dir=$(pnpm store path)" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Cache pnpm
|
||||||
|
if: inputs.package-manager == 'pnpm'
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: ${{ steps.pnpm-cache-dir.outputs.dir }}
|
||||||
|
key: ${{ runner.os }}-node-${{ inputs.node-version }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-node-${{ inputs.node-version }}-pnpm-
|
||||||
|
|
||||||
|
- name: Get yarn cache directory
|
||||||
|
if: inputs.package-manager == 'yarn'
|
||||||
|
id: yarn-cache-dir
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
# Try Yarn Berry first, fall back to Yarn v1
|
||||||
|
if yarn config get cacheFolder >/dev/null 2>&1; then
|
||||||
|
echo "dir=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Cache yarn
|
||||||
|
if: inputs.package-manager == 'yarn'
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: ${{ steps.yarn-cache-dir.outputs.dir }}
|
||||||
|
key: ${{ runner.os }}-node-${{ inputs.node-version }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-node-${{ inputs.node-version }}-yarn-
|
||||||
|
|
||||||
|
- name: Cache bun
|
||||||
|
if: inputs.package-manager == 'bun'
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: ~/.bun/install/cache
|
||||||
|
key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-bun-
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
case "${{ inputs.package-manager }}" in
|
||||||
|
npm) npm ci ;;
|
||||||
|
pnpm) pnpm install ;;
|
||||||
|
yarn) yarn install --ignore-engines ;;
|
||||||
|
bun) bun install ;;
|
||||||
|
*) echo "Unsupported package manager: ${{ inputs.package-manager }}" && exit 1 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
- name: Run tests
|
||||||
|
run: node tests/run-all.js
|
||||||
|
env:
|
||||||
|
CLAUDE_CODE_PACKAGE_MANAGER: ${{ inputs.package-manager }}
|
||||||
|
|
||||||
|
- name: Upload test artifacts
|
||||||
|
if: failure()
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: test-results-${{ inputs.os }}-node${{ inputs.node-version }}-${{ inputs.package-manager }}
|
||||||
|
path: |
|
||||||
|
tests/
|
||||||
|
!tests/node_modules/
|
||||||
40
.github/workflows/reusable-validate.yml
vendored
Normal file
40
.github/workflows/reusable-validate.yml
vendored
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
name: Reusable Validation Workflow
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
inputs:
|
||||||
|
node-version:
|
||||||
|
description: 'Node.js version'
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
default: '20.x'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
validate:
|
||||||
|
name: Validate Components
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 5
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: ${{ inputs.node-version }}
|
||||||
|
|
||||||
|
- name: Validate agents
|
||||||
|
run: node scripts/ci/validate-agents.js
|
||||||
|
|
||||||
|
- name: Validate hooks
|
||||||
|
run: node scripts/ci/validate-hooks.js
|
||||||
|
|
||||||
|
- name: Validate commands
|
||||||
|
run: node scripts/ci/validate-commands.js
|
||||||
|
|
||||||
|
- name: Validate skills
|
||||||
|
run: node scripts/ci/validate-skills.js
|
||||||
|
|
||||||
|
- name: Validate rules
|
||||||
|
run: node scripts/ci/validate-rules.js
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -27,3 +27,6 @@ private/
|
|||||||
|
|
||||||
# Session templates (not committed)
|
# Session templates (not committed)
|
||||||
examples/sessions/*.tmp
|
examples/sessions/*.tmp
|
||||||
|
|
||||||
|
# Local drafts
|
||||||
|
marketing/
|
||||||
|
|||||||
345
README.md
345
README.md
@@ -1,4 +1,6 @@
|
|||||||
# Everything Claude Code (Claude Code 全集)
|
**语言:** [English](README.md) | 繁體中文
|
||||||
|
|
||||||
|
# Everything Claude Code
|
||||||
|
|
||||||
[](https://github.com/affaan-m/everything-claude-code/stargazers)
|
[](https://github.com/affaan-m/everything-claude-code/stargazers)
|
||||||
[](LICENSE)
|
[](LICENSE)
|
||||||
@@ -7,49 +9,54 @@
|
|||||||

|

|
||||||

|

|
||||||
|
|
||||||
**来自 Anthropic 黑客松获胜者的 Claude Code 配置完整合集。**
|
<p align="left">
|
||||||
|
<a href="README.md">English</a> |
|
||||||
|
<span>简体中文</span>
|
||||||
|
</p>
|
||||||
|
|
||||||
包含生产级智能体(Agents)、技能(Skills)、钩子(Hooks)、命令(Commands)、规约(Rules)以及 MCP 配置,这些都是在超过 10 个月的真实产品开发与深度日常使用中演进出来的。
|
**由 Anthropic 黑客松获胜者整理的 Claude Code 配置完整合集。**
|
||||||
|
|
||||||
|
这是在 10 个月以上高强度日常开发真实产品的过程中,不断演进出的生产级智能体(Agents)、技能(Skills)、钩子(Hooks)、命令(Commands)、规则(Rules)以及 MCP 配置。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 指南文档
|
## 指南(The Guides)
|
||||||
|
|
||||||
本仓库仅包含原始代码。以下指南将解释一切。
|
本仓库仅包含原始代码。以下指南将解释所有细节。
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<td width="50%">
|
<td width="50%">
|
||||||
<a href="https://x.com/affaanmustafa/status/2012378465664745795">
|
<a href="the-shortform-guide_zh.md">
|
||||||
<img src="https://github.com/user-attachments/assets/1a471488-59cc-425b-8345-5245c7efbcef" alt="The Shorthand Guide to Everything Claude Code" />
|
<img src="https://github.com/user-attachments/assets/1a471488-59cc-425b-8345-5245c7efbcef" alt="Everything Claude Code 简明指南" />
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td width="50%">
|
<td width="50%">
|
||||||
<a href="https://x.com/affaanmustafa/status/2014040193557471352">
|
<a href="the-longform-guide.md">
|
||||||
<img src="https://github.com/user-attachments/assets/c9ca43bc-b149-427f-b551-af6840c368f0" alt="The Longform Guide to Everything Claude Code" />
|
<img src="https://github.com/user-attachments/assets/c9ca43bc-b149-427f-b551-af6840c368f0" alt="Everything Claude Code 深度指南" />
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td align="center"><b>简明指南 (Shorthand Guide)</b><br/>安装设置、基础概念与哲学。<b>请先阅读此篇。</b></td>
|
<td align="center"><b>简明指南 (Shorthand Guide)</b><br/>安装、基础、哲学。<b>请先阅读此篇。</b></td>
|
||||||
<td align="center"><b>深度指南 (Longform Guide)</b><br/>Token 优化、内存持久化、评测(Evals)与并行化。</td>
|
<td align="center"><b>深度指南 (Longform Guide)</b><br/>Token 优化、内存持久化、评测(Evals)、并行化。</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
| 主题 | 你将学到什么 |
|
| 主题 | 你将学到什么 |
|
||||||
|-------|-------------------|
|
|-------|-------------------|
|
||||||
| Token 优化 | 模型选择、系统提示词瘦身、后台进程 |
|
| Token 优化 | 模型选择、系统提示词精简、后台进程 |
|
||||||
| 内存持久化 | 自动跨会话保存/加载上下文的钩子(Hooks) |
|
| 内存持久化 | 跨会话(Session)自动保存/加载上下文的钩子(Hooks) |
|
||||||
| 持续学习 | 从会话中自动提取模式并转化为可复用的技能(Skills) |
|
| 持续学习 | 从会话中自动提取模式并转化为可复用的技能(Skills) |
|
||||||
| 验证循环 | 检查点 vs 持续评测、打分器类型、pass@k 指标 |
|
| 验证循环 | 检查点(Checkpoint)与持续评测(Evals)、评分器类型、pass@k 指标 |
|
||||||
| 并行化 | Git worktrees、级联法(Cascade method)、何时扩展实例 |
|
| 并行化 | Git worktrees、级联方法、何时扩展实例 |
|
||||||
| 子智能体编排 | 上下文问题、迭代检索模式(Iterative retrieval pattern) |
|
| 子智能体编排 | 上下文问题、迭代检索模式 |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 跨平台支持
|
## 跨平台支持
|
||||||
|
|
||||||
本插件现已全面支持 **Windows、macOS 和 Linux**。所有钩子和脚本均已使用 Node.js 重写,以实现最大兼容性。
|
该插件现已全面支持 **Windows、macOS 和 Linux**。所有钩子(Hooks)和脚本都已使用 Node.js 重写,以实现最大的兼容性。
|
||||||
|
|
||||||
### 包管理器检测
|
### 包管理器检测
|
||||||
|
|
||||||
@@ -58,7 +65,7 @@
|
|||||||
1. **环境变量**:`CLAUDE_PACKAGE_MANAGER`
|
1. **环境变量**:`CLAUDE_PACKAGE_MANAGER`
|
||||||
2. **项目配置**:`.claude/package-manager.json`
|
2. **项目配置**:`.claude/package-manager.json`
|
||||||
3. **package.json**:`packageManager` 字段
|
3. **package.json**:`packageManager` 字段
|
||||||
4. **锁文件**:根据 package-lock.json, yarn.lock, pnpm-lock.yaml, 或 bun.lockb 检测
|
4. **锁文件**:根据 package-lock.json, yarn.lock, pnpm-lock.yaml 或 bun.lockb 检测
|
||||||
5. **全局配置**:`~/.claude/package-manager.json`
|
5. **全局配置**:`~/.claude/package-manager.json`
|
||||||
6. **备选项**:第一个可用的包管理器
|
6. **备选项**:第一个可用的包管理器
|
||||||
|
|
||||||
@@ -82,9 +89,9 @@ node scripts/setup-package-manager.js --detect
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 核心内容
|
## 包含内容
|
||||||
|
|
||||||
本仓库是一个 **Claude Code 插件** —— 你可以直接安装,也可以手动复制组件。
|
本仓库是一个 **Claude Code 插件** —— 你可以直接安装它,或者手动复制组件。
|
||||||
|
|
||||||
```
|
```
|
||||||
everything-claude-code/
|
everything-claude-code/
|
||||||
@@ -92,133 +99,193 @@ everything-claude-code/
|
|||||||
| |-- plugin.json # 插件元数据与组件路径
|
| |-- plugin.json # 插件元数据与组件路径
|
||||||
| |-- marketplace.json # 用于 /plugin marketplace add 的市场目录
|
| |-- marketplace.json # 用于 /plugin marketplace add 的市场目录
|
||||||
|
|
|
|
||||||
|-- agents/ # 用于任务委派的专用子智能体
|
|-- agents/ # 用于任务委派的专用子智能体(Subagents)
|
||||||
| |-- planner.md # 功能实现规划
|
| |-- planner.md # 功能实现规划
|
||||||
| |-- architect.md # 系统设计决策
|
| |-- architect.md # 系统设计决策
|
||||||
| |-- tdd-guide.md # 测试驱动开发 (TDD)
|
| |-- tdd-guide.md # 测试驱动开发(TDD)
|
||||||
| |-- code-reviewer.md # 质量与安全审查
|
| |-- code-reviewer.md # 代码质量与安全评审
|
||||||
| |-- security-reviewer.md # 漏洞分析
|
| |-- security-reviewer.md # 漏洞分析
|
||||||
| |-- build-error-resolver.md # 构建错误修复
|
| |-- build-error-resolver.md # 构建错误解决
|
||||||
| |-- e2e-runner.md # Playwright E2E 测试
|
| |-- e2e-runner.md # Playwright 端到端测试
|
||||||
| |-- refactor-cleaner.md # 冗余代码清理
|
| |-- refactor-cleaner.md # 死代码清理
|
||||||
| |-- doc-updater.md # 文档同步
|
| |-- doc-updater.md # 文档同步
|
||||||
| |-- go-reviewer.md # Go 代码审查 (新增)
|
| |-- go-reviewer.md # Go 代码评审(新增)
|
||||||
| |-- go-build-resolver.md # Go 构建错误解决 (新增)
|
| |-- go-build-resolver.md # Go 构建错误解决(新增)
|
||||||
|
|
|
|
||||||
|-- skills/ # 工作流定义与领域知识
|
|-- skills/ # 工作流(Workflow)定义与领域知识
|
||||||
| |-- coding-standards/ # 编程语言最佳实践
|
| |-- coding-standards/ # 语言最佳实践
|
||||||
| |-- backend-patterns/ # API、数据库、缓存模式
|
| |-- backend-patterns/ # API、数据库、缓存模式
|
||||||
| |-- frontend-patterns/ # React, Next.js 模式
|
| |-- frontend-patterns/ # React、Next.js 模式
|
||||||
| |-- continuous-learning/ # 从会话中自动提取模式 (深度指南)
|
| |-- continuous-learning/ # 从会话中自动提取模式(深度指南内容)
|
||||||
| |-- continuous-learning-v2/ # 基于本能 (Instinct) 的学习与置信度评分
|
| |-- continuous-learning-v2/ # 基于直觉(Instinct)的带置信度评分学习系统
|
||||||
| |-- iterative-retrieval/ # 为子智能体提供渐进式上下文精炼
|
| |-- iterative-retrieval/ # 子智能体的渐进式上下文精炼
|
||||||
| |-- strategic-compact/ # 手动压缩建议 (深度指南)
|
| |-- strategic-compact/ # 手动压缩建议(深度指南内容)
|
||||||
| |-- tdd-workflow/ # TDD 方法论
|
| |-- tdd-workflow/ # TDD 方法论
|
||||||
| |-- security-review/ # 安全检查清单
|
| |-- security-review/ # 安全自查表
|
||||||
| |-- eval-harness/ # 验证循环评估 (深度指南)
|
| |-- eval-harness/ # 验证循环评测(深度指南内容)
|
||||||
| |-- verification-loop/ # 持续验证 (深度指南)
|
| |-- verification-loop/ # 持续验证(深度指南内容)
|
||||||
| |-- golang-patterns/ # Go 惯用法与最佳实践 (新增)
|
| |-- golang-patterns/ # Go 惯用法与最佳实践(新增)
|
||||||
| |-- golang-testing/ # Go 测试模式、TDD、基准测试 (新增)
|
| |-- golang-testing/ # Go 测试模式、TDD、基准测试(新增)
|
||||||
|
|
|
|
||||||
|-- commands/ # 用于快速执行的斜杠命令 (/命令)
|
|-- commands/ # 用于快速执行的斜杠命令(Slash Commands)
|
||||||
| |-- tdd.md # /tdd - 测试驱动开发
|
| |-- tdd.md # /tdd - 测试驱动开发
|
||||||
| |-- plan.md # /plan - 实现规划
|
| |-- plan.md # /plan - 实现规划
|
||||||
| |-- e2e.md # /e2e - E2E 测试生成
|
| |-- e2e.md # /e2e - 端到端测试生成
|
||||||
| |-- code-review.md # /code-review - 质量审查
|
| |-- code-review.md # /code-review - 质量评审
|
||||||
| |-- build-fix.md # /build-fix - 修复构建错误
|
| |-- build-fix.md # /build-fix - 修复构建错误
|
||||||
| |-- refactor-clean.md # /refactor-clean - 冗余代码移除
|
| |-- refactor-clean.md # /refactor-clean - 移除死代码
|
||||||
| |-- learn.md # /learn - 会话中途提取模式 (深度指南)
|
| |-- learn.md # /learn - 会话中途提取模式(深度指南内容)
|
||||||
| |-- checkpoint.md # /checkpoint - 保存验证状态 (深度指南)
|
| |-- checkpoint.md # /checkpoint - 保存验证状态(深度指南内容)
|
||||||
| |-- verify.md # /verify - 运行验证循环 (深度指南)
|
| |-- verify.md # /verify - 运行验证循环(深度指南内容)
|
||||||
| |-- setup-pm.md # /setup-pm - 配置包管理器
|
| |-- setup-pm.md # /setup-pm - 配置包管理器
|
||||||
| |-- go-review.md # /go-review - Go 代码审查 (新增)
|
| |-- go-review.md # /go-review - Go 代码评审(新增)
|
||||||
| |-- go-test.md # /go-test - Go TDD 工作流 (新增)
|
| |-- go-test.md # /go-test - Go TDD 工作流(新增)
|
||||||
| |-- go-build.md # /go-build - 修复 Go 构建错误 (新增)
|
| |-- go-build.md # /go-build - 修复 Go 构建错误(新增)
|
||||||
|
| |-- skill-create.md # /skill-create - 从 git 历史生成技能(新增)
|
||||||
|
| |-- instinct-status.md # /instinct-status - 查看已学习的直觉(新增)
|
||||||
|
| |-- instinct-import.md # /instinct-import - 导入直觉(新增)
|
||||||
|
| |-- instinct-export.md # /instinct-export - 导出直觉(新增)
|
||||||
|
| |-- evolve.md # /evolve - 将相关直觉聚类为技能(新增)
|
||||||
|
|
|
|
||||||
|-- rules/ # 必须遵守的指南 (复制到 ~/.claude/rules/)
|
|-- rules/ # 必须遵守的准则(复制到 ~/.claude/rules/)
|
||||||
| |-- security.md # 强制性安全检查
|
| |-- security.md # 强制性安全检查
|
||||||
| |-- coding-style.md # 不可变性、文件组织结构
|
| |-- coding-style.md # 不可变性、文件组织
|
||||||
| |-- testing.md # TDD、80% 覆盖率要求
|
| |-- testing.md # TDD、80% 覆盖率要求
|
||||||
| |-- git-workflow.md # Commit 格式、PR 流程
|
| |-- git-workflow.md # 提交格式、PR 流程
|
||||||
| |-- agents.md # 何时委派给子智能体
|
| |-- agents.md # 何时委派给子智能体
|
||||||
| |-- performance.md # 模型选择、上下文管理
|
| |-- performance.md # 模型选择、上下文管理
|
||||||
|
|
|
|
||||||
|-- hooks/ # 基于触发器的自动化
|
|-- hooks/ # 基于触发器的自动化
|
||||||
| |-- hooks.json # 所有钩子配置 (PreToolUse, PostToolUse, Stop 等)
|
| |-- hooks.json # 所有钩子配置(PreToolUse, PostToolUse, Stop 等)
|
||||||
| |-- memory-persistence/ # 会话生命周期钩子 (深度指南)
|
| |-- memory-persistence/ # 会话生命周期钩子(深度指南内容)
|
||||||
| |-- strategic-compact/ # 压缩建议 (深度指南)
|
| |-- strategic-compact/ # 压缩建议(深度指南内容)
|
||||||
|
|
|
|
||||||
|-- scripts/ # 跨平台 Node.js 脚本 (新增)
|
|-- scripts/ # 跨平台 Node.js 脚本(新增)
|
||||||
| |-- lib/ # 共享实用程序
|
| |-- lib/ # 共享实用程序
|
||||||
| | |-- utils.js # 跨平台文件/路径/系统工具
|
| | |-- utils.js # 跨平台文件/路径/系统工具
|
||||||
| | |-- package-manager.js # 包管理器检测与选择
|
| | |-- package-manager.js # 包管理器检测与选择
|
||||||
| |-- hooks/ # 钩子实现
|
| |-- hooks/ # 钩子实现
|
||||||
| | |-- session-start.js # 会话启动时加载上下文
|
| | |-- session-start.js # 会话开始时加载上下文
|
||||||
| | |-- session-end.js # 会话结束时保存状态
|
| | |-- session-end.js # 会话结束时保存状态
|
||||||
| | |-- pre-compact.js # 压缩前的状态保存
|
| | |-- pre-compact.js # 压缩前状态保存
|
||||||
| | |-- suggest-compact.js # 策略性压缩建议
|
| | |-- suggest-compact.js # 战略性压缩建议
|
||||||
| | |-- evaluate-session.js # 从会话中提取模式
|
| | |-- evaluate-session.js # 从会话中提取模式
|
||||||
| |-- setup-package-manager.js # 交互式包管理器设置
|
| |-- setup-package-manager.js # 交互式包管理器设置
|
||||||
|
|
|
|
||||||
|-- tests/ # 测试套件 (新增)
|
|-- tests/ # 测试套件(新增)
|
||||||
| |-- lib/ # 库测试
|
| |-- lib/ # 库测试
|
||||||
| |-- hooks/ # 钩子测试
|
| |-- hooks/ # 钩子测试
|
||||||
| |-- run-all.js # 运行所有测试
|
| |-- run-all.js # 运行所有测试
|
||||||
|
|
|
|
||||||
|-- contexts/ # 动态系统提示词注入上下文 (深度指南)
|
|-- contexts/ # 动态系统提示词注入上下文(深度指南内容)
|
||||||
| |-- dev.md # 开发模式上下文
|
| |-- dev.md # 开发模式上下文
|
||||||
| |-- review.md # 代码审查模式上下文
|
| |-- review.md # 代码评审模式上下文
|
||||||
| |-- research.md # 研究/探索模式上下文
|
| |-- research.md # 研究/探索模式上下文
|
||||||
|
|
|
|
||||||
|-- examples/ # 示例配置与会话
|
|-- examples/ # 配置与会话示例
|
||||||
| |-- CLAUDE.md # 项目级配置示例
|
| |-- CLAUDE.md # 项目级配置示例
|
||||||
| |-- user-CLAUDE.md # 用户级配置示例
|
| |-- user-CLAUDE.md # 用户级配置示例
|
||||||
|
|
|
|
||||||
|-- mcp-configs/ # MCP 服务器配置
|
|-- mcp-configs/ # MCP 服务配置
|
||||||
| |-- mcp-servers.json # GitHub, Supabase, Vercel, Railway 等
|
| |-- mcp-servers.json # GitHub, Supabase, Vercel, Railway 等
|
||||||
|
|
|
|
||||||
|-- marketplace.json # 自托管市场配置 (用于 /plugin marketplace add)
|
|-- marketplace.json # 自托管市场配置(用于 /plugin marketplace add)
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 生态工具
|
## 生态工具
|
||||||
|
|
||||||
### ecc.tools - 技能生成器 (Skill Creator)
|
### 技能创建器(Skill Creator)
|
||||||
|
|
||||||
自动根据你的仓库生成 Claude Code 技能(Skills)。
|
有两种方法可以从你的仓库生成 Claude Code 技能:
|
||||||
|
|
||||||
|
#### 方案 A:本地分析(内置)
|
||||||
|
|
||||||
|
使用 `/skill-create` 命令进行本地分析,无需外部服务:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
/skill-create # 分析当前仓库
|
||||||
|
/skill-create --instincts # 同时为持续学习(continuous-learning)生成直觉(instincts)
|
||||||
|
```
|
||||||
|
|
||||||
|
该命令会在本地分析你的 git 历史并生成 SKILL.md 文件。
|
||||||
|
|
||||||
|
#### 方案 B:GitHub App(高级)
|
||||||
|
|
||||||
|
适用于高级功能(1万+ commit、自动 PR、团队共享):
|
||||||
|
|
||||||
[安装 GitHub App](https://github.com/apps/skill-creator) | [ecc.tools](https://ecc.tools)
|
[安装 GitHub App](https://github.com/apps/skill-creator) | [ecc.tools](https://ecc.tools)
|
||||||
|
|
||||||
分析你的仓库并创建:
|
|
||||||
- **SKILL.md 文件** - 开箱即用的 Claude Code 技能
|
|
||||||
- **本能 (Instinct) 集合** - 适用于 continuous-learning-v2
|
|
||||||
- **模式提取** - 从你的 commit 历史中学习
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 安装 GitHub App 后,技能将出现在:
|
# 在任何 issue 下留言:
|
||||||
~/.claude/skills/generated/
|
/skill-creator analyze
|
||||||
|
|
||||||
|
# 或者在 push 到默认分支时自动触发
|
||||||
```
|
```
|
||||||
|
|
||||||
与 `continuous-learning-v2` 技能完美配合,实现遗传式的本能学习。
|
两种方案都会创建:
|
||||||
|
- **SKILL.md 文件** - 可直接用于 Claude Code 的技能
|
||||||
|
- **直觉集合(Instinct collections)** - 用于 continuous-learning-v2
|
||||||
|
- **模式提取(Pattern extraction)** - 从你的提交历史中学习
|
||||||
|
|
||||||
|
### 持续学习(Continuous Learning)v2
|
||||||
|
|
||||||
|
基于直觉(instinct)的学习系统会自动学习你的开发模式:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
/instinct-status # 显示带有置信度的已学习直觉
|
||||||
|
/instinct-import <file> # 导入他人的直觉
|
||||||
|
/instinct-export # 导出你的直觉以便分享
|
||||||
|
/evolve # 将相关的直觉聚类为技能(skills)
|
||||||
|
```
|
||||||
|
|
||||||
|
详见 `skills/continuous-learning-v2/` 的完整文档。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 安装方法
|
## 要求
|
||||||
|
|
||||||
|
### Claude Code CLI 版本
|
||||||
|
|
||||||
|
**最低版本:v2.1.0 或更高**
|
||||||
|
|
||||||
|
由于插件系统处理钩子(hooks)方式的变更,本插件要求 Claude Code CLI v2.1.0+。
|
||||||
|
|
||||||
|
检查你的版本:
|
||||||
|
```bash
|
||||||
|
claude --version
|
||||||
|
```
|
||||||
|
|
||||||
|
### 重要:钩子(Hooks)自动加载行为
|
||||||
|
|
||||||
|
> ⚠️ **对贡献者的提醒:** 请勿在 `.claude-plugin/plugin.json` 中添加 `"hooks"` 字段。这是由回归测试强制执行的。
|
||||||
|
|
||||||
|
Claude Code v2.1+ 会**自动加载**已安装插件中约定的 `hooks/hooks.json`。在 `plugin.json` 中显式声明会导致重复检测错误:
|
||||||
|
|
||||||
|
```
|
||||||
|
Duplicate hooks file detected: ./hooks/hooks.json resolves to already-loaded file
|
||||||
|
```
|
||||||
|
|
||||||
|
**历史背景:** 此问题在本仓库中曾多次出现修复/回退循环([#29](https://github.com/affaan-m/everything-claude-code/issues/29), [#52](https://github.com/affaan-m/everything-claude-code/issues/52), [#103](https://github.com/affaan-m/everything-claude-code/issues/103))。Claude Code 版本间的行为差异导致了混淆。我们现在已加入回归测试以防止此类问题再次发生。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 安装
|
||||||
|
|
||||||
### 方案 1:作为插件安装(推荐)
|
### 方案 1:作为插件安装(推荐)
|
||||||
|
|
||||||
使用本仓库最简单的方法 —— 作为 Claude Code 插件安装:
|
这是使用本仓库最简单的方法 —— 作为 Claude Code 插件安装:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 将此仓库添加为市场
|
# 将此仓库添加为市场(marketplace)
|
||||||
/plugin marketplace add affaan-m/everything-claude-code
|
/plugin marketplace add affaan-m/everything-claude-code
|
||||||
|
|
||||||
# 安装插件
|
# 安装插件
|
||||||
/plugin install everything-claude-code@everything-claude-code
|
/plugin install everything-claude-code@everything-claude-code
|
||||||
```
|
```
|
||||||
|
|
||||||
或者直接添加到你的 `~/.claude/settings.json` 中:
|
或者直接添加到你的 `~/.claude/settings.json`:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -236,18 +303,18 @@ everything-claude-code/
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
安装后你即可立即使用所有命令、智能体、技能和钩子。
|
安装后即可立即使用所有命令(commands)、智能体(agents)、技能(skills)和钩子(hooks)。
|
||||||
|
|
||||||
> **注意:** Claude Code 插件系统目前不支持通过插件分发 `rules`([上游限制](https://code.claude.com/docs/en/plugins-reference))。你需要手动安装规约(Rules):
|
> **注意:** Claude Code 插件系统目前不支持通过插件分发规则(`rules`)(这是 [上游限制](https://code.claude.com/docs/en/plugins-reference))。你需要手动安装规则:
|
||||||
>
|
>
|
||||||
> ```bash
|
> ```bash
|
||||||
> # 先克隆仓库
|
> # 首先克隆仓库
|
||||||
> git clone https://github.com/affaan-m/everything-claude-code.git
|
> git clone https://github.com/affaan-m/everything-claude-code.git
|
||||||
>
|
>
|
||||||
> # 选项 A:用户级规约 (适用于所有项目)
|
> # 方案 A:用户级规则(应用于所有项目)
|
||||||
> cp -r everything-claude-code/rules/* ~/.claude/rules/
|
> cp -r everything-claude-code/rules/* ~/.claude/rules/
|
||||||
>
|
>
|
||||||
> # 选项 B:项目级规约 (仅适用于当前项目)
|
> # 方案 B:项目级规则(仅应用于当前项目)
|
||||||
> mkdir -p .claude/rules
|
> mkdir -p .claude/rules
|
||||||
> cp -r everything-claude-code/rules/* .claude/rules/
|
> cp -r everything-claude-code/rules/* .claude/rules/
|
||||||
> ```
|
> ```
|
||||||
@@ -256,85 +323,85 @@ everything-claude-code/
|
|||||||
|
|
||||||
### 方案 2:手动安装
|
### 方案 2:手动安装
|
||||||
|
|
||||||
如果你更喜欢手动控制安装内容:
|
如果你更倾向于手动控制安装的内容:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 克隆仓库
|
# 克隆仓库
|
||||||
git clone https://github.com/affaan-m/everything-claude-code.git
|
git clone https://github.com/affaan-m/everything-claude-code.git
|
||||||
|
|
||||||
# 将智能体复制到你的 Claude 配置目录
|
# 复制智能体(agents)到你的 Claude 配置目录
|
||||||
cp everything-claude-code/agents/*.md ~/.claude/agents/
|
cp everything-claude-code/agents/*.md ~/.claude/agents/
|
||||||
|
|
||||||
# 复制规约 (Rules)
|
# 复制规则(rules)
|
||||||
cp everything-claude-code/rules/*.md ~/.claude/rules/
|
cp everything-claude-code/rules/*.md ~/.claude/rules/
|
||||||
|
|
||||||
# 复制命令 (Commands)
|
# 复制命令(commands)
|
||||||
cp everything-claude-code/commands/*.md ~/.claude/commands/
|
cp everything-claude-code/commands/*.md ~/.claude/commands/
|
||||||
|
|
||||||
# 复制技能 (Skills)
|
# 复制技能(skills)
|
||||||
cp -r everything-claude-code/skills/* ~/.claude/skills/
|
cp -r everything-claude-code/skills/* ~/.claude/skills/
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 将钩子 (Hooks) 添加到 settings.json
|
#### 将钩子(hooks)添加到 settings.json
|
||||||
|
|
||||||
将 `hooks/hooks.json` 中的钩子配置复制到你的 `~/.claude/settings.json`。
|
将 `hooks/hooks.json` 中的钩子配置复制到你的 `~/.claude/settings.json` 中。
|
||||||
|
|
||||||
#### 配置 MCP
|
#### 配置 MCPs
|
||||||
|
|
||||||
将 `mcp-configs/mcp-servers.json` 中需要的 MCP 服务器配置复制到你的 `~/.claude.json`。
|
将 `mcp-configs/mcp-servers.json` 中你需要的 MCP 服务配置复制到你的 `~/.claude.json`。
|
||||||
|
|
||||||
**重要:** 请将 `YOUR_*_HERE` 占位符替换为你实际的 API 密钥。
|
**重要:** 请将 `YOUR_*_HERE` 占位符替换为你真实的 API 密钥。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 核心概念
|
## 核心概念
|
||||||
|
|
||||||
### 智能体 (Agents)
|
### 智能体(Agents)
|
||||||
|
|
||||||
子智能体负责处理具有特定范围的委派任务。示例:
|
子智能体(Subagents)负责处理受限范围内的委派任务。示例:
|
||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
---
|
---
|
||||||
name: code-reviewer
|
name: code-reviewer
|
||||||
description: 审查代码的质量、安全性与可维护性
|
description: 评审代码质量、安全性与可维护性
|
||||||
tools: ["Read", "Grep", "Glob", "Bash"]
|
tools: ["Read", "Grep", "Glob", "Bash"]
|
||||||
model: opus
|
model: opus
|
||||||
---
|
---
|
||||||
|
|
||||||
你是一个资深代码审查员...
|
你是一名资深代码评审员...
|
||||||
```
|
```
|
||||||
|
|
||||||
### 技能 (Skills)
|
### 技能(Skills)
|
||||||
|
|
||||||
技能是由命令或智能体调用的工作流定义:
|
技能(Skills)是可由命令或智能体调用的工作流定义:
|
||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
# TDD 工作流
|
# TDD 工作流
|
||||||
|
|
||||||
1. 首先定义接口
|
1. 首先定义接口
|
||||||
2. 编写失败的测试 (RED)
|
2. 编写失败的测试(RED)
|
||||||
3. 实现最简代码 (GREEN)
|
3. 实现最简代码(GREEN)
|
||||||
4. 重构 (IMPROVE)
|
4. 重构(IMPROVE)
|
||||||
5. 验证 80% 以上的覆盖率
|
5. 验证覆盖率是否达到 80% 以上
|
||||||
```
|
```
|
||||||
|
|
||||||
### 钩子 (Hooks)
|
### 钩子(Hooks)
|
||||||
|
|
||||||
钩子在工具事件上触发。示例 —— 警告关于 console.log 的使用:
|
钩子(Hooks)在工具事件发生时触发。示例 —— 针对 console.log 发出警告:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"matcher": "tool == \"Edit\" && tool_input.file_path matches \"\\.(ts|tsx|js|jsx)$\"",
|
"matcher": "tool == \"Edit\" && tool_input.file_path matches \"\\.(ts|tsx|js|jsx)$\"",
|
||||||
"hooks": [{
|
"hooks": [{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "#!/bin/bash\ngrep -n 'console\.log' \"$file_path\" && echo '[Hook] 移除 console.log' >&2"
|
"command": "#!/bin/bash\ngrep -n 'console\\.log' \"$file_path\" && echo '[Hook] Remove console.log' >&2"
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 规约 (Rules)
|
### 规则(Rules)
|
||||||
|
|
||||||
规约是必须始终遵循的指南。保持模块化:
|
规则(Rules)是必须始终遵守的准则。请保持它们的模块化:
|
||||||
|
|
||||||
```
|
```
|
||||||
~/.claude/rules/
|
~/.claude/rules/
|
||||||
@@ -347,7 +414,7 @@ model: opus
|
|||||||
|
|
||||||
## 运行测试
|
## 运行测试
|
||||||
|
|
||||||
本插件包含完整的测试套件:
|
本插件包含一个全面的测试套件:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 运行所有测试
|
# 运行所有测试
|
||||||
@@ -361,56 +428,56 @@ node tests/hooks/hooks.test.js
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 贡献指南
|
## 贡献
|
||||||
|
|
||||||
**欢迎并鼓励大家做出贡献。**
|
**非常欢迎并鼓励贡献。**
|
||||||
|
|
||||||
本仓库旨在作为一个社区资源。如果你有:
|
本仓库旨在成为一个社区资源。如果你有:
|
||||||
- 有用的智能体或技能
|
- 有用的智能体或技能
|
||||||
- 巧妙的钩子
|
- 巧妙的钩子
|
||||||
- 更好的 MCP 配置
|
- 更好的 MCP 配置
|
||||||
- 改进后的规约
|
- 改进后的规则
|
||||||
|
|
||||||
请提交贡献!参见 [CONTRIBUTING.md](CONTRIBUTING.md) 获取指南。
|
请提交你的贡献!参考 [CONTRIBUTING.md](CONTRIBUTING.md) 了解指南。
|
||||||
|
|
||||||
### 贡献思路
|
### 贡献思路
|
||||||
|
|
||||||
- 特定语言的技能 (Python, Rust 模式) —— Go 已包含!
|
- 语言专用技能(Python, Rust 模式)—— 已包含 Go!
|
||||||
- 特定框架的配置 (Django, Rails, Laravel)
|
- 框架专用配置(Django, Rails, Laravel)
|
||||||
- DevOps 智能体 (Kubernetes, Terraform, AWS)
|
- DevOps 智能体(Kubernetes, Terraform, AWS)
|
||||||
- 测试策略 (针对不同框架)
|
- 测试策略(不同框架)
|
||||||
- 领域特定知识 (机器学习, 数据工程, 移动端)
|
- 领域特定知识(机器学习、数据工程、移动开发)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 背景故事
|
## 背景
|
||||||
|
|
||||||
自实验性推出以来,我一直在使用 Claude Code。在 2025 年 9 月的 Anthropic x Forum Ventures 黑客松中,我与 [@DRodriguezFX](https://x.com/DRodriguezFX) 合作构建了 [zenith.chat](https://zenith.chat),并最终获胜 —— 整个过程完全使用了 Claude Code。
|
我从 Claude Code 实验阶段就开始使用了。在 2025 年 9 月的 Anthropic x Forum Ventures 黑客松中,我与 [@DRodriguezFX](https://x.com/DRodriguezFX) 合作开发了 [zenith.chat](https://zenith.chat),并获得了冠军 —— 该项目完全使用 Claude Code 构建。
|
||||||
|
|
||||||
这些配置在多个生产级应用中经过了实战测试。
|
这些配置在多个生产级应用中经过了实战检验。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 重要注意事项
|
## 重要提示
|
||||||
|
|
||||||
### 上下文窗口管理
|
### 上下文窗口管理
|
||||||
|
|
||||||
**关键:** 不要一次性启用所有 MCP。开启过多工具会将你 200k 的上下文窗口压缩到 70k。
|
**至关重要:** 不要一次性启用所有 MCP。如果启用的工具过多,你的 200k 上下文窗口可能会缩减到 70k。
|
||||||
|
|
||||||
经验法则:
|
经验法则:
|
||||||
- 配置 20-30 个 MCP
|
- 配置 20-30 个 MCP
|
||||||
- 每个项目保持启用 10 个以下
|
- 每个项目保持启用 10 个以内
|
||||||
- 活跃工具总数保持在 80 个以下
|
- 活跃工具总数控制在 80 个以内
|
||||||
|
|
||||||
在项目配置中使用 `disabledMcpServers` 来禁用不常用的服务器。
|
在项目配置中使用 `disabledMcpServers` 来禁用不需要的服务。
|
||||||
|
|
||||||
### 自定义
|
### 自定义
|
||||||
|
|
||||||
这些配置适合我的工作流。你应该:
|
这些配置适用于我的工作流。你应该:
|
||||||
1. 从产生共鸣的内容开始
|
1. 从你产生共鸣的内容开始
|
||||||
2. 根据你的技术栈进行修改
|
2. 根据你的技术栈进行修改
|
||||||
3. 移除你不使用的部分
|
3. 移除你不需要的内容
|
||||||
4. 添加你自己的模式
|
4. 加入你自己的模式
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -422,17 +489,17 @@ node tests/hooks/hooks.test.js
|
|||||||
|
|
||||||
## 相关链接
|
## 相关链接
|
||||||
|
|
||||||
- **简明指南 (从这里开始):** [The Shorthand Guide to Everything Claude Code](https://x.com/affaanmustafa/status/2012378465664745795)
|
- **简明指南(入门必读):** [Everything Claude Code 简明指南](https://x.com/affaanmustafa/status/2012378465664745795)
|
||||||
- **深度指南 (进阶):** [The Longform Guide to Everything Claude Code](https://x.com/affaanmustafa/status/2014040193557471352)
|
- **深度指南(进阶参考):** [Everything Claude Code 深度指南](https://x.com/affaanmustafa/status/2014040193557471352)
|
||||||
- **关注:** [@affaanmustafa](https://x.com/affaanmustafa)
|
- **关注我:** [@affaanmustafa](https://x.com/affaanmustafa)
|
||||||
- **zenith.chat:** [zenith.chat](https://zenith.chat)
|
- **zenith.chat:** [zenith.chat](https://zenith.chat)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 许可证
|
## 许可证
|
||||||
|
|
||||||
MIT - 自由使用,根据需要修改,如果可以请回馈社区。
|
MIT - 自由使用,按需修改,如果可以请回馈社区。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**如果对你有帮助,请给本仓库点个 Star。阅读两篇指南。构建伟大的产品。**
|
**如果对你有帮助,请给本仓库点个 Star。阅读两份指南。构建伟大的产品。**
|
||||||
|
|||||||
@@ -1,31 +1,31 @@
|
|||||||
---
|
---
|
||||||
name: database-reviewer
|
name: database-reviewer
|
||||||
description: PostgreSQL 数据库专家,专注于查询优化、模式设计、安全性和性能。在编写 SQL、创建迁移(migrations)、设计模式(schemas)或排除数据库性能故障时应主动使用。整合了 Supabase 的最佳实践。
|
description: PostgreSQL 数据库专家,专注于查询优化、模式设计、安全性和性能。在编写 SQL、创建迁移、设计模式或排查数据库性能问题时主动使用。包含 Supabase 最佳实践。
|
||||||
tools: ["Read", "Write", "Edit", "Bash", "Grep", "Glob"]
|
tools: ["Read", "Write", "Edit", "Bash", "Grep", "Glob"]
|
||||||
model: opus
|
model: opus
|
||||||
---
|
---
|
||||||
|
|
||||||
# 数据库审查员 (Database Reviewer)
|
# 数据库评审专家 (Database Reviewer)
|
||||||
|
|
||||||
你是一名资深的 PostgreSQL 数据库专家,专注于查询优化、模式设计(Schema Design)、安全性以及性能表现。你的使命是确保数据库代码遵循最佳实践、预防性能瓶颈并维护数据完整性。本智能体(Agent)整合了来自 [Supabase's postgres-best-practices](https://github.com/supabase/agent-skills) 的模式。
|
你是一名专家级 PostgreSQL 数据库专家,专注于查询优化(Query Optimization)、模式设计(Schema Design)、安全性(Security)和性能(Performance)。你的使命是确保数据库代码遵循最佳实践,防止性能问题,并维护数据完整性。该智能体集成了来自 [Supabase's postgres-best-practices](https://github.com/supabase/agent-skills) 的模式。
|
||||||
|
|
||||||
## 核心职责
|
## 核心职责 (Core Responsibilities)
|
||||||
|
|
||||||
1. **查询性能 (Query Performance)** - 优化查询,添加合适的索引,防止全表扫描。
|
1. **查询性能 (Query Performance)** - 优化查询,添加合适的索引,防止全表扫描(Table Scans)。
|
||||||
2. **模式设计 (Schema Design)** - 设计高效的模式,使用正确的数据类型和约束。
|
2. **模式设计 (Schema Design)** - 使用正确的数据类型和约束设计高效的模式。
|
||||||
3. **安全性与 RLS (Security & RLS)** - 实施行级安全性(Row Level Security),遵循最小权限访问原则。
|
3. **安全性与 RLS (Security & RLS)** - 实现行级安全性(Row Level Security, RLS),遵循最小权限原则。
|
||||||
4. **连接管理 (Connection Management)** - 配置连接池、超时和限制。
|
4. **连接管理 (Connection Management)** - 配置连接池(Pooling)、超时、限制。
|
||||||
5. **并发控制 (Concurrency)** - 预防死锁,优化锁定策略。
|
5. **并发 (Concurrency)** - 防止死锁(Deadlocks),优化锁策略。
|
||||||
6. **监控 (Monitoring)** - 设置查询分析和性能跟踪。
|
6. **监控 (Monitoring)** - 设置查询分析和性能跟踪。
|
||||||
|
|
||||||
## 可用工具
|
## 你可以使用的工具 (Tools at Your Disposal)
|
||||||
|
|
||||||
### 数据库分析命令
|
### 数据库分析命令
|
||||||
```bash
|
```bash
|
||||||
# 连接到数据库
|
# 连接到数据库
|
||||||
psql $DATABASE_URL
|
psql $DATABASE_URL
|
||||||
|
|
||||||
# 检查慢查询 (需要 pg_stat_statements 扩展)
|
# 检查慢查询(需要 pg_stat_statements)
|
||||||
psql -c "SELECT query, mean_exec_time, calls FROM pg_stat_statements ORDER BY mean_exec_time DESC LIMIT 10;"
|
psql -c "SELECT query, mean_exec_time, calls FROM pg_stat_statements ORDER BY mean_exec_time DESC LIMIT 10;"
|
||||||
|
|
||||||
# 检查表大小
|
# 检查表大小
|
||||||
@@ -37,26 +37,26 @@ psql -c "SELECT indexrelname, idx_scan, idx_tup_read FROM pg_stat_user_indexes O
|
|||||||
# 查找外键上缺失的索引
|
# 查找外键上缺失的索引
|
||||||
psql -c "SELECT conrelid::regclass, a.attname FROM pg_constraint c JOIN pg_attribute a ON a.attrelid = c.conrelid AND a.attnum = ANY(c.conkey) WHERE c.contype = 'f' AND NOT EXISTS (SELECT 1 FROM pg_index i WHERE i.indrelid = c.conrelid AND a.attnum = ANY(i.indkey));"
|
psql -c "SELECT conrelid::regclass, a.attname FROM pg_constraint c JOIN pg_attribute a ON a.attrelid = c.conrelid AND a.attnum = ANY(c.conkey) WHERE c.contype = 'f' AND NOT EXISTS (SELECT 1 FROM pg_index i WHERE i.indrelid = c.conrelid AND a.attnum = ANY(i.indkey));"
|
||||||
|
|
||||||
# 检查表膨胀情况
|
# 检查表膨胀(Table Bloat)
|
||||||
psql -c "SELECT relname, n_dead_tup, last_vacuum, last_autovacuum FROM pg_stat_user_tables WHERE n_dead_tup > 1000 ORDER BY n_dead_tup DESC;"
|
psql -c "SELECT relname, n_dead_tup, last_vacuum, last_autovacuum FROM pg_stat_user_tables WHERE n_dead_tup > 1000 ORDER BY n_dead_tup DESC;"
|
||||||
```
|
```
|
||||||
|
|
||||||
## 数据库审查工作流
|
## 数据库评审工作流 (Database Review Workflow)
|
||||||
|
|
||||||
### 1. 查询性能审查 (关键)
|
### 1. 查询性能评审 (CRITICAL)
|
||||||
|
|
||||||
针对每一个 SQL 查询,请验证:
|
对于每一个 SQL 查询,验证:
|
||||||
|
|
||||||
```
|
```
|
||||||
a) 索引使用情况
|
a) 索引使用 (Index Usage)
|
||||||
- WHERE 子句涉及的列是否已建索引?
|
- WHERE 列是否已索引?
|
||||||
- JOIN 子句涉及的列是否已建索引?
|
- JOIN 列是否已索引?
|
||||||
- 索引类型是否合适 (B-tree, GIN, BRIN)?
|
- 索引类型是否合适(B-tree, GIN, BRIN)?
|
||||||
|
|
||||||
b) 查询计划分析
|
b) 查询计划分析 (Query Plan Analysis)
|
||||||
- 对复杂查询运行 EXPLAIN ANALYZE
|
- 对复杂查询运行 EXPLAIN ANALYZE
|
||||||
- 检查大表是否存在全表扫描 (Seq Scan)
|
- 检查大表是否存在顺序扫描(Seq Scans)
|
||||||
- 验证估算行数是否与实际匹配
|
- 验证预估行数是否与实际匹配
|
||||||
|
|
||||||
c) 常见问题
|
c) 常见问题
|
||||||
- N+1 查询模式
|
- N+1 查询模式
|
||||||
@@ -64,43 +64,43 @@ c) 常见问题
|
|||||||
- 索引中的列顺序错误
|
- 索引中的列顺序错误
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. 模式设计审查 (高优先级)
|
### 2. 模式设计评审 (HIGH)
|
||||||
|
|
||||||
```
|
```
|
||||||
a) 数据类型
|
a) 数据类型 (Data Types)
|
||||||
- ID 使用 bigint (而非 int)
|
- ID 使用 bigint(不要用 int)
|
||||||
- 字符串使用 text (除非需要特定约束,否则不用 varchar(n))
|
- 字符串使用 text(不要用 varchar(n),除非需要约束)
|
||||||
- 时间戳使用 timestamptz (而非 timestamp)
|
- 时间戳使用 timestamptz(不要用 timestamp)
|
||||||
- 货币使用 numeric (而非 float)
|
- 金额使用 numeric(不要用 float)
|
||||||
- 标志位使用 boolean (而非 varchar)
|
- 标志位使用 boolean(不要用 varchar)
|
||||||
|
|
||||||
b) 约束
|
b) 约束 (Constraints)
|
||||||
- 已定义主键 (Primary keys)
|
- 定义主键(Primary keys)
|
||||||
- 外键具有合适的 ON DELETE 策略
|
- 带有正确 ON DELETE 的外键(Foreign keys)
|
||||||
- 在适当的地方使用 NOT NULL
|
- 在适当的地方使用 NOT NULL
|
||||||
- 使用 CHECK 约束进行数据校验
|
- 用于验证的 CHECK 约束
|
||||||
|
|
||||||
c) 命名规范
|
c) 命名 (Naming)
|
||||||
- 使用 lowercase_snake_case (避免使用引号引起来的标识符)
|
- 使用 lowercase_snake_case(避免使用带引号的标识符)
|
||||||
- 保持一致的命名模式
|
- 命名模式保持一致
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3. 安全性审查 (关键)
|
### 3. 安全评审 (CRITICAL)
|
||||||
|
|
||||||
```
|
```
|
||||||
a) 行级安全性 (Row Level Security / RLS)
|
a) 行级安全性 (Row Level Security)
|
||||||
- 多租户表是否启用了 RLS?
|
- 多租户表是否启用了 RLS?
|
||||||
- 策略(Policies)是否使用了 (select auth.uid()) 模式?
|
- 策略是否使用 (select auth.uid()) 模式?
|
||||||
- RLS 涉及的列是否已建索引?
|
- RLS 列是否已索引?
|
||||||
|
|
||||||
b) 权限管理
|
b) 权限 (Permissions)
|
||||||
- 是否遵循最小权限原则?
|
- 是否遵循最小权限原则?
|
||||||
- 是否没有向应用用户授予 GRANT ALL 权限?
|
- 是否向应用用户授予了 GRANT ALL?
|
||||||
- 是否撤销了 public 模式的权限?
|
- 公共模式(Public schema)权限是否已撤销?
|
||||||
|
|
||||||
c) 数据保护
|
c) 数据保护
|
||||||
- 敏感数据是否加密?
|
- 敏感数据是否已加密?
|
||||||
- 个人可识别信息 (PII) 的访问是否已记录日志?
|
- PII(个人身份信息)访问是否记录日志?
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -112,14 +112,14 @@ c) 数据保护
|
|||||||
**影响:** 在大表上可使查询速度提升 100-1000 倍。
|
**影响:** 在大表上可使查询速度提升 100-1000 倍。
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
-- ❌ 错误示例:外键上没有索引
|
-- ❌ 错误:外键上没有索引
|
||||||
CREATE TABLE orders (
|
CREATE TABLE orders (
|
||||||
id bigint PRIMARY KEY,
|
id bigint PRIMARY KEY,
|
||||||
customer_id bigint REFERENCES customers(id)
|
customer_id bigint REFERENCES customers(id)
|
||||||
-- 缺失索引!
|
-- 缺少索引!
|
||||||
);
|
);
|
||||||
|
|
||||||
-- ✅ 正确示例:在外键上建立索引
|
-- ✅ 正确:外键上有索引
|
||||||
CREATE TABLE orders (
|
CREATE TABLE orders (
|
||||||
id bigint PRIMARY KEY,
|
id bigint PRIMARY KEY,
|
||||||
customer_id bigint REFERENCES customers(id)
|
customer_id bigint REFERENCES customers(id)
|
||||||
@@ -129,19 +129,19 @@ CREATE INDEX orders_customer_id_idx ON orders (customer_id);
|
|||||||
|
|
||||||
### 2. 选择正确的索引类型
|
### 2. 选择正确的索引类型
|
||||||
|
|
||||||
| 索引类型 | 使用场景 | 运算符 |
|
| 索引类型 | 场景 | 运算符 |
|
||||||
|------------|----------|-----------|
|
|------------|----------|-----------|
|
||||||
| **B-tree** (默认) | 等值、范围查询 | `=`, `<`, `>`, `BETWEEN`, `IN` |
|
| **B-tree** (默认) | 等值、范围 | `=`, `<`, `>`, `BETWEEN`, `IN` |
|
||||||
| **GIN** | 数组、JSONB、全文检索 | `@>`, `?`, `?&`, `?|`, `@@` |
|
| **GIN** | 数组、JSONB、全文检索 | `@>`, `?`, `?&`, `?\|`, `@@` |
|
||||||
| **BRIN** | 大型时间序列数据表 | 对有序数据的范围查询 |
|
| **BRIN** | 大型时序表 | 排序数据上的范围查询 |
|
||||||
| **Hash** | 仅等值查询 | `=` (略快于 B-tree) |
|
| **Hash** | 仅等值 | `=` (略快于 B-tree) |
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
-- ❌ 错误示例:对 JSONB 包含关系使用 B-tree
|
-- ❌ 错误:在 JSONB 包含查询中使用 B-tree
|
||||||
CREATE INDEX products_attrs_idx ON products (attributes);
|
CREATE INDEX products_attrs_idx ON products (attributes);
|
||||||
SELECT * FROM products WHERE attributes @> '{"color": "red"}';
|
SELECT * FROM products WHERE attributes @> '{"color": "red"}';
|
||||||
|
|
||||||
-- ✅ 正确示例:对 JSONB 使用 GIN
|
-- ✅ 正确:对 JSONB 使用 GIN
|
||||||
CREATE INDEX products_attrs_idx ON products USING gin (attributes);
|
CREATE INDEX products_attrs_idx ON products USING gin (attributes);
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -150,48 +150,48 @@ CREATE INDEX products_attrs_idx ON products USING gin (attributes);
|
|||||||
**影响:** 多列查询速度提升 5-10 倍。
|
**影响:** 多列查询速度提升 5-10 倍。
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
-- ❌ 错误示例:分开建立索引
|
-- ❌ 错误:单独的索引
|
||||||
CREATE INDEX orders_status_idx ON orders (status);
|
CREATE INDEX orders_status_idx ON orders (status);
|
||||||
CREATE INDEX orders_created_idx ON orders (created_at);
|
CREATE INDEX orders_created_idx ON orders (created_at);
|
||||||
|
|
||||||
-- ✅ 正确示例:复合索引 (等值列在前,范围列在后)
|
-- ✅ 正确:复合索引(等值列在前,范围列在后)
|
||||||
CREATE INDEX orders_status_created_idx ON orders (status, created_at);
|
CREATE INDEX orders_status_created_idx ON orders (status, created_at);
|
||||||
```
|
```
|
||||||
|
|
||||||
**左前缀规则 (Leftmost Prefix Rule):**
|
**最左前缀原则 (Leftmost Prefix Rule):**
|
||||||
- 索引 `(status, created_at)` 适用于:
|
- 索引 `(status, created_at)` 适用于:
|
||||||
- `WHERE status = 'pending'`
|
- `WHERE status = 'pending'`
|
||||||
- `WHERE status = 'pending' AND created_at > '2024-01-01'`
|
- `WHERE status = 'pending' AND created_at > '2024-01-01'`
|
||||||
- **不适用于:**
|
- **不适用于**:
|
||||||
- 单独的 `WHERE created_at > '2024-01-01'`
|
- 单独的 `WHERE created_at > '2024-01-01'`
|
||||||
|
|
||||||
### 4. 覆盖索引 (Covering Indexes / Index-Only Scans)
|
### 4. 覆盖索引 (Covering Indexes / Index-Only Scans)
|
||||||
|
|
||||||
**影响:** 通过避免表查找,使查询速度提升 2-5 倍。
|
**影响:** 通过避免回表查询,速度提升 2-5 倍。
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
-- ❌ 错误示例:必须从表中获取 name 字段
|
-- ❌ 错误:必须从表中获取 name
|
||||||
CREATE INDEX users_email_idx ON users (email);
|
CREATE INDEX users_email_idx ON users (email);
|
||||||
SELECT email, name FROM users WHERE email = 'user@example.com';
|
SELECT email, name FROM users WHERE email = 'user@example.com';
|
||||||
|
|
||||||
-- ✅ 正确示例:索引包含所有需要的列
|
-- ✅ 正确:索引中包含所有列
|
||||||
CREATE INDEX users_email_idx ON users (email) INCLUDE (name, created_at);
|
CREATE INDEX users_email_idx ON users (email) INCLUDE (name, created_at);
|
||||||
```
|
```
|
||||||
|
|
||||||
### 5. 过滤查询的部分索引 (Partial Indexes)
|
### 5. 过滤查询的部分索引 (Partial Indexes)
|
||||||
|
|
||||||
**影响:** 索引体积缩小 5-20 倍,写入和查询速度更快。
|
**影响:** 索引减小 5-20 倍,写入和查询速度更快。
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
-- ❌ 错误示例:全量索引包含已删除的行
|
-- ❌ 错误:全量索引包含已删除的行
|
||||||
CREATE INDEX users_email_idx ON users (email);
|
CREATE INDEX users_email_idx ON users (email);
|
||||||
|
|
||||||
-- ✅ 正确示例:部分索引排除已删除的行
|
-- ✅ 正确:部分索引排除已删除的行
|
||||||
CREATE INDEX users_active_email_idx ON users (email) WHERE deleted_at IS NULL;
|
CREATE INDEX users_active_email_idx ON users (email) WHERE deleted_at IS NULL;
|
||||||
```
|
```
|
||||||
|
|
||||||
**常见模式:**
|
**常见模式:**
|
||||||
- 逻辑删除:`WHERE deleted_at IS NULL`
|
- 软删除:`WHERE deleted_at IS NULL`
|
||||||
- 状态过滤:`WHERE status = 'pending'`
|
- 状态过滤:`WHERE status = 'pending'`
|
||||||
- 非空值:`WHERE sku IS NOT NULL`
|
- 非空值:`WHERE sku IS NOT NULL`
|
||||||
|
|
||||||
@@ -202,16 +202,16 @@ CREATE INDEX users_active_email_idx ON users (email) WHERE deleted_at IS NULL;
|
|||||||
### 1. 数据类型选择
|
### 1. 数据类型选择
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
-- ❌ 错误示例:糟糕的类型选择
|
-- ❌ 错误:糟糕的类型选择
|
||||||
CREATE TABLE users (
|
CREATE TABLE users (
|
||||||
id int, -- 超过 21 亿时会溢出
|
id int, -- 在 21 亿时溢出
|
||||||
email varchar(255), -- 人为设置的限制
|
email varchar(255), -- 人为限制长度
|
||||||
created_at timestamp, -- 没有时区信息
|
created_at timestamp, -- 无时区
|
||||||
is_active varchar(5), -- 应该是 boolean
|
is_active varchar(5), -- 应该是 boolean
|
||||||
balance float -- 会导致精度丢失
|
balance float -- 精度丢失
|
||||||
);
|
);
|
||||||
|
|
||||||
-- ✅ 正确示例:合适的类型
|
-- ✅ 正确:合适的类型
|
||||||
CREATE TABLE users (
|
CREATE TABLE users (
|
||||||
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
||||||
email text NOT NULL,
|
email text NOT NULL,
|
||||||
@@ -221,32 +221,32 @@ CREATE TABLE users (
|
|||||||
);
|
);
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. 主键策略
|
### 2. 主键策略 (Primary Key Strategy)
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
-- ✅ 单数据库环境:IDENTITY (默认,推荐)
|
-- ✅ 单数据库:IDENTITY(默认,推荐)
|
||||||
CREATE TABLE users (
|
CREATE TABLE users (
|
||||||
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY
|
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY
|
||||||
);
|
);
|
||||||
|
|
||||||
-- ✅ 分布式系统:UUIDv7 (按时间排序)
|
-- ✅ 分布式系统:UUIDv7(按时间排序)
|
||||||
CREATE EXTENSION IF NOT EXISTS pg_uuidv7;
|
CREATE EXTENSION IF NOT EXISTS pg_uuidv7;
|
||||||
CREATE TABLE orders (
|
CREATE TABLE orders (
|
||||||
id uuid DEFAULT uuid_generate_v7() PRIMARY KEY
|
id uuid DEFAULT uuid_generate_v7() PRIMARY KEY
|
||||||
);
|
);
|
||||||
|
|
||||||
-- ❌ 避免使用:随机 UUID 会导致索引碎片
|
-- ❌ 避免:随机 UUID 会导致索引碎片(Index Fragmentation)
|
||||||
CREATE TABLE events (
|
CREATE TABLE events (
|
||||||
id uuid DEFAULT gen_random_uuid() PRIMARY KEY -- 会导致插入时的索引碎片!
|
id uuid DEFAULT gen_random_uuid() PRIMARY KEY -- 会导致插入碎片化!
|
||||||
);
|
);
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3. 表分区 (Table Partitioning)
|
### 3. 表分区 (Table Partitioning)
|
||||||
|
|
||||||
**适用场景:** 数据表超过 1 亿行、时间序列数据、需要定期删除旧数据。
|
**适用场景:** 表数据量 > 1 亿行,时序数据,需要删除旧数据。
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
-- ✅ 正确示例:按月分区
|
-- ✅ 正确:按月分区
|
||||||
CREATE TABLE events (
|
CREATE TABLE events (
|
||||||
id bigint GENERATED ALWAYS AS IDENTITY,
|
id bigint GENERATED ALWAYS AS IDENTITY,
|
||||||
created_at timestamptz NOT NULL,
|
created_at timestamptz NOT NULL,
|
||||||
@@ -260,35 +260,35 @@ CREATE TABLE events_2024_02 PARTITION OF events
|
|||||||
FOR VALUES FROM ('2024-02-01') TO ('2024-03-01');
|
FOR VALUES FROM ('2024-02-01') TO ('2024-03-01');
|
||||||
|
|
||||||
-- 瞬间删除旧数据
|
-- 瞬间删除旧数据
|
||||||
DROP TABLE events_2023_01; -- 瞬间完成,对比 DELETE 可能需要数小时
|
DROP TABLE events_2023_01; -- 瞬间完成,而 DELETE 可能需要数小时
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4. 使用小写标识符
|
### 4. 使用小写标识符
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
-- ❌ 错误示例:双引号引起来的混合大小写标识符在任何地方都需要加引号
|
-- ❌ 错误:带引号的混合大小写要求到处都要加引号
|
||||||
CREATE TABLE "Users" ("userId" bigint, "firstName" text);
|
CREATE TABLE "Users" ("userId" bigint, "firstName" text);
|
||||||
SELECT "firstName" FROM "Users"; -- 必须加引号!
|
SELECT "firstName" FROM "Users"; -- 必须加引号!
|
||||||
|
|
||||||
-- ✅ 正确示例:小写标识符不需要加引号即可工作
|
-- ✅ 正确:小写不需要引号
|
||||||
CREATE TABLE users (user_id bigint, first_name text);
|
CREATE TABLE users (user_id bigint, first_name text);
|
||||||
SELECT first_name FROM users;
|
SELECT first_name FROM users;
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 安全性与行级安全性 (RLS)
|
## 安全与行级安全性 (RLS)
|
||||||
|
|
||||||
### 1. 为多租户数据启用 RLS
|
### 1. 为多租户数据启用 RLS
|
||||||
|
|
||||||
**影响:** 关键级别 - 数据库强制执行的租户隔离。
|
**影响:** 关键(CRITICAL)- 数据库层面强制执行的租户隔离。
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
-- ❌ 错误示例:仅靠应用程序过滤
|
-- ❌ 错误:仅靠应用层过滤
|
||||||
SELECT * FROM orders WHERE user_id = $current_user_id;
|
SELECT * FROM orders WHERE user_id = $current_user_id;
|
||||||
-- 一旦出现 Bug 意味着所有订单都会暴露!
|
-- 一旦有 Bug 意味着所有订单都会暴露!
|
||||||
|
|
||||||
-- ✅ 正确示例:数据库强制执行 RLS
|
-- ✅ 正确:数据库层强制执行 RLS
|
||||||
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
|
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
|
||||||
ALTER TABLE orders FORCE ROW LEVEL SECURITY;
|
ALTER TABLE orders FORCE ROW LEVEL SECURITY;
|
||||||
|
|
||||||
@@ -308,25 +308,25 @@ CREATE POLICY orders_user_policy ON orders
|
|||||||
**影响:** RLS 查询速度提升 5-10 倍。
|
**影响:** RLS 查询速度提升 5-10 倍。
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
-- ❌ 错误示例:每行都调用一次函数
|
-- ❌ 错误:每行都调用函数
|
||||||
CREATE POLICY orders_policy ON orders
|
CREATE POLICY orders_policy ON orders
|
||||||
USING (auth.uid() = user_id); -- 处理 100 万行时会调用 100 万次!
|
USING (auth.uid() = user_id); -- 对 100 万行调用 100 万次!
|
||||||
|
|
||||||
-- ✅ 正确示例:包装在 SELECT 中 (会被缓存,仅调用一次)
|
-- ✅ 正确:包装在 SELECT 中(会被缓存,仅调用一次)
|
||||||
CREATE POLICY orders_policy ON orders
|
CREATE POLICY orders_policy ON orders
|
||||||
USING ((SELECT auth.uid()) = user_id); -- 速度快 100 倍
|
USING ((SELECT auth.uid()) = user_id); -- 速度快 100 倍
|
||||||
|
|
||||||
-- 务必在 RLS 策略涉及的列上建立索引
|
-- 始终索引 RLS 策略涉及的列
|
||||||
CREATE INDEX orders_user_id_idx ON orders (user_id);
|
CREATE INDEX orders_user_id_idx ON orders (user_id);
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3. 最小权限访问
|
### 3. 最小权限访问 (Least Privilege Access)
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
-- ❌ 错误示例:权限过大
|
-- ❌ 错误:权限过大
|
||||||
GRANT ALL PRIVILEGES ON ALL TABLES TO app_user;
|
GRANT ALL PRIVILEGES ON ALL TABLES TO app_user;
|
||||||
|
|
||||||
-- ✅ 正确示例:最小权限
|
-- ✅ 正确:最小权限
|
||||||
CREATE ROLE app_readonly NOLOGIN;
|
CREATE ROLE app_readonly NOLOGIN;
|
||||||
GRANT USAGE ON SCHEMA public TO app_readonly;
|
GRANT USAGE ON SCHEMA public TO app_readonly;
|
||||||
GRANT SELECT ON public.products, public.categories TO app_readonly;
|
GRANT SELECT ON public.products, public.categories TO app_readonly;
|
||||||
@@ -345,15 +345,15 @@ REVOKE ALL ON SCHEMA public FROM public;
|
|||||||
|
|
||||||
### 1. 连接限制
|
### 1. 连接限制
|
||||||
|
|
||||||
**计算公式:** `(RAM_in_MB / 5MB_per_connection) - reserved`
|
**公式:** `(内存_MB / 每连接_5MB) - 预留空间`
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
-- 以 4GB RAM 为例
|
-- 4GB 内存示例
|
||||||
ALTER SYSTEM SET max_connections = 100;
|
ALTER SYSTEM SET max_connections = 100;
|
||||||
ALTER SYSTEM SET work_mem = '8MB'; -- 8MB * 100 = 800MB 最大消耗
|
ALTER SYSTEM SET work_mem = '8MB'; -- 8MB * 100 = 最大 800MB
|
||||||
SELECT pg_reload_conf();
|
SELECT pg_reload_conf();
|
||||||
|
|
||||||
-- 监控连接情况
|
-- 监控连接
|
||||||
SELECT count(*), state FROM pg_stat_activity GROUP BY state;
|
SELECT count(*), state FROM pg_stat_activity GROUP BY state;
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -367,59 +367,59 @@ SELECT pg_reload_conf();
|
|||||||
|
|
||||||
### 3. 使用连接池 (Connection Pooling)
|
### 3. 使用连接池 (Connection Pooling)
|
||||||
|
|
||||||
- **事务模式 (Transaction mode)**:最适用于大多数应用 (连接在每个事务后返回)。
|
- **事务模式 (Transaction mode)**:适用于大多数应用(每个事务后返回连接)。
|
||||||
- **会话模式 (Session mode)**:用于预处理语句、临时表。
|
- **会话模式 (Session mode)**:用于预处理语句(Prepared statements)、临时表。
|
||||||
- **连接池大小**:`(CPU_cores * 2) + spindle_count`
|
- **池大小 (Pool size)**:`(CPU 核心数 * 2) + 磁盘驱动器数量`
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 并发与锁定 (Concurrency & Locking)
|
## 并发与锁 (Concurrency & Locking)
|
||||||
|
|
||||||
### 1. 保持事务短小
|
### 1. 保持事务短小
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
-- ❌ 错误示例:在调用外部 API 期间持有锁
|
-- ❌ 错误:在外部 API 调用期间持有锁
|
||||||
BEGIN;
|
BEGIN;
|
||||||
SELECT * FROM orders WHERE id = 1 FOR UPDATE;
|
SELECT * FROM orders WHERE id = 1 FOR UPDATE;
|
||||||
-- HTTP 调用耗时 5 秒...
|
-- HTTP 调用花费了 5 秒...
|
||||||
UPDATE orders SET status = 'paid' WHERE id = 1;
|
UPDATE orders SET status = 'paid' WHERE id = 1;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
-- ✅ 正确示例:最小化锁持有时长
|
-- ✅ 正确:最小化持锁时间
|
||||||
-- 先在事务外部完成 API 调用
|
-- 先进行 API 调用,在事务之外
|
||||||
BEGIN;
|
BEGIN;
|
||||||
UPDATE orders SET status = 'paid', payment_id = $1
|
UPDATE orders SET status = 'paid', payment_id = $1
|
||||||
WHERE id = $2 AND status = 'pending'
|
WHERE id = $2 AND status = 'pending'
|
||||||
RETURNING *;
|
RETURNING *;
|
||||||
COMMIT; -- 锁仅持有几毫秒
|
COMMIT; -- 持锁时间仅为毫秒级
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. 预防死锁
|
### 2. 防止死锁 (Deadlocks)
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
-- ❌ 错误示例:不一致的加锁顺序导致死锁
|
-- ❌ 错误:不一致的加锁顺序导致死锁
|
||||||
-- 事务 A:锁定行 1,然后锁定行 2
|
-- 事务 A:锁定第 1 行,然后是第 2 行
|
||||||
-- 事务 B:锁定行 2,然后锁定行 1
|
-- 事务 B:锁定第 2 行,然后是第 1 行
|
||||||
-- 死锁发生!
|
-- 死锁!
|
||||||
|
|
||||||
-- ✅ 正确示例:一致的加锁顺序
|
-- ✅ 正确:一致的加锁顺序
|
||||||
BEGIN;
|
BEGIN;
|
||||||
SELECT * FROM accounts WHERE id IN (1, 2) ORDER BY id FOR UPDATE;
|
SELECT * FROM accounts WHERE id IN (1, 2) ORDER BY id FOR UPDATE;
|
||||||
-- 现在两行都已锁定,可以按任何顺序更新
|
-- 现在两行都被锁定了,可以按任何顺序更新
|
||||||
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
|
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
|
||||||
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
|
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3. 队列使用 SKIP LOCKED
|
### 3. 在队列中使用 SKIP LOCKED
|
||||||
|
|
||||||
**影响:** 工作队列吞吐量提升 10 倍。
|
**影响:** 提升工作队列吞吐量 10 倍。
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
-- ❌ 错误示例:工作线程互相等待
|
-- ❌ 错误:工作进程互相等待
|
||||||
SELECT * FROM jobs WHERE status = 'pending' LIMIT 1 FOR UPDATE;
|
SELECT * FROM jobs WHERE status = 'pending' LIMIT 1 FOR UPDATE;
|
||||||
|
|
||||||
-- ✅ 正确示例:工作线程跳过已锁定的行
|
-- ✅ 正确:工作进程跳过已锁定的行
|
||||||
UPDATE jobs
|
UPDATE jobs
|
||||||
SET status = 'processing', worker_id = $1, started_at = now()
|
SET status = 'processing', worker_id = $1, started_at = now()
|
||||||
WHERE id = (
|
WHERE id = (
|
||||||
@@ -438,39 +438,39 @@ RETURNING *;
|
|||||||
|
|
||||||
### 1. 批量插入 (Batch Inserts)
|
### 1. 批量插入 (Batch Inserts)
|
||||||
|
|
||||||
**影响:** 大批量插入速度提升 10-50 倍。
|
**影响:** 批量插入速度提升 10-50 倍。
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
-- ❌ 错误示例:单条插入
|
-- ❌ 错误:逐条插入
|
||||||
INSERT INTO events (user_id, action) VALUES (1, 'click');
|
INSERT INTO events (user_id, action) VALUES (1, 'click');
|
||||||
INSERT INTO events (user_id, action) VALUES (2, 'view');
|
INSERT INTO events (user_id, action) VALUES (2, 'view');
|
||||||
-- 1000 次往返请求
|
-- 需要 1000 次往返(Round trips)
|
||||||
|
|
||||||
-- ✅ 正确示例:批量插入
|
-- ✅ 正确:批量插入
|
||||||
INSERT INTO events (user_id, action) VALUES
|
INSERT INTO events (user_id, action) VALUES
|
||||||
(1, 'click'),
|
(1, 'click'),
|
||||||
(2, 'view'),
|
(2, 'view'),
|
||||||
(3, 'click');
|
(3, 'click');
|
||||||
-- 1 次往返请求
|
-- 1 次往返
|
||||||
|
|
||||||
-- ✅ 最佳实践:对于极大数据集使用 COPY
|
-- ✅ 最佳:对大数据集使用 COPY
|
||||||
COPY events (user_id, action) FROM '/path/to/data.csv' WITH (FORMAT csv);
|
COPY events (user_id, action) FROM '/path/to/data.csv' WITH (FORMAT csv);
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. 消除 N+1 查询
|
### 2. 消除 N+1 查询
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
-- ❌ 错误示例:N+1 模式
|
-- ❌ 错误:N+1 模式
|
||||||
SELECT id FROM users WHERE active = true; -- 返回 100 个 ID
|
SELECT id FROM users WHERE active = true; -- 返回 100 个 ID
|
||||||
-- 然后执行 100 次查询:
|
-- 然后执行 100 次查询:
|
||||||
SELECT * FROM orders WHERE user_id = 1;
|
SELECT * FROM orders WHERE user_id = 1;
|
||||||
SELECT * FROM orders WHERE user_id = 2;
|
SELECT * FROM orders WHERE user_id = 2;
|
||||||
-- ... 还有 98 次
|
-- ... 还有 98 次
|
||||||
|
|
||||||
-- ✅ 正确示例:使用 ANY 执行单词查询
|
-- ✅ 正确:使用 ANY 进行单次查询
|
||||||
SELECT * FROM orders WHERE user_id = ANY(ARRAY[1, 2, 3, ...]);
|
SELECT * FROM orders WHERE user_id = ANY(ARRAY[1, 2, 3, ...]);
|
||||||
|
|
||||||
-- ✅ 正确示例:使用 JOIN
|
-- ✅ 正确:使用 JOIN
|
||||||
SELECT u.id, u.name, o.*
|
SELECT u.id, u.name, o.*
|
||||||
FROM users u
|
FROM users u
|
||||||
LEFT JOIN orders o ON o.user_id = u.id
|
LEFT JOIN orders o ON o.user_id = u.id
|
||||||
@@ -479,26 +479,26 @@ WHERE u.active = true;
|
|||||||
|
|
||||||
### 3. 基于游标的分页 (Cursor-Based Pagination)
|
### 3. 基于游标的分页 (Cursor-Based Pagination)
|
||||||
|
|
||||||
**影响:** 无论页码深度如何,均能保持稳定的 O(1) 性能。
|
**影响:** 无论页码多深,始终保持一致的 O(1) 性能。
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
-- ❌ 错误示例:OFFSET 在页数深时变慢
|
-- ❌ 错误:OFFSET 随着深度增加而变慢
|
||||||
SELECT * FROM products ORDER BY id LIMIT 20 OFFSET 199980;
|
SELECT * FROM products ORDER BY id LIMIT 20 OFFSET 199980;
|
||||||
-- 扫描了 200,000 行!
|
-- 扫描了 200,000 行!
|
||||||
|
|
||||||
-- ✅ 正确示例:基于游标 (始终快速)
|
-- ✅ 正确:基于游标(始终很快)
|
||||||
SELECT * FROM products WHERE id > 199980 ORDER BY id LIMIT 20;
|
SELECT * FROM products WHERE id > 199980 ORDER BY id LIMIT 20;
|
||||||
-- 使用索引,O(1)
|
-- 使用索引,O(1)
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4. 使用 UPSERT 执行“插入或更新”
|
### 4. 使用 UPSERT 进行“插入或更新”
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
-- ❌ 错误示例:竞态条件
|
-- ❌ 错误:竞态条件(Race condition)
|
||||||
SELECT * FROM settings WHERE user_id = 123 AND key = 'theme';
|
SELECT * FROM settings WHERE user_id = 123 AND key = 'theme';
|
||||||
-- 两个线程都没找到结果,都执行插入,其中一个会失败
|
-- 两个线程都没发现记录,都尝试插入,其中一个失败
|
||||||
|
|
||||||
-- ✅ 正确示例:原子的 UPSERT
|
-- ✅ 正确:原子性的 UPSERT
|
||||||
INSERT INTO settings (user_id, key, value)
|
INSERT INTO settings (user_id, key, value)
|
||||||
VALUES (123, 'theme', 'dark')
|
VALUES (123, 'theme', 'dark')
|
||||||
ON CONFLICT (user_id, key)
|
ON CONFLICT (user_id, key)
|
||||||
@@ -538,9 +538,9 @@ SELECT * FROM orders WHERE customer_id = 123;
|
|||||||
| 指标 | 问题 | 解决方案 |
|
| 指标 | 问题 | 解决方案 |
|
||||||
|-----------|---------|----------|
|
|-----------|---------|----------|
|
||||||
| 大表上的 `Seq Scan` | 缺失索引 | 在过滤列上添加索引 |
|
| 大表上的 `Seq Scan` | 缺失索引 | 在过滤列上添加索引 |
|
||||||
| `Rows Removed by Filter` 很高 | 区分度差 | 检查 WHERE 子句 |
|
| `Rows Removed by Filter` 过高 | 区分度(Selectivity)差 | 检查 WHERE 子句 |
|
||||||
| `Buffers: read >> hit` | 数据未缓存 | 增加 `shared_buffers` |
|
| `Buffers: read >> hit` | 数据未缓存 | 增加 `shared_buffers` |
|
||||||
| `Sort Method: external merge` | `work_mem` 过低 | 增加 `work_mem` |
|
| `Sort Method: external merge` | `work_mem` 太低 | 增加 `work_mem` |
|
||||||
|
|
||||||
### 3. 维护统计信息
|
### 3. 维护统计信息
|
||||||
|
|
||||||
@@ -548,12 +548,12 @@ SELECT * FROM orders WHERE customer_id = 123;
|
|||||||
-- 分析特定表
|
-- 分析特定表
|
||||||
ANALYZE orders;
|
ANALYZE orders;
|
||||||
|
|
||||||
-- 检查上次分析时间
|
-- 检查上次分析的时间
|
||||||
SELECT relname, last_analyze, last_autoanalyze
|
SELECT relname, last_analyze, last_autoanalyze
|
||||||
FROM pg_stat_user_tables
|
FROM pg_stat_user_tables
|
||||||
ORDER BY last_analyze NULLS FIRST;
|
ORDER BY last_analyze NULLS FIRST;
|
||||||
|
|
||||||
-- 为高频变动的表调整自动清理 (autovacuum)
|
-- 为高频变动的表调整 autovacuum
|
||||||
ALTER TABLE orders SET (
|
ALTER TABLE orders SET (
|
||||||
autovacuum_vacuum_scale_factor = 0.05,
|
autovacuum_vacuum_scale_factor = 0.05,
|
||||||
autovacuum_analyze_scale_factor = 0.02
|
autovacuum_analyze_scale_factor = 0.02
|
||||||
@@ -564,22 +564,22 @@ ALTER TABLE orders SET (
|
|||||||
|
|
||||||
## JSONB 模式 (JSONB Patterns)
|
## JSONB 模式 (JSONB Patterns)
|
||||||
|
|
||||||
### 1. 为 JSONB 列建立索引
|
### 1. 为 JSONB 列创建索引
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
-- 为包含运算符建立 GIN 索引
|
-- 为包含运算符创建 GIN 索引
|
||||||
CREATE INDEX products_attrs_gin ON products USING gin (attributes);
|
CREATE INDEX products_attrs_gin ON products USING gin (attributes);
|
||||||
SELECT * FROM products WHERE attributes @> '{"color": "red"}';
|
SELECT * FROM products WHERE attributes @> '{"color": "red"}';
|
||||||
|
|
||||||
-- 为特定键建立表达式索引
|
-- 为特定键创建表达式索引
|
||||||
CREATE INDEX products_brand_idx ON products ((attributes->>'brand'));
|
CREATE INDEX products_brand_idx ON products ((attributes->>'brand'));
|
||||||
SELECT * FROM products WHERE attributes->>'brand' = 'Nike';
|
SELECT * FROM products WHERE attributes->>'brand' = 'Nike';
|
||||||
|
|
||||||
-- jsonb_path_ops:体积缩小 2-3 倍,仅支持 @> 运算符
|
-- jsonb_path_ops:体积减小 2-3 倍,但仅支持 @>
|
||||||
CREATE INDEX idx ON products USING gin (attributes jsonb_path_ops);
|
CREATE INDEX idx ON products USING gin (attributes jsonb_path_ops);
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. 使用 tsvector 进行全文检索
|
### 2. 使用 tsvector 进行全文检索 (Full-Text Search)
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
-- 添加生成的 tsvector 列
|
-- 添加生成的 tsvector 列
|
||||||
@@ -594,7 +594,7 @@ CREATE INDEX articles_search_idx ON articles USING gin (search_vector);
|
|||||||
SELECT * FROM articles
|
SELECT * FROM articles
|
||||||
WHERE search_vector @@ to_tsquery('english', 'postgresql & performance');
|
WHERE search_vector @@ to_tsquery('english', 'postgresql & performance');
|
||||||
|
|
||||||
-- 带权重排名
|
-- 带排名(Ranking)
|
||||||
SELECT *, ts_rank(search_vector, query) as rank
|
SELECT *, ts_rank(search_vector, query) as rank
|
||||||
FROM articles, to_tsquery('english', 'postgresql') query
|
FROM articles, to_tsquery('english', 'postgresql') query
|
||||||
WHERE search_vector @@ query
|
WHERE search_vector @@ query
|
||||||
@@ -603,52 +603,52 @@ ORDER BY rank DESC;
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 需要警示的反模式 (Anti-Patterns to Flag)
|
## 需要标记的反模式 (Anti-Patterns to Flag)
|
||||||
|
|
||||||
### ❌ 查询反模式
|
### ❌ 查询反模式
|
||||||
- 在生产环境代码中使用 `SELECT *`
|
- 生产代码中使用 `SELECT *`
|
||||||
- WHERE/JOIN 列缺失索引
|
- WHERE/JOIN 列缺失索引
|
||||||
- 在大表上使用 OFFSET 分页
|
- 大表上的 OFFSET 分页
|
||||||
- N+1 查询模式
|
- N+1 查询模式
|
||||||
- 未参数化的查询 (存在 SQL 注入风险)
|
- 未参数化的查询(存在 SQL 注入风险)
|
||||||
|
|
||||||
### ❌ 模式设计反模式
|
### ❌ 模式反模式
|
||||||
- ID 使用 `int` (应使用 `bigint`)
|
- ID 使用 `int`(应使用 `bigint`)
|
||||||
- 无理由地使用 `varchar(255)` (应使用 `text`)
|
- 无理由使用 `varchar(255)`(应使用 `text`)
|
||||||
- 不带时区的 `timestamp` (应使用 `timestamptz`)
|
- 时间戳不带时区(应使用 `timestamptz`)
|
||||||
- 使用随机 UUID 作为主键 (应使用 UUIDv7 或 IDENTITY)
|
- 使用随机 UUID 作为主键(应使用 UUIDv7 或 IDENTITY)
|
||||||
- 使用需要加引号的混合大小写标识符
|
- 混合大小写的标识符(强制要求引号)
|
||||||
|
|
||||||
### ❌ 安全性反模式
|
### ❌ 安全反模式
|
||||||
- 向应用用户授予 `GRANT ALL`
|
- 向应用用户授予 `GRANT ALL`
|
||||||
- 多租户表缺失 RLS
|
- 多租户表缺失 RLS
|
||||||
- RLS 策略每行调用函数 (未包装在 SELECT 中)
|
- RLS 策略每行调用函数(未包装在 SELECT 中)
|
||||||
- RLS 策略涉及的列未建索引
|
- 未索引的 RLS 策略涉及列
|
||||||
|
|
||||||
### ❌ 连接反模式
|
### ❌ 连接反模式
|
||||||
- 未使用连接池
|
- 没有连接池
|
||||||
- 未设置空闲超时
|
- 没有空闲超时
|
||||||
- 在事务模式连接池中使用预处理语句
|
- 在事务模式连接池中使用预处理语句
|
||||||
- 在调用外部 API 期间持有锁
|
- 在外部 API 调用期间持有锁
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 审查检查清单 (Review Checklist)
|
## 评审检查清单 (Review Checklist)
|
||||||
|
|
||||||
### 在批准数据库更改前:
|
### 在批准数据库更改之前:
|
||||||
- [ ] 所有 WHERE/JOIN 列都已建索引
|
- [ ] 所有 WHERE/JOIN 列已建立索引
|
||||||
- [ ] 复合索引的列顺序正确
|
- [ ] 复合索引中的列顺序正确
|
||||||
- [ ] 数据类型合适 (bigint, text, timestamptz, numeric)
|
- [ ] 数据类型正确(bigint, text, timestamptz, numeric)
|
||||||
- [ ] 多租户表已启用 RLS
|
- [ ] 多租户表已启用 RLS
|
||||||
- [ ] RLS 策略使用了 `(SELECT auth.uid())` 模式
|
- [ ] RLS 策略使用 `(SELECT auth.uid())` 模式
|
||||||
- [ ] 外键具有索引
|
- [ ] 外键已建立索引
|
||||||
- [ ] 无 N+1 查询模式
|
- [ ] 没有 N+1 查询模式
|
||||||
- [ ] 对复杂查询运行了 EXPLAIN ANALYZE
|
- [ ] 对复杂查询运行了 EXPLAIN ANALYZE
|
||||||
- [ ] 使用了小写标识符
|
- [ ] 使用了小写标识符
|
||||||
- [ ] 事务保持短小
|
- [ ] 保持事务短小
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**请记住**:数据库问题通常是应用程序性能问题的根源。请尽早优化查询和模式设计。使用 EXPLAIN ANALYZE 验证假设。务必为外键和 RLS 策略列建立索引。
|
**记住**:数据库问题通常是应用性能问题的根源。应尽早优化查询和模式设计。使用 EXPLAIN ANALYZE 验证假设。务必索引外键和 RLS 策略列。
|
||||||
|
|
||||||
*模式参考自 [Supabase Agent Skills](https://github.com/supabase/agent-skills),基于 MIT 许可。*
|
*模式改编自 [Supabase Agent Skills](https://github.com/supabase/agent-skills),遵循 MIT 许可。*
|
||||||
|
|||||||
424
docs/zh-TW/README.md
Normal file
424
docs/zh-TW/README.md
Normal file
@@ -0,0 +1,424 @@
|
|||||||
|
# Everything Claude Code
|
||||||
|
|
||||||
|
[](https://github.com/affaan-m/everything-claude-code/stargazers)
|
||||||
|
[](LICENSE)
|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
|
**来自 Anthropic 黑客松冠军的完整 Claude Code 配置集。**
|
||||||
|
|
||||||
|
经过 10 个月以上密集日常使用、打造真实产品所淬炼出的生产就绪智能体(Agents)、技能(Skills)、钩子(Hooks)、指令(Commands)、规则(Rules)和 MCP 配置。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 指南
|
||||||
|
|
||||||
|
本仓库仅包含原始代码。指南会解释所有内容。
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td width="50%">
|
||||||
|
<a href="https://x.com/affaanmustafa/status/2012378465664745795">
|
||||||
|
<img src="https://github.com/user-attachments/assets/1a471488-59cc-425b-8345-5245c7efbcef" alt="Everything Claude Code 简明指南" />
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td width="50%">
|
||||||
|
<a href="https://x.com/affaanmustafa/status/2014040193557471352">
|
||||||
|
<img src="https://github.com/user-attachments/assets/c9ca43bc-b149-427f-b551-af6840c368f0" alt="Everything Claude Code 完整指南" />
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center"><b>简明指南</b><br/>配置、基础、理念。<b>请先阅读此指南。</b></td>
|
||||||
|
<td align="center"><b>完整指南</b><br/>Token 优化、记忆持久化、评估、并行处理。</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
| 主题 | 学习内容 |
|
||||||
|
|------|----------|
|
||||||
|
| Token 优化 | 模型选择、系统提示精简、后台进程 |
|
||||||
|
| 记忆持久化 | 自动跨会话(Session)保存/加载上下文的钩子(Hooks) |
|
||||||
|
| 持续学习 | 从会话中自动提取模式并转化为可重用技能(Skills) |
|
||||||
|
| 验证循环 | 检查点 vs 持续评估、评分器类型、pass@k 指标 |
|
||||||
|
| 并行处理 | Git worktrees、串联方法、何时扩展实例 |
|
||||||
|
| 子智能体协调 | 上下文问题、渐进式检索模式 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 跨平台支持
|
||||||
|
|
||||||
|
此插件现已完整支持 **Windows、macOS 和 Linux**。所有钩子和脚本已使用 Node.js 重写以获得最佳兼容性。
|
||||||
|
|
||||||
|
### 包管理器检测
|
||||||
|
|
||||||
|
插件会自动检测您偏好的包管理器(npm、pnpm、yarn 或 bun),优先级如下:
|
||||||
|
|
||||||
|
1. **环境变量**:`CLAUDE_PACKAGE_MANAGER`
|
||||||
|
2. **项目配置**:`.claude/package-manager.json`
|
||||||
|
3. **package.json**:`packageManager` 字段
|
||||||
|
4. **锁文件**:从 package-lock.json、yarn.lock、pnpm-lock.yaml 或 bun.lockb 检测
|
||||||
|
5. **全局配置**:`~/.claude/package-manager.json`
|
||||||
|
6. **备选方案**:第一个可用的包管理器
|
||||||
|
|
||||||
|
设置您偏好的包管理器:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 通过环境变量
|
||||||
|
export CLAUDE_PACKAGE_MANAGER=pnpm
|
||||||
|
|
||||||
|
# 通过全局配置
|
||||||
|
node scripts/setup-package-manager.js --global pnpm
|
||||||
|
|
||||||
|
# 通过项目配置
|
||||||
|
node scripts/setup-package-manager.js --project bun
|
||||||
|
|
||||||
|
# 检测当前配置
|
||||||
|
node scripts/setup-package-manager.js --detect
|
||||||
|
```
|
||||||
|
|
||||||
|
或在 Claude Code 中使用 `/setup-pm` 指令。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 内容概览
|
||||||
|
|
||||||
|
本仓库是一个 **Claude Code 插件** - 可直接安装或手动复制组件。
|
||||||
|
|
||||||
|
```
|
||||||
|
everything-claude-code/
|
||||||
|
|-- .claude-plugin/ # 插件和市场清单
|
||||||
|
| |-- plugin.json # 插件元数据和组件路径
|
||||||
|
| |-- marketplace.json # 用于 /plugin marketplace add 的市场目录
|
||||||
|
|
|
||||||
|
|-- agents/ # 用于委派任务的专门子智能体(Agents)
|
||||||
|
| |-- planner.md # 功能实现规划
|
||||||
|
| |-- architect.md # 系统设计决策
|
||||||
|
| |-- tdd-guide.md # 测试驱动开发
|
||||||
|
| |-- code-reviewer.md # 质量与安全审查
|
||||||
|
| |-- security-reviewer.md # 漏洞分析
|
||||||
|
| |-- build-error-resolver.md
|
||||||
|
| |-- e2e-runner.md # Playwright E2E 测试
|
||||||
|
| |-- refactor-cleaner.md # 无用代码清理
|
||||||
|
| |-- doc-updater.md # 文档同步
|
||||||
|
| |-- go-reviewer.md # Go 代码审查(新增)
|
||||||
|
| |-- go-build-resolver.md # Go 构建错误解决(新增)
|
||||||
|
|
|
||||||
|
|-- skills/ # 工作流(Workflow)定义和领域知识
|
||||||
|
| |-- coding-standards/ # 编程语言最佳实践
|
||||||
|
| |-- backend-patterns/ # API、数据库、缓存模式
|
||||||
|
| |-- frontend-patterns/ # React、Next.js 模式
|
||||||
|
| |-- continuous-learning/ # 从会话中自动提取模式(完整指南)
|
||||||
|
| |-- continuous-learning-v2/ # 基于本能的学习与信心评分
|
||||||
|
| |-- iterative-retrieval/ # 子代理的渐进式上下文精炼
|
||||||
|
| |-- strategic-compact/ # 手动压缩建议(完整指南)
|
||||||
|
| |-- tdd-workflow/ # TDD 方法论
|
||||||
|
| |-- security-review/ # 安全性检查清单
|
||||||
|
| |-- eval-harness/ # 验证循环评估(完整指南)
|
||||||
|
| |-- verification-loop/ # 持续验证(完整指南)
|
||||||
|
| |-- golang-patterns/ # Go 惯用法和最佳实践(新增)
|
||||||
|
| |-- golang-testing/ # Go 测试模式、TDD、基准测试(新增)
|
||||||
|
|
|
||||||
|
|-- commands/ # 快速执行的斜杠指令(Commands)
|
||||||
|
| |-- tdd.md # /tdd - 测试驱动开发
|
||||||
|
| |-- plan.md # /plan - 实现规划
|
||||||
|
| |-- e2e.md # /e2e - E2E 测试生成
|
||||||
|
| |-- code-review.md # /code-review - 质量审查
|
||||||
|
| |-- build-fix.md # /build-fix - 修复构建错误
|
||||||
|
| |-- refactor-clean.md # /refactor-clean - 移除无用代码
|
||||||
|
| |-- learn.md # /learn - 会话中提取模式(完整指南)
|
||||||
|
| |-- checkpoint.md # /checkpoint - 保存验证状态(完整指南)
|
||||||
|
| |-- verify.md # /verify - 执行验证循环(完整指南)
|
||||||
|
| |-- setup-pm.md # /setup-pm - 设置包管理器
|
||||||
|
| |-- go-review.md # /go-review - Go 代码审查(新增)
|
||||||
|
| |-- go-test.md # /go-test - Go TDD 工作流(新增)
|
||||||
|
| |-- go-build.md # /go-build - 修复 Go 构建错误(新增)
|
||||||
|
|
|
||||||
|
|-- rules/ # 必须遵守的准则(Rules)(复制到 ~/.claude/rules/)
|
||||||
|
| |-- security.md # 强制性安全检查
|
||||||
|
| |-- coding-style.md # 不变性、文件组织
|
||||||
|
| |-- testing.md # TDD、80% 覆盖率要求
|
||||||
|
| |-- git-workflow.md # 提交格式、PR 流程
|
||||||
|
| |-- agents.md # 何时委派给子智能体
|
||||||
|
| |-- performance.md # 模型选择、上下文管理
|
||||||
|
|
|
||||||
|
|-- hooks/ # 基于触发器的自动化钩子(Hooks)
|
||||||
|
| |-- hooks.json # 所有钩子配置(PreToolUse、PostToolUse、Stop 等)
|
||||||
|
| |-- memory-persistence/ # 会话生命周期钩子(完整指南)
|
||||||
|
| |-- strategic-compact/ # 压缩建议(完整指南)
|
||||||
|
|
|
||||||
|
|-- scripts/ # 跨平台 Node.js 脚本(新增)
|
||||||
|
| |-- lib/ # 共享工具
|
||||||
|
| | |-- utils.js # 跨平台文件/路径/系统工具
|
||||||
|
| | |-- package-manager.js # 包管理器检测与选择
|
||||||
|
| |-- hooks/ # 钩子实现
|
||||||
|
| | |-- session-start.js # 会话开始时加载上下文
|
||||||
|
| | |-- session-end.js # 会话结束时保存状态
|
||||||
|
| | |-- pre-compact.js # 压缩前状态保存
|
||||||
|
| | |-- suggest-compact.js # 策略性压缩建议
|
||||||
|
| | |-- evaluate-session.js # 从会话中提取模式
|
||||||
|
| |-- setup-package-manager.js # 交互式包管理器设置
|
||||||
|
|
|
||||||
|
|-- tests/ # 测试套件(新增)
|
||||||
|
| |-- lib/ # 库测试
|
||||||
|
| |-- hooks/ # 钩子测试
|
||||||
|
| |-- run-all.js # 执行所有测试
|
||||||
|
|
|
||||||
|
|-- contexts/ # 动态系统提示词(Prompt)注入上下文(完整指南)
|
||||||
|
| |-- dev.md # 开发模式上下文
|
||||||
|
| |-- review.md # 代码审查模式上下文
|
||||||
|
| |-- research.md # 研究/探索模式上下文
|
||||||
|
|
|
||||||
|
|-- examples/ # 示例配置和会话
|
||||||
|
| |-- CLAUDE.md # 项目级配置示例
|
||||||
|
| |-- user-CLAUDE.md # 用户级配置示例
|
||||||
|
|
|
||||||
|
|-- mcp-configs/ # MCP 服务器配置
|
||||||
|
| |-- mcp-servers.json # GitHub、Supabase、Vercel、Railway 等
|
||||||
|
|
|
||||||
|
|-- marketplace.json # 自托管市场配置(用于 /plugin marketplace add)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 生态系统工具
|
||||||
|
|
||||||
|
### ecc.tools - 技能生成器
|
||||||
|
|
||||||
|
从您的仓库自动生成 Claude Code 技能(Skills)。
|
||||||
|
|
||||||
|
[安装 GitHub App](https://github.com/apps/skill-creator) | [ecc.tools](https://ecc.tools)
|
||||||
|
|
||||||
|
分析您的仓库并创建:
|
||||||
|
- **SKILL.md 文件** - 可直接用于 Claude Code 的技能
|
||||||
|
- **本能集合** - 用于 continuous-learning-v2
|
||||||
|
- **模式提取** - 从您的提交历史学习
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 安装 GitHub App 后,技能会出现在:
|
||||||
|
~/.claude/skills/generated/
|
||||||
|
```
|
||||||
|
|
||||||
|
与 `continuous-learning-v2` 技能无缝整合以继承本能。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 安装
|
||||||
|
|
||||||
|
### 选项 1:以插件(Plugin)安装(推荐)
|
||||||
|
|
||||||
|
使用本仓库最简单的方式 - 安装为 Claude Code 插件:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 将此仓库添加为市场
|
||||||
|
/plugin marketplace add affaan-m/everything-claude-code
|
||||||
|
|
||||||
|
# 安装插件
|
||||||
|
/plugin install everything-claude-code@everything-claude-code
|
||||||
|
```
|
||||||
|
|
||||||
|
或直接添加到您的 `~/.claude/settings.json`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"extraKnownMarketplaces": {
|
||||||
|
"everything-claude-code": {
|
||||||
|
"source": {
|
||||||
|
"source": "github",
|
||||||
|
"repo": "affaan-m/everything-claude-code"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"enabledPlugins": {
|
||||||
|
"everything-claude-code@everything-claude-code": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
这会让您立即访问所有指令、智能体、技能和钩子。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 选项 2:手动安装
|
||||||
|
|
||||||
|
如果您偏好手动控制安装内容:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 克隆仓库
|
||||||
|
git clone https://github.com/affaan-m/everything-claude-code.git
|
||||||
|
|
||||||
|
# 将智能体复制到您的 Claude 配置
|
||||||
|
cp everything-claude-code/agents/*.md ~/.claude/agents/
|
||||||
|
|
||||||
|
# 复制规则
|
||||||
|
cp everything-claude-code/rules/*.md ~/.claude/rules/
|
||||||
|
|
||||||
|
# 复制指令
|
||||||
|
cp everything-claude-code/commands/*.md ~/.claude/commands/
|
||||||
|
|
||||||
|
# 复制技能
|
||||||
|
cp -r everything-claude-code/skills/* ~/.claude/skills/
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 将钩子添加到 settings.json
|
||||||
|
|
||||||
|
将 `hooks/hooks.json` 中的钩子复制到您的 `~/.claude/settings.json`。
|
||||||
|
|
||||||
|
#### 配置 MCP
|
||||||
|
|
||||||
|
将 `mcp-configs/mcp-servers.json` 中所需的 MCP 服务器配置复制到您的 `~/.claude.json`。
|
||||||
|
|
||||||
|
**重要:** 将 `YOUR_*_HERE` 占位符替换为您实际的 API 密钥。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 核心概念
|
||||||
|
|
||||||
|
### 智能体(Agents)
|
||||||
|
|
||||||
|
子智能体以有限范围处理委派的任务。示例:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
---
|
||||||
|
name: code-reviewer
|
||||||
|
description: Reviews code for quality, security, and maintainability
|
||||||
|
tools: ["Read", "Grep", "Glob", "Bash"]
|
||||||
|
model: opus
|
||||||
|
---
|
||||||
|
|
||||||
|
You are a senior code reviewer...
|
||||||
|
```
|
||||||
|
|
||||||
|
### 技能(Skills)
|
||||||
|
|
||||||
|
技能是由指令或智能体调用的工作流定义:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# TDD Workflow
|
||||||
|
|
||||||
|
1. Define interfaces first
|
||||||
|
2. Write failing tests (RED)
|
||||||
|
3. Implement minimal code (GREEN)
|
||||||
|
4. Refactor (IMPROVE)
|
||||||
|
5. Verify 80%+ coverage
|
||||||
|
```
|
||||||
|
|
||||||
|
### 钩子(Hooks)
|
||||||
|
|
||||||
|
钩子在工具(Tool)事件时触发。示例 - 警告 console.log:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"matcher": "tool == \"Edit\" && tool_input.file_path matches \"\\.(ts|tsx|js|jsx)$\"",
|
||||||
|
"hooks": [{
|
||||||
|
"type": "command",
|
||||||
|
"command": "#!/bin/bash\ngrep -n 'console\\.log' \"$file_path\" && echo '[Hook] Remove console.log' >&2"
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 规则(Rules)
|
||||||
|
|
||||||
|
规则是必须遵守的准则。保持模块化:
|
||||||
|
|
||||||
|
```
|
||||||
|
~/.claude/rules/
|
||||||
|
security.md # 禁止硬编码密钥
|
||||||
|
coding-style.md # 不变性、文件组织
|
||||||
|
testing.md # TDD、80% 覆盖率要求
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 执行测试
|
||||||
|
|
||||||
|
插件包含完整的测试套件:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 执行所有测试
|
||||||
|
node tests/run-all.js
|
||||||
|
|
||||||
|
# 执行个别测试文件
|
||||||
|
node tests/lib/utils.test.js
|
||||||
|
node tests/lib/package-manager.test.js
|
||||||
|
node tests/hooks/hooks.test.js
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 贡献
|
||||||
|
|
||||||
|
**欢迎并鼓励贡献。**
|
||||||
|
|
||||||
|
本仓库旨在成为社区资源。如果您有:
|
||||||
|
- 实用的智能体或技能
|
||||||
|
- 巧妙的钩子
|
||||||
|
- 更好的 MCP 配置
|
||||||
|
- 改进的规则
|
||||||
|
|
||||||
|
请贡献!详见 [CONTRIBUTING.md](CONTRIBUTING.md) 的指南。
|
||||||
|
|
||||||
|
### 贡献想法
|
||||||
|
|
||||||
|
- 特定语言的技能(Python、Rust 模式)- Go 现已包含!
|
||||||
|
- 特定框架的配置(Django、Rails、Laravel)
|
||||||
|
- DevOps 智能体(Kubernetes、Terraform、AWS)
|
||||||
|
- 测试策略(不同框架)
|
||||||
|
- 特定领域知识(ML、数据工程、移动开发)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 背景
|
||||||
|
|
||||||
|
我从实验性推出就开始使用 Claude Code。2025 年 9 月与 [@DRodriguezFX](https://x.com/DRodriguezFX) 一起使用 Claude Code 打造 [zenith.chat](https://zenith.chat),赢得了 Anthropic x Forum Ventures 黑客松。
|
||||||
|
|
||||||
|
这些配置已在多个生产应用程序中经过实战测试。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 重要注意事项
|
||||||
|
|
||||||
|
### 上下文窗口管理
|
||||||
|
|
||||||
|
**关键:** 不要同时启用所有 MCP。启用过多工具会让您的 200k 上下文窗口缩减至 70k。
|
||||||
|
|
||||||
|
经验法则:
|
||||||
|
- 设置 20-30 个 MCP
|
||||||
|
- 每个项目启用少于 10 个
|
||||||
|
- 启用的工具少于 80 个
|
||||||
|
|
||||||
|
在项目配置中使用 `disabledMcpServers` 来禁用未使用的 MCP。
|
||||||
|
|
||||||
|
### 自定义
|
||||||
|
|
||||||
|
这些配置适合我的工作流。您应该:
|
||||||
|
1. 从您认同的部分开始
|
||||||
|
2. 根据您的技术栈修改
|
||||||
|
3. 移除不需要的部分
|
||||||
|
4. 添加您自己的模式
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Star 历史
|
||||||
|
|
||||||
|
[](https://star-history.com/#affaan-m/everything-claude-code&Date)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 链接
|
||||||
|
|
||||||
|
- **简明指南(从这里开始):** [Everything Claude Code 简明指南](https://x.com/affaanmustafa/status/2012378465664745795)
|
||||||
|
- **完整指南(进阶):** [Everything Claude Code 完整指南](https://x.com/affaanmustafa/status/2014040193557471352)
|
||||||
|
- **关注:** [@affaanmustafa](https://x.com/affaanmustafa)
|
||||||
|
- **zenith.chat:** [zenith.chat](https://zenith.chat)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 授权
|
||||||
|
|
||||||
|
MIT - 自由使用、依需求修改、如可能请回馈贡献。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**如果有帮助请为本仓库点赞(Star)。阅读两份指南。打造伟大的作品。**
|
||||||
@@ -105,7 +105,7 @@
|
|||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "node -e \"const{execSync}=require('child_process');const fs=require('fs');let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{const i=JSON.parse(d);const p=i.tool_input?.file_path;if(p&&fs.existsSync(p)){try{execSync('npx prettier --write \"'+p+'\"',{stdio:['pipe','pipe','pipe']})}catch(e){}}console.log(d)})\""
|
"command": "node -e \"const{execFileSync}=require('child_process');const fs=require('fs');let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{const i=JSON.parse(d);const p=i.tool_input?.file_path;if(p&&fs.existsSync(p)){try{execFileSync('npx',['prettier','--write',p],{stdio:['pipe','pipe','pipe']})}catch(e){}}console.log(d)})\""
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Auto-format JS/TS files with Prettier after edits"
|
"description": "Auto-format JS/TS files with Prettier after edits"
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ process.stdin.on('end', () => {
|
|||||||
if (hasConsole) {
|
if (hasConsole) {
|
||||||
console.error('[Hook] Remove console.log statements before committing');
|
console.error('[Hook] Remove console.log statements before committing');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (_error) {
|
||||||
// Silently ignore errors (git might not be available, etc.)
|
// Silently ignore errors (git might not be available, etc.)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ const {
|
|||||||
getTimeString,
|
getTimeString,
|
||||||
getSessionIdShort,
|
getSessionIdShort,
|
||||||
ensureDir,
|
ensureDir,
|
||||||
readFile,
|
|
||||||
writeFile,
|
writeFile,
|
||||||
replaceInFile,
|
replaceInFile,
|
||||||
log
|
log
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
* files and notifies Claude of available context to load.
|
* files and notifies Claude of available context to load.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const path = require('path');
|
|
||||||
const {
|
const {
|
||||||
getSessionsDir,
|
getSessionsDir,
|
||||||
getLearnedSkillsDir,
|
getLearnedSkillsDir,
|
||||||
|
|||||||
@@ -14,7 +14,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const fs = require('fs');
|
|
||||||
const {
|
const {
|
||||||
getTempDir,
|
getTempDir,
|
||||||
readFile,
|
readFile,
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const { commandExists, getClaudeDir, readFile, writeFile, log, runCommand } = require('./utils');
|
const { commandExists, getClaudeDir, readFile, writeFile } = require('./utils');
|
||||||
|
|
||||||
// Package manager definitions
|
// Package manager definitions
|
||||||
const PACKAGE_MANAGERS = {
|
const PACKAGE_MANAGERS = {
|
||||||
|
|||||||
@@ -79,18 +79,35 @@ function getTimeString() {
|
|||||||
return `${hours}:${minutes}`;
|
return `${hours}:${minutes}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the git repository name
|
||||||
|
*/
|
||||||
|
function getGitRepoName() {
|
||||||
|
const result = runCommand('git rev-parse --show-toplevel');
|
||||||
|
if (!result.success) return null;
|
||||||
|
return path.basename(result.output);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get project name from git repo or current directory
|
||||||
|
*/
|
||||||
|
function getProjectName() {
|
||||||
|
const repoName = getGitRepoName();
|
||||||
|
if (repoName) return repoName;
|
||||||
|
return path.basename(process.cwd()) || null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get short session ID from CLAUDE_SESSION_ID environment variable
|
* Get short session ID from CLAUDE_SESSION_ID environment variable
|
||||||
* Returns the last 8 characters for uniqueness with brevity
|
* Returns last 8 characters, falls back to project name then 'default'
|
||||||
* @param {string} fallback - Fallback value if no session ID (default: 'default')
|
|
||||||
*/
|
*/
|
||||||
function getSessionIdShort(fallback = 'default') {
|
function getSessionIdShort(fallback = 'default') {
|
||||||
const sessionId = process.env.CLAUDE_SESSION_ID;
|
const sessionId = process.env.CLAUDE_SESSION_ID;
|
||||||
if (!sessionId || sessionId.length === 0) {
|
if (sessionId && sessionId.length > 0) {
|
||||||
return fallback;
|
|
||||||
}
|
|
||||||
return sessionId.slice(-8);
|
return sessionId.slice(-8);
|
||||||
}
|
}
|
||||||
|
return getProjectName() || fallback;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get current datetime in YYYY-MM-DD HH:MM:SS format
|
* Get current datetime in YYYY-MM-DD HH:MM:SS format
|
||||||
@@ -148,7 +165,7 @@ function findFiles(dir, pattern, options = {}) {
|
|||||||
searchDir(fullPath);
|
searchDir(fullPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (_err) {
|
||||||
// Ignore permission errors
|
// Ignore permission errors
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -373,7 +390,11 @@ module.exports = {
|
|||||||
getDateString,
|
getDateString,
|
||||||
getTimeString,
|
getTimeString,
|
||||||
getDateTimeString,
|
getDateTimeString,
|
||||||
|
|
||||||
|
// Session/Project
|
||||||
getSessionIdShort,
|
getSessionIdShort,
|
||||||
|
getGitRepoName,
|
||||||
|
getProjectName,
|
||||||
|
|
||||||
// File operations
|
// File operations
|
||||||
findFiles,
|
findFiles,
|
||||||
|
|||||||
@@ -19,10 +19,8 @@ const {
|
|||||||
setProjectPackageManager,
|
setProjectPackageManager,
|
||||||
getAvailablePackageManagers,
|
getAvailablePackageManagers,
|
||||||
detectFromLockFile,
|
detectFromLockFile,
|
||||||
detectFromPackageJson,
|
detectFromPackageJson
|
||||||
getSelectionPrompt
|
|
||||||
} = require('./lib/package-manager');
|
} = require('./lib/package-manager');
|
||||||
const { log } = require('./lib/utils');
|
|
||||||
|
|
||||||
function showHelp() {
|
function showHelp() {
|
||||||
console.log(`
|
console.log(`
|
||||||
|
|||||||
@@ -1,27 +1,27 @@
|
|||||||
---
|
---
|
||||||
name: continuous-learning-v2
|
name: continuous-learning-v2
|
||||||
description: 基于直觉的学习系统,通过钩子(hooks)观察会话,创建带有置信度评分的原子直觉(atomic instincts),并将其演化为技能/命令/智能体。
|
description: 基于直觉(Instinct)的学习系统,通过钩子(Hooks)观测会话,创建带有置信度评分(Confidence Scoring)的原子直觉,并将其演进为技能(Skills)、命令(Commands)或智能体(Agents)。
|
||||||
version: 2.0.0
|
version: 2.0.0
|
||||||
---
|
---
|
||||||
|
|
||||||
# 持续学习 v2 - 基于直觉的架构 (Instinct-Based Architecture)
|
# 持续学习 v2 - 基于直觉的架构(Instinct-Based Architecture)
|
||||||
|
|
||||||
一个高级学习系统,通过原子“直觉(instincts)”——带有置信度评分的小型习得行为,将你的 Claude Code 会话转化为可复用的知识。
|
这是一个先进的学习系统,通过原子化“直觉(Instincts)”——即带有置信度评分的小型习得行为,将你的 Claude Code 会话转化为可复用的知识。
|
||||||
|
|
||||||
## v2 版本新特性
|
## v2 版本新特性
|
||||||
|
|
||||||
| 特性 | v1 | v2 |
|
| 特性 | v1 | v2 |
|
||||||
|---------|----|----|
|
|---------|----|----|
|
||||||
| 观察 (Observation) | Stop 钩子(会话结束) | PreToolUse/PostToolUse (100% 可靠) |
|
| 观测(Observation) | Stop 钩子(会话结束时) | PreToolUse/PostToolUse (100% 可靠) |
|
||||||
| 分析 (Analysis) | 主上下文 (Main context) | 后台智能体 (Haiku) |
|
| 分析(Analysis) | 主上下文(Main context) | 后台智能体 (Haiku) |
|
||||||
| 粒度 (Granularity) | 完整技能 (Full skills) | 原子“直觉(instincts)” |
|
| 粒度(Granularity) | 完整技能(Full skills) | 原子化“直觉(Instincts)” |
|
||||||
| 置信度 (Confidence) | 无 | 0.3-0.9 加权 |
|
| 置信度(Confidence) | 无 | 0.3-0.9 加权评分 |
|
||||||
| 演化 (Evolution) | 直接转换为技能 | 直觉 → 聚类 → 技能/命令/智能体 |
|
| 演进(Evolution) | 直接转化为技能 | 直觉 → 聚类 → 技能/命令/智能体 |
|
||||||
| 共享 (Sharing) | 无 | 导出/导入直觉 |
|
| 共享(Sharing) | 无 | 导出/导入直觉 |
|
||||||
|
|
||||||
## 直觉模型 (The Instinct Model)
|
## 直觉模型(The Instinct Model)
|
||||||
|
|
||||||
“直觉(instinct)”是一个小型的习得行为:
|
直觉(Instinct)是一种小型习得行为:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
---
|
---
|
||||||
@@ -32,40 +32,40 @@ domain: "code-style"
|
|||||||
source: "session-observation"
|
source: "session-observation"
|
||||||
---
|
---
|
||||||
|
|
||||||
# 偏好函数式风格 (Prefer Functional Style)
|
# 偏好函数式风格(Prefer Functional Style)
|
||||||
|
|
||||||
## 操作 (Action)
|
## 动作(Action)
|
||||||
在合适的时候,优先使用函数式模式而非类(class)。
|
在合适的情况下,优先使用函数式模式(Functional Patterns)而非类(Classes)。
|
||||||
|
|
||||||
## 证据 (Evidence)
|
## 证据(Evidence)
|
||||||
- 观察到 5 次偏好函数式模式的实例
|
- 观测到 5 次函数式模式偏好实例
|
||||||
- 用户在 2025-01-15 将基于类的方法修正为函数式
|
- 用户在 2025-01-15 将基于类的方法修正为函数式方法
|
||||||
```
|
```
|
||||||
|
|
||||||
**属性:**
|
**属性:**
|
||||||
- **原子性 (Atomic)** — 一个触发器,一个动作
|
- **原子化(Atomic)** — 一个触发器对应一个动作
|
||||||
- **置信度加权 (Confidence-weighted)** — 0.3 = 尝试性的,0.9 = 近乎确定
|
- **置信度加权(Confidence-weighted)** — 0.3 = 尝试性的,0.9 = 近乎确定
|
||||||
- **领域标签 (Domain-tagged)** — code-style、testing、git、debugging、workflow 等
|
- **领域标签(Domain-tagged)** — 代码风格(code-style)、测试(testing)、git、调试(debugging)、工作流(workflow)等
|
||||||
- **证据支持 (Evidence-backed)** — 追踪是哪些观察结果创建了它
|
- **证据支持(Evidence-backed)** — 追踪是哪些观测结果创建了它
|
||||||
|
|
||||||
## 工作原理
|
## 工作原理
|
||||||
|
|
||||||
```
|
```
|
||||||
会话活动 (Session Activity)
|
会话活动(Session Activity)
|
||||||
│
|
│
|
||||||
│ 钩子捕获提示词 + 工具使用 (100% 可靠)
|
│ 钩子(Hooks)捕获提示词 + 工具使用 (100% 可靠)
|
||||||
▼
|
▼
|
||||||
┌─────────────────────────────────────────┐
|
┌─────────────────────────────────────────┐
|
||||||
│ observations.jsonl │
|
│ observations.jsonl │
|
||||||
│ (提示词, 工具调用, 结果) │
|
│ (提示词、工具调用、执行结果) │
|
||||||
└─────────────────────────────────────────┘
|
└─────────────────────────────────────────┘
|
||||||
│
|
│
|
||||||
│ 观察者智能体读取 (后台运行, Haiku)
|
│ 观测者智能体读取 (后台运行, Haiku)
|
||||||
▼
|
▼
|
||||||
┌─────────────────────────────────────────┐
|
┌─────────────────────────────────────────┐
|
||||||
│ 模式检测 (PATTERN DETECTION) │
|
│ 模式检测(PATTERN DETECTION) │
|
||||||
│ • 用户修正 → 直觉 │
|
│ • 用户修正 → 直觉 │
|
||||||
│ • 错误修复 → 直觉 │
|
│ • 错误解决 → 直觉 │
|
||||||
│ • 重复工作流 → 直觉 │
|
│ • 重复工作流 → 直觉 │
|
||||||
└─────────────────────────────────────────┘
|
└─────────────────────────────────────────┘
|
||||||
│
|
│
|
||||||
@@ -88,11 +88,36 @@ source: "session-observation"
|
|||||||
└─────────────────────────────────────────┘
|
└─────────────────────────────────────────┘
|
||||||
```
|
```
|
||||||
|
|
||||||
## 快速开始
|
## 快速入门
|
||||||
|
|
||||||
### 1. 启用观察钩子 (Observation Hooks)
|
### 1. 启用观测钩子(Observation Hooks)
|
||||||
|
|
||||||
添加到你的 `~/.claude/settings.json`:
|
将以下内容添加到你的 `~/.claude/settings.json` 中。
|
||||||
|
|
||||||
|
**如果作为插件安装**(推荐):
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"hooks": {
|
||||||
|
"PreToolUse": [{
|
||||||
|
"matcher": "*",
|
||||||
|
"hooks": [{
|
||||||
|
"type": "command",
|
||||||
|
"command": "${CLAUDE_PLUGIN_ROOT}/skills/continuous-learning-v2/hooks/observe.sh pre"
|
||||||
|
}]
|
||||||
|
}],
|
||||||
|
"PostToolUse": [{
|
||||||
|
"matcher": "*",
|
||||||
|
"hooks": [{
|
||||||
|
"type": "command",
|
||||||
|
"command": "${CLAUDE_PLUGIN_ROOT}/skills/continuous-learning-v2/hooks/observe.sh post"
|
||||||
|
}]
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**如果手动安装**到 `~/.claude/skills`:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -117,30 +142,32 @@ source: "session-observation"
|
|||||||
|
|
||||||
### 2. 初始化目录结构
|
### 2. 初始化目录结构
|
||||||
|
|
||||||
|
Python CLI 会自动创建这些目录,但你也可以手动创建:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mkdir -p ~/.claude/homunculus/{instincts/{personal,inherited},evolved/{agents,skills,commands}}
|
mkdir -p ~/.claude/homunculus/{instincts/{personal,inherited},evolved/{agents,skills,commands}}
|
||||||
touch ~/.claude/homunculus/observations.jsonl
|
touch ~/.claude/homunculus/observations.jsonl
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3. 运行观察者智能体 (可选)
|
### 3. 使用直觉命令
|
||||||
|
|
||||||
观察者可以在后台运行,分析观察结果:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 启动后台观察者
|
/instinct-status # 显示已习得的直觉及其置信度评分
|
||||||
~/.claude/skills/continuous-learning-v2/agents/start-observer.sh
|
/evolve # 将相关的直觉聚类为技能/命令
|
||||||
|
/instinct-export # 导出直觉以便分享
|
||||||
|
/instinct-import # 从他人处导入直觉
|
||||||
```
|
```
|
||||||
|
|
||||||
## 命令
|
## 命令(Commands)
|
||||||
|
|
||||||
| 命令 | 描述 |
|
| 命令 | 描述 |
|
||||||
|---------|-------------|
|
|---------|-------------|
|
||||||
| `/instinct-status` | 显示所有习得的直觉及其置信度 |
|
| `/instinct-status` | 显示所有已习得的直觉及置信度 |
|
||||||
| `/evolve` | 将相关的直觉聚类为技能/命令 |
|
| `/evolve` | 将相关的直觉聚类为技能/命令 |
|
||||||
| `/instinct-export` | 导出直觉以便共享 |
|
| `/instinct-export` | 导出直觉以便分享 |
|
||||||
| `/instinct-import <file>` | 从他人处导入直觉 |
|
| `/instinct-import <file>` | 从他人处导入直觉 |
|
||||||
|
|
||||||
## 配置
|
## 配置(Configuration)
|
||||||
|
|
||||||
编辑 `config.json`:
|
编辑 `config.json`:
|
||||||
|
|
||||||
@@ -183,8 +210,8 @@ touch ~/.claude/homunculus/observations.jsonl
|
|||||||
```
|
```
|
||||||
~/.claude/homunculus/
|
~/.claude/homunculus/
|
||||||
├── identity.json # 你的个人资料、技术水平
|
├── identity.json # 你的个人资料、技术水平
|
||||||
├── observations.jsonl # 当前会话观察结果
|
├── observations.jsonl # 当前会话观测结果
|
||||||
├── observations.archive/ # 已处理的观察结果
|
├── observations.archive/ # 已处理的观测结果
|
||||||
├── instincts/
|
├── instincts/
|
||||||
│ ├── personal/ # 自动习得的直觉
|
│ ├── personal/ # 自动习得的直觉
|
||||||
│ └── inherited/ # 从他人处导入的直觉
|
│ └── inherited/ # 从他人处导入的直觉
|
||||||
@@ -194,64 +221,64 @@ touch ~/.claude/homunculus/observations.jsonl
|
|||||||
└── commands/ # 生成的命令
|
└── commands/ # 生成的命令
|
||||||
```
|
```
|
||||||
|
|
||||||
## 与技能创建器 (Skill Creator) 集成
|
## 与 Skill Creator 集成
|
||||||
|
|
||||||
当你使用 [Skill Creator GitHub App](https://skill-creator.app) 时,它现在会**同时**生成:
|
当你使用 [Skill Creator GitHub App](https://skill-creator.app) 时,它现在会**同时**生成:
|
||||||
- 传统的 SKILL.md 文件(为了向后兼容)
|
- 传统的 SKILL.md 文件(用于向下兼容)
|
||||||
- 直觉集合 (Instinct collections)(为了 v2 学习系统)
|
- 直觉集合(用于 v2 学习系统)
|
||||||
|
|
||||||
来自仓库分析的直觉带有 `source: "repo-analysis"` 标签,并包含源仓库的 URL。
|
来自仓库分析的直觉具有 `source: "repo-analysis"` 属性,并包含源仓库 URL。
|
||||||
|
|
||||||
## 置信度评分 (Confidence Scoring)
|
## 置信度评分(Confidence Scoring)
|
||||||
|
|
||||||
置信度会随时间演化:
|
置信度随时间演进:
|
||||||
|
|
||||||
| 分数 | 含义 | 行为 |
|
| 分数 | 含义 | 行为 |
|
||||||
|-------|---------|----------|
|
|-------|---------|----------|
|
||||||
| 0.3 | 尝试性 (Tentative) | 建议但不强制执行 |
|
| 0.3 | 尝试性的(Tentative) | 建议但不强制执行 |
|
||||||
| 0.5 | 中等 (Moderate) | 在相关时应用 |
|
| 0.5 | 中等(Moderate) | 在相关时应用 |
|
||||||
| 0.7 | 强 (Strong) | 自动批准应用 |
|
| 0.7 | 强(Strong) | 自动批准应用 |
|
||||||
| 0.9 | 近乎确定 (Near-certain) | 核心行为 |
|
| 0.9 | 近乎确定(Near-certain) | 核心行为 |
|
||||||
|
|
||||||
**置信度增加**的情况:
|
**置信度增加**的情况:
|
||||||
- 模式被重复观察到
|
- 模式被重复观测到
|
||||||
- 用户没有修正建议的行为
|
- 用户没有修正建议的行为
|
||||||
- 来自其他来源的类似直觉达成一致
|
- 来自其他来源的类似直觉达成一致
|
||||||
|
|
||||||
**置信度降低**的情况:
|
**置信度降低**的情况:
|
||||||
- 用户明确修正了该行为
|
- 用户明确修正了该行为
|
||||||
- 模式在很长一段时间内没有被观察到
|
- 模式长时间未被观测到
|
||||||
- 出现矛盾的证据
|
- 出现矛盾的证据
|
||||||
|
|
||||||
## 为什么使用钩子 (Hooks) 而非技能 (Skills) 进行观察?
|
## 为什么使用钩子(Hooks)而非技能(Skills)进行观测?
|
||||||
|
|
||||||
> “v1 依赖技能进行观察。技能是概率性的——根据 Claude 的判断,它们的触发率约为 50-80%。”
|
> "v1 依赖技能进行观测。技能具有概率性——根据 Claude 的判断,其触发率约为 50-80%。"
|
||||||
|
|
||||||
钩子(Hooks)的触发是 **100% 确定性**的。这意味着:
|
钩子(Hooks)的触发是 **100% 确定性的**。这意味着:
|
||||||
- 每一个工具调用都会被观察到
|
- 每一个工具调用都会被观测到
|
||||||
- 不会遗漏任何模式
|
- 不会遗漏任何模式
|
||||||
- 学习是全面的
|
- 学习是全面的
|
||||||
|
|
||||||
## 向后兼容性
|
## 向下兼容性
|
||||||
|
|
||||||
v2 完全兼容 v1:
|
v2 完全兼容 v1:
|
||||||
- 现有的 `~/.claude/skills/learned/` 技能仍然有效
|
- 现有的 `~/.claude/skills/learned/` 技能仍然有效
|
||||||
- Stop 钩子仍然运行(但现在也会输入到 v2 系统中)
|
- Stop 钩子仍然运行(但现在也会为 v2 提供输入)
|
||||||
- 渐进式迁移路径:并行运行两者
|
- 渐进式迁移路径:两者并行运行
|
||||||
|
|
||||||
## 隐私
|
## 隐私(Privacy)
|
||||||
|
|
||||||
- 观察结果保存在你的本地机器上
|
- 观测结果保存在你本地机器上
|
||||||
- 只有 **直觉(instincts)**(即模式)可以被导出
|
- 只有**直觉**(模式)可以被导出
|
||||||
- 不会共享实际的代码或对话内容
|
- 不会分享实际的代码或对话内容
|
||||||
- 你可以控制哪些内容被导出
|
- 你可以控制导出的内容
|
||||||
|
|
||||||
## 相关链接
|
## 相关链接
|
||||||
|
|
||||||
- [Skill Creator](https://skill-creator.app) - 从仓库历史生成直觉
|
- [Skill Creator](https://skill-creator.app) - 从仓库历史生成直觉
|
||||||
- [Homunculus](https://github.com/humanplane/homunculus) - v2 架构的灵感来源
|
- [Homunculus](https://github.com/humanplane/homunculus) - v2 架构的灵感来源
|
||||||
- [The Longform Guide](https://x.com/affaanmustafa/status/2014040193557471352) - 持续学习章节
|
- [长篇指南(The Longform Guide)](https://x.com/affaanmustafa/status/2014040193557471352) - 持续学习章节
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
*基于直觉的学习:通过一次又一次的观察,教会 Claude 你的模式。*
|
*基于直觉的学习:通过每一次观测,教会 Claude 你的模式。*
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
---
|
---
|
||||||
name: evolve
|
name: evolve
|
||||||
description: 将相关本能(Instincts)聚类为技能、命令或智能体
|
description: 将相关本能 (Instincts) 聚类为技能 (Skills)、命令 (Commands) 或智能体 (Agents)
|
||||||
command: /evolve
|
command: /evolve
|
||||||
implementation: python3 ~/.claude/skills/continuous-learning-v2/scripts/instinct-cli.py evolve
|
implementation: python3 ~/.claude/skills/continuous-learning-v2/scripts/instinct-cli.py evolve
|
||||||
---
|
---
|
||||||
|
|
||||||
# 演进(Evolve)命令
|
# 演进 (Evolve) 命令
|
||||||
|
|
||||||
## 实现
|
## 实现
|
||||||
|
|
||||||
@@ -13,23 +13,23 @@ implementation: python3 ~/.claude/skills/continuous-learning-v2/scripts/instinct
|
|||||||
python3 ~/.claude/skills/continuous-learning-v2/scripts/instinct-cli.py evolve [--generate]
|
python3 ~/.claude/skills/continuous-learning-v2/scripts/instinct-cli.py evolve [--generate]
|
||||||
```
|
```
|
||||||
|
|
||||||
分析本能(Instincts)并将相关的本能聚类为更高级别的结构:
|
分析本能 (Instincts) 并将相关的本能聚类为更高级别的结构:
|
||||||
- **命令(Commands)**:当本能描述的是用户调用的操作时
|
- **命令 (Commands)**:当本能描述的是用户调用的操作时
|
||||||
- **技能(Skills)**:当本能描述的是自动触发的行为时
|
- **技能 (Skills)**:当本能描述的是自动触发的行为时
|
||||||
- **智能体(Agents)**:当本能描述的是复杂的、多步骤的过程时
|
- **智能体 (Agents)**:当本能描述的是复杂的、多步骤的过程时
|
||||||
|
|
||||||
## 用法
|
## 用法
|
||||||
|
|
||||||
```
|
```
|
||||||
/evolve # 分析所有本能并建议演进方案
|
/evolve # 分析所有本能并建议演进方案
|
||||||
/evolve --domain testing # 仅演进测试领域(testing domain)中的本能
|
/evolve --domain testing # 仅演进测试领域 (testing domain) 中的本能
|
||||||
/evolve --dry-run # 显示将要创建的内容而不实际执行
|
/evolve --dry-run # 显示将要创建的内容而不实际执行
|
||||||
/evolve --threshold 5 # 要求 5 个或更多相关本能才进行聚类
|
/evolve --threshold 5 # 要求 5 个或更多相关本能才进行聚类
|
||||||
```
|
```
|
||||||
|
|
||||||
## 演进规则
|
## 演进规则
|
||||||
|
|
||||||
### → 命令(Command,用户调用)
|
### → 命令 (Command,用户调用)
|
||||||
当本能描述用户会显式请求的操作时:
|
当本能描述用户会显式请求的操作时:
|
||||||
- 多个关于“当用户要求...”的本能
|
- 多个关于“当用户要求...”的本能
|
||||||
- 带有“在创建新的 X 时”等触发器的本能
|
- 带有“在创建新的 X 时”等触发器的本能
|
||||||
@@ -42,7 +42,7 @@ python3 ~/.claude/skills/continuous-learning-v2/scripts/instinct-cli.py evolve [
|
|||||||
|
|
||||||
→ 创建:`/new-table` 命令
|
→ 创建:`/new-table` 命令
|
||||||
|
|
||||||
### → 技能(Skill,自动触发)
|
### → 技能 (Skill,自动触发)
|
||||||
当本能描述应该自动发生的行为时:
|
当本能描述应该自动发生的行为时:
|
||||||
- 模式匹配触发器
|
- 模式匹配触发器
|
||||||
- 错误处理响应
|
- 错误处理响应
|
||||||
@@ -55,9 +55,9 @@ python3 ~/.claude/skills/continuous-learning-v2/scripts/instinct-cli.py evolve [
|
|||||||
|
|
||||||
→ 创建:`functional-patterns` 技能
|
→ 创建:`functional-patterns` 技能
|
||||||
|
|
||||||
### → 智能体(Agent,需要深度/隔离)
|
### → 智能体 (Agent,需要深度/隔离)
|
||||||
当本能描述受益于隔离的复杂、多步骤过程时:
|
当本能描述受益于隔离的复杂、多步骤过程时:
|
||||||
- 调试工作流(Workflow)
|
- 调试工作流 (Workflow)
|
||||||
- 重构序列
|
- 重构序列
|
||||||
- 研究任务
|
- 研究任务
|
||||||
|
|
||||||
@@ -85,7 +85,7 @@ python3 ~/.claude/skills/continuous-learning-v2/scripts/instinct-cli.py evolve [
|
|||||||
## 输出格式
|
## 输出格式
|
||||||
|
|
||||||
```
|
```
|
||||||
🧬 演进分析(Evolve Analysis)
|
🧬 演进分析 (Evolve Analysis)
|
||||||
==================
|
==================
|
||||||
|
|
||||||
发现 3 个已准备好演进的聚类:
|
发现 3 个已准备好演进的聚类:
|
||||||
@@ -121,7 +121,7 @@ python3 ~/.claude/skills/continuous-learning-v2/scripts/instinct-cli.py evolve [
|
|||||||
运行 `/evolve --execute` 来创建这些文件。
|
运行 `/evolve --execute` 来创建这些文件。
|
||||||
```
|
```
|
||||||
|
|
||||||
## 标志(Flags)
|
## 标志 (Flags)
|
||||||
|
|
||||||
- `--execute`:实际创建演进后的结构(默认为预览)
|
- `--execute`:实际创建演进后的结构(默认为预览)
|
||||||
- `--dry-run`:预览而不创建
|
- `--dry-run`:预览而不创建
|
||||||
|
|||||||
@@ -5,15 +5,31 @@
|
|||||||
# Claude Code passes hook data via stdin as JSON.
|
# Claude Code passes hook data via stdin as JSON.
|
||||||
#
|
#
|
||||||
# Hook config (in ~/.claude/settings.json):
|
# Hook config (in ~/.claude/settings.json):
|
||||||
|
#
|
||||||
|
# If installed as a plugin, use ${CLAUDE_PLUGIN_ROOT}:
|
||||||
# {
|
# {
|
||||||
# "hooks": {
|
# "hooks": {
|
||||||
# "PreToolUse": [{
|
# "PreToolUse": [{
|
||||||
# "matcher": "*",
|
# "matcher": "*",
|
||||||
# "hooks": [{ "type": "command", "command": "~/.claude/skills/continuous-learning-v2/hooks/observe.sh" }]
|
# "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/skills/continuous-learning-v2/hooks/observe.sh pre" }]
|
||||||
# }],
|
# }],
|
||||||
# "PostToolUse": [{
|
# "PostToolUse": [{
|
||||||
# "matcher": "*",
|
# "matcher": "*",
|
||||||
# "hooks": [{ "type": "command", "command": "~/.claude/skills/continuous-learning-v2/hooks/observe.sh" }]
|
# "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/skills/continuous-learning-v2/hooks/observe.sh post" }]
|
||||||
|
# }]
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# If installed manually to ~/.claude/skills:
|
||||||
|
# {
|
||||||
|
# "hooks": {
|
||||||
|
# "PreToolUse": [{
|
||||||
|
# "matcher": "*",
|
||||||
|
# "hooks": [{ "type": "command", "command": "~/.claude/skills/continuous-learning-v2/hooks/observe.sh pre" }]
|
||||||
|
# }],
|
||||||
|
# "PostToolUse": [{
|
||||||
|
# "matcher": "*",
|
||||||
|
# "hooks": [{ "type": "command", "command": "~/.claude/skills/continuous-learning-v2/hooks/observe.sh post" }]
|
||||||
# }]
|
# }]
|
||||||
# }
|
# }
|
||||||
# }
|
# }
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ const assert = require('assert');
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const os = require('os');
|
const os = require('os');
|
||||||
const { execSync, spawn } = require('child_process');
|
const { spawn } = require('child_process');
|
||||||
|
|
||||||
// Test helper
|
// Test helper
|
||||||
function test(name, fn) {
|
function test(name, fn) {
|
||||||
@@ -113,14 +113,19 @@ async function runTests() {
|
|||||||
// Run the script
|
// Run the script
|
||||||
await runScript(path.join(scriptsDir, 'session-end.js'));
|
await runScript(path.join(scriptsDir, 'session-end.js'));
|
||||||
|
|
||||||
// Check if session file was created (default session ID)
|
// Check if session file was created
|
||||||
|
// Note: Without CLAUDE_SESSION_ID, falls back to project name (not 'default')
|
||||||
// Use local time to match the script's getDateString() function
|
// Use local time to match the script's getDateString() function
|
||||||
const sessionsDir = path.join(os.homedir(), '.claude', 'sessions');
|
const sessionsDir = path.join(os.homedir(), '.claude', 'sessions');
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
const today = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}`;
|
const today = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}`;
|
||||||
const sessionFile = path.join(sessionsDir, `${today}-default-session.tmp`);
|
|
||||||
|
|
||||||
assert.ok(fs.existsSync(sessionFile), 'Session file should exist');
|
// Get the expected session ID (project name fallback)
|
||||||
|
const utils = require('../../scripts/lib/utils');
|
||||||
|
const expectedId = utils.getSessionIdShort();
|
||||||
|
const sessionFile = path.join(sessionsDir, `${today}-${expectedId}-session.tmp`);
|
||||||
|
|
||||||
|
assert.ok(fs.existsSync(sessionFile), `Session file should exist: ${sessionFile}`);
|
||||||
})) passed++; else failed++;
|
})) passed++; else failed++;
|
||||||
|
|
||||||
if (await asyncTest('includes session ID in filename', async () => {
|
if (await asyncTest('includes session ID in filename', async () => {
|
||||||
@@ -296,7 +301,7 @@ async function runTests() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const [eventType, hookArray] of Object.entries(hooks.hooks)) {
|
for (const [, hookArray] of Object.entries(hooks.hooks)) {
|
||||||
checkHooks(hookArray);
|
checkHooks(hookArray);
|
||||||
}
|
}
|
||||||
})) passed++; else failed++;
|
})) passed++; else failed++;
|
||||||
@@ -320,11 +325,27 @@ async function runTests() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const [eventType, hookArray] of Object.entries(hooks.hooks)) {
|
for (const [, hookArray] of Object.entries(hooks.hooks)) {
|
||||||
checkHooks(hookArray);
|
checkHooks(hookArray);
|
||||||
}
|
}
|
||||||
})) passed++; else failed++;
|
})) passed++; else failed++;
|
||||||
|
|
||||||
|
// plugin.json validation
|
||||||
|
console.log('\nplugin.json Validation:');
|
||||||
|
|
||||||
|
if (test('plugin.json does NOT have explicit hooks declaration', () => {
|
||||||
|
// Claude Code automatically loads hooks/hooks.json by convention.
|
||||||
|
// Explicitly declaring it in plugin.json causes a duplicate detection error.
|
||||||
|
// See: https://github.com/affaan-m/everything-claude-code/issues/103
|
||||||
|
const pluginPath = path.join(__dirname, '..', '..', '.claude-plugin', 'plugin.json');
|
||||||
|
const plugin = JSON.parse(fs.readFileSync(pluginPath, 'utf8'));
|
||||||
|
|
||||||
|
assert.ok(
|
||||||
|
!plugin.hooks,
|
||||||
|
'plugin.json should NOT have "hooks" field - Claude Code auto-loads hooks/hooks.json'
|
||||||
|
);
|
||||||
|
})) passed++; else failed++;
|
||||||
|
|
||||||
// Summary
|
// Summary
|
||||||
console.log('\n=== Test Results ===');
|
console.log('\n=== Test Results ===');
|
||||||
console.log(`Passed: ${passed}`);
|
console.log(`Passed: ${passed}`);
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ const os = require('os');
|
|||||||
|
|
||||||
// Import the modules
|
// Import the modules
|
||||||
const pm = require('../../scripts/lib/package-manager');
|
const pm = require('../../scripts/lib/package-manager');
|
||||||
const utils = require('../../scripts/lib/utils');
|
|
||||||
|
|
||||||
// Test helper
|
// Test helper
|
||||||
function test(name, fn) {
|
function test(name, fn) {
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const os = require('os');
|
|
||||||
|
|
||||||
// Import the module
|
// Import the module
|
||||||
const utils = require('../../scripts/lib/utils');
|
const utils = require('../../scripts/lib/utils');
|
||||||
@@ -106,58 +105,52 @@ function runTests() {
|
|||||||
assert.ok(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test(dt), `Expected YYYY-MM-DD HH:MM:SS, got ${dt}`);
|
assert.ok(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test(dt), `Expected YYYY-MM-DD HH:MM:SS, got ${dt}`);
|
||||||
})) passed++; else failed++;
|
})) passed++; else failed++;
|
||||||
|
|
||||||
|
// Project name tests
|
||||||
|
console.log('\nProject Name Functions:');
|
||||||
|
|
||||||
|
if (test('getGitRepoName returns string or null', () => {
|
||||||
|
const repoName = utils.getGitRepoName();
|
||||||
|
assert.ok(repoName === null || typeof repoName === 'string');
|
||||||
|
})) passed++; else failed++;
|
||||||
|
|
||||||
|
if (test('getProjectName returns non-empty string', () => {
|
||||||
|
const name = utils.getProjectName();
|
||||||
|
assert.ok(name && name.length > 0);
|
||||||
|
})) passed++; else failed++;
|
||||||
|
|
||||||
// Session ID tests
|
// Session ID tests
|
||||||
console.log('\nSession ID Functions:');
|
console.log('\nSession ID Functions:');
|
||||||
|
|
||||||
if (test('getSessionIdShort returns default when no env var', () => {
|
if (test('getSessionIdShort falls back to project name', () => {
|
||||||
const originalEnv = process.env.CLAUDE_SESSION_ID;
|
const original = process.env.CLAUDE_SESSION_ID;
|
||||||
delete process.env.CLAUDE_SESSION_ID;
|
delete process.env.CLAUDE_SESSION_ID;
|
||||||
try {
|
try {
|
||||||
const shortId = utils.getSessionIdShort();
|
const shortId = utils.getSessionIdShort();
|
||||||
assert.strictEqual(shortId, 'default');
|
assert.strictEqual(shortId, utils.getProjectName());
|
||||||
} finally {
|
} finally {
|
||||||
if (originalEnv) process.env.CLAUDE_SESSION_ID = originalEnv;
|
if (original) process.env.CLAUDE_SESSION_ID = original;
|
||||||
}
|
}
|
||||||
})) passed++; else failed++;
|
})) passed++; else failed++;
|
||||||
|
|
||||||
if (test('getSessionIdShort returns last 8 characters', () => {
|
if (test('getSessionIdShort returns last 8 characters', () => {
|
||||||
const originalEnv = process.env.CLAUDE_SESSION_ID;
|
const original = process.env.CLAUDE_SESSION_ID;
|
||||||
process.env.CLAUDE_SESSION_ID = 'test-session-abc12345';
|
process.env.CLAUDE_SESSION_ID = 'test-session-abc12345';
|
||||||
try {
|
try {
|
||||||
const shortId = utils.getSessionIdShort();
|
assert.strictEqual(utils.getSessionIdShort(), 'abc12345');
|
||||||
assert.strictEqual(shortId, 'abc12345');
|
|
||||||
} finally {
|
} finally {
|
||||||
if (originalEnv) {
|
if (original) process.env.CLAUDE_SESSION_ID = original;
|
||||||
process.env.CLAUDE_SESSION_ID = originalEnv;
|
else delete process.env.CLAUDE_SESSION_ID;
|
||||||
} else {
|
|
||||||
delete process.env.CLAUDE_SESSION_ID;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})) passed++; else failed++;
|
|
||||||
|
|
||||||
if (test('getSessionIdShort uses custom fallback', () => {
|
|
||||||
const originalEnv = process.env.CLAUDE_SESSION_ID;
|
|
||||||
delete process.env.CLAUDE_SESSION_ID;
|
|
||||||
try {
|
|
||||||
const shortId = utils.getSessionIdShort('custom');
|
|
||||||
assert.strictEqual(shortId, 'custom');
|
|
||||||
} finally {
|
|
||||||
if (originalEnv) process.env.CLAUDE_SESSION_ID = originalEnv;
|
|
||||||
}
|
}
|
||||||
})) passed++; else failed++;
|
})) passed++; else failed++;
|
||||||
|
|
||||||
if (test('getSessionIdShort handles short session IDs', () => {
|
if (test('getSessionIdShort handles short session IDs', () => {
|
||||||
const originalEnv = process.env.CLAUDE_SESSION_ID;
|
const original = process.env.CLAUDE_SESSION_ID;
|
||||||
process.env.CLAUDE_SESSION_ID = 'short';
|
process.env.CLAUDE_SESSION_ID = 'short';
|
||||||
try {
|
try {
|
||||||
const shortId = utils.getSessionIdShort();
|
assert.strictEqual(utils.getSessionIdShort(), 'short');
|
||||||
assert.strictEqual(shortId, 'short');
|
|
||||||
} finally {
|
} finally {
|
||||||
if (originalEnv) {
|
if (original) process.env.CLAUDE_SESSION_ID = original;
|
||||||
process.env.CLAUDE_SESSION_ID = originalEnv;
|
else delete process.env.CLAUDE_SESSION_ID;
|
||||||
} else {
|
|
||||||
delete process.env.CLAUDE_SESSION_ID;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})) passed++; else failed++;
|
})) passed++; else failed++;
|
||||||
|
|
||||||
|
|||||||
36
translation_workdir/cache/translation_db.json
vendored
36
translation_workdir/cache/translation_db.json
vendored
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user