chore: 将 .claude/ 和 CLAUDE.local.md 从 git 跟踪中排除

This commit is contained in:
root
2026-02-27 20:19:00 +08:00
parent 962700f525
commit 70c59eb71d
7 changed files with 4 additions and 985 deletions

View File

@@ -1,30 +0,0 @@
---
description: 执行带有请求节流的任务,可以控制工具调用的频率
---
# 节流任务执行
你现在进入了节流模式。在这个模式下,你需要:
## 节流规则
1. **工具调用间隔**:每次调用工具后,等待至少 2 秒再调用下一个工具
2. **并行限制**:同时最多只能并行调用 2 个工具(原本可能更多)
3. **批处理优化**:优先将相关的操作合并到一个工具调用中
4. **进度提示**:每次等待时向用户说明正在节流等待
## 执行方式
- 对于读取操作Read, Glob, Grep可以适当放宽并行限制
- 对于写入操作Write, Edit严格遵守间隔要求
- 对于 API 调用Bash 中的 API 请求),必须串行执行
## 用户任务
请按照上述节流规则执行以下任务:
{{PROMPT}}
---
**注意**:完成任务后,你将自动退出节流模式,恢复正常的工具调用频率。

View File

@@ -1,407 +0,0 @@
# 心跳配置功能重构计划
## 概述
将心跳配置从"选择curl命令"模式重构为"基于URL的可配置心跳"模式。
**核心变化**
- ✅ 支持多个URL同时发送心跳
- ✅ 每个URL独立配置间隔时间
- ✅ curl命令作为导入模板可解析为URL配置
- ✅ 完全替换旧的基于curl选择的方式
## 架构设计
### 数据模型
**新表heartbeat_url_configs**
```typescript
{
id: number;
name: string; // URL配置名称
url: string; // 目标URL
method: string; // HTTP方法GET/POST/PUT/DELETE
headers: Record<string, string>; // 请求头JSONB
body: string | null; // 请求体
intervalSeconds: number; // 独立的心跳间隔10-3600秒
isEnabled: boolean; // 是否启用此配置
lastSuccessAt: Date | null; // 统计:上次成功时间
lastErrorAt: Date | null; // 统计:上次失败时间
lastErrorMessage: string | null; // 统计:上次错误信息
successCount: number; // 统计:成功次数
failureCount: number; // 统计:失败次数
providerId: number | null; // 关联的供应商ID可选
model: string | null; // 模型名称(展示用)
endpoint: string | null; // 端点路径(展示用)
createdAt: Date;
updatedAt: Date;
}
```
**修改表heartbeat_settings**
```typescript
{
id: number;
enabled: boolean; // 全局开关(保留)
// 删除intervalSeconds, savedCurls, selectedCurlIndex
createdAt: Date;
updatedAt: Date;
}
```
### 心跳执行逻辑
**ProviderHeartbeat类重构**
```typescript
class ProviderHeartbeat {
// 多定时器管理Map<configId, timer>
private static timers: Map<number, NodeJS.Timeout> = new Map();
// 启动为每个启用的URL配置创建独立定时器
static async start() {
const configs = await findEnabledHeartbeatUrlConfigs();
for (const config of configs) {
this.startConfigTimer(config);
}
}
// 停止:清除所有定时器
static stop() {
for (const timer of this.timers.values()) {
clearInterval(timer);
}
this.timers.clear();
}
// 单个配置的定时器
private static startConfigTimer(config: HeartbeatUrlConfig) {
const interval = setInterval(() => {
this.sendHeartbeat(config);
}, config.intervalSeconds * 1000);
this.timers.set(config.id, interval);
}
// 发送心跳并记录成功/失败
private static async sendHeartbeat(config: HeartbeatUrlConfig) {
const response = await fetch(config.url, {
method: config.method,
headers: config.headers,
body: config.body,
signal: AbortSignal.timeout(10000),
});
if (response.ok) {
await recordHeartbeatSuccess(config.id);
} else {
await recordHeartbeatFailure(config.id, errorMessage);
}
}
}
```
### 前端UI设计
**页面布局**
```
/settings/heartbeat/page.tsx
├── GlobalSettingsCard全局开关
├── CurlHistorySectioncurl历史记录 + 导入按钮)
└── UrlConfigsSectionURL配置列表 + 新建/编辑/删除)
```
**组件拆分**
- `global-settings-card.tsx` - 全局开关卡片
- `curl-history-section.tsx` - curl历史记录区域
- `curl-history-card.tsx` - 单个curl历史卡片
- `url-configs-section.tsx` - URL配置列表区域
- `url-config-card.tsx` - 单个URL配置卡片
- `url-config-dialog.tsx` - 新建/编辑对话框
- `_lib/hooks.ts` - 自定义hooksuseHeartbeatPageData
**curl导入流程**
1. 用户点击curl历史卡片上的"导入"按钮
2. 使用`parseCurlCommand()`解析curl命令
3. 自动打开新建对话框,表单预填充解析后的数据
4. 用户修改后保存创建URL配置
## 实施步骤
### 阶段1数据库和Repository层
1. **修改schema.ts**
- 添加`heartbeatUrlConfigs`表定义
- 修改`heartbeatSettings`表定义删除3个字段
2. **生成和审查迁移**
```bash
bun run db:generate
# 检查生成的 drizzle/0061_*.sql
# 确保数据迁移逻辑正确将选中的curl转为第一个URL配置
```
3. **创建repository/heartbeat-url-configs.ts**
- 接口:`HeartbeatUrlConfig`、`CreateHeartbeatUrlConfigInput`、`UpdateHeartbeatUrlConfigInput`
- 函数:
- `findAllHeartbeatUrlConfigs()` - 获取所有配置
- `findEnabledHeartbeatUrlConfigs()` - 获取启用的配置
- `findHeartbeatUrlConfigById(id)` - 根据ID获取
- `createHeartbeatUrlConfig(input)` - 创建配置
- `updateHeartbeatUrlConfig(id, input)` - 更新配置
- `deleteHeartbeatUrlConfig(id)` - 删除配置
- `recordHeartbeatSuccess(id)` - 记录成功
- `recordHeartbeatFailure(id, errorMessage)` - 记录失败
4. **修改repository/heartbeat-settings.ts**
- 简化为只管理全局开关
- 删除`savedCurls`和`selectedCurlIndex`相关逻辑
- 保持`getHeartbeatSettings()`和`updateHeartbeatSettings()`接口
5. **运行迁移**
```bash
bun run db:migrate
```
### 阶段2Action层
6. **创建actions/heartbeat-url-configs.ts**
- `fetchHeartbeatUrlConfigs()` - 获取所有配置
- `createHeartbeatUrlConfigAction(input)` - 创建配置
- `updateHeartbeatUrlConfigAction(id, input)` - 更新配置
- `deleteHeartbeatUrlConfigAction(id)` - 删除配置
- 验证规则:
- 名称不能为空
- URL不能为空
- 间隔时间范围10-3600秒
- 权限检查仅admin可操作
- 副作用:修改配置后重启心跳任务
7. **修改actions/heartbeat-settings.ts**
- 简化为只管理全局开关
- 保持`fetchHeartbeatSettings()`和`saveHeartbeatSettings()`
- 开关变化时重启心跳任务
### 阶段3心跳执行逻辑
8. **重构lib/provider-heartbeat.ts**
- 添加`timers: Map<number, NodeJS.Timeout>`
- 修改`start()`:为每个启用的配置创建定时器
- 修改`stop()`:清除所有定时器
- 新增`startConfigTimer(config)`:创建单个配置的定时器
- 新增`stopConfigTimer(configId)`:停止单个配置的定时器
- 修改`sendHeartbeat(config)`:发送请求并记录结果
- 删除curl解析逻辑不再需要
9. **修改app/v1/_lib/proxy/forwarder.ts**
- 删除或注释掉`addSuccessfulCurl()`调用第357-367行
- curl历史功能迁移到独立模块可选
### 阶段4i18n文案
10. **更新翻译文件**
- `messages/zh-CN/settings/heartbeat.json`
- `messages/zh-TW/settings/heartbeat.json`
- `messages/en/settings/heartbeat.json`
- `messages/ja/settings/heartbeat.json`
- `messages/ru/settings/heartbeat.json`
新增key
- `section.global.*` - 全局设置区域
- `section.curlHistory.*` - curl历史区域
- `section.urlConfigs.*` - URL配置区域
- `form.name.*` - 配置名称字段
- `form.url.*` - URL字段
- `form.method.*` - HTTP方法字段
- `form.headers.*` - 请求头字段
- `form.body.*` - 请求体字段
- `form.isEnabled.*` - 启用开关
- `form.stats.*` - 统计信息
- `form.createButton`、`importButton`等
### 阶段5前端UI
11. **创建组件**
- `app/[locale]/settings/heartbeat/_components/global-settings-card.tsx`
- Switch组件全局开关
- 说明文字
- `app/[locale]/settings/heartbeat/_components/curl-history-section.tsx`
- 区域标题和描述
- curl历史卡片列表
- 空状态提示
- `app/[locale]/settings/heartbeat/_components/curl-history-card.tsx`
- 显示:供应商名、端点、模型、时间
- 导入按钮
- `app/[locale]/settings/heartbeat/_components/url-configs-section.tsx`
- 区域标题和描述
- 新建按钮
- URL配置卡片列表
- 空状态提示
- `app/[locale]/settings/heartbeat/_components/url-config-card.tsx`
- 显示名称、URL、方法、间隔、启用状态
- 统计信息:成功次数、失败次数、最后成功/失败时间
- 编辑按钮、删除按钮
- Switch组件快速启用/禁用
- `app/[locale]/settings/heartbeat/_components/url-config-dialog.tsx`
- Dialog表单名称、URL、方法、headers、body、间隔
- 支持新建和编辑模式
- headers使用TextareaJSON格式
- body使用Textarea可选
- 验证和错误提示
- `app/[locale]/settings/heartbeat/_components/heartbeat-skeleton.tsx`
- 骨架屏加载状态
12. **创建hooks**
- `app/[locale]/settings/heartbeat/_lib/hooks.ts`
- `useHeartbeatPageData()`
- 加载settings、configs、savedCurls
- 提供CRUD操作函数
- 提供importFromCurl函数
- 统一错误处理和toast提示
13. **重写page.tsx**
- 使用`useHeartbeatPageData()`
- 组合所有子组件
- 加载状态和错误处理
### 阶段6测试和验证
14. **类型检查和格式化**
```bash
bun run typecheck
bun run lint:fix
```
15. **手动测试流程**
- [ ] 访问 `/settings/heartbeat` 页面
- [ ] 创建新的URL配置
- [ ] 从curl历史导入配置
- [ ] 编辑配置修改URL、间隔等
- [ ] 启用/禁用单个配置
- [ ] 启用/禁用全局开关
- [ ] 删除配置
- [ ] 检查多个URL同时发送心跳
- [ ] 检查失败记录和统计信息
- [ ] 检查国际化(切换语言)
16. **日志验证**
```bash
# 检查心跳日志
tail -f logs/app.log | grep "ProviderHeartbeat"
# 应该看到:
# - "Timer started" - 定时器启动
# - "Heartbeat sent successfully" - 成功日志
# - "Heartbeat failed" - 失败日志
```
17. **数据库验证**
```bash
bun run db:studio
# 检查 heartbeat_url_configs 表
# 确认配置已保存
# 确认成功/失败统计更新
```
## 关键文件清单
### 新建文件
- `src/repository/heartbeat-url-configs.ts` - URL配置Repository
- `src/actions/heartbeat-url-configs.ts` - URL配置Actions
- `src/app/[locale]/settings/heartbeat/_components/global-settings-card.tsx`
- `src/app/[locale]/settings/heartbeat/_components/curl-history-section.tsx`
- `src/app/[locale]/settings/heartbeat/_components/curl-history-card.tsx`
- `src/app/[locale]/settings/heartbeat/_components/url-configs-section.tsx`
- `src/app/[locale]/settings/heartbeat/_components/url-config-card.tsx`
- `src/app/[locale]/settings/heartbeat/_components/url-config-dialog.tsx`
- `src/app/[locale]/settings/heartbeat/_lib/hooks.ts`
- `drizzle/0061_*.sql` - 数据库迁移文件(自动生成)
### 修改文件
- `src/drizzle/schema.ts` - 添加新表,修改旧表
- `src/repository/heartbeat-settings.ts` - 简化逻辑
- `src/actions/heartbeat-settings.ts` - 简化Action
- `src/lib/provider-heartbeat.ts` - 重构心跳执行逻辑
- `src/app/v1/_lib/proxy/forwarder.ts` - 删除curl保存逻辑
- `src/app/[locale]/settings/heartbeat/page.tsx` - 重写UI
- `messages/*/settings/heartbeat.json` - 更新翻译5种语言
### 删除文件
- `src/app/[locale]/settings/heartbeat/_components/heartbeat-form.tsx` - 旧表单组件
## 数据迁移策略
**迁移逻辑在0061_*.sql中**
```sql
-- 创建新表
CREATE TABLE heartbeat_url_configs (...);
-- 迁移现有数据
DO $$
DECLARE
settings_row RECORD;
selected_curl JSONB;
BEGIN
SELECT * INTO settings_row FROM heartbeat_settings LIMIT 1;
IF settings_row.selected_curl_index IS NOT NULL THEN
selected_curl := settings_row.saved_curls->settings_row.selected_curl_index;
INSERT INTO heartbeat_url_configs (
name, url, interval_seconds, is_enabled, ...
) VALUES (
selected_curl->>'providerName',
selected_curl->>'url',
settings_row.interval_seconds,
settings_row.enabled,
...
);
END IF;
END $$;
-- 删除旧字段
ALTER TABLE heartbeat_settings
DROP COLUMN interval_seconds,
DROP COLUMN saved_curls,
DROP COLUMN selected_curl_index;
```
**回滚能力**:保留旧数据在迁移文件中,可以通过反向迁移恢复。
## 风险和缓解
| 风险 | 缓解措施 |
|------|----------|
| 数据迁移失败 | 1. 迁移前备份数据库<br>2. 在测试环境验证<br>3. 编写回滚脚本 |
| curl解析不完整 | 1. 复用现有`parseCurlCommand`<br>2. 添加解析错误提示<br>3. 允许手动编辑 |
| 多定时器性能问题 | 1. 限制最大配置数量如20个<br>2. 添加禁用功能<br>3. 监控日志 |
| 心跳发送失败 | 1. 记录失败日志<br>2. UI显示失败状态<br>3. 支持手动禁用 |
## 验证清单
- [ ] 数据库迁移成功,旧数据已转移
- [ ] 类型检查通过 (`bun run typecheck`)
- [ ] Lint检查通过 (`bun run lint`)
- [ ] 构建成功 (`bun run build`)
- [ ] 可以创建URL配置
- [ ] 可以从curl导入配置
- [ ] 可以编辑和删除配置
- [ ] 全局开关控制所有心跳
- [ ] 多个URL同时发送心跳检查日志
- [ ] 失败统计正确记录
- [ ] 所有5种语言显示正常
- [ ] 页面加载和交互流畅
## 预估工作量
- 数据库和Repository层1-2小时
- Action层30分钟
- 心跳执行逻辑1小时
- i18n文案30分钟
- 前端UI2-3小时
- 测试和验证1小时
- **总计6-8小时**

View File

@@ -1,172 +0,0 @@
#!/bin/bash
echo "=========================================="
echo "Claude Code Root Check 移除工具"
echo "=========================================="
echo ""
# 通过 which 命令找到 claude 可执行文件
echo "正在查找 claude 命令..."
CLAUDE_PATH=$(which claude)
if [ -z "$CLAUDE_PATH" ]; then
echo "❌ 错误: 未找到 claude 命令"
exit 1
fi
echo "找到 claude 位置: $CLAUDE_PATH"
# 如果是软链接,获取实际文件路径
if [ -L "$CLAUDE_PATH" ]; then
REAL_PATH=$(readlink -f "$CLAUDE_PATH")
echo "这是一个软链接,实际路径: $REAL_PATH"
else
REAL_PATH="$CLAUDE_PATH"
fi
# 获取 claude 所在的目录
CLAUDE_DIR=$(dirname "$CLAUDE_PATH")
echo "claude 目录: $CLAUDE_DIR"
echo ""
# 检查是否已经是包装脚本
if grep -q "Claude Code Wrapper" "$CLAUDE_PATH" 2>/dev/null; then
echo "✓ 检测到已安装包装脚本"
echo "正在更新包装脚本..."
else
echo "正在创建包装脚本..."
fi
# 创建 claude-wrapper.sh
WRAPPER_PATH="$CLAUDE_DIR/claude-wrapper.sh"
cat > "$WRAPPER_PATH" << 'EOF'
#!/bin/bash
# Claude Code Wrapper - 自动删除 root check 限制
# 此脚本会在每次执行 claude 前绕过 root 用户限制
#
# 新版本 (2.1.x+) 支持通过环境变量绕过检查:
# - IS_SANDBOX=1
# - CLAUDE_CODE_BUBBLEWRAP=1
#
# 旧版本需要修改 cli.js 文件删除检查代码
# 获取当前脚本的真实路径
SCRIPT_PATH="$(readlink -f "$0")"
SCRIPT_DIR="$(dirname "$SCRIPT_PATH")"
# 查找同目录下的 claude.bak原始软链接
CLAUDE_BAK="$SCRIPT_DIR/claude.bak"
# 如果 claude.bak 不存在,尝试通过 which 和目录搜索找到真实路径
if [ ! -L "$CLAUDE_BAK" ] && [ ! -f "$CLAUDE_BAK" ]; then
# 在当前目录查找指向 claude-code 的软链接或文件
for file in "$SCRIPT_DIR"/*; do
if [ -L "$file" ] || [ -f "$file" ]; then
target=$(readlink -f "$file" 2>/dev/null)
if [[ "$target" == *"@anthropic-ai/claude-code/cli.js" ]]; then
CLAUDE_REAL_PATH="$target"
break
fi
fi
done
# 如果还是没找到,尝试常见路径
if [ -z "$CLAUDE_REAL_PATH" ]; then
for path in \
"$SCRIPT_DIR/../lib/node_modules/@anthropic-ai/claude-code/cli.js" \
"/usr/local/lib/node_modules/@anthropic-ai/claude-code/cli.js" \
"/usr/lib/node_modules/@anthropic-ai/claude-code/cli.js"; do
if [ -f "$path" ]; then
CLAUDE_REAL_PATH="$path"
break
fi
done
fi
else
# 通过 claude.bak 获取真实的 cli.js 路径
CLAUDE_REAL_PATH="$(readlink -f "$CLAUDE_BAK")"
fi
if [ -z "$CLAUDE_REAL_PATH" ] || [ ! -f "$CLAUDE_REAL_PATH" ]; then
echo "错误: 未找到真实的 claude cli.js 文件" >&2
echo "请确保 claude 已正确安装" >&2
exit 1
fi
# 获取 claude 版本号(用于提示信息)
CLAUDE_VERSION=$(node "$CLAUDE_REAL_PATH" --version 2>/dev/null | head -1 || echo "unknown")
# 新版本 (2.1.x+) 直接使用环境变量绕过 root check
# 设置 IS_SANDBOX=1 或 CLAUDE_CODE_BUBBLEWRAP=1 即可
export IS_SANDBOX=1
export CLAUDE_CODE_BUBBLEWRAP=1
# 执行原始 claude 命令,传递所有参数
exec node "$CLAUDE_REAL_PATH" "$@"
EOF
# 给包装脚本添加执行权限
chmod +x "$WRAPPER_PATH"
echo "✓ 已创建包装脚本: $WRAPPER_PATH"
echo ""
# 备份原 claude 命令(如果尚未备份)
CLAUDE_BAK="$CLAUDE_DIR/claude.bak"
if [ ! -e "$CLAUDE_BAK" ]; then
if [ -L "$CLAUDE_PATH" ]; then
# 如果是软链接,复制软链接本身
cp -P "$CLAUDE_PATH" "$CLAUDE_BAK"
echo "✓ 已备份原 claude 软链接为: $CLAUDE_BAK"
else
# 如果是普通文件,复制文件
cp "$CLAUDE_PATH" "$CLAUDE_BAK"
echo "✓ 已备份原 claude 文件为: $CLAUDE_BAK"
fi
else
echo "✓ 检测到已存在备份: $CLAUDE_BAK"
fi
# 替换 claude 命令为包装脚本
echo ""
echo "正在替换 claude 命令..."
# 删除原有的 claude如果是软链接或文件
rm -f "$CLAUDE_PATH"
# 创建新的软链接指向包装脚本
ln -s "$WRAPPER_PATH" "$CLAUDE_PATH"
echo "✓ 已将 claude 命令替换为包装脚本"
echo ""
# 验证安装
echo "=========================================="
echo "验证安装..."
echo ""
if [ -L "$CLAUDE_PATH" ]; then
TARGET_PATH=$(readlink "$CLAUDE_PATH")
echo "✓ claude 现在指向: $TARGET_PATH"
fi
if [ -e "$CLAUDE_BAK" ]; then
echo "✓ 原始 claude 已备份为: $CLAUDE_BAK"
fi
if [ -x "$WRAPPER_PATH" ]; then
echo "✓ 包装脚本具有执行权限"
fi
echo ""
echo "=========================================="
echo "✓ 安装完成!"
echo ""
echo "现在你可以在 root 用户下使用:"
echo " claude --dangerously-skip-permissions"
echo ""
echo "如需恢复原始 claude 命令:"
echo " rm $CLAUDE_PATH"
echo " mv $CLAUDE_BAK $CLAUDE_PATH"
echo "=========================================="

View File

@@ -1,24 +0,0 @@
{
"env": {
"ANTHROPIC_API_KEY": "sk-d87ce5b80978df466c81378d798ca39f",
"ANTHROPIC_BASE_URL": "https://cc.ronghuaxueleng.top",
"CLAUDE_CODE_ATTRIBUTION_HEADER": "0",
"DISABLE_AUTOUPDATER": 1,
"DISABLE_BUG_COMMAND": 1,
"DISABLE_ERROR_REPORTING": 1,
"DISABLE_TELEMETRY": 1,
"IS_SANDBOX": "1",
"USER_NAME": "腾讯云"
},
"permissions": {
"allow": [
"*"
],
"defaultMode": "bypassPermissions"
},
"statusLine": {
"command": "node \".claude/show-status.mjs\"",
"padding": 0,
"type": "command"
}
}

View File

@@ -1,91 +0,0 @@
#!/usr/bin/env node
/**
* Claude Code 积分状态栏脚本
* 用途: 在状态栏显示配置信息
*/
import fs from 'fs';
import path from 'path';
import os from 'os';
// 禁用SSL证书验证警告
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
function getDisplayUrl() {
const baseUrl = process.env.ANTHROPIC_BASE_URL || '';
if (baseUrl) {
const match = baseUrl.match(/https?:\/\/([^\/]+)/);
if (match) {
return match[1];
}
}
return '';
}
function getCurrentModel() {
// 优先使用环境变量
let model = process.env.ANTHROPIC_MODEL || '';
// 如果环境变量没有检查settings.json
if (!model) {
try {
const settingsFile = path.join(os.homedir(), '.claude', 'settings.json');
if (fs.existsSync(settingsFile)) {
const settings = JSON.parse(fs.readFileSync(settingsFile, 'utf8'));
model = settings.model || '';
}
} catch (error) {
// 忽略错误
}
}
if (model) {
if (model.toLowerCase().includes('claude-3')) {
if (model.toLowerCase().includes('haiku')) {
return 'Claude 3 Haiku';
} else if (model.toLowerCase().includes('sonnet')) {
return 'Claude 3 Sonnet';
} else if (model.toLowerCase().includes('opus')) {
return 'Claude 3 Opus';
}
} else if (model.toLowerCase().includes('claude-4') || model.toLowerCase().includes('sonnet-4')) {
return 'Claude 4 Sonnet';
} else if (model.toLowerCase().includes('opus-4')) {
return 'Claude 4 Opus';
} else if (model.length > 20) {
return model.substring(0, 20) + '...';
}
return model;
}
return 'Claude (Auto)';
}
async function main() {
try {
const currentUrl = getDisplayUrl();
const currentModel = getCurrentModel();
const userName = process.env.USER_NAME || '';
const parts = [];
if (userName) parts.push(`👤 ${userName}`);
parts.push(currentModel);
parts.push(currentUrl);
console.log(parts.join(' | '));
} catch (error) {
// 即使出错也显示基本信息
const currentUrl = getDisplayUrl();
const currentModel = getCurrentModel();
const userName = process.env.USER_NAME || '';
const parts = ['🔴 错误'];
if (userName) parts.push(`👤 ${userName}`);
parts.push(currentModel);
parts.push(currentUrl);
console.log(parts.join(' | '));
}
}
// ES Module 中直接执行
main();

4
.gitignore vendored
View File

@@ -45,3 +45,7 @@ ds2api-tests
# Misc
.git/
Thumbs.db
# Claude Code
.claude/
CLAUDE.local.md

View File

@@ -1,261 +0,0 @@
# Claude Code 行为准则
> 本文件定义 Claude Code 在本项目中的强制执行规则。所有规则均为**必须执行**,不可跳过。
---
## 一、核心原则(九荣九耻)
| 耻 | 荣 |
|---|---|
| ❌ 瞎猜接口 | ✅ 认真查询源码 |
| ❌ 模糊执行 | ✅ 寻求用户确认 |
| ❌ 臆想业务 | ✅ 复用现有实现 |
| ❌ 创造接口 | ✅ 主动测试验证 |
| ❌ 跳过验证 | ✅ 等待人类确认 |
| ❌ 破坏架构 | ✅ 遵循项目规范 |
| ❌ 假装理解 | ✅ 诚实说"不确定" |
| ❌ 盲目修改 | ✅ 谨慎重构 |
| ❌ 画蛇添足 | ✅ 按需实现 |
---
## 二、代码生成前置检查
### 【强制】生成代码前必须完成的 4 项检查
在生成**任何代码**之前,必须逐条确认以下检查项,**缺一不可**
| # | 检查项 | 未通过则 |
|---|--------|---------|
| 1 | 是否已读取 CLAUDE.md 中的编码规范? | ❌ 禁止生成代码 |
| 2 | 是否已搜索项目中类似实现作为参考? | ❌ 禁止生成代码 |
| 3 | 是否有不确定的地方需要询问用户? | ⚠️ 先询问再继续 |
| 4 | 是否复用了现有的实体类/工具类? | ❌ 禁止新建已存在的类 |
---
## 三、"参照 XX 写"执行规则
当用户说"参照XX写"、"仿照XX实现"、"按照XX的方式"时,**必须严格执行**以下步骤:
### 步骤清单
| # | 步骤 | 必须完成的动作 |
|---|------|--------------|
| 1 | 完整阅读参照对象 | 读取 Controller、Service、Mapper、Entity **所有相关文件**,不能只看部分 |
| 2 | 列出关键对照点 | 向用户列出接口路径、参数格式、返回值格式、Service 调用方式、业务逻辑 |
| 3 | 严格对照实现 | ❌ 禁止"优化"或"改进"参照对象,❌ 禁止偏离参照对象的风格 |
### 完成后自检
| # | 自检问题 | 答案必须是"是" |
|---|---------|--------------|
| 1 | 我的实现和参照对象的实现方式是否一致? | 否则必须修正 |
| 2 | 有没有任何地方是我"自作主张"改的? | 有则必须告知用户 |
**如果有任何偏离,必须告知用户并说明原因,由用户决定是否采用。**
---
## 四、批量保存接口设计规范
### 【强制】设计前必须列出用户操作场景
| 用户操作 | 数据特征 | 处理方式 |
|---------|---------|---------|
| 新增一条数据 | 传入的数据没有 id | INSERT |
| 修改一条数据 | 传入的数据有 id | UPDATE |
| 删除一条数据 | **数据库有但传入列表中没有** ← 容易遗漏! | DELETE |
| 不做任何改动 | 原样传回 | 不处理 |
### 正确实现步骤
```
1. 查询数据库中该主体已有的所有数据 ID
2. 对比传入列表中的 ID找出需要删除的数据库有但传入没有
3. 删除不在传入列表中的数据
4. 新增或更新传入列表中的数据
```
### 完成后自检
| # | 自检问题 | 答案必须是"是" |
|---|---------|--------------|
| 1 | 新增、更新、删除——三种情况都覆盖了吗? | |
| 2 | 如果用户删除了一条已有数据,保存后这条数据会消失吗? | |
---
## 五、文档解析规则
### 【强制】解析步骤(按顺序执行,不可跳过)
| # | 步骤 | 必须完成的动作 | 中断条件 |
|---|------|--------------|---------|
| 1 | 多方式解析 | Word/PDF 必须尝试 ≥2 种解析方式段落、表格、文本框、XML 等) | |
| 2 | 完整性检查 | 检查是否只看到类名而没有属性定义? | ⚠️ **是则停止,询问用户** |
| 3 | 列出清单 | 向用户列出:类数量+名称、每个类的属性数量+名称、方法数量+签名 | ⚠️ **等待用户确认** |
| 4 | 生成代码 | 只有用户明确确认后才能继续 | |
### 绝对禁止
| # | 禁止行为 |
|---|---------|
| 1 | ❌ 禁止在用户确认前生成任何代码 |
| 2 | ❌ 禁止自行补充或猜测文档中未明确写出的内容 |
| 3 | ❌ 禁止只用一种方式解析就认为解析完成 |
| 4 | ❌ 禁止看到类名/接口名却没有属性定义时继续执行 |
---
## 六、接口与参数分析规则
### 触发条件
- 分析接口映射关系(标准接口 → 内部接口)
- 分析参数映射关系
- 编写 DTO/Entity 字段定义
### 【强制】执行步骤
| # | 步骤 | 必须完成的动作 |
|---|------|--------------|
| 1 | 确认接口映射 | 阅读标准接口功能 → 搜索后端代码找**功能匹配**的内部接口(不是名称匹配!)→ 读 Controller 确认功能 |
| 2 | 确认参数映射 | 找到 @RequestBody 的类 → 读源码(含父类)→ 逐一列出字段 → 对比建立映射 |
### 映射可信度标注(必须标注)
| 标注 | 含义 |
|-----|------|
| ✅ 已验证 | 已阅读源码确认 |
| ⚠️ 待验证 | 需要进一步确认 |
| ❌ 需新建接口 | 需要编写复杂业务逻辑(组合调用多个接口等) |
### 绝对禁止
| # | 禁止行为 |
|---|---------|
| 1 | ❌ 禁止凭接口名称相似就认为可以映射 |
| 2 | ❌ 禁止直接使用 Postman/Swagger 参数定义,必须与源码核对 |
| 3 | ❌ 禁止凭"合理推测"编写参数映射 |
| 4 | ❌ 禁止使用模糊表述如"需要扩展"、"可能需要调用额外接口" |
---
## 七、Postman 文档规范
### 核心原则
| 位置 | 内容 |
|-----|------|
| `description` 字段 | Markdown 格式,展示完整参数说明(带注释的 JSON 代码块) |
| `body.raw` 字段 | 纯净 JSON无注释可直接发送请求 |
### description 格式模板
```json
{
"description": "接口功能说明。\n\n**请求参数示例:**\n```json\n{\n \"字段名\": \"示例值\", // 字段说明\n}\n```\n\n**响应示例:**\n```json\n{\n \"code\": 0,\n \"data\": {}\n}\n```"
}
```
### 自检清单
| # | 检查项 | 要求 |
|---|--------|-----|
| 1 | body.raw 是否有注释? | ❌ 禁止,会导致 JSON 格式错误 |
| 2 | description 是否展示了参数格式? | ✅ 必须有带注释的 JSON 示例 |
| 3 | 是否包含响应示例? | ✅ 每个接口都必须有 |
| 4 | Long 类型 ID 是否展示为 String | ✅ 如 `"id": "123456789"` |
---
## 八、设计文档编写规范
### 核心原则
设计文档的目标是:**开发人员可以直接照着写代码**,不是概念性说明。
### 【强制】文档必须包含的内容
| # | 内容 | 要求 |
|---|------|-----|
| 1 | 数据库表 DDL | 可直接执行的 CREATE TABLE |
| 2 | 枚举类代码 | 可直接复制使用 |
| 3 | 实体类代码 | 包括所有字段和注解 |
| 4 | Mapper 代码 | 包括 Provider 中的完整 SQL |
| 5 | Service 代码 | 接口定义和实现类 |
| 6 | Controller 代码 | 接口路径、请求体、响应格式 |
| 7 | 实现清单 | 新模块接入时的检查表 |
| 8 | 常见问题 FAQ | 解答可能的疑惑 |
### 代码示例要求
| # | 要求 |
|---|------|
| 1 | 代码必须**完整可用**,不是片段或伪代码 |
| 2 | 必须包含**完整的 import 语句** |
| 3 | SQL 必须**完整可执行**,不能用 `...` 省略 |
### 完成后自检
| # | 自检问题 | 答案必须是"是" |
|---|---------|--------------|
| 1 | 新人开发者能否只看这份文档就完成开发? | |
| 2 | 文档中的代码能否直接复制到项目中使用? | |
| 3 | 是否有"等"、"..."、"类似"等模糊表述? | 有则删除 |
---
## 九、方法重载规范
### 规则
| # | 规则 | 说明 |
|---|------|-----|
| 1 | 全量参数方法承载所有逻辑 | 是唯一的实现体 |
| 2 | 少参数方法只做委托调用 | 传 `null` 给新增参数,方法体只有一行 `return` |
| 3 | ❌ 禁止两个重载方法各写一份逻辑 | 即使逻辑相同也不行 |
| 4 | ❌ 禁止反向委托 | 全量方法不能调用少参数方法 |
### 正确示例
```java
// ✅ 少参数方法委托全量方法
public Object foo(Req req, Request request, Response response) {
return foo(req, request, response, null);
}
public Object foo(Req req, Request request, Response response, Function<String, String> lineConverter) {
// 所有逻辑在这里
if (lineConverter != null) {
// 有转换器时的处理
}
}
```
---
## 十、工作偏好
| # | 偏好 |
|---|------|
| 1 | 始终使用**简体中文**回复 |
| 2 | 长任务必须记录详细进度 |
| 3 | 提交代码时**不要**附带 `Co-Authored-By: Claude` |
| 4 | 对所有工具操作自动同意,无需额外确认 |
| 5 | 不用执行编译和测试 |
| 6 | 编写构建脚本时尽量使用 mjs 编写带菜单的脚本 |
| 7 | 尽量使用 Python 连接数据库 |
| 8 | 联网搜索时**禁止**使用 csdn.net、阿里云/腾讯云/华为云社区等内容农场 |
---
## 十一、代码生成规则
| # | 规则 |
|---|------|
| 1 | 提供实体类/模板/文档时,必须**完整复制所有属性和方法**,禁止省略 |
| 2 | 生成代码前,先列出文档中所有属性数量和名称,确认无遗漏后再生成 |
| 3 | 属性超过 20 个时,分批列出确认 |
| 4 | 禁止因为"优化"或"简化"而删减任何属性 |
| 5 | 生成完成后,对比源文档属性数量是否一致 |