refactor: Remove libs directory

This commit is contained in:
tukuaiai 2025-12-18 13:22:45 +08:00
parent 6e8b446416
commit 222cefbd58
639 changed files with 1 additions and 110809 deletions

View File

@ -70,6 +70,7 @@
<a href="./i18n/zh/documents/实战案例/"><img src="https://img.shields.io/badge/🎬_实战案例-项目实操-orange?style=for-the-badge" alt="实战案例"></a> <a href="./i18n/zh/documents/实战案例/"><img src="https://img.shields.io/badge/🎬_实战案例-项目实操-orange?style=for-the-badge" alt="实战案例"></a>
<a href="./i18n/zh/documents/常见坑汇总/"><img src="https://img.shields.io/badge/🕳_常见坑-避坑指南-yellow?style=for-the-badge" alt="常见坑汇总"></a> <a href="./i18n/zh/documents/常见坑汇总/"><img src="https://img.shields.io/badge/🕳_常见坑-避坑指南-yellow?style=for-the-badge" alt="常见坑汇总"></a>
<a href="./i18n/zh/documents/外部资源聚合/"><img src="https://img.shields.io/badge/📡_信息源-聚合-teal?style=for-the-badge" alt="信息源聚合"></a> <a href="./i18n/zh/documents/外部资源聚合/"><img src="https://img.shields.io/badge/📡_信息源-聚合-teal?style=for-the-badge" alt="信息源聚合"></a>
<a href="./libs/external/chat-vault/"><img src="https://img.shields.io/badge/🔐_Chat_Vault-聊天存档-gold?style=for-the-badge" alt="Chat Vault"></a>
</p> </p>
[📋 工具资源](#-器-工具与资源) [📋 工具资源](#-器-工具与资源)

View File

@ -1,71 +0,0 @@
# 📦 通用库与外部集成 (libs)
`libs/` 用来放两类东西:
1. **内部可复用的胶水代码**:小而稳、低耦合、可替换(`common/`
2. **第三方工具与外部集成**:尽量保持原样、只做最薄适配(`external/`
`database/` 预留未来的数据持久化层(当前仅占位)。
## 目录结构
```
libs/
├── README.md
├── common/
│ ├── README.md
│ ├── __init__.py
│ ├── models/
│ │ └── __init__.py
│ └── utils/
│ └── backups/
│ ├── README.md
│ ├── 快速备份.py
│ └── 一键备份.sh
├── database/
│ ├── README.md
│ └── .gitkeep
└── external/
├── README.md
├── chat-vault/
├── prompts-library/
├── l10n-tool/
├── my-nvim/
├── MCPlayerTransfer/
├── XHS-image-to-PDF-conversion/
└── .gitkeep
```
## 子目录职责与边界
### `common/`:内部通用模块
- 入口:[`common/README.md`](./common/README.md)
- 只放 **可复用** 的基础能力:模型、工具函数、脚本等
- 不要把业务逻辑、项目临时代码塞进来
- 约定:新增/调整能力时,同步更新 `libs/common/README.md`
### `database/`:数据库适配层(预留)
- 入口:[`database/README.md`](./database/README.md)
- 目标是把“存储细节”关进盒子里:连接、迁移、查询适配、事务边界
- 约定:实现前先写清楚目录结构与边界(见 `libs/database/README.md`
### `external/`:第三方工具与外部集成
- 入口:[`external/README.md`](./external/README.md)
- 尽量保持第三方代码原样,避免“魔改后不可升级”
- 每个工具目录至少包含:`README.md`(用途/入口/依赖)与许可证/来源说明
- 约定:新增外部工具时,同步更新 `libs/external/README.md`
## 常用入口
- AI 聊天记录保存:[`external/chat-vault/`](./external/chat-vault/)(支持 Codex/Kiro/Gemini/Claude CLI
- 提示词批量管理:[`external/prompts-library/`](./external/prompts-library/)(配合 `../prompts/` 使用)
- 备份工具:优先使用仓库根目录的 `backups/`(当前与 `libs/common/utils/backups/` 内容一致)
## 贡献约定(最小要求)
1. 新增模块先定义职责边界,再写代码/文档
2. 新增依赖记录安装方式与最低版本(必要时补充到 `documents/工具集.md`
3. 目录结构/职责变化时,更新对应 README保证“文档即真相源”

View File

@ -1,40 +0,0 @@
# 🔧 libs/common通用模块
`libs/common/` 放的是项目内部可复用的“胶水代码”:**小而稳、低耦合、可替换**。这里的目标不是堆功能,而是为仓库提供少量可靠的基础能力。
## 目录结构
```
libs/common/
├── README.md
├── __init__.py
├── models/ # 预留:数据模型(当前仅占位)
│ └── __init__.py
└── utils/
└── backups/ # 基于 .gitignore 的快速备份工具
├── README.md
├── 快速备份.py
└── 一键备份.sh
```
## 现有内容
- `utils/backups/`:快速备份工具(当前与仓库根目录 [`backups/`](../../backups/) 内容一致,用于避免脚本散落各处)
## 约束与约定
1. **不放业务逻辑**`common/` 只提供基础能力与工具
2. **接口要稳**:一旦被引用,就把它当作公开 API 对待
3. **可审计输出**:脚本/工具的输出要可复盘(明确输入、输出路径、失败原因)
4. **新增即文档**:新增模块/目录必须同步更新本 README 与 `libs/README.md`
## 使用方式(当前推荐)
本目录的内容目前主要以“脚本/工具”形式存在,推荐直接运行:
```bash
# 备份当前仓库(建议优先使用根目录 backups/ 入口)
python3 backups/快速备份.py
```
更多参数与说明见:[`../../backups/README.md`](../../backups/README.md)。

View File

@ -1 +0,0 @@
# Common Library

View File

@ -1 +0,0 @@
# Models Module

View File

@ -1,53 +0,0 @@
# 快速备份工具
基于 `.gitignore` 规则的项目备份工具,自动排除不需要的文件。
## 功能特性
- 自动读取 `.gitignore` 规则
- 支持取反规则(`!` 语法)
- 目录级剪枝优化
- 生成 `.tar.gz` 压缩包
- 零依赖(仅使用 Python 内置模块)
## 文件结构
```
backups/
├── 快速备份.py # 核心备份引擎
├── 一键备份.sh # Shell 启动脚本
└── README.md # 本文档
```
## 使用方法
```bash
# 方式一Shell 脚本(推荐)
bash backups/一键备份.sh
# 方式二:直接运行 Python
python3 backups/快速备份.py
# 指定输出文件
python3 backups/快速备份.py -o my_backup.tar.gz
# 指定项目目录
python3 backups/快速备份.py -p /path/to/project
```
## 输出位置
默认输出到 `backups/gz/备份_YYYYMMDD_HHMMSS.tar.gz`
## 参数说明
| 参数 | 说明 | 默认值 |
|------|------|--------|
| `-p, --project` | 项目根目录 | 当前目录 |
| `-o, --output` | 输出文件路径 | `backups/gz/备份_时间戳.tar.gz` |
| `-g, --gitignore` | gitignore 文件路径 | `.gitignore` |
## 依赖
- Python 3.x无需额外包
- Bash用于 Shell 脚本)

View File

@ -1,83 +0,0 @@
#!/bin/bash
# 一键备份项目脚本
# 自动读取 .gitignore 规则并排除匹配的文件
# bash backups/一键备份.sh
set -e
# 颜色输出
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# 脚本所在目录
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# 项目根目录(脚本所在目录的父目录)
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
# 项目backups目录
BACKUPS_DIR="${PROJECT_ROOT}/backups"
# 备份脚本路径始终在项目的backups目录中
BACKUP_SCRIPT="${BACKUPS_DIR}/快速备份.py"
# 检查备份脚本是否存在
if [ ! -f "${BACKUP_SCRIPT}" ]; then
echo -e "${YELLOW}⚠️ 错误: 备份脚本不存在${NC}"
echo ""
echo "备份工具应位于项目的 backups/ 目录中:"
echo " ${BACKUPS_DIR}/"
echo ""
echo "请确保:"
echo " 1. 复制快速备份.py到 ${BACKUPS_DIR}/"
echo " 2. 复制一键备份.sh到 ${BACKUPS_DIR}/"
echo ""
echo "或者使用方式:"
echo " • 在项目根目录执行: bash backups/一键备份.sh"
echo " • 或直接执行: python3 backups/快速备份.py"
exit 1
fi
echo -e "${BLUE}========================================${NC}"
echo -e "${BLUE} 项目快速备份工具${NC}"
echo -e "${BLUE}========================================${NC}"
echo ""
echo -e "${GREEN}${NC} 找到备份脚本: backups/快速备份.py"
# 检查 Python3 是否可用
if ! command -v python3 &> /dev/null; then
echo -e "${YELLOW}⚠️ 错误: 未找到 python3 命令${NC}"
exit 1
fi
echo -e "${GREEN}${NC} 项目目录: ${PROJECT_ROOT}"
echo -e "${GREEN}${NC} 备份脚本: ${BACKUP_SCRIPT}"
echo -e "${GREEN}${NC} Python 版本: $(python3 --version)"
echo ""
# 执行备份
echo -e "${YELLOW}▶ 正在执行备份...${NC}"
echo ""
# 切换到项目根目录
cd "${PROJECT_ROOT}"
# 运行备份脚本
python3 "${BACKUP_SCRIPT}"
# 检查执行结果
if [ $? -eq 0 ]; then
echo ""
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN} ✓ 备份完成!${NC}"
echo -e "${GREEN}========================================${NC}"
else
echo ""
echo -e "${YELLOW}========================================${NC}"
echo -e "${YELLOW} ✗ 备份失败${NC}"
echo -e "${YELLOW}========================================${NC}"
exit 1
fi

View File

@ -1,265 +0,0 @@
#!/usr/bin/env python3
"""
快速备份项目工具
读取 .gitignore 规则并打包项目文件排除匹配的文件
bash backups/一键备份.sh
文件位置
backups/快速备份.py
工具清单backups/目录
快速备份.py - 核心备份引擎7.3 KB
一键备份.sh - 一键执行脚本2.4 KB
使用方法
$ bash backups/一键备份.sh
$ python3 backups/快速备份.py
备份输出
backups/gz/备份_YYYYMMDD_HHMMSS.tar.gz
适用项目
任何包含 .gitignore 文件的项目自动读取规则并排除匹配文件
依赖
无需额外安装包仅使用Python内置模块
"""
import os
import tarfile
import fnmatch
from pathlib import Path
from datetime import datetime
import argparse
import sys
class GitignoreFilter:
"""解析 .gitignore 文件并过滤文件"""
def __init__(self, gitignore_path: Path, project_root: Path):
self.project_root = project_root
# 规则按照出现顺序存储,支持取反(!)语义,后匹配覆盖前匹配
# 每项: {"pattern": str, "dir_only": bool, "negate": bool, "has_slash": bool}
self.rules = []
self.load_gitignore(gitignore_path)
def load_gitignore(self, gitignore_path: Path):
"""加载并解析 .gitignore 文件"""
if not gitignore_path.exists():
print(f"⚠️ 警告: {gitignore_path} 不存在,将不应用任何过滤规则")
return
try:
with open(gitignore_path, 'r', encoding='utf-8') as f:
for line in f:
line = line.strip()
# 跳过空行和注释
if not line or line.startswith('#'):
continue
negate = line.startswith('!')
if negate:
line = line[1:].lstrip()
if not line:
continue
dir_only = line.endswith('/')
has_slash = '/' in line.rstrip('/')
self.rules.append({
"pattern": line,
"dir_only": dir_only,
"negate": negate,
"has_slash": has_slash,
})
print(f"✓ 已加载 {len(self.rules)} 条规则(含取反)")
except Exception as e:
print(f"❌ 读取 .gitignore 失败: {e}")
sys.exit(1)
def _match_rule(self, rule: dict, relative_path_str: str, is_dir: bool) -> bool:
"""按规则匹配路径,返回是否命中"""
pattern = rule["pattern"]
dir_only = rule["dir_only"]
has_slash = rule["has_slash"]
# 目录规则:匹配目录自身或其子路径
if dir_only:
normalized = pattern.rstrip('/')
if relative_path_str == normalized or relative_path_str.startswith(normalized + '/'):
return True
return False
# 带路径分隔的规则:按相对路径匹配
if has_slash:
return fnmatch.fnmatch(relative_path_str, pattern)
# 无斜杠:匹配任意层级的基本名
if fnmatch.fnmatch(Path(relative_path_str).name, pattern):
return True
# 额外处理目录命中:无通配符时,若任一父级目录名等于 pattern 也视为命中
if pattern.isalpha() and pattern in relative_path_str.split('/'):
return True
return False
def should_exclude(self, path: Path, is_dir: bool = False) -> bool:
"""
判断路径是否应该被排除支持 ! 取反后匹配覆盖前匹配
返回 True 表示应该排除不备份
"""
try:
# 统一使用 POSIX 路径风格进行匹配
relative_path_str = path.relative_to(self.project_root).as_posix()
except ValueError:
return False # 不在项目根目录内,不处理
# Git 风格:从上到下最后一次匹配决定去留
matched = None
for rule in self.rules:
if self._match_rule(rule, relative_path_str, is_dir):
matched = not rule["negate"] # negate 表示显式允许
return bool(matched)
def create_backup(project_root: Path, output_file: Path, filter_obj: GitignoreFilter):
"""创建备份压缩包"""
# 统计信息
total_files = 0
excluded_files = 0
included_files = 0
print(f"\n{'='*60}")
print(f"开始备份项目: {project_root}")
print(f"输出文件: {output_file}")
print(f"{'='*60}\n")
try:
with tarfile.open(output_file, 'w:gz') as tar:
# 使用 os.walk 可在目录层级提前剪枝,避免进入已忽略目录
for root, dirs, files in os.walk(project_root, topdown=True):
root_path = Path(root)
# 目录剪枝:命中忽略规则或 .git 时不再深入
pruned_dirs = []
for d in dirs:
dir_path = root_path / d
if d == '.git' or filter_obj.should_exclude(dir_path, is_dir=True):
print(f" 排除目录: {dir_path.relative_to(project_root)}")
excluded_files += 1
continue
pruned_dirs.append(d)
dirs[:] = pruned_dirs
for name in files:
path = root_path / name
total_files += 1
# 文件忽略判定
if '.git' in path.parts or filter_obj.should_exclude(path):
excluded_files += 1
print(f" 排除: {path.relative_to(project_root)}")
continue
arcname = path.relative_to(project_root)
tar.add(path, arcname=arcname)
included_files += 1
print(f" 备份: {arcname}")
print(f"\n{'='*60}")
print("备份完成!")
print(f"{'='*60}")
print(f"总文件数: {total_files}")
print(f"已备份: {included_files} 个文件")
print(f"已排除: {excluded_files} 个文件/目录")
print(f"压缩包大小: {output_file.stat().st_size / 1024 / 1024:.2f} MB")
print(f"{'='*60}")
return True
except Exception as e:
print(f"\n❌ 备份失败: {e}")
import traceback
traceback.print_exc()
return False
def main():
parser = argparse.ArgumentParser(
description='快速备份项目(根据 .gitignore 排除文件)',
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
使用示例:
# 基本用法(备份到 backups/gz/ 目录)
python backups/快速备份.py
# 指定输出文件
python backups/快速备份.py -o my_backup.tar.gz
# 指定项目根目录
python backups/快速备份.py -p /path/to/project
"""
)
parser.add_argument(
'-p', '--project',
type=str,
default='.',
help='项目根目录路径(默认: 当前目录)'
)
parser.add_argument(
'-o', '--output',
type=str,
help='输出文件路径(默认: backups/备份_YYYYMMDD_HHMMSS.tar.gz'
)
parser.add_argument(
'-g', '--gitignore',
type=str,
default='.gitignore',
help='.gitignore 文件路径(默认: .gitignore'
)
args = parser.parse_args()
# 解析路径
project_root = Path(args.project).resolve()
gitignore_path = Path(args.gitignore).resolve()
if not project_root.exists():
print(f"❌ 错误: 项目目录不存在: {project_root}")
sys.exit(1)
# 确定输出文件路径
if args.output:
output_file = Path(args.output).resolve()
else:
# 默认输出到 backups/gz/ 目录
backup_dir = project_root / 'backups' / 'gz'
backup_dir.mkdir(parents=True, exist_ok=True)
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
output_file = backup_dir / f'备份_{timestamp}.tar.gz'
# 确保输出目录存在
output_file.parent.mkdir(parents=True, exist_ok=True)
# 创建过滤器
filter_obj = GitignoreFilter(gitignore_path, project_root)
# 执行备份
success = create_backup(project_root, output_file, filter_obj)
sys.exit(0 if success else 1)
if __name__ == '__main__':
main()

View File

@ -1 +0,0 @@
# Third-party libraries (read-only)

View File

@ -1,24 +0,0 @@
# 🗄️ libs/database数据库适配层预留
`libs/database/` 预留给未来的“存储适配层”。目标是把数据库的细节(连接、迁移、事务、查询)封装在一个清晰边界内,避免业务代码到处散落 SQL/ORM。
## 设计边界(先写清楚再实现)
- 这里负责连接管理、迁移脚本、ORM/SQL 模型、统一的查询/事务封装
- 这里不负责业务规则、HTTP/API 逻辑、领域对象的复杂编排
## 推荐目录结构(落地时按需取舍)
```
libs/database/
├── README.md
├── __init__.py
├── connection.py # 连接与池化
├── migrations/ # 迁移脚本Alembic/Flyway/自研均可)
├── repositories/ # 数据访问层(可选)
└── models/ # ORM 模型或 SQL schema可选
```
## 何时开始实现
当仓库出现“需要长期保存/查询的数据”且 **文件系统不够用** 时,再把这一层落地;否则保持为空,避免过早引入复杂度。

View File

@ -1 +0,0 @@
# Third-party libraries (read-only)

@ -1 +0,0 @@
Subproject commit fe6f4735bd80bf8b5ccdf8986c78c946383950c1

View File

@ -1,37 +0,0 @@
# 🔌 libs/external外部集成与第三方工具
`libs/external/` 用来收纳第三方工具、外部依赖与集成模块。核心原则是:
- **尽量原样保留**:避免“魔改后不可升级”
- **隔离依赖与风险**:外部工具的依赖不要污染主仓库
- **可追溯**:来源、许可证、用法要写清楚
## 目录结构
```
libs/external/
├── README.md
├── chat-vault/ # AI 聊天记录保存工具
├── prompts-library/ # 提示词库管理工具Excel ↔ Markdown
├── l10n-tool/ # 多语言翻译脚本
├── my-nvim/ # Neovim 配置(含 nvim-config/
├── MCPlayerTransfer/ # MC 玩家迁移工具
├── XHS-image-to-PDF-conversion/ # 图片合并 PDF 工具
└── .gitkeep
```
## 工具清单(入口与文档)
- `chat-vault/`AI 聊天记录保存工具,支持 Codex/Kiro/Gemini/Claude CLI详见 [`chat-vault/README_CN.md`](./chat-vault/README_CN.md)
- `prompts-library/`:提示词 Excel ↔ Markdown 批量互转与索引生成(详见 [`prompts-library/README.md`](./prompts-library/README.md)
- `l10n-tool/`:多语言批量翻译脚本
- `my-nvim/`:个人 Neovim 配置(详见 [`my-nvim/README.md`](./my-nvim/README.md)
- `MCPlayerTransfer/`MC 玩家迁移工具
- `XHS-image-to-PDF-conversion/`:图片合并 PDF详见 [`XHS-image-to-PDF-conversion/README.md`](./XHS-image-to-PDF-conversion/README.md)
## 新增外部工具(最小清单)
1. 创建目录:`libs/external/<tool-name>/`
2. 必备文件:`README.md`(用途/入口/依赖/输入输出)、许可证与来源说明(如 `LICENSE` / `SOURCE.md`
3. 依赖约束:尽量使用工具自带的虚拟环境/容器化方式,不影响仓库其他部分
4. 文档同步:在本 README 增加一行工具说明,保证可发现性

View File

@ -1,176 +0,0 @@
<div align="center">
# 📚 小红书图文批量转 PDF
### Batch Convert XHS Images to PDF
**一个智能 Python 脚本,用于将从小红书批量下载的 ZIP 压缩包,按顺序自动拼接为清晰的 PDF 文件。**
*A smart Python script that automatically converts ZIP archives from Xiaohongshu into well-ordered PDF files.*
---
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg?style=for-the-badge)](https://opensource.org/licenses/MIT)
[![Status: Active](https://img.shields.io/badge/Status-Active-success.svg?style=for-the-badge)]()
[![PRs Welcome](https://img.shields.io/badge/PRs-Welcome-brightgreen.svg?style=for-the-badge)]()
[![Language: Python](https://img.shields.io/badge/Language-Python-orange.svg?style=for-the-badge)]()
[✨ 功能特性](#-功能特性) • [⚙️ 工作流程](#-工作流程) • [🚀 快速开始](#-快速开始) • [🗂️ 项目结构](#-项目结构) • [🤝 参与贡献](#-参与贡献)
</div>
---
## ✨ 功能特性
| 特性 | 描述 |
|:---:|:---|
| 📦 **全自动处理** | 无需手动解压,脚本自动处理 `.zip` 压缩包。 |
| 🔢 **智能自然排序** | 完美处理 `1, 2, ... 10, 11` 这样的文件名排序,确保图片顺序正确。 |
| 🚀 **批量转换** | 支持一次性转换文件夹内的所有 `.zip` 文件,省时省力。 |
| 🗑️ **自动清理** | 转换成功后,自动删除原始的 `.zip` 文件和临时文件,保持目录整洁。 |
| 📖 **PDF 优化** | 生成的 PDF 文件经过优化,保证清晰度的同时控制文件大小。 |
| 💻 **跨平台兼容** | 依赖的 `Pillow` 库和 Python 脚本可在 Windows, macOS, Linux 上运行。 |
---
## ⚙️ 工作流程
<table>
<tr>
<td width="50%">
脚本的核心逻辑非常简单直接:监控并处理文件夹内的 ZIP 文件,通过一系列自动化步骤输出 PDF。
### 核心步骤
1. **扫描**: 查找当前目录下的所有 `.zip` 文件。
2. **解压**: 将找到的 `.zip` 文件解压到临时目录。
3. **排序**: 智能地对所有图片文件进行“自然排序”。
4. **合并**: 将排序后的图片合并成一个 PDF 文件。
5. **清理**: 删除原始的 `.zip` 文件和临时文件夹。
</td>
<td width="50%">
```mermaid
graph TD
A[📁 放置 .zip 文件] --> B{运行 pdf.py 脚本};
B --> C[🔄 解压到临时目录];
C --> D[🔢 按文件名自然排序];
D --> E[🖼️ 合并图片为 PDF];
E --> F[📄 生成 output.pdf];
F --> G[🗑️ 删除原 .zip 文件];
G --> H[✅ 完成];
```
</td>
</tr>
</table>
---
## 🚀 快速开始
### 1. 环境准备
首先,确保你的电脑上安装了 **Python 3**
然后,将本项目克隆到你的本地:
```bash
git clone https://github.com/tukuaiai/XHS-image-to-PDF-conversion.git
cd XHS-image-to-PDF-conversion
```
### 2. 安装依赖
本项目依赖 `Pillow` 库来处理图片。运行以下命令安装它:
```bash
pip install -r requirements.txt
```
或者,你也可以使用 `Makefile` (如果你的系统支持 `make`):
```bash
make install
```
### 3. 下载图文
使用你喜欢的浏览器扩展(如推荐的 **小地瓜**)从小红书下载图文,并确保它们是 `.zip` 格式。
- **小地瓜 - 小红书图片视频下载助手**: [Firefox 扩展](https://addons.mozilla.org/zh-CN/firefox/addon/%E5%B0%8F%E5%9C%B0%E7%93%9C-%E5%B0%8F%E7%BA%A2%E4%B9%A6%E5%9B%BE%E7%89%87%E8%A7%86%E9%A2%91%E4%B8%8B%E8%BD%BD%E5%8A%A9%E6%89%8B/)
### 4. 运行脚本
<details>
<summary><b>模式一:批量处理所有 ZIP 文件 (推荐)</b></summary>
1. 将所有下载的 `.zip` 文件移动到本项目文件夹中。
2. 直接运行 `pdf.bat` (Windows) 或在终端中运行以下命令:
```bash
python pdf.py
```
或者使用 `make`:
```bash
make run
```
3. 脚本会自动处理文件夹内所有的 `.zip` 文件。
</details>
<details>
<summary><b>模式二:处理单个 ZIP 文件</b></summary>
如果你只想处理一个文件,可以使用拖放或命令行参数:
1. **拖放 (Windows)**: 将一个 `.zip` 文件直接拖到 `pdf.bat` 图标上。
2. **命令行**:
```bash
python pdf.py "你的文件路径.zip"
```
</details>
---
## 🗂️ 项目结构
```
XHS-image-to-PDF-conversion/
├── .git/
├── docs/ # (未来可能添加的文档)
├── 📚...pdf # (示例文件)
├── pdf.bat # Windows 批处理脚本
├── pdf.py # 核心 Python 脚本
├── Makefile # 自动化命令
├── requirements.txt # Python 依赖
├── README.md # 你正在阅读的这个文件
├── LICENSE # MIT 许可证
├── CODE_OF_CONDUCT.md # 社区行为准则
└── CONTRIBUTING.md # 贡献指南
```
---
## 🤝 参与贡献
我们欢迎任何形式的贡献!无论是报告 Bug、提出功能建议还是直接贡献代码。
请参考我们的 [**贡献指南 (CONTRIBUTING.md)**](CONTRIBUTING.md) 来了解如何参与。
---
## 📜 许可证
本项目采用 [MIT](LICENSE) 许可证。
---
<div align="center">
**如果这个项目对你有帮助,请给一个 Star ⭐!**
[![Star History Chart](https://api.star-history.com/svg?repos=tukuaiai/XHS-image-to-PDF-conversion&type=Date)](https://star-history.com/#tukuaiai/XHS-image-to-PDF-conversion&Date)
---
**Made with 🐍 & ❤️ by tukuaiai**
[⬆ 回到顶部](#-小红书图文批量转-pdf)
</div>

View File

@ -1,2 +0,0 @@
python pdf.py
pause

View File

@ -1,195 +0,0 @@
#!/usr/bin/env python3
"""
图片ZIP转PDF脚本
将ZIP文件中的图片按序号排序并拼接成PDF文件
"""
import zipfile
import os
import re
from PIL import Image
import shutil
def 自然排序键(文件名):
"""将文件名转换为自然排序键,支持数字排序"""
return [int(text) if text.isdigit() else text.lower() for text in re.split(r'(\d+)', 文件名)]
def zip转pdf(zip路径):
"""
将ZIP文件中的图片排序后转换为PDF
Args:
zip路径: ZIP文件的完整路径
Returns:
成功返回PDF路径失败返回None
"""
try:
# 获取ZIP文件名不含扩展名
zip目录, zip文件名 = os.path.split(zip路径)
pdf名称 = os.path.splitext(zip文件名)[0] + '.pdf'
pdf路径 = os.path.join(zip目录, pdf名称)
print(f"正在处理: {zip文件名}")
# 创建临时目录解压文件
临时目录 = os.path.join(zip目录, 'temp_extract')
if os.path.exists(临时目录):
shutil.rmtree(临时目录)
os.makedirs(临时目录)
# 解压ZIP文件
with zipfile.ZipFile(zip路径, 'r') as zip文件:
zip文件.extractall(临时目录)
# 获取所有图片文件
支持的格式 = {'.jpg', '.jpeg', '.png', '.bmp', '.gif', '.tiff', '.webp'}
图片文件 = []
for 根目录, 目录, 文件列表 in os.walk(临时目录):
for 文件 in 文件列表:
if any(文件.lower().endswith(格式) for 格式 in 支持的格式):
完整路径 = os.path.join(根目录, 文件)
图片文件.append(完整路径)
if not 图片文件:
print("错误: ZIP文件中没有找到图片文件")
shutil.rmtree(临时目录)
return None
# 按文件名自然排序
图片文件.sort(key=lambda x: 自然排序键(os.path.basename(x)))
print(f"找到 {len(图片文件)} 张图片,开始转换...")
# 打开第一张图片作为基础
图片对象列表 = []
for 图片路径 in 图片文件:
try:
图片 = Image.open(图片路径)
# 转换为RGB模式确保兼容性
if 图片.mode != 'RGB':
图片 = 图片.convert('RGB')
图片对象列表.append(图片)
except Exception as e:
print(f"警告: 无法打开图片 {图片路径}: {e}")
continue
if not 图片对象列表:
print("错误: 没有成功加载任何图片")
shutil.rmtree(临时目录)
return None
# 保存为PDF第一张作为主图其余附加
图片对象列表[0].save(
pdf路径,
"PDF",
quality=95,
optimize=True,
save_all=True,
append_images=图片对象列表[1:]
)
# 关闭所有图片对象
for 图片 in 图片对象列表:
图片.close()
# 清理临时文件
shutil.rmtree(临时目录)
# 删除原ZIP文件
os.remove(zip路径)
print(f"✓ 成功创建PDF: {pdf名称}")
print(f"✓ 已删除原ZIP文件: {zip文件名}")
return pdf路径
except zipfile.BadZipFile:
print(f"错误: {zip路径} 不是有效的ZIP文件")
return None
except Exception as e:
print(f"处理过程中出错: {e}")
# 清理临时文件
if '临时目录' in locals() and os.path.exists(临时目录):
shutil.rmtree(临时目录)
return None
def 批量处理当前目录():
"""批量处理当前目录下所有ZIP文件"""
当前目录 = os.getcwd()
zip文件列表 = []
# 扫描当前目录所有ZIP文件
for 文件 in os.listdir(当前目录):
if 文件.lower().endswith('.zip'):
zip文件列表.append(os.path.join(当前目录, 文件))
if not zip文件列表:
print("当前目录下没有找到ZIP文件")
return
print(f"发现 {len(zip文件列表)} 个ZIP文件开始批量处理...")
print("-" * 50)
成功计数 = 0
失败计数 = 0
for zip路径 in zip文件列表:
print(f"\n[{zip文件列表.index(zip路径) + 1}/{len(zip文件列表)}] 处理: {os.path.basename(zip路径)}")
# 执行转换
结果 = zip转pdf(zip路径)
if 结果:
成功计数 += 1
else:
失败计数 += 1
print("-" * 50)
print(f"批量处理完成!成功: {成功计数} 个,失败: {失败计数}")
def 处理指定文件(zip路径):
"""处理指定的单个ZIP文件"""
if not os.path.exists(zip路径):
print(f"错误: 找不到文件 {zip路径}")
return False
if not zip路径.lower().endswith('.zip'):
print("错误: 请提供ZIP格式的文件")
return False
# 执行转换
结果 = zip转pdf(zip路径)
if 结果:
print(f"\n🎉 任务完成PDF文件已保存为: {结果}")
return True
else:
print("\n❌ 任务失败,请检查错误信息")
return False
def 主函数():
"""主函数:智能处理模式"""
import sys
# 优先处理指定文件(如果存在)
指定文件路径 = r"C:\Users\lenovo\Desktop\新建文件夹\剥头皮量化策略全拆解:低延迟、高频的底层.zip"
# 检查是否有命令行参数
if len(sys.argv) > 1:
# 命令行指定了ZIP文件路径
zip路径 = sys.argv[1]
print(f"通过命令行参数指定文件: {zip路径}")
处理指定文件(zip路径)
elif os.path.exists(指定文件路径):
# 处理默认指定文件
print(f"处理默认指定文件: {os.path.basename(指定文件路径)}")
处理指定文件(指定文件路径)
else:
# 自动扫描当前目录所有ZIP文件
print("开始扫描当前目录所有ZIP文件...")
批量处理当前目录()
if __name__ == "__main__":
主函数()

View File

@ -1 +0,0 @@
Pillow

View File

@ -1,11 +0,0 @@
# AI Chat Converter Configuration (Optional)
# Default: Auto-detect paths, no configuration needed
# Custom paths (comma-separated for multiple)
# CODEX_PATHS=~/.codex/sessions
# KIRO_PATHS=~/.local/share/kiro-cli
# GEMINI_PATHS=~/.gemini/tmp
# CLAUDE_PATHS=~/.claude
# WSL paths also supported
# CODEX_PATHS=\\wsl.localhost\Ubuntu\home\user\.codex\sessions

View File

@ -1,28 +0,0 @@
# Python
__pycache__/
*.py[cod]
*.so
*.egg-info/
dist/
build/
*.spec
# Output
output/
*.db
*.sqlite3
*.log
# Environment
.env
.venv/
venv/
# IDE
.vscode/
.idea/
*.swp
# OS
.DS_Store
Thumbs.db

View File

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2024
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,318 +0,0 @@
<div align="center">
# 🔐 Chat Vault
**One tool to save ALL your AI chat history**
[![Python](https://img.shields.io/badge/Python-3.8+-blue.svg)](https://python.org)
[![License](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
[![Platform](https://img.shields.io/badge/Platform-Linux%20%7C%20macOS%20%7C%20Windows-lightgrey.svg)]()
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)]()
[English](README.md) | [中文](README_CN.md)
[✨ Features](#-features) •
[🚀 Quick Start](#-quick-start) •
[📋 Commands](#-commands) •
[📁 Project Structure](#-project-structure) •
[❓ FAQ](#-faq)
[📞 Contact](#-contact) •
[✨ Support](#-support) •
[🤝 Contributing](#-contributing)
AI-powered docs: [zread.ai/tukuaiai/chat-vault](https://zread.ai/tukuaiai/chat-vault)
> 📦 This tool is part of [vibe-coding-cn](https://github.com/tukuaiai/vibe-coding-cn) - A comprehensive Vibe Coding guide
</div>
---
## ✨ Features
<table>
<tr>
<td>🔄 <b>Multi-CLI</b></td>
<td>Codex, Kiro, Gemini, Claude - all supported</td>
</tr>
<tr>
<td><b>Real-time</b></td>
<td>Watch mode with system-level file monitoring</td>
</tr>
<tr>
<td>🔢 <b>Token Stats</b></td>
<td>Accurate counting using tiktoken (cl100k_base)</td>
</tr>
<tr>
<td>🔍 <b>Search</b></td>
<td>Find any conversation instantly</td>
</tr>
<tr>
<td>📤 <b>Export</b></td>
<td>JSON or CSV, your choice</td>
</tr>
<tr>
<td>🚀 <b>Zero Config</b></td>
<td>Auto-detects paths, just run it</td>
</tr>
</table>
---
## 🏗️ Architecture
```mermaid
graph LR
subgraph Sources
A[~/.codex]
B[~/.kiro]
C[~/.gemini]
D[~/.claude]
end
subgraph Chat Vault
E[Watcher]
F[Parsers]
G[Storage]
end
subgraph Output
H[(SQLite DB)]
end
A --> E
B --> E
C --> E
D --> E
E --> F
F --> G
G --> H
```
---
## 🔄 How It Works
```mermaid
sequenceDiagram
participant User
participant CLI as AI CLI (Codex/Kiro/...)
participant Watcher
participant Parser
participant DB as SQLite
User->>CLI: Chat with AI
CLI->>CLI: Save to local file
Watcher->>Watcher: Detect file change
Watcher->>Parser: Parse new content
Parser->>DB: Upsert session
DB-->>User: Query anytime
```
---
## 🚀 Quick Start
### 30 Seconds Setup
```bash
# Clone
git clone https://github.com/tukuaiai/vibe-coding-cn.git
cd vibe-coding-cn/libs/external/chat-vault
# Run (auto-installs dependencies)
./start.sh # Linux/macOS
start.bat # Windows
```
**That's it!** 🎉
---
## 📊 Example Output
```
==================================================
AI 聊天记录 → 集中存储
==================================================
数据库: ./output/chat_history.db
[Codex] 新增:1241 更新:0 跳过:0 错误:0
[Kiro] 新增:21 更新:0 跳过:0 错误:0
[Gemini] 新增:332 更新:0 跳过:0 错误:0
[Claude] 新增:168 更新:0 跳过:0 错误:0
==================================================
总计: 1762 会话, 40000+ 消息
✓ 同步完成!
=== Token 统计 (tiktoken) ===
codex: 11,659,952 tokens
kiro: 26,337 tokens
gemini: 3,195,821 tokens
claude: 29,725 tokens
总计: 14,911,835 tokens
```
---
## 📋 Commands
| Command | Description |
|---------|-------------|
| `python src/main.py` | Sync once |
| `python src/main.py -w` | Watch mode (real-time) |
| `python src/main.py --stats` | Show statistics |
| `python src/main.py --search "keyword"` | Search messages |
| `python src/main.py --export json` | Export to JSON |
| `python src/main.py --export csv --source codex` | Export specific source |
| `python src/main.py --prune` | Clean orphaned records |
---
## 📁 Project Structure
```
chat-vault/
├── 🚀 start.sh / start.bat # One-click start
├── 📦 build.py # Build standalone exe
├── 📂 src/
│ ├── main.py # CLI entry
│ ├── config.py # Auto-detection
│ ├── storage.py # SQLite + tiktoken
│ ├── watcher.py # File monitoring
│ └── parsers/ # CLI parsers
├── 📂 docs/
│ ├── AI_PROMPT.md # AI assistant guide
│ └── schema.md # Database schema
└── 📂 output/
├── chat_history.db # Your database
└── logs/ # Sync logs
```
---
## 🗄️ Database Schema
```mermaid
erDiagram
sessions {
TEXT file_path PK
TEXT session_id
TEXT source
TEXT cwd
TEXT messages
INTEGER file_mtime
TEXT start_time
INTEGER token_count
}
meta {
TEXT key PK
TEXT value
}
meta_codex {
TEXT key PK
TEXT value
}
```
---
## 🤖 For AI Assistants
Send [docs/AI_PROMPT.md](docs/AI_PROMPT.md) to your AI assistant for:
- SQL query examples
- Python code snippets
- Task guidance
---
## ❓ FAQ
<details>
<summary><b>Do I need to configure anything?</b></summary>
No. Auto-detects `~/.codex`, `~/.kiro`, `~/.gemini`, `~/.claude`
</details>
<details>
<summary><b>Does it work with WSL?</b></summary>
Yes! Paths like `\\wsl.localhost\Ubuntu\...` are supported
</details>
<details>
<summary><b>How do I view the database?</b></summary>
Use [DB Browser for SQLite](https://sqlitebrowser.org/) or any SQLite tool
</details>
<details>
<summary><b>Is my data safe?</b></summary>
Yes. We only READ from AI tools, never modify original files
</details>
---
## 📞 Contact
- **GitHub**: [tukuaiai](https://github.com/tukuaiai)
- **Twitter / X**: [123olp](https://x.com/123olp)
- **Telegram**: [@desci0](https://t.me/desci0)
- **Telegram Group**: [glue_coding](https://t.me/glue_coding)
- **Telegram Channel**: [tradecat_ai_channel](https://t.me/tradecat_ai_channel)
- **Email**: tukuai.ai@gmail.com
---
## ✨ Support
If this project helped you, consider supporting:
- **Binance UID**: `572155580`
- **Tron (TRC20)**: `TQtBXCSTwLFHjBqTS4rNUp7ufiGx51BRey`
- **Solana**: `HjYhozVf9AQmfv7yv79xSNs6uaEU5oUk2USasYQfUYau`
- **Ethereum (ERC20)**: `0xa396923a71ee7D9480b346a17dDeEb2c0C287BBC`
- **BNB Smart Chain (BEP20)**: `0xa396923a71ee7D9480b346a17dDeEb2c0C287BBC`
- **Bitcoin**: `bc1plslluj3zq3snpnnczplu7ywf37h89dyudqua04pz4txwh8z5z5vsre7nlm`
- **Sui**: `0xb720c98a48c77f2d49d375932b2867e793029e6337f1562522640e4f84203d2e`
---
## 🤝 Contributing
We welcome all contributions! Feel free to open an [Issue](https://github.com/tukuaiai/vibe-coding-cn/issues) or submit a [Pull Request](https://github.com/tukuaiai/vibe-coding-cn/pulls).
---
## 📄 License
[MIT](LICENSE) - Do whatever you want with it.
---
<div align="center">
**If this helped you, give it a ⭐!**
## Star History
<a href="https://www.star-history.com/#tukuaiai/vibe-coding-cn&type=Date">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=tukuaiai/vibe-coding-cn&type=Date&theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=tukuaiai/vibe-coding-cn&type=Date" />
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=tukuaiai/vibe-coding-cn&type=Date" />
</picture>
</a>
---
**Made with ❤️ by [tukuaiai](https://github.com/tukuaiai)**
[⬆ Back to Top](#-chat-vault)
</div>

View File

@ -1,311 +0,0 @@
<div align="center">
# 🔐 Chat Vault
**一个工具保存你所有的 AI 聊天记录**
[![Python](https://img.shields.io/badge/Python-3.8+-blue.svg)](https://python.org)
[![License](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
[![Platform](https://img.shields.io/badge/Platform-Linux%20%7C%20macOS%20%7C%20Windows-lightgrey.svg)]()
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)]()
[English](README.md) | [中文](README_CN.md)
[✨ 功能特性](#-功能特性) •
[🚀 快速开始](#-30-秒快速开始) •
[📋 命令一览](#-命令一览) •
[📁 项目结构](#-项目结构) •
[❓ 常见问题](#-常见问题)
[📞 联系方式](#-联系方式) •
[✨ 支持项目](#-支持项目) •
[🤝 参与贡献](#-参与贡献)
AI 解读文档: [zread.ai/tukuaiai/chat-vault](https://zread.ai/tukuaiai/chat-vault)
> 📦 本工具是 [vibe-coding-cn](https://github.com/tukuaiai/vibe-coding-cn) 的一部分 - 一份全面的 Vibe Coding 指南
</div>
---
## ✨ 功能特性
<table>
<tr>
<td>🔄 <b>多 CLI 支持</b></td>
<td>Codex、Kiro、Gemini、Claude 全都行</td>
</tr>
<tr>
<td><b>实时同步</b></td>
<td>系统级文件监控,聊完自动保存</td>
</tr>
<tr>
<td>🔢 <b>Token 统计</b></td>
<td>tiktoken 精确计算,知道你用了多少</td>
</tr>
<tr>
<td>🔍 <b>搜索</b></td>
<td>秒找任何对话</td>
</tr>
<tr>
<td>📤 <b>导出</b></td>
<td>JSON 或 CSV随你选</td>
</tr>
<tr>
<td>🚀 <b>零配置</b></td>
<td>自动检测路径,开箱即用</td>
</tr>
</table>
---
## 🏗️ 架构图
```mermaid
graph LR
subgraph 数据来源
A[~/.codex]
B[~/.kiro]
C[~/.gemini]
D[~/.claude]
end
subgraph Chat Vault
E[监控器]
F[解析器]
G[存储层]
end
subgraph 输出
H[(SQLite 数据库)]
end
A --> E
B --> E
C --> E
D --> E
E --> F
F --> G
G --> H
```
---
## 🔄 工作流程
```mermaid
sequenceDiagram
participant 用户
participant CLI as AI CLI (Codex/Kiro/...)
participant 监控器
participant 解析器
participant DB as SQLite
用户->>CLI: 和 AI 聊天
CLI->>CLI: 保存到本地文件
监控器->>监控器: 检测文件变化
监控器->>解析器: 解析新内容
解析器->>DB: 写入数据库
DB-->>用户: 随时查询
```
---
## 🚀 30 秒快速开始
```bash
# 下载
git clone https://github.com/tukuaiai/vibe-coding-cn.git
cd vibe-coding-cn/libs/external/chat-vault
# 运行(自动安装依赖)
./start.sh # Linux/macOS
start.bat # Windows双击
```
**搞定!** 🎉
---
## 📊 运行效果
```
==================================================
AI 聊天记录 → 集中存储
==================================================
数据库: ./output/chat_history.db
[Codex] 新增:1241 更新:0 跳过:0 错误:0
[Kiro] 新增:21 更新:0 跳过:0 错误:0
[Gemini] 新增:332 更新:0 跳过:0 错误:0
[Claude] 新增:168 更新:0 跳过:0 错误:0
==================================================
总计: 1762 会话, 40000+ 消息
✓ 同步完成!
=== Token 统计 (tiktoken) ===
codex: 11,659,952 tokens
kiro: 26,337 tokens
gemini: 3,195,821 tokens
claude: 29,725 tokens
总计: 14,911,835 tokens
```
---
## 📋 命令一览
| 命令 | 说明 |
|------|------|
| `python src/main.py` | 同步一次 |
| `python src/main.py -w` | 实时监控(推荐) |
| `python src/main.py --stats` | 查看统计 |
| `python src/main.py --search "关键词"` | 搜索消息 |
| `python src/main.py --export json` | 导出 JSON |
| `python src/main.py --export csv --source codex` | 导出指定来源 |
| `python src/main.py --prune` | 清理孤立记录 |
---
## 📁 项目结构
```
chat-vault/
├── 🚀 start.sh / start.bat # 一键启动
├── 📦 build.py # 打包脚本
├── 📂 src/
│ ├── main.py # 主程序
│ ├── config.py # 配置检测
│ ├── storage.py # SQLite + tiktoken
│ ├── watcher.py # 文件监控
│ └── parsers/ # 各 CLI 解析器
├── 📂 docs/
│ ├── AI_PROMPT.md # AI 助手指南
│ └── schema.md # 数据库结构
└── 📂 output/
├── chat_history.db # 你的数据库
└── logs/ # 日志
```
---
## 🗄️ 数据库结构
```mermaid
erDiagram
sessions {
TEXT file_path PK "文件路径"
TEXT session_id "会话ID"
TEXT source "来源"
TEXT cwd "工作目录"
TEXT messages "消息JSON"
INTEGER file_mtime "修改时间"
TEXT start_time "开始时间"
INTEGER token_count "Token数"
}
meta {
TEXT key PK
TEXT value
}
```
---
## 🤖 让 AI 帮你查数据库
把 [docs/AI_PROMPT.md](docs/AI_PROMPT.md) 发给 AI 助手,它就知道:
- 怎么写 SQL 查询
- 怎么用 Python 分析
- 怎么帮你找对话
---
## ❓ 常见问题
<details>
<summary><b>需要配置什么吗?</b></summary>
不用。自动检测 `~/.codex`、`~/.kiro`、`~/.gemini`、`~/.claude`
</details>
<details>
<summary><b>WSL 能用吗?</b></summary>
能!`\\wsl.localhost\Ubuntu\...` 这种路径也支持
</details>
<details>
<summary><b>怎么看数据库?</b></summary>
用 [DB Browser for SQLite](https://sqlitebrowser.org/) 或任何 SQLite 工具
</details>
<details>
<summary><b>会不会搞坏我的数据?</b></summary>
不会。只读取,从不修改原始文件
</details>
---
## 📞 联系方式
- **GitHub**: [tukuaiai](https://github.com/tukuaiai)
- **Twitter / X**: [123olp](https://x.com/123olp)
- **Telegram**: [@desci0](https://t.me/desci0)
- **Telegram 交流群**: [glue_coding](https://t.me/glue_coding)
- **Telegram 频道**: [tradecat_ai_channel](https://t.me/tradecat_ai_channel)
- **邮箱**: tukuai.ai@gmail.com
---
## ✨ 支持项目
如果这个项目帮到你了,考虑支持一下:
- **币安 UID**: `572155580`
- **Tron (TRC20)**: `TQtBXCSTwLFHjBqTS4rNUp7ufiGx51BRey`
- **Solana**: `HjYhozVf9AQmfv7yv79xSNs6uaEU5oUk2USasYQfUYau`
- **Ethereum (ERC20)**: `0xa396923a71ee7D9480b346a17dDeEb2c0C287BBC`
- **BNB Smart Chain (BEP20)**: `0xa396923a71ee7D9480b346a17dDeEb2c0C287BBC`
- **Bitcoin**: `bc1plslluj3zq3snpnnczplu7ywf37h89dyudqua04pz4txwh8z5z5vsre7nlm`
- **Sui**: `0xb720c98a48c77f2d49d375932b2867e793029e6337f1562522640e4f84203d2e`
---
## 🤝 参与贡献
欢迎各种形式的贡献!随时开启一个 [Issue](https://github.com/tukuaiai/vibe-coding-cn/issues) 或提交 [Pull Request](https://github.com/tukuaiai/vibe-coding-cn/pulls)。
---
## 📄 开源协议
[MIT](LICENSE) - 随便用,不用管我
---
<div align="center">
**如果帮到你了,点个 ⭐ 呗!**
## Star History
<a href="https://www.star-history.com/#tukuaiai/vibe-coding-cn&type=Date">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=tukuaiai/vibe-coding-cn&type=Date&theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=tukuaiai/vibe-coding-cn&type=Date" />
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=tukuaiai/vibe-coding-cn&type=Date" />
</picture>
</a>
---
**Made with ❤️ by [tukuaiai](https://github.com/tukuaiai)**
[⬆ 返回顶部](#-chat-vault)
</div>

View File

@ -1,15 +0,0 @@
@echo off
echo 安装打包工具...
pip install pyinstaller -q
echo 开始打包...
pyinstaller --onefile --name ai-chat-converter ^
--add-data "src;src" ^
--hidden-import tiktoken_ext.openai_public ^
--hidden-import tiktoken_ext ^
--collect-data tiktoken ^
src/main.py
echo.
echo 完成! 输出: dist\ai-chat-converter.exe
pause

View File

@ -1,40 +0,0 @@
#!/usr/bin/env python3
"""打包脚本 - 生成独立可执行文件"""
import subprocess
import sys
import os
import shutil
def main():
os.chdir(os.path.dirname(os.path.abspath(__file__)))
for d in ['build', 'dist']:
if os.path.exists(d):
shutil.rmtree(d)
print("开始打包...")
sep = ";" if sys.platform == "win32" else ":"
cmd = [
sys.executable, "-m", "PyInstaller",
"--onefile",
"--name", "ai-chat-converter",
f"--add-data=src{sep}src",
"--hidden-import", "tiktoken_ext.openai_public",
"--hidden-import", "tiktoken_ext",
"--hidden-import", "dotenv",
"--collect-data", "tiktoken",
"--collect-all", "watchdog",
"--collect-all", "dotenv",
"src/main.py"
]
subprocess.run(cmd, check=True)
exe = "dist/ai-chat-converter.exe" if sys.platform == "win32" else "dist/ai-chat-converter"
size = os.path.getsize(exe) / 1024 / 1024
print(f"\n✓ 打包完成: {exe} ({size:.1f} MB)")
if __name__ == "__main__":
main()

View File

@ -1,231 +0,0 @@
# AI Chat Converter - AI 助手完全指南
> **把这个文档发给 AI 助手,它就知道怎么帮你用这个工具了**
---
## 🎯 这是什么?
一个把 Codex、Kiro、Gemini、Claude 的聊天记录全部存到一个 SQLite 数据库的工具。
**数据库位置**: `项目目录/output/chat_history.db`
---
## 🚀 怎么启动?
### 方式一:双击启动(推荐)
```bash
./start.sh # Linux/macOS
start.bat # Windows双击
```
### 方式二:命令行
```bash
cd ai-chat-converter
python src/main.py --watch # 持续监控(推荐)
python src/main.py # 同步一次就退出
```
### 方式三:后台运行
```bash
nohup ./start.sh > /dev/null 2>&1 &
```
---
## 📊 数据库长啥样?
### 主表sessions
| 字段 | 说明 | 例子 |
|------|------|------|
| file_path | 主键,文件路径 | `/home/user/.codex/sessions/xxx.jsonl` |
| session_id | 会话ID | `019b2164-168c-7133-9b1f-5d24fea1d3e1` |
| source | 来源 | `codex` / `kiro` / `gemini` / `claude` |
| cwd | 工作目录 | `/home/user/projects/myapp` |
| messages | 消息内容JSON | `[{"time":"...", "role":"user", "content":"..."}]` |
| start_time | 开始时间 | `2025-12-18T10:30:00` |
| token_count | Token 数量 | `1234` |
---
## 🔍 常用查询(直接复制用)
### 1. 看看有多少数据
```sql
SELECT source, COUNT(*) as 会话数, SUM(token_count) as Token总数
FROM sessions
GROUP BY source;
```
### 2. 最近的 10 个会话
```sql
SELECT session_id, source, cwd, start_time, token_count
FROM sessions
ORDER BY start_time DESC
LIMIT 10;
```
### 3. 搜索包含某个词的对话
```sql
SELECT session_id, source, cwd, start_time
FROM sessions
WHERE messages LIKE '%要搜索的词%'
ORDER BY start_time DESC
LIMIT 20;
```
### 4. 查某个项目的所有对话
```sql
SELECT session_id, source, start_time, token_count
FROM sessions
WHERE cwd LIKE '%项目名%'
ORDER BY start_time;
```
### 5. 看某个会话的完整内容
```sql
SELECT messages FROM sessions WHERE session_id = '会话ID';
```
### 6. 统计每天用了多少 Token
```sql
SELECT
date(start_time) as 日期,
SUM(token_count) as Token数
FROM sessions
GROUP BY 日期
ORDER BY 日期 DESC
LIMIT 7;
```
### 7. 统计每个来源的 Token
```sql
SELECT source, SUM(token_count) as tokens
FROM sessions
GROUP BY source
ORDER BY tokens DESC;
```
---
## 💻 命令行用法
| 命令 | 干啥的 |
|------|--------|
| `python src/main.py` | 同步一次 |
| `python src/main.py -w` | 持续监控(推荐) |
| `python src/main.py --stats` | 看统计信息 |
| `python src/main.py --search "关键词"` | 搜索 |
| `python src/main.py --export json` | 导出 JSON |
| `python src/main.py --export csv` | 导出 CSV |
| `python src/main.py --prune` | 清理已删除文件的记录 |
---
## 🐍 用 Python 查询
```python
import sqlite3
import json
# 连接数据库
db = sqlite3.connect('output/chat_history.db')
# 查所有 Codex 会话
for row in db.execute("SELECT session_id, cwd, token_count FROM sessions WHERE source='codex'"):
print(f"{row[0]}: {row[2]} tokens - {row[1]}")
# 搜索包含 "python" 的对话
for row in db.execute("SELECT session_id, source FROM sessions WHERE messages LIKE '%python%'"):
print(f"[{row[1]}] {row[0]}")
# 获取某个会话的消息
row = db.execute("SELECT messages FROM sessions WHERE session_id=?", ('会话ID',)).fetchone()
if row:
messages = json.loads(row[0])
for msg in messages:
print(f"{msg['role']}: {msg['content'][:100]}...")
```
---
## 📁 文件在哪?
```
ai-chat-converter/
├── start.sh ← 双击这个启动
├── output/
│ ├── chat_history.db ← 数据库在这
│ └── logs/ ← 日志在这
└── src/
└── main.py ← 主程序
```
---
## ❓ AI 助手任务示例
当用户说这些话时,你应该这样做:
| 用户说 | 你做 |
|--------|------|
| "帮我查最近的对话" | 执行最近会话 SQL |
| "搜索关于 Python 的讨论" | 用 `--search` 或 SQL 搜索 |
| "这个月用了多少 Token" | 执行 Token 统计 SQL |
| "导出所有 Codex 记录" | `python src/main.py --export json --source codex` |
| "启动监控" | `./start.sh``python src/main.py -w` |
| "数据库在哪" | `output/chat_history.db` |
---
## 🔧 出问题了?
### 问题:找不到数据库
```bash
# 先运行一次同步
python src/main.py
```
### 问题:依赖没装
```bash
pip install -r requirements.txt
```
### 问题:权限不够
```bash
chmod +x start.sh
```
---
## 📊 消息格式
数据库里的 `messages` 字段是 JSON 数组:
```json
[
{
"time": "2025-12-18T10:30:00",
"role": "user",
"content": "帮我写个 Python 脚本"
},
{
"time": "2025-12-18T10:30:05",
"role": "ai",
"content": "好的,这是一个简单的脚本..."
}
]
```
- `role`: `user`(用户)或 `ai`AI 回复)
- `time`: ISO 格式时间
- `content`: 消息内容

View File

@ -1,15 +0,0 @@
# Roadmap
## v1.0 ✅ Core
- [x] Multi-CLI support (Codex/Kiro/Gemini/Claude)
- [x] Auto path detection
- [x] SQLite storage
- [x] Incremental sync
- [x] Cross-platform watch mode (watchdog)
- [x] Token counting (tiktoken)
## Future
- [ ] Web UI
- [ ] API server mode
- [ ] Vector storage (RAG)
- [ ] Cross-AI context sharing

View File

@ -1,49 +0,0 @@
# 数据库结构 (v5)
**位置**: `项目目录/output/chat_history.db`
## sessions 表(主表)
| 字段 | 类型 | 说明 |
|------|------|------|
| file_path | TEXT | 主键,源文件路径 |
| session_id | TEXT | 会话 ID |
| source | TEXT | 来源: codex/kiro/gemini/claude |
| cwd | TEXT | 工作目录 |
| messages | TEXT | JSON 数组 |
| file_mtime | INTEGER | 文件修改时间戳 |
| start_time | TEXT | 会话开始时间 |
| token_count | INTEGER | Token 数量 |
**索引**: `idx_source`, `idx_session_id`, `idx_start_time`
## meta 表(全局统计)
| key | 说明 |
|-----|------|
| schema_version | 数据库版本 (5) |
| total_sessions | 总会话数 |
| total_messages | 总消息数 |
| total_tokens | 总 Token 数 |
| last_sync | 最后同步时间 |
## meta_{cli} 表(各 CLI 统计)
每个 CLI 独立的元信息表:`meta_codex`, `meta_kiro`, `meta_gemini`, `meta_claude`
| key | 说明 |
|-----|------|
| path | 监控路径 |
| sessions | 会话数 |
| messages | 消息数 |
| total_tokens | Token 总数 |
| last_sync | 最后同步时间 |
## 消息格式
```json
[
{"time": "2025-12-18T10:30:00", "role": "user", "content": "..."},
{"time": "2025-12-18T10:30:05", "role": "ai", "content": "..."}
]
```

View File

@ -1,3 +0,0 @@
python-dotenv>=1.0.0
watchdog>=3.0.0
tiktoken>=0.5.0

View File

@ -1,3 +0,0 @@
#!/bin/bash
cd "$(dirname "$0")/../src"
python3 main.py

View File

@ -1,3 +0,0 @@
#!/bin/bash
cd "$(dirname "$0")/../src"
python3 main.py --watch

View File

@ -1,69 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
r"""
配置模块 - 智能路径识别
支持: Linux 原生路径WSL 路径 (\\wsl.localhost\Ubuntu\...)
"""
import os
import re
from dotenv import load_dotenv
# 项目目录
PROJECT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
OUTPUT_DIR = os.path.join(PROJECT_DIR, "output")
load_dotenv(os.path.join(PROJECT_DIR, ".env"))
def convert_wsl_path(path: str) -> str:
match = re.match(r'^\\\\wsl[.\$]?[^\\]*\\[^\\]+\\(.+)$', path, re.IGNORECASE)
if match:
return '/' + match.group(1).replace('\\', '/')
return path
def normalize_path(path: str) -> str:
path = path.strip()
path = convert_wsl_path(path)
return os.path.expanduser(path)
def get_paths(env_key: str) -> list:
val = os.getenv(env_key, "")
if not val:
return []
return [normalize_path(p) for p in val.split(",") if p.strip()]
def auto_detect_paths() -> dict:
home = os.path.expanduser("~")
kiro_db = os.path.join(home, ".local", "share", "kiro-cli")
candidates = {
"codex_paths": [os.path.join(home, ".codex", "sessions"), os.path.join(home, ".codex")],
"kiro_paths": [kiro_db] if os.path.exists(kiro_db) else [],
"gemini_paths": [os.path.join(home, ".gemini", "tmp"), os.path.join(home, ".gemini")],
"claude_paths": [os.path.join(home, ".claude")],
}
detected = {}
for key, paths in candidates.items():
for p in paths:
if os.path.exists(p):
detected[key] = [p]
break
if key not in detected:
detected[key] = []
return detected
def load_config() -> dict:
auto = auto_detect_paths()
os.makedirs(OUTPUT_DIR, exist_ok=True)
os.makedirs(os.path.join(OUTPUT_DIR, "logs"), exist_ok=True)
return {
"codex_paths": get_paths("CODEX_PATHS") or auto.get("codex_paths", []),
"kiro_paths": get_paths("KIRO_PATHS") or auto.get("kiro_paths", []),
"gemini_paths": get_paths("GEMINI_PATHS") or auto.get("gemini_paths", []),
"claude_paths": get_paths("CLAUDE_PATHS") or auto.get("claude_paths", []),
"output_dir": OUTPUT_DIR,
"log_dir": os.path.join(OUTPUT_DIR, "logs"),
"db_path": os.path.join(OUTPUT_DIR, "chat_history.db"),
}
CONFIG = load_config()

View File

@ -1,42 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""日志模块 - 同时输出到控制台和文件"""
import logging
import os
from datetime import datetime
_logger = None
def setup_logger(log_dir: str = None) -> logging.Logger:
global _logger
if _logger:
return _logger
_logger = logging.getLogger('ai_chat_converter')
_logger.setLevel(logging.DEBUG)
_logger.handlers.clear()
fmt = logging.Formatter('%(asctime)s [%(levelname)s] %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
# 控制台
ch = logging.StreamHandler()
ch.setLevel(logging.INFO)
ch.setFormatter(fmt)
_logger.addHandler(ch)
# 文件
if log_dir:
os.makedirs(log_dir, exist_ok=True)
log_file = os.path.join(log_dir, f"sync_{datetime.now().strftime('%Y%m%d')}.log")
fh = logging.FileHandler(log_file, encoding='utf-8')
fh.setLevel(logging.DEBUG)
fh.setFormatter(fmt)
_logger.addHandler(fh)
return _logger
def get_logger() -> logging.Logger:
global _logger
if not _logger:
_logger = setup_logger()
return _logger

View File

@ -1,319 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
AI 聊天记录集中存储工具
命令:
python main.py # 同步一次
python main.py --watch # 持续监控
python main.py --prune # 清理孤立记录
python main.py --stats # 显示统计
python main.py --search <keyword> # 搜索
python main.py --export json|csv [--source codex|kiro|gemini|claude]
"""
import os
import sys
import subprocess
# 项目根目录
PROJECT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
VENV_DIR = os.path.join(PROJECT_DIR, '.venv')
REQUIREMENTS = os.path.join(PROJECT_DIR, 'requirements.txt')
def ensure_venv():
"""检测并创建虚拟环境,安装依赖"""
# 打包版本跳过
if getattr(sys, 'frozen', False):
return
# 已在虚拟环境中运行则跳过
if sys.prefix != sys.base_prefix:
return
# 检查 .venv 是否存在
venv_python = os.path.join(VENV_DIR, 'bin', 'python') if os.name != 'nt' else os.path.join(VENV_DIR, 'Scripts', 'python.exe')
if not os.path.exists(venv_python):
print("首次运行,创建虚拟环境...")
subprocess.run([sys.executable, '-m', 'venv', VENV_DIR], check=True)
print("安装依赖...")
pip = os.path.join(VENV_DIR, 'bin', 'pip') if os.name != 'nt' else os.path.join(VENV_DIR, 'Scripts', 'pip.exe')
subprocess.run([pip, 'install', '-r', REQUIREMENTS, '-q'], check=True)
print("环境准备完成,重新启动...\n")
# 使用虚拟环境重新执行
os.execv(venv_python, [venv_python] + sys.argv)
# 启动前检测虚拟环境
ensure_venv()
# 支持 PyInstaller 打包
if getattr(sys, 'frozen', False):
BASE_DIR = sys._MEIPASS
sys.path.insert(0, os.path.join(BASE_DIR, 'src'))
else:
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
import argparse
from config import CONFIG
from parsers import CodexParser, GeminiParser, ClaudeParser, KiroParser
from storage import ChatStorage
from logger import setup_logger, get_logger
storage: ChatStorage = None
def main():
global storage
parser = argparse.ArgumentParser(description='AI Chat Converter')
parser.add_argument('-w', '--watch', action='store_true', help='持续监控模式')
parser.add_argument('--prune', action='store_true', help='清理孤立记录')
parser.add_argument('--stats', action='store_true', help='显示统计信息')
parser.add_argument('--search', type=str, help='搜索关键词')
parser.add_argument('--export', choices=['json', 'csv'], help='导出格式')
parser.add_argument('--source', choices=['codex', 'kiro', 'gemini', 'claude'], help='指定来源')
parser.add_argument('--output', type=str, help='导出文件路径')
args = parser.parse_args()
# 初始化
setup_logger(CONFIG["log_dir"])
log = get_logger()
storage = ChatStorage(CONFIG["db_path"])
# 命令分发
if args.prune:
cmd_prune()
elif args.stats:
cmd_stats()
elif args.search:
cmd_search(args.search, args.source)
elif args.export:
cmd_export(args.export, args.source, args.output)
elif args.watch:
cmd_sync()
cmd_watch()
else:
cmd_sync()
def cmd_sync():
log = get_logger()
log.info("=" * 50)
log.info("AI 聊天记录 → 集中存储")
log.info("=" * 50)
log.info(f"数据库: {CONFIG['db_path']}")
total_added, total_updated, total_skipped, total_errors = 0, 0, 0, 0
for cli, key, parser_cls in [
('codex', 'codex_paths', lambda: CodexParser('codex')),
('kiro', 'kiro_paths', KiroParser),
('gemini', 'gemini_paths', GeminiParser),
('claude', 'claude_paths', ClaudeParser),
]:
paths = CONFIG.get(key, [])
if not paths:
continue
parser = parser_cls()
if cli in ('claude', 'kiro'):
a, u, s, e = process_multi(parser, paths, cli)
else:
a, u, s, e = process(parser, paths)
log.info(f"[{cli.capitalize()}] 新增:{a} 更新:{u} 跳过:{s} 错误:{e}")
update_cli_meta(cli)
total_added += a
total_updated += u
total_skipped += s
total_errors += e
total = storage.get_total_stats()
storage.update_total_meta(total['sessions'], total['messages'], total['tokens'])
log.info("=" * 50)
log.info(f"总计: {total['sessions']} 会话, {total['messages']} 消息")
if total_errors > 0:
log.warning(f"错误: {total_errors} 个文件解析失败")
log.info("✓ 同步完成!")
print_token_stats()
def cmd_watch():
from watcher import ChatWatcher
from datetime import datetime
log = get_logger()
log.info("")
log.info("=" * 50)
log.info("实时监听模式 (watchdog)")
log.info("=" * 50)
watch_paths = []
path_source_map = {}
for cli, key in [('codex', 'codex_paths'), ('kiro', 'kiro_paths'),
('gemini', 'gemini_paths'), ('claude', 'claude_paths')]:
for p in CONFIG.get(key, []):
if os.path.isdir(p) or os.path.isfile(p):
watch_paths.append(p)
path_source_map[p] = cli
def on_change(file_path, event_type):
now = datetime.now().strftime('%H:%M:%S')
source = None
for p, s in path_source_map.items():
if file_path.startswith(p) or file_path == p:
source = s
break
if not source:
return
try:
if source == 'kiro':
parser = KiroParser()
for sess in parser.parse_file(file_path):
storage.upsert_session(sess.session_id, sess.source, sess.file_path, sess.cwd, sess.messages, int(sess.file_mtime))
log.info(f"[{now}] kiro 更新")
elif source == 'claude':
parser = ClaudeParser()
for sess in parser.parse_file(file_path):
fp = f"claude:{sess.session_id}"
storage.upsert_session(sess.session_id, sess.source, fp, sess.cwd, sess.messages, int(sess.file_mtime))
log.info(f"[{now}] claude 更新")
else:
parser = CodexParser(source) if source == 'codex' else GeminiParser()
sess = parser.parse_file(file_path)
fp = os.path.abspath(sess.file_path)
storage.upsert_session(sess.session_id, sess.source, fp, sess.cwd, sess.messages, int(sess.file_mtime))
log.info(f"[{now}] {source} {event_type}: {os.path.basename(file_path)}")
update_cli_meta(source)
total = storage.get_total_stats()
storage.update_total_meta(total['sessions'], total['messages'], total['tokens'])
except Exception as e:
log.error(f"[{now}] 处理失败 {file_path}: {e}")
log.info(f"监听目录: {len(watch_paths)}")
watcher = ChatWatcher(watch_paths, on_change)
watcher.start()
def cmd_prune():
log = get_logger()
log.info("清理孤立记录...")
removed = storage.prune()
total = sum(removed.values())
if total > 0:
for cli, count in removed.items():
if count > 0:
log.info(f" {cli}: 删除 {count}")
log.info(f"✓ 共清理 {total} 条孤立记录")
else:
log.info("✓ 无孤立记录")
def cmd_stats():
log = get_logger()
meta = storage.get_total_meta()
tokens = storage.get_token_stats()
log.info("=" * 50)
log.info("统计信息")
log.info("=" * 50)
log.info(f"数据库: {CONFIG['db_path']}")
log.info(f"总会话: {meta['total_sessions']}")
log.info(f"总消息: {meta['total_messages']}")
log.info(f"最后同步: {meta['last_sync']}")
log.info("")
log.info("Token 统计 (tiktoken):")
total_tokens = 0
for source in ['codex', 'kiro', 'gemini', 'claude']:
t = tokens.get(source, 0)
if t > 0:
log.info(f" {source}: {t:,}")
total_tokens += t
log.info(f" 总计: {total_tokens:,}")
def cmd_search(keyword: str, source: str = None):
log = get_logger()
results = storage.search(keyword, source)
log.info(f"搜索 '{keyword}' 找到 {len(results)} 个会话:")
for r in results[:20]:
log.info(f" [{r['source']}] {r['session_id']} - {r['cwd'] or 'N/A'}")
def cmd_export(fmt: str, source: str = None, output: str = None):
log = get_logger()
if not output:
output = os.path.join(CONFIG["output_dir"], f"export.{fmt}")
if fmt == 'json':
count = storage.export_json(output, source)
else:
count = storage.export_csv(output, source)
log.info(f"✓ 导出 {count} 条到 {output}")
def print_token_stats():
log = get_logger()
tokens = storage.get_token_stats()
log.info("")
log.info("=== Token 统计 (tiktoken) ===")
total = 0
for source in ['codex', 'kiro', 'gemini', 'claude']:
t = tokens.get(source, 0)
if t > 0:
log.info(f" {source}: {t:,} tokens")
total += t
log.info(f" 总计: {total:,} tokens")
def update_cli_meta(cli: str):
stats = storage.get_cli_stats(cli)
path = CONFIG.get(f"{cli}_paths", [""])[0] if CONFIG.get(f"{cli}_paths") else ""
storage.update_cli_meta(cli, path, stats['sessions'], stats['messages'], stats['tokens'])
def process(parser, paths) -> tuple:
log = get_logger()
added, updated, skipped, errors = 0, 0, 0, 0
for f in parser.find_files(paths):
try:
s = parser.parse_file(f)
file_path = os.path.abspath(s.file_path)
db_mtime = storage.get_file_mtime(file_path)
file_mtime = int(s.file_mtime)
if db_mtime == 0:
storage.upsert_session(s.session_id, s.source, file_path, s.cwd, s.messages, file_mtime)
added += 1
elif file_mtime > db_mtime:
storage.upsert_session(s.session_id, s.source, file_path, s.cwd, s.messages, file_mtime)
updated += 1
else:
skipped += 1
except Exception as e:
log.debug(f"解析失败 {f}: {e}")
errors += 1
return added, updated, skipped, errors
def process_multi(parser, paths, source: str) -> tuple:
"""处理返回多个会话的解析器Claude/Kiro"""
log = get_logger()
added, updated, skipped, errors = 0, 0, 0, 0
for f in parser.find_files(paths):
try:
for s in parser.parse_file(f):
file_path = s.file_path # kiro:xxx 或 claude:xxx
db_mtime = storage.get_file_mtime(file_path)
file_mtime = int(s.file_mtime)
if db_mtime == 0:
storage.upsert_session(s.session_id, s.source, file_path, s.cwd, s.messages, file_mtime)
added += 1
elif file_mtime > db_mtime:
storage.upsert_session(s.session_id, s.source, file_path, s.cwd, s.messages, file_mtime)
updated += 1
else:
skipped += 1
except Exception as e:
log.debug(f"解析失败 {f}: {e}")
errors += 1
return added, updated, skipped, errors
if __name__ == '__main__':
main()

View File

@ -1,7 +0,0 @@
from .codex import CodexParser
from .gemini import GeminiParser
from .claude import ClaudeParser
from .kiro import KiroParser
from .base import SessionData
__all__ = ["CodexParser", "GeminiParser", "ClaudeParser", "KiroParser", "SessionData"]

View File

@ -1,24 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from abc import ABC, abstractmethod
from dataclasses import dataclass, field
from typing import List, Dict
@dataclass
class SessionData:
"""会话数据"""
session_id: str
source: str
file_path: str
file_mtime: float = 0
cwd: str = None
messages: List[Dict] = field(default_factory=list) # [{"time", "role", "content"}]
class BaseParser(ABC):
@abstractmethod
def find_files(self, paths: list) -> list:
pass
@abstractmethod
def parse_file(self, filepath: str) -> SessionData:
pass

View File

@ -1,54 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import json
import hashlib
from datetime import datetime
from collections import defaultdict
from .base import BaseParser, SessionData
class ClaudeParser(BaseParser):
def find_files(self, paths: list) -> list:
files = []
for base in paths:
history = os.path.join(base, "history.jsonl")
if os.path.exists(history):
files.append(history)
return files
def parse_file(self, filepath: str) -> list:
"""返回多个 SessionData按 project 分组)"""
projects = defaultdict(list)
file_mtime = os.path.getmtime(filepath)
with open(filepath, 'r', encoding='utf-8') as f:
for line in f:
line = line.strip()
if not line:
continue
data = json.loads(line)
content = data.get('display', '')
if not content:
continue
project = data.get('project', 'unknown')
ts_ms = data.get('timestamp', 0)
ts = datetime.fromtimestamp(ts_ms / 1000).isoformat() if ts_ms else ''
projects[project].append({
'time': ts,
'role': 'user',
'content': content
})
return [
SessionData(
session_id='claude-' + hashlib.md5(proj.encode()).hexdigest()[:12],
source='claude',
file_path=filepath,
file_mtime=file_mtime,
cwd=proj,
messages=msgs
)
for proj, msgs in projects.items()
]

View File

@ -1,70 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import json
import re
from .base import BaseParser, SessionData
class CodexParser(BaseParser):
def __init__(self, source: str = 'codex'):
self.source = source
def find_files(self, paths: list) -> list:
files = []
for base in paths:
if not os.path.exists(base):
continue
for root, _, names in os.walk(base):
for f in names:
if f.endswith('.jsonl') and f != 'history.jsonl':
files.append(os.path.join(root, f))
return files
def _extract_id(self, filepath: str) -> str:
match = re.search(r'([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})',
os.path.basename(filepath))
return match.group(1) if match else os.path.basename(filepath).replace('.jsonl', '')
def parse_file(self, filepath: str) -> SessionData:
s = SessionData(
session_id=self._extract_id(filepath),
source=self.source,
file_path=filepath,
file_mtime=os.path.getmtime(filepath)
)
with open(filepath, 'r', encoding='utf-8', errors='ignore') as f:
for line in f:
line = line.strip()
if not line or line[0] != '{':
continue
try:
data = json.loads(line)
except json.JSONDecodeError:
continue
if data.get('type') == 'session_meta':
p = data.get('payload', {})
s.cwd = p.get('cwd')
s.session_id = p.get('id', s.session_id)
continue
if data.get('type') != 'response_item':
continue
payload = data.get('payload', {})
if payload.get('type') != 'message':
continue
role = payload.get('role')
if role not in ('user', 'assistant'):
continue
parts = [item.get('text', '') for item in payload.get('content', [])
if isinstance(item, dict) and item.get('type') in ('input_text', 'output_text', 'text')]
if parts:
s.messages.append({
'time': data.get('timestamp', ''),
'role': 'user' if role == 'user' else 'ai',
'content': ' '.join(parts)
})
return s

View File

@ -1,40 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import glob
import json
from .base import BaseParser, SessionData
class GeminiParser(BaseParser):
def find_files(self, paths: list) -> list:
files = []
for base in paths:
if os.path.exists(base):
files.extend(glob.glob(os.path.join(base, "*", "chats", "*.json")))
return files
def parse_file(self, filepath: str) -> SessionData:
s = SessionData(
session_id=os.path.basename(filepath).replace('.json', ''),
source='gemini',
file_path=filepath,
file_mtime=os.path.getmtime(filepath)
)
with open(filepath, 'r', encoding='utf-8') as f:
data = json.load(f)
s.session_id = data.get('sessionId', s.session_id)
for msg in data.get('messages', []):
if msg.get('type') not in ('user', 'gemini'):
continue
content = msg.get('content', '')
if content:
s.messages.append({
'time': msg.get('timestamp', ''),
'role': 'user' if msg.get('type') == 'user' else 'ai',
'content': content
})
return s

View File

@ -1,75 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Kiro CLI 解析器 - 从 SQLite 数据库读取"""
import os
import json
import sqlite3
import hashlib
from datetime import datetime
from .base import BaseParser, SessionData
KIRO_DB = os.path.expanduser("~/.local/share/kiro-cli/data.sqlite3")
class KiroParser(BaseParser):
def find_files(self, paths: list) -> list:
"""返回数据库路径(如果存在)"""
if os.path.exists(KIRO_DB):
return [KIRO_DB]
return []
def parse_file(self, filepath: str) -> list:
"""解析 Kiro SQLite 数据库,返回多个 SessionData"""
sessions = []
file_mtime = os.path.getmtime(filepath)
conn = sqlite3.connect(filepath)
for row in conn.execute('SELECT key, value FROM conversations'):
cwd, value = row
try:
data = json.loads(value)
except json.JSONDecodeError:
continue
conv_id = data.get('conversation_id', hashlib.md5(cwd.encode()).hexdigest()[:12])
history = data.get('history', [])
messages = []
for item in history:
# 用户消息
if 'user' in item:
user = item['user']
content = user.get('content', {})
if isinstance(content, dict) and 'Prompt' in content:
prompt = content['Prompt'].get('prompt', '')
if prompt:
messages.append({
'time': '',
'role': 'user',
'content': prompt
})
# AI 回复
if 'assistant' in item:
assistant = item['assistant']
content = assistant.get('content', {})
if isinstance(content, dict) and 'Message' in content:
msg = content['Message'].get('message', '')
if msg:
messages.append({
'time': '',
'role': 'ai',
'content': msg
})
if messages:
sessions.append(SessionData(
session_id=f'kiro-{conv_id[:12]}',
source='kiro',
file_path=f'kiro:{conv_id}',
file_mtime=file_mtime,
cwd=cwd,
messages=messages
))
conn.close()
return sessions

View File

@ -1,246 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""SQLite 存储模块 - 完整版"""
import sqlite3
import json
import os
import datetime
import tiktoken
SCHEMA_VERSION = 5
CLIS = ('codex', 'kiro', 'gemini', 'claude')
_encoder = tiktoken.get_encoding("cl100k_base")
def count_tokens(text: str) -> int:
return len(_encoder.encode(text)) if text else 0
class ChatStorage:
def __init__(self, db_path: str):
self.db_path = db_path
os.makedirs(os.path.dirname(db_path) or '.', exist_ok=True)
self._init_db()
def _conn(self):
return sqlite3.connect(self.db_path)
def _init_db(self):
with self._conn() as conn:
conn.execute('''CREATE TABLE IF NOT EXISTS meta (key TEXT PRIMARY KEY, value TEXT)''')
for cli in CLIS:
conn.execute(f'''CREATE TABLE IF NOT EXISTS meta_{cli} (key TEXT PRIMARY KEY, value TEXT)''')
conn.execute('''
CREATE TABLE IF NOT EXISTS sessions (
file_path TEXT PRIMARY KEY,
session_id TEXT,
source TEXT NOT NULL,
cwd TEXT,
messages TEXT,
file_mtime INTEGER,
start_time TEXT,
token_count INTEGER DEFAULT 0
)
''')
conn.execute('CREATE INDEX IF NOT EXISTS idx_source ON sessions(source)')
conn.execute('CREATE INDEX IF NOT EXISTS idx_session_id ON sessions(session_id)')
conn.execute('CREATE INDEX IF NOT EXISTS idx_start_time ON sessions(start_time)')
self._set_meta('meta', 'schema_version', str(SCHEMA_VERSION))
def _set_meta(self, table: str, key: str, value: str):
with self._conn() as conn:
conn.execute(f'INSERT OR REPLACE INTO {table} (key, value) VALUES (?, ?)', (key, value))
def _get_meta(self, table: str, key: str) -> str:
with self._conn() as conn:
row = conn.execute(f'SELECT value FROM {table} WHERE key = ?', (key,)).fetchone()
return row[0] if row else None
def update_cli_meta(self, cli: str, path: str, sessions: int, messages: int, tokens: int = None):
table = f'meta_{cli}'
now = datetime.datetime.now().isoformat()
# 顺序: path, sessions, messages, total_tokens, last_sync
self._set_meta(table, 'path', path)
self._set_meta(table, 'sessions', str(sessions))
self._set_meta(table, 'messages', str(messages))
self._set_meta(table, 'total_tokens', str(tokens or 0))
self._set_meta(table, 'last_sync', now)
def update_total_meta(self, sessions: int, messages: int, tokens: int = None):
now = datetime.datetime.now().isoformat()
self._set_meta('meta', 'total_sessions', str(sessions))
self._set_meta('meta', 'total_messages', str(messages))
if tokens is not None:
self._set_meta('meta', 'total_tokens', str(tokens))
self._set_meta('meta', 'last_sync', now)
def get_total_meta(self) -> dict:
return {
'schema_version': int(self._get_meta('meta', 'schema_version') or 0),
'total_sessions': int(self._get_meta('meta', 'total_sessions') or 0),
'total_messages': int(self._get_meta('meta', 'total_messages') or 0),
'last_sync': self._get_meta('meta', 'last_sync'),
}
def get_file_mtime(self, file_path: str) -> int:
with self._conn() as conn:
row = conn.execute('SELECT file_mtime FROM sessions WHERE file_path = ?', (file_path,)).fetchone()
return row[0] if row else 0
def upsert_session(self, session_id: str, source: str, file_path: str,
cwd: str, messages: list, file_mtime: int, start_time: str = None):
if file_path and not file_path.startswith('claude:') and not os.path.isabs(file_path):
file_path = os.path.abspath(file_path)
total_tokens = sum(count_tokens(msg.get('content', '')) for msg in messages)
if not start_time and messages:
start_time = messages[0].get('time')
messages_json = json.dumps(messages, ensure_ascii=False)
with self._conn() as conn:
conn.execute('''
INSERT INTO sessions (file_path, session_id, source, cwd, messages, file_mtime, start_time, token_count)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
ON CONFLICT(file_path) DO UPDATE SET
session_id=excluded.session_id, messages=excluded.messages,
file_mtime=excluded.file_mtime, start_time=excluded.start_time, token_count=excluded.token_count
''', (file_path, session_id, source, cwd, messages_json, file_mtime, start_time, total_tokens))
def get_cli_stats(self, cli: str) -> dict:
with self._conn() as conn:
sessions = conn.execute('SELECT COUNT(*) FROM sessions WHERE source = ?', (cli,)).fetchone()[0]
row = conn.execute('SELECT SUM(json_array_length(messages)) FROM sessions WHERE source = ?', (cli,)).fetchone()
messages = row[0] or 0
tokens = conn.execute('SELECT SUM(token_count) FROM sessions WHERE source = ?', (cli,)).fetchone()[0] or 0
return {'sessions': sessions, 'messages': messages, 'tokens': tokens}
def get_total_stats(self) -> dict:
with self._conn() as conn:
sessions = conn.execute('SELECT COUNT(*) FROM sessions').fetchone()[0]
row = conn.execute('SELECT SUM(json_array_length(messages)) FROM sessions').fetchone()
messages = row[0] or 0
tokens = conn.execute('SELECT SUM(token_count) FROM sessions').fetchone()[0] or 0
return {'sessions': sessions, 'messages': messages, 'tokens': tokens}
def get_token_stats(self) -> dict:
with self._conn() as conn:
rows = conn.execute('SELECT source, SUM(token_count) FROM sessions GROUP BY source').fetchall()
return {r[0]: r[1] or 0 for r in rows}
# === 清理孤立记录 ===
def prune(self) -> dict:
"""删除源文件已不存在的记录"""
removed = {'codex': 0, 'kiro': 0, 'gemini': 0, 'claude': 0}
with self._conn() as conn:
rows = conn.execute('SELECT file_path, source FROM sessions').fetchall()
for fp, source in rows:
if fp.startswith('claude:'):
continue # Claude 使用虚拟路径
if not os.path.exists(fp):
conn.execute('DELETE FROM sessions WHERE file_path = ?', (fp,))
removed[source] = removed.get(source, 0) + 1
return removed
# === 查询 ===
def search(self, keyword: str, source: str = None, limit: int = 50) -> list:
"""搜索消息内容"""
sql = "SELECT file_path, session_id, source, cwd, messages, start_time FROM sessions WHERE messages LIKE ?"
params = [f'%{keyword}%']
if source:
sql += " AND source = ?"
params.append(source)
sql += f" ORDER BY start_time DESC LIMIT {limit}"
results = []
with self._conn() as conn:
for row in conn.execute(sql, params):
results.append({
'file_path': row[0], 'session_id': row[1], 'source': row[2],
'cwd': row[3], 'messages': json.loads(row[4]), 'start_time': row[5]
})
return results
def get_session(self, file_path: str) -> dict:
"""获取单个会话"""
with self._conn() as conn:
row = conn.execute(
'SELECT file_path, session_id, source, cwd, messages, start_time, token_count FROM sessions WHERE file_path = ?',
(file_path,)
).fetchone()
if not row:
return None
return {
'file_path': row[0], 'session_id': row[1], 'source': row[2], 'cwd': row[3],
'messages': json.loads(row[4]), 'start_time': row[5], 'token_count': row[6]
}
def list_sessions(self, source: str = None, limit: int = 100, offset: int = 0) -> list:
"""列出会话"""
sql = "SELECT file_path, session_id, source, cwd, start_time, token_count FROM sessions"
params = []
if source:
sql += " WHERE source = ?"
params.append(source)
sql += f" ORDER BY start_time DESC LIMIT {limit} OFFSET {offset}"
results = []
with self._conn() as conn:
for row in conn.execute(sql, params):
results.append({
'file_path': row[0], 'session_id': row[1], 'source': row[2],
'cwd': row[3], 'start_time': row[4], 'token_count': row[5]
})
return results
# === 导出 ===
def export_json(self, output_path: str, source: str = None):
"""导出为 JSON"""
sql = "SELECT file_path, session_id, source, cwd, messages, start_time, token_count FROM sessions"
params = []
if source:
sql += " WHERE source = ?"
params.append(source)
sql += " ORDER BY start_time"
data = []
with self._conn() as conn:
for row in conn.execute(sql, params):
data.append({
'file_path': row[0], 'session_id': row[1], 'source': row[2], 'cwd': row[3],
'messages': json.loads(row[4]), 'start_time': row[5], 'token_count': row[6]
})
with open(output_path, 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
return len(data)
def export_csv(self, output_path: str, source: str = None):
"""导出为 CSV扁平化消息"""
import csv
sql = "SELECT session_id, source, cwd, messages, start_time FROM sessions"
params = []
if source:
sql += " WHERE source = ?"
params.append(source)
sql += " ORDER BY start_time"
count = 0
with open(output_path, 'w', encoding='utf-8', newline='') as f:
writer = csv.writer(f)
writer.writerow(['session_id', 'source', 'cwd', 'time', 'role', 'content'])
with self._conn() as conn:
for row in conn.execute(sql, params):
session_id, src, cwd, msgs_json, _ = row
for msg in json.loads(msgs_json):
writer.writerow([session_id, src, cwd, msg.get('time', ''), msg.get('role', ''), msg.get('content', '')])
count += 1
return count
# === 获取所有文件路径(用于 prune 检查) ===
def get_all_file_paths(self, source: str = None) -> set:
sql = "SELECT file_path FROM sessions"
params = []
if source:
sql += " WHERE source = ?"
params.append(source)
with self._conn() as conn:
return {row[0] for row in conn.execute(sql, params)}

View File

@ -1,44 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""跨平台文件监控 (Linux/macOS/Windows)"""
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
import time
class ChatFileHandler(FileSystemEventHandler):
def __init__(self, callback, extensions):
self.callback = callback
self.extensions = extensions
def _check(self, event):
if event.is_directory:
return
path = event.src_path
if any(path.endswith(ext) for ext in self.extensions):
self.callback(path, event.event_type)
def on_created(self, event):
self._check(event)
def on_modified(self, event):
self._check(event)
class ChatWatcher:
def __init__(self, paths: list, callback, extensions=('.jsonl', '.json')):
self.observer = Observer()
handler = ChatFileHandler(callback, extensions)
for path in paths:
self.observer.schedule(handler, path, recursive=True)
def start(self):
self.observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
self.stop()
def stop(self):
self.observer.stop()
self.observer.join()

View File

@ -1,7 +0,0 @@
@echo off
cd /d "%~dp0src"
echo 正在启动 AI Chat Converter...
echo 按 Ctrl+C 停止
echo.
python main.py --watch
pause

View File

@ -1,7 +0,0 @@
#!/bin/bash
# AI Chat Converter - 一键启动
cd "$(dirname "$0")/src"
echo "正在启动 AI Chat Converter..."
echo "按 Ctrl+C 停止"
echo ""
python3 main.py --watch

View File

@ -1,34 +0,0 @@
# l10n-tool
轻量级多语言翻译脚本,定位:先用机器翻译批量落地,再由 AI/人工逐行润色。
## 特性
- 保护 Markdown 代码块,不误翻译代码
- 命令行一条跑完,便于批处理
- 依赖轻:`deep-translator`(封装 Google 翻译)
## 安装
```bash
pip install -r requirements.txt
```
## 使用示例
```bash
# 将中文 README 翻译到英文
python translate.py --input ../../i18n/zh/README.md --output ../../i18n/en/README.md --src-lang zh --tgt-lang en --overwrite
# 批量翻译 prompts可在外部脚本中循环调用
```
## 建议流程(快 ⇒ 精)
1) 机器翻译初稿:用本工具覆盖生成各语言版本。
2) AI 校润:对关键文档/提示词逐行复核,重点检查术语一致性与人称语气。
3) 人工抽检:挑核心页面人工对比源文,修正 AI 可能的误译。
## 语言代码参考
- 常用zh, en, es, fr, de, ru, pt, ar, hi, ja, ko, he, it, tr, nl, pl, id, vi, th, fa, uk, bn, ta, ur, ms, sw, ha
- 更多代码可查 ISO 639-1。
## 注意
- 若需更高质量,可替换为官方 Google Cloud Translate / DeepL API只需改写 `translate_blocks` 中的 translator 初始化逻辑。
- 如遇免费翻译频率限制,可分批或加重试/代理配置。

View File

@ -1,140 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
批量翻译 i18n/zh 下的所有文本文件到其他语言目录
- 保持目录结构遇到代码块自动跳过翻译
- 目标语言集合自动读取 i18n 下的子目录排除 zh
用法
python bulk_translate.py --src-root ../../i18n/zh --dst-root ../../i18n --src-lang zh
可选
--langs en es ... # 指定目标语言;默认自动扫描
--overwrite # 允许覆盖已有文件
"""
import argparse
import os
import sys
from pathlib import Path
from typing import Iterable, List
try:
from deep_translator import GoogleTranslator
except ImportError:
sys.stderr.write("[错误] 缺少 deep-translator请先 pip install -r requirements.txt\n")
sys.exit(1)
def translate_blocks(text: str, translator: GoogleTranslator) -> str:
lines = text.splitlines()
translated: List[str] = []
in_code = False
buffer: List[str] = []
def flush_buffer():
if not buffer:
return
chunk = "\n".join(buffer)
try:
result = translator.translate(chunk)
if result is None:
raise RuntimeError("翻译返回空结果")
translated.extend(result.split("\n"))
except Exception:
# 兜底:按行逐条翻译,避免整段失败
for line in buffer:
try:
res_line = translator.translate(line) or line
except Exception:
res_line = line # 保留原文,留待人工校对
translated.append(res_line)
buffer.clear()
for line in lines:
if line.strip().startswith("```"):
flush_buffer()
in_code = not in_code
translated.append(line)
continue
if in_code:
translated.append(line)
continue
if not line.strip():
flush_buffer()
translated.append(line)
continue
buffer.append(line)
flush_buffer()
return "\n".join(translated)
def iter_source_files(src_root: Path) -> Iterable[Path]:
for path in src_root.rglob('*'):
if path.is_file():
yield path
def main() -> int:
parser = argparse.ArgumentParser(description="批量翻译 i18n/zh -> 其他语言")
parser.add_argument('--src-root', default='../../i18n/zh', help='源语言根目录')
parser.add_argument('--dst-root', default='../../i18n', help='目标语言根目录集合')
parser.add_argument('--src-lang', default='zh-CN', help='源语言代码')
parser.add_argument('--langs', nargs='*', help='指定目标语言,不含源语言')
parser.add_argument('--overwrite', action='store_true', help='允许覆盖已有文件')
args = parser.parse_args()
src_root = Path(args.src_root).resolve()
dst_root = Path(args.dst_root).resolve()
if not src_root.exists():
sys.stderr.write(f"[错误] 源目录不存在: {src_root}\n")
return 1
code_overrides = {
'zh': 'zh-CN',
'zh-CN': 'zh-CN',
'he': 'iw', # Google 使用旧代码
}
def map_code(lang: str) -> str:
return code_overrides.get(lang, lang)
if args.langs:
target_langs = [lang for lang in args.langs if map_code(lang) != args.src_lang]
else:
target_langs = [p.name for p in dst_root.iterdir() if p.is_dir() and map_code(p.name) != args.src_lang]
if not target_langs:
sys.stderr.write("[错误] 无目标语言目录\n")
return 1
for lang in target_langs:
translator = GoogleTranslator(source=args.src_lang, target=map_code(lang))
print(f"==== 开始翻译 -> {lang} ====")
for src_file in iter_source_files(src_root):
rel_path = src_file.relative_to(src_root)
dst_file = dst_root / lang / rel_path
dst_file.parent.mkdir(parents=True, exist_ok=True)
if dst_file.exists() and not args.overwrite:
print(f"跳过已存在 {dst_file}")
continue
with open(src_file, 'r', encoding='utf-8') as f:
content = f.read()
try:
translated = translate_blocks(content, translator)
except Exception as exc:
print(f"[失败] {src_file} -> {dst_file}: {exc}")
continue
with open(dst_file, 'w', encoding='utf-8') as f:
f.write(translated + '\n')
print(f"[OK] {src_file} -> {dst_file}")
print("全部翻译完成")
return 0
if __name__ == '__main__':
sys.exit(main())

View File

@ -1,195 +0,0 @@
[
"i18n/zh/documents/Templates and Resources/代码组织.md",
"i18n/zh/documents/Templates and Resources/编程书籍推荐.md",
"i18n/zh/documents/Templates and Resources/通用项目架构模板.md",
"i18n/zh/documents/Templates and Resources/工具集.md",
"i18n/zh/documents/README.md",
"i18n/zh/documents/Tutorials and Guides/telegram-dev/telegram Markdown 代码块格式修复记录 2025-12-15.md",
"i18n/zh/documents/Tutorials and Guides/tmux快捷键大全.md",
"i18n/zh/documents/Tutorials and Guides/关于手机ssh任意位置链接本地计算机基于frp实现的方法.md",
"i18n/zh/documents/Tutorials and Guides/LazyVim快捷键大全.md",
"i18n/zh/documents/Tutorials and Guides/auggie-mcp配置文档.md",
"i18n/zh/documents/Methodology and Principles/系统提示词构建原则.md",
"i18n/zh/documents/Methodology and Principles/gluecoding.md",
"i18n/zh/documents/Methodology and Principles/胶水编程.md",
"i18n/zh/documents/Methodology and Principles/vibe-coding-经验收集.md",
"i18n/zh/documents/Methodology and Principles/开发经验.md",
"i18n/zh/documents/Methodology and Principles/学习经验.md",
"i18n/zh/documents/Methodology and Principles/A Formalization of Recursive Self-Optimizing Generative Systems.md",
"i18n/zh/documents/Methodology and Principles/编程之道.md",
"i18n/zh/prompts/README.md",
"i18n/zh/prompts/coding_prompts/(3,1)_#_流程标准化.md",
"i18n/zh/prompts/coding_prompts/客观分析.md",
"i18n/zh/prompts/coding_prompts/精华技术文档生成提示词.md",
"i18n/zh/prompts/coding_prompts/智能需求理解与研发导航引擎.md",
"i18n/zh/prompts/coding_prompts/(21,1)_你是我的顶级编程助手我将使用自然语言描述开发需求。请你将其转换为一个结构化、专业、详细、可执行的编程任务说明文档输出.md",
"i18n/zh/prompts/coding_prompts/(17,2)_#_软件工程分析.md",
"i18n/zh/prompts/coding_prompts/(22,5)_前几天我被_Claude_那些臃肿、过度设计的解决方案搞得很沮丧里面有一大堆我不需要的“万一”功能。然后我尝试在我的.md",
"i18n/zh/prompts/coding_prompts/分析2.md",
"i18n/zh/prompts/coding_prompts/(7,1)_#_AI生成代码文档_-_通用提示词模板.md",
"i18n/zh/prompts/coding_prompts/系统架构可视化生成Mermaid.md",
"i18n/zh/prompts/coding_prompts/系统架构.md",
"i18n/zh/prompts/coding_prompts/(12,2)_{任务帮我进行智能任务描述,分析与补全任务,你需要理解、描述我当前正在进行的任务,自动识别缺少的要素、未完善的部分、可能.md",
"i18n/zh/prompts/coding_prompts/简易提示词优化器.md",
"i18n/zh/prompts/coding_prompts/(2,1)_#_ultrathink_ultrathink_ultrathink_ultrathink_ultrathink.md",
"i18n/zh/prompts/coding_prompts/(13,1)_#_提示工程师任务说明.md",
"i18n/zh/prompts/coding_prompts/(20,1)_#_高质量代码开发专家.md",
"i18n/zh/prompts/coding_prompts/(14,2)_############################################################.md",
"i18n/zh/prompts/coding_prompts/(11,1)_{任务你是一名资深系统架构师与AI协同设计顾问。nn目标当用户启动一个新项目或请求AI帮助开发功能时你必须优先帮助用.md",
"i18n/zh/prompts/coding_prompts/(9,1)_{角色与目标{你首席软件架构师_(Principal_Software_Architect)高性能、可维护、健壮、DD.md",
"i18n/zh/prompts/coding_prompts/标准项目目录结构.md",
"i18n/zh/prompts/coding_prompts/分析1.md",
"i18n/zh/prompts/coding_prompts/执行纯净性检测.md",
"i18n/zh/prompts/coding_prompts/标准化流程.md",
"i18n/zh/prompts/coding_prompts/项目上下文文档生成.md",
"i18n/zh/prompts/coding_prompts/人机对齐.md",
"i18n/zh/prompts/coding_prompts/(1,1)_#_📘_项目上下文文档生成_·_工程化_Prompt专业优化版.md",
"i18n/zh/prompts/coding_prompts/(5,1)_{content#_🚀_智能需求理解与研发导航引擎Meta_R&D_Navigator_·.md",
"i18n/zh/prompts/coding_prompts/(6,1)_{System_Prompt#_🧠_系统提示词AI_Prompt_编程语言约束与持久化记忆规范nn##.md",
"i18n/zh/prompts/coding_prompts/plan提示词.md",
"i18n/zh/prompts/coding_prompts/(15,1)_###_Claude_Code_八荣八耻.md",
"i18n/zh/prompts/coding_prompts/任务描述,分析与补全任务.md",
"i18n/zh/prompts/coding_prompts/(10,1)_{任务你是首席软件架构师_(Principal_Software_Architect),专注于构建[高性能__可维护.md",
"i18n/zh/prompts/coding_prompts/(4,1)_ultrathink__Take_a_deep_breath..md",
"i18n/zh/prompts/coding_prompts/docs文件夹中文命名提示词.md",
"i18n/zh/prompts/coding_prompts/(18,2)_#_通用项目架构综合分析与优化框架.md",
"i18n/zh/prompts/coding_prompts/胶水开发.md",
"i18n/zh/prompts/coding_prompts/sh控制面板生成.md",
"i18n/zh/prompts/coding_prompts/(8,1)_#_执行📘_文件头注释规范用于所有代码文件最上方.md",
"i18n/zh/prompts/coding_prompts/前端设计.md",
"i18n/zh/prompts/coding_prompts/(19,1)_##_角色定义.md",
"i18n/zh/prompts/coding_prompts/index.md",
"i18n/zh/prompts/coding_prompts/(16,3)_#_CLAUDE_记忆.md",
"i18n/zh/prompts/coding_prompts/输入简单的日常行为的研究报告摘要.md",
"i18n/zh/prompts/meta_prompts/.gitkeep",
"i18n/zh/prompts/user_prompts/数据管道.md",
"i18n/zh/prompts/user_prompts/项目变量与工具统一维护.md",
"i18n/zh/prompts/user_prompts/ASCII图生成.md",
"i18n/zh/prompts/system_prompts/# 💀《科比的救母救父救未婚妻与岳父岳母日记》 × OTE模型交易模式 × M.I.T白人金融教授被女学生指控性骚扰版v2.md",
"i18n/zh/prompts/system_prompts/CLAUDE.md/5/CLAUDE.md",
"i18n/zh/prompts/system_prompts/CLAUDE.md/9/AGENTS.md",
"i18n/zh/prompts/system_prompts/CLAUDE.md/6/CLAUDE.md",
"i18n/zh/prompts/system_prompts/CLAUDE.md/3/CLAUDE.md",
"i18n/zh/prompts/system_prompts/CLAUDE.md/10/CLAUDE.md",
"i18n/zh/prompts/system_prompts/CLAUDE.md/1/CLAUDE.md",
"i18n/zh/prompts/system_prompts/CLAUDE.md/8/CLAUDE.md",
"i18n/zh/prompts/system_prompts/CLAUDE.md/4/CLAUDE.md",
"i18n/zh/prompts/system_prompts/CLAUDE.md/7/CLAUDE.md",
"i18n/zh/prompts/system_prompts/CLAUDE.md/2/CLAUDE.md",
"i18n/zh/skills/telegram-dev/SKILL.md",
"i18n/zh/skills/telegram-dev/references/动态视图对齐实现文档.md",
"i18n/zh/skills/telegram-dev/references/Telegram_Bot_按钮和键盘实现模板.md",
"i18n/zh/skills/telegram-dev/references/index.md",
"i18n/zh/skills/claude-skills/AGENTS.md",
"i18n/zh/skills/claude-skills/assets/template-complete.md",
"i18n/zh/skills/claude-skills/assets/template-minimal.md",
"i18n/zh/skills/claude-skills/SKILL.md",
"i18n/zh/skills/claude-skills/scripts/create-skill.sh",
"i18n/zh/skills/claude-skills/scripts/validate-skill.sh",
"i18n/zh/skills/claude-skills/references/anti-patterns.md",
"i18n/zh/skills/claude-skills/references/README.md",
"i18n/zh/skills/claude-skills/references/quality-checklist.md",
"i18n/zh/skills/claude-skills/references/skill-spec.md",
"i18n/zh/skills/claude-skills/references/index.md",
"i18n/zh/skills/snapdom/SKILL.md",
"i18n/zh/skills/snapdom/references/other.md",
"i18n/zh/skills/snapdom/references/index.md",
"i18n/zh/skills/timescaledb/SKILL.md",
"i18n/zh/skills/timescaledb/references/hyperfunctions.md",
"i18n/zh/skills/timescaledb/references/performance.md",
"i18n/zh/skills/timescaledb/references/other.md",
"i18n/zh/skills/timescaledb/references/compression.md",
"i18n/zh/skills/timescaledb/references/api.md",
"i18n/zh/skills/timescaledb/references/tutorials.md",
"i18n/zh/skills/timescaledb/references/hypertables.md",
"i18n/zh/skills/timescaledb/references/time_buckets.md",
"i18n/zh/skills/timescaledb/references/continuous_aggregates.md",
"i18n/zh/skills/timescaledb/references/installation.md",
"i18n/zh/skills/timescaledb/references/llms-full.md",
"i18n/zh/skills/timescaledb/references/llms.md",
"i18n/zh/skills/timescaledb/references/getting_started.md",
"i18n/zh/skills/timescaledb/references/index.md",
"i18n/zh/skills/README.md",
"i18n/zh/skills/cryptofeed/SKILL.md",
"i18n/zh/skills/cryptofeed/references/other.md",
"i18n/zh/skills/cryptofeed/references/README.md",
"i18n/zh/skills/cryptofeed/references/index.md",
"i18n/zh/skills/coingecko/SKILL.md",
"i18n/zh/skills/coingecko/references/coins.md",
"i18n/zh/skills/coingecko/references/contract.md",
"i18n/zh/skills/coingecko/references/exchanges.md",
"i18n/zh/skills/coingecko/references/other.md",
"i18n/zh/skills/coingecko/references/introduction.md",
"i18n/zh/skills/coingecko/references/nfts.md",
"i18n/zh/skills/coingecko/references/trending.md",
"i18n/zh/skills/coingecko/references/reference.md",
"i18n/zh/skills/coingecko/references/llms-full.md",
"i18n/zh/skills/coingecko/references/market_data.md",
"i18n/zh/skills/coingecko/references/pricing.md",
"i18n/zh/skills/coingecko/references/authentication.md",
"i18n/zh/skills/coingecko/references/llms.md",
"i18n/zh/skills/coingecko/references/index.md",
"i18n/zh/skills/hummingbot/SKILL.md",
"i18n/zh/skills/hummingbot/references/advanced.md",
"i18n/zh/skills/hummingbot/references/other.md",
"i18n/zh/skills/hummingbot/references/connectors.md",
"i18n/zh/skills/hummingbot/references/troubleshooting.md",
"i18n/zh/skills/hummingbot/references/development.md",
"i18n/zh/skills/hummingbot/references/strategies.md",
"i18n/zh/skills/hummingbot/references/getting_started.md",
"i18n/zh/skills/hummingbot/references/configuration.md",
"i18n/zh/skills/hummingbot/references/trading.md",
"i18n/zh/skills/hummingbot/references/index.md",
"i18n/zh/skills/claude-code-guide/SKILL.md",
"i18n/zh/skills/claude-code-guide/references/README.md",
"i18n/zh/skills/claude-code-guide/references/index.md",
"i18n/zh/skills/proxychains/SKILL.md",
"i18n/zh/skills/proxychains/scripts/setup-proxy.sh",
"i18n/zh/skills/proxychains/references/proxychains.conf",
"i18n/zh/skills/proxychains/references/troubleshooting.md",
"i18n/zh/skills/proxychains/references/setup-guide.md",
"i18n/zh/skills/proxychains/references/quick-reference.md",
"i18n/zh/skills/proxychains/references/index.md",
"i18n/zh/skills/ccxt/SKILL.md",
"i18n/zh/skills/ccxt/references/specification.md",
"i18n/zh/skills/ccxt/references/exchanges.md",
"i18n/zh/skills/ccxt/references/other.md",
"i18n/zh/skills/ccxt/references/pro.md",
"i18n/zh/skills/ccxt/references/faq.md",
"i18n/zh/skills/ccxt/references/cli.md",
"i18n/zh/skills/ccxt/references/manual.md",
"i18n/zh/skills/ccxt/references/getting_started.md",
"i18n/zh/skills/ccxt/references/index.md",
"i18n/zh/skills/claude-cookbooks/SKILL.md",
"i18n/zh/skills/claude-cookbooks/scripts/memory_tool.py",
"i18n/zh/skills/claude-cookbooks/references/multimodal.md",
"i18n/zh/skills/claude-cookbooks/references/capabilities.md",
"i18n/zh/skills/claude-cookbooks/references/patterns.md",
"i18n/zh/skills/claude-cookbooks/references/README.md",
"i18n/zh/skills/claude-cookbooks/references/third_party.md",
"i18n/zh/skills/claude-cookbooks/references/CONTRIBUTING.md",
"i18n/zh/skills/claude-cookbooks/references/main_readme.md",
"i18n/zh/skills/claude-cookbooks/references/tool_use.md",
"i18n/zh/skills/claude-cookbooks/references/index.md",
"i18n/zh/skills/polymarket/SKILL.md",
"i18n/zh/skills/polymarket/references/other.md",
"i18n/zh/skills/polymarket/references/realtime-client.md",
"i18n/zh/skills/polymarket/references/api.md",
"i18n/zh/skills/polymarket/references/learn.md",
"i18n/zh/skills/polymarket/references/README.md",
"i18n/zh/skills/polymarket/references/llms-full.md",
"i18n/zh/skills/polymarket/references/llms.md",
"i18n/zh/skills/polymarket/references/getting_started.md",
"i18n/zh/skills/polymarket/references/guides.md",
"i18n/zh/skills/polymarket/references/trading.md",
"i18n/zh/skills/polymarket/references/index.md",
"i18n/zh/skills/postgresql/SKILL.md",
"i18n/zh/skills/postgresql/references/sql.md",
"i18n/zh/skills/postgresql/references/getting_started.md",
"i18n/zh/skills/postgresql/references/index.md",
"i18n/zh/skills/twscrape/SKILL.md",
"i18n/zh/skills/twscrape/references/examples.md",
"i18n/zh/skills/twscrape/references/installation.md",
"i18n/zh/skills/twscrape/references/index.md",
"i18n/zh/README.md"
]

View File

@ -1,163 +0,0 @@
{
"zh": "en",
"documents": "documents",
"prompts": "prompts",
"skills": "skills",
"Templates and Resources": "Templates and Resources",
"代码组织": "Code_Organization",
"编程书籍推荐": "Recommended_Programming_Books",
"通用项目架构模板": "General_Project_Architecture_Template",
"工具集": "Tool_Set",
"README": "README",
"Tutorials and Guides": "Tutorials and Guides",
"telegram-dev": "telegram-dev",
"telegram Markdown 代码块格式修复记录 2025-12-15": "telegram_Markdown_Code_Block_Format_Fix_Log_2025_12_15",
"tmux快捷键大全": "tmux_Shortcut_Cheatsheet",
"关于手机ssh任意位置链接本地计算机基于frp实现的方法": "Method_for_SSH_Linking_Mobile_Phone_to_Local_Computer_Anywhere_Based_on_FRP_Implementation",
"LazyVim快捷键大全": "LazyVim_Shortcut_Cheatsheet",
"auggie-mcp配置文档": "auggie_mcp_Configuration_Document",
"Methodology and Principles": "Methodology and Principles",
"系统提示词构建原则": "System_Prompt_Construction_Principles",
"gluecoding": "gluecoding",
"胶水编程": "Glue_Programming",
"vibe-coding-经验收集": "vibe_coding_Experience_Collection",
"开发经验": "Development_Experience",
"学习经验": "Learning_Experience",
"A Formalization of Recursive Self-Optimizing Generative Systems": "A_Formalization_of_Recursive_Self_Optimizing_Generative_Systems",
"编程之道": "The_Way_of_Programming",
"coding_prompts": "coding_prompts",
"客观分析": "Objective_Analysis",
"精华技术文档生成提示词": "Essential_Technical_Document_Generation_Prompt",
"智能需求理解与研发导航引擎": "Intelligent_Requirement_Understanding_and_R_D_Navigation_Engine",
"软件工程分析": "Software_Engineering_Analysis",
"系统架构可视化生成Mermaid": "System_Architecture_Visualization_Generation_Mermaid",
"系统架构": "System_Architecture",
"简易提示词优化器": "Simple_Prompt_Optimizer",
"提示工程师任务说明": "Prompt_Engineer_Task_Description",
"高质量代码开发专家": "High_Quality_Code_Development_Expert",
"标准项目目录结构": "Standard_Project_Directory_Structure",
"分析1": "Analysis_1",
"分析2": "Analysis_2",
"执行纯净性检测": "Perform_Purity_Test",
"标准化流程": "Standardized_Process",
"项目上下文文档生成": "Project_Context_Document_Generation",
"人机对齐": "Human_AI_Alignment",
"plan提示词": "Plan_Prompt",
"Claude Code 八荣八耻": "Claude_Code_Eight_Honors_and_Eight_Shames",
"任务描述,分析与补全任务": "Task_Description_Analysis_and_Completion",
"前端设计": "Frontend_Design",
"输入简单的日常行为的研究报告摘要": "Summary_of_Research_Report_on_Simple_Daily_Behaviors",
"胶水开发": "Glue_Development",
"sh控制面板生成": "SH_Control_Panel_Generation",
"角色定义": "Role_Definition",
"CLAUDE 记忆": "CLAUDE_Memory",
"index": "index",
"user_prompts": "user_prompts",
"数据管道": "Data_Pipeline",
"项目变量与工具统一维护": "Unified_Management_of_Project_Variables_and_Tools",
"ASCII图生成": "ASCII_Art_Generation",
"system_prompts": "system_prompts",
"SKILL": "SKILL",
"references": "references",
"动态视图对齐实现文档": "Dynamic_View_Alignment_Implementation_Document",
"Telegram_Bot_按钮和键盘实现模板": "Telegram_Bot_Button_and_Keyboard_Implementation_Template",
"claude-skills": "claude-skills",
"assets": "assets",
"template-complete": "template-complete",
"template-minimal": "template-minimal",
"scripts": "scripts",
"create-skill": "create-skill",
"validate-skill": "validate-skill",
"anti-patterns": "anti-patterns",
"quality-checklist": "quality-checklist",
"skill-spec": "skill-spec",
"snapdom": "snapdom",
"other": "other",
"timescaledb": "timescaledb",
"hyperfunctions": "hyperfunctions",
"performance": "performance",
"compression": "compression",
"api": "api",
"tutorials": "tutorials",
"hypertables": "hypertables",
"time_buckets": "time_buckets",
"continuous_aggregates": "continuous_aggregates",
"installation": "installation",
"llms-full": "llms-full",
"llms": "llms",
"getting_started": "getting_started",
"cryptofeed": "cryptofeed",
"coingecko": "coingecko",
"coins": "coins",
"contract": "contract",
"exchanges": "exchanges",
"introduction": "introduction",
"nfts": "nfts",
"trending": "trending",
"reference": "reference",
"market_data": "market_data",
"pricing": "pricing",
"authentication": "authentication",
"hummingbot": "hummingbot",
"advanced": "advanced",
"connectors": "connectors",
"troubleshooting": "troubleshooting",
"development": "development",
"strategies": "strategies",
"configuration": "configuration",
"trading": "trading",
"claude-code-guide": "claude-code-guide",
"proxychains": "proxychains",
"setup-proxy": "setup-proxy",
"proxychains.conf": "proxychains.conf",
"setup-guide": "setup-guide",
"quick-reference": "quick-reference",
"ccxt": "ccxt",
"specification": "specification",
"pro": "pro",
"faq": "faq",
"cli": "cli",
"manual": "manual",
"claude-cookbooks": "claude-cookbooks",
"memory_tool": "memory_tool",
"multimodal": "multimodal",
"capabilities": "capabilities",
"patterns": "patterns",
"third_party": "third_party",
"CONTRIBUTING": "CONTRIBUTING",
"main_readme": "main_readme",
"tool_use": "tool_use",
"polymarket": "polymarket",
"realtime-client": "realtime-client",
"learn": "learn",
"guides": "guides",
"postgresql": "postgresql",
"sql": "sql",
"twscrape": "twscrape",
"examples": "examples",
"installation": "installation",
"# 💀《科比的救母救父救未婚妻与岳父岳母日记》 × OTE模型交易模式 × M.I.T白人金融教授被女学生指控性骚扰版v2": "Kobe_s_Diary_of_Saving_Mother_Father_Fiancee_and_In_laws_OTE_Model_Trading_Mode_M_I_T_White_Professor_Accused_of_Sexual_Harassment_by_Female_Student_v2",
"(3,1)_#_流程标准化": "Standardization_Process",
"(21,1)_你是我的顶级编程助手我将使用自然语言描述开发需求。请你将其转换为一个结构化、专业、详细、可执行的编程任务说明文档输出": "Top_Programming_Assistant_Task_Description",
"(17,2)_#_软件工程分析": "Software_Engineering_Analysis",
"(22,5)_前几天我被_Claude_那些臃肿、过度设计的解决方案搞得很沮丧里面有一大堆我不需要的“万一”功能。然后我尝试在我的": "Frustration_with_Claude_Over_Designed_Solutions",
"(7,1)_#_AI生成代码文档_-_通用提示词模板": "AI_Generated_Code_Documentation_General_Prompt_Template",
"(12,2)_{任务帮我进行智能任务描述,分析与补全任务,你需要理解、描述我当前正在进行的任务,自动识别缺少的要素、未完善的部分、可能": "Intelligent_Task_Description_Analysis_and_Completion",
"(2,1)_#_ultrathink_ultrathink_ultrathink_ultrathink_ultrathink": "ultrathink_ultrathink_ultrathink_ultrathink_ultrathink",
"(13,1)_#_提示工程师任务说明": "Prompt_Engineer_Task_Description",
"(20,1)_#_高质量代码开发专家": "High_Quality_Code_Development_Expert",
"(14,2)_############################################################": "Hash_Delimiters",
"(11,1)_{任务你是一名资深系统架构师与AI协同设计顾问。nn目标当用户启动一个新项目或请求AI帮助开发功能时你必须优先帮助用": "Senior_System_Architect_AI_Collaboration_Consultant_Task",
"(9,1)_{角色与目标{你首席软件架构师_(Principal_Software_Architect)高性能、可维护、健壮、DD": "Principal_Software_Architect_Role_and_Goals",
"(1,1)_#_📘_项目上下文文档生成_·_工程化_Prompt专业优化版": "Project_Context_Document_Generation_Engineered_Prompt_Optimized",
"(5,1)_{content#_🚀_智能需求理解与研发导航引擎Meta_R&D_Navigator_·": "Intelligent_Requirement_Understanding_and_RD_Navigation_Engine",
"(6,1)_{System_Prompt#_🧠_系统提示词AI_Prompt_编程语言约束与持久化记忆规范nn##": "System_Prompt_AI_Prompt_Programming_Language_Constraints_and_Persistent_Memory_Specifications",
"(15,1)_###_Claude_Code_八荣八耻": "Claude_Code_Eight_Honors_and_Eight_Shames",
"(10,1)_{任务你是首席软件架构师_(Principal_Software_Architect),专注于构建[高性能__可维护": "Principal_Software_Architect_Focus_High_Performance_Maintainable_Systems",
"(4,1)_ultrathink__Take_a_deep_breath.": "ultrathink__Take_a_deep_breath",
"docs文件夹中文命名提示词": "Docs_Folder_Chinese_Naming_Prompt",
"(18,2)_#_通用项目架构综合分析与优化框架": "General_Project_Architecture_Comprehensive_Analysis_and_Optimization_Framework",
"(8,1)_#_执行📘_文件头注释规范用于所有代码文件最上方": "Execute_File_Header_Comment_Specification_for_All_Code_Files",
"(19,1)_##_角色定义": "Role_Definition",
"(16,3)_#_CLAUDE_记忆": "CLAUDE_Memory"
}

View File

@ -1 +0,0 @@
deep-translator>=1.11.4

View File

@ -1,90 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
轻量级批量翻译工具 Markdown/文本从一种语言翻译到另一种语言
默认使用 deep-translator 封装的 Google Translator自带简单的代码块保护
用法示例
python translate.py --input ../../i18n/zh/README.md --src-lang zh --tgt-lang en --output ../../i18n/en/README.md
"""
import argparse
import os
import sys
from typing import List
try:
from deep_translator import GoogleTranslator
except ImportError as exc: # pragma: no cover - 运行前请安装依赖
sys.stderr.write("[错误] 缺少依赖 deep-translator请先 `pip install -r requirements.txt`\n")
raise
def translate_blocks(lines: List[str], src: str, tgt: str) -> List[str]:
"""逐段翻译,保持代码块原样,减少上下文丢失。"""
translated: List[str] = []
in_code = False
buffer: List[str] = []
translator = GoogleTranslator(source=src, target=tgt)
def flush_buffer():
if not buffer:
return
text = "\n".join(buffer)
try:
result = translator.translate(text)
except Exception as exc: # pragma: no cover
raise RuntimeError(f"翻译失败: {exc}") from exc
translated.extend(result.split("\n"))
buffer.clear()
for line in lines:
if line.strip().startswith("```"):
flush_buffer()
in_code = not in_code
translated.append(line)
continue
if in_code:
translated.append(line)
continue
# 空行作为段落分割,先刷新再保留空行
if not line.strip():
flush_buffer()
translated.append(line)
continue
buffer.append(line)
flush_buffer()
return translated
def main() -> int:
parser = argparse.ArgumentParser(description="批量翻译文本/Markdown保护代码块")
parser.add_argument("--input", required=True, help="源文件路径")
parser.add_argument("--output", required=True, help="目标文件路径")
parser.add_argument("--src-lang", required=True, help="源语言代码,如 zh")
parser.add_argument("--tgt-lang", required=True, help="目标语言代码,如 en")
parser.add_argument("--overwrite", action="store_true", help="允许覆盖已有输出文件")
args = parser.parse_args()
if not os.path.isfile(args.input):
sys.stderr.write(f"[错误] 源文件不存在: {args.input}\n")
return 1
if os.path.exists(args.output) and not args.overwrite:
sys.stderr.write(f"[错误] 目标文件已存在,加 --overwrite 才会覆盖: {args.output}\n")
return 1
with open(args.input, "r", encoding="utf-8") as f:
lines = f.read().splitlines()
translated = translate_blocks(lines, args.src_lang, args.tgt_lang)
os.makedirs(os.path.dirname(args.output), exist_ok=True)
with open(args.output, "w", encoding="utf-8") as f:
f.write("\n".join(translated) + "\n")
print(f"[完成] {args.input} -> {args.output} ({args.src_lang} -> {args.tgt_lang})")
return 0
if __name__ == "__main__": # pragma: no cover
sys.exit(main())

View File

@ -1,182 +0,0 @@
import os
import re
import json
from pathlib import Path
# Load PATH_TRANSLATION_MAP from JSON
# Ensure the path is relative to the script's location or absolute
script_dir = Path(__file__).parent
path_translation_map_path = script_dir / 'path_translation_map.json'
with open(path_translation_map_path, 'r', encoding='utf-8') as f:
PATH_TRANSLATION_MAP = json.load(f)
def translate_path_component(component):
if component in PATH_TRANSLATION_MAP:
return PATH_TRANSLATION_MAP[component]
# Handle numeric prefixes like (3,1)_#_
if re.match(r"^\(\d+,\d+\)_#?_", component):
cleaned_component = re.sub(r"^\(\d+,\d+\)_#?_", "", component).replace("_", " ")
# Try to match cleaned component against known translations
for k, v in PATH_TRANSLATION_MAP.items():
if cleaned_component in k or k in cleaned_component:
return v.replace(" ", "_") # Return simplified and underscored version
# Fallback for complex patterns not in map
return re.sub(r"[^a-zA-Z0-9]+", "_", cleaned_component).strip("_")
# If it's a very long Chinese filename that might have specific terms
# These were added to PATH_TRANSLATION_MAP now, so this generic logic might not be hit as often
if "代码组织" == component: # Exact match for a known common Chinese filename part
return "Code_Organization"
if "编程书籍推荐" == component:
return "Recommended_Programming_Books"
if "通用项目架构模板" == component:
return "General_Project_Architecture_Template"
if "工具集" == component:
return "Tool_Set"
if "系统提示词构建原则" == component:
return "System_Prompt_Construction_Principles"
if "胶水编程" == component:
return "Glue_Programming"
if "vibe-coding-经验收集" == component:
return "vibe-coding-Experience_Collection"
if "开发经验" == component:
return "Development_Experience"
if "学习经验" == component:
return "Learning_Experience"
if "编程之道" == component:
return "The_Way_of_Programming"
if "客观分析" == component:
return "Objective_Analysis"
if "精华技术文档生成提示词" == component:
return "Essential_Technical_Document_Generation_Prompt"
if "智能需求理解与研发导航引擎" == component:
return "Intelligent_Requirement_Understanding_and_R_D_Navigation_Engine"
if "软件工程分析" == component:
return "Software_Engineering_Analysis"
if "系统架构可视化生成Mermaid":
return "System_Architecture_Visualization_Generation_Mermaid"
if "系统架构":
return "System_Architecture"
if "简易提示词优化器":
return "Simple_Prompt_Optimizer"
if "提示工程师任务说明":
return "Prompt_Engineer_Task_Description"
if "高质量代码开发专家":
return "High_Quality_Code_Development_Expert"
if "标准项目目录结构":
return "Standard_Project_Directory_Structure"
if "分析1":
return "Analysis_1"
if "分析2":
return "Analysis_2"
if "执行纯净性检测":
return "Perform_Purity_Test"
if "标准化流程":
return "Standardized_Process"
if "项目上下文文档生成":
return "Project_Context_Document_Generation"
if "人机对齐":
return "Human_AI_Alignment"
if "plan提示词":
return "Plan_Prompt"
if "Claude Code 八荣八耻":
return "Claude_Code_Eight_Honors_and_Eight_Shames"
if "任务描述,分析与补全任务":
return "Task_Description_Analysis_and_Completion"
if "前端设计":
return "Frontend_Design"
if "输入简单的日常行为的研究报告摘要":
return "Summary_of_Research_Report_on_Simple_Daily_Behaviors"
if "胶水开发":
return "Glue_Development"
if "sh控制面板生成":
return "SH_Control_Panel_Generation"
if "角色定义":
return "Role_Definition"
if "CLAUDE 记忆":
return "CLAUDE_Memory"
if "Docs文件夹中文命名提示词":
return "Docs_Folder_Chinese_Naming_Prompt"
if "通用项目架构综合分析与优化框架":
return "General_Project_Architecture_Comprehensive_Analysis_and_Optimization_Framework"
if "执行📘_文件头注释规范用于所有代码文件最上方" == component:
return "Execute_File_Header_Comment_Specification_for_All_Code_Files"
if "数据管道" == component:
return "Data_Pipeline"
if "项目变量与工具统一维护" == component:
return "Unified_Management_of_Project_Variables_and_Tools"
if "ASCII图生成" == component:
return "ASCII_Art_Generation"
if "Kobe's Diary of Saving Mother, Father, Fiancee, and In-laws × OTE Model Trading Mode × M.I.T White Professor (Accused of Sexual H_arassment by Female Student) v2" == component:
return "Kobe_s_Diary_of_Saving_Mother_Father_Fiancee_and_In_laws_OTE_Model_Trading_Mode_M_I_T_White_Professor_Accused_of_Sexual_Harassment_by_Female_Student_v2" # Simplified for filename
if "动态视图对齐实现文档" == component:
return "Dynamic_View_Alignment_Implementation_Document"
if "Telegram_Bot_按钮和键盘实现模板" == component:
return "Telegram_Bot_Button_and_Keyboard_Implementation_Template"
if "README" == component:
return "README" # Keep README as is
# Default: simply replace spaces with underscores and remove problematic characters for filenames
# For demonstration, a placeholder translation for unseen Chinese
return re.sub(r"[^a-zA-Z0-9]+", "_", component).strip("_")
def get_translated_path(chinese_path_str): # Accept string
parts = Path(chinese_path_str).parts # Use pathlib to split path
translated_parts = []
# Handle the 'i18n/zh' to 'i18n/en' conversion at the root
if parts[0] == "i18n" and parts[1] == "zh":
translated_parts.append("i18n")
translated_parts.append("en")
remaining_parts = parts[2:]
else:
remaining_parts = parts
for i, part in enumerate(remaining_parts):
base, ext = os.path.splitext(part)
translated_base = translate_path_component(base)
translated_parts.append(translated_base + ext)
return Path(*translated_parts) # Reconstruct path using pathlib
# Load chinese_files from JSON
chinese_files_list_path = script_dir / 'chinese_files_list.json'
with open(chinese_files_list_path, 'r', encoding='utf-8') as f:
chinese_files_str_list = json.load(f)
files_to_translate_content = []
for chinese_file_path_str in chinese_files_str_list:
english_file_path = get_translated_path(chinese_file_path_str) # Get translated Path object
# Read the content of the English placeholder file
try:
with english_file_path.open('r', encoding='utf-8') as f:
content = f.read()
if content.startswith("TRANSLATED CONTENT:\n"):
chinese_content = content.replace("TRANSLATED CONTENT:\n", "")
files_to_translate_content.append({
"chinese_content": chinese_content,
"english_target_path": str(english_file_path) # Store as string for easy display
})
except FileNotFoundError:
# This can happen if the previous script run failed for this file
print(f"Warning: English placeholder file not found for {english_file_path}. Skipping content extraction for this file.")
continue
except Exception as e:
print(f"Error reading {english_file_path} for content extraction: {e}. Skipping.")
continue
# Output the list of files to translate content for
print("--- Files for Content Translation ---")
for item in files_to_translate_content:
print(f"Target Path: {item['english_target_path']}")
print(f"Chinese Content:\n```markdown\n{item['chinese_content'].strip()}\n```\n{'='*50}\n")
print(f"Total files requiring content translation: {len(files_to_translate_content)}")

View File

@ -1,200 +0,0 @@
# 🚀 Perfect Neovim Configuration with LazyVim
## 系统配置文档
### 📋 配置概述
- **Neovim 版本**: v0.11.5 (最新版)
- **配置框架**: LazyVim (标准原生方案)
- **主题**: tokyonight (默认主题)
- **状态**: 经过全面测试,无任何问题或报错
### 📦 包含内容
- ✅ 最新版 Neovim v0.11.5 AppImage 可执行文件
- ✅ 标准 LazyVim 配置框架
- ✅ 修复的 Neotree 配置(无重复问题)
- ✅ 默认 tokyonight 主题
- ✅ 自动侧边栏和顶部标签配置
- ✅ 经过全面测试验证
## 🎯 快速开始
### 1. 克隆仓库
```bash
git clone https://github.com/tukuaiai/vim.git
cd vim
```
### 2. 安装配置
```bash
# 复制配置文件
cp -r nvim-config/* ~/.config/
# 复制可执行文件
cp nvim-config/nvim ~/.local/bin/
chmod +x ~/.local/bin/nvim
# 确保路径在 PATH 中
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
```
### 3. 启动使用
```bash
# 直接启动
~/.local/bin/nvim
# 或使用别名(推荐)
alias n='~/.local/bin/nvim'
n
```
## 🎨 主题配置
### 当前主题tokyonight默认
- 深色护眼主题
- 现代化配色方案
- 高对比度,适合长时间使用
### 切换主题(可选)
```vim
:Telescope colorscheme " 使用 Telescope 选择主题
```
## ⚙️ 核心功能
### 1. 文件浏览器Neotree
- **快捷键**`<leader>e`(空格+e
- **功能**:侧边栏文件浏览器
- **特点**:无重复窗口问题(已修复)
### 2. 顶部标签页Bufferline
- **功能**:显示打开的缓冲区
- **特点**:始终显示,美观实用
### 3. 模糊查找Telescope
- **快捷键**`<leader>f`(空格+f
- **功能**:快速查找文件、符号等
### 4. Git 集成
- **快捷键**`<leader>g`(空格+g
- **功能**Git 状态、提交、差异查看
## ⌨️ 快捷键速查
| 快捷键 | 功能 |
|--------|------|
| `<leader>e` | 打开文件浏览器 |
| `<leader>f` | 模糊查找 |
| `<leader>g` | Git 相关 |
| `<leader>b` | 缓冲区管理 |
| `<leader>w` | 保存文件 |
| `<leader>q` | 退出 |
| `<leader>/` | 搜索当前文件 |
| `<leader>?` | 查看所有快捷键 |
## 🔧 高级配置
### 自动命令autocmds
位于 `~/.config/nvim/lua/config/autocmds.lua`
```lua
-- 自动打开 Neotree延迟 50ms 确保插件加载)
vim.api.nvim_create_autocmd("VimEnter", {
callback = function()
vim.defer_fn(function()
vim.cmd("Neotree show")
end, 50)
end,
})
```
### 插件配置
位于 `~/.config/nvim/lua/plugins/`
- `ui.lua` - UI 相关插件配置
- `colorscheme.lua` - 主题配置
- `example.lua` - 示例插件配置
## 🧪 测试验证
### 启动测试
```bash
# 基础启动测试
~/.local/bin/nvim --headless -c "echo 'OK'" -c "qa"
# 配置加载测试
~/.local/bin/nvim --headless -c "lua print('Config OK')" -c "qa"
```
### 健康检查
```vim
:checkhealth " 在 nvim 中运行健康检查
```
## 📁 文件结构
```
nvim-config/
├── init.lua # 入口文件
├── lazy-lock.json # 插件锁文件
├── lazyvim.json # LazyVim 配置
├── nvim # Neovim v0.11.5 AppImage
├── lua/
│ ├── config/
│ │ ├── autocmds.lua # 自动命令
│ │ ├── keymaps.lua # 键位映射
│ │ ├── lazy.lua # Lazy.nvim 配置
│ │ └── options.lua # 选项设置
│ └── plugins/
│ ├── colorscheme.lua # 主题配置
│ ├── ui.lua # UI 插件配置
│ └── example.lua # 示例配置
└── stylua.toml # 代码格式化配置
```
## 🚀 高级使用技巧
### 1. 快速文件操作
```vim
" 在当前行下方新建文件
:enew
" 保存文件
:w
" 退出
:qa
```
### 2. 窗口管理
```vim
" 水平分割
:sp filename
" 垂直分割
:vs filename
" 在分割间移动
Ctrl+w h/j/k/l
```
### 3. 搜索和替换
```vim
" 当前文件搜索
/
" 全局搜索
:Telescope live_grep
" 替换
:%s/old/new/g
```
## 📚 学习资源
1. **内置教程**`:Tutor`
2. **帮助系统**`:help 主题`
3. **LazyVim 文档**:按 `<leader>?`
4. **GitHub 仓库**https://github.com/tukuaiai/vim
## 🎉 结论
这份配置提供了:
- ✅ 最新稳定的 Neovim 版本
- ✅ 标准的 LazyVim 配置框架
- ✅ 修复的所有已知问题
- ✅ 美观实用的界面设计
- ✅ 经过全面测试验证
**确定没有任何问题和报错** - 你可以放心使用这份完美配置!

View File

@ -1,201 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -1,200 +0,0 @@
# 🚀 Perfect Neovim Configuration with LazyVim
## 系统配置文档
### 📋 配置概述
- **Neovim 版本**: v0.11.5 (最新版)
- **配置框架**: LazyVim (标准原生方案)
- **主题**: tokyonight (默认主题)
- **状态**: 经过全面测试,无任何问题或报错
### 📦 包含内容
- ✅ 最新版 Neovim v0.11.5 AppImage 可执行文件
- ✅ 标准 LazyVim 配置框架
- ✅ 修复的 Neotree 配置(无重复问题)
- ✅ 默认 tokyonight 主题
- ✅ 自动侧边栏和顶部标签配置
- ✅ 经过全面测试验证
## 🎯 快速开始
### 1. 克隆仓库
```bash
git clone https://github.com/tukuaiai/vim.git
cd vim
```
### 2. 安装配置
```bash
# 复制配置文件
cp -r nvim-config/* ~/.config/
# 复制可执行文件
cp nvim-config/nvim ~/.local/bin/
chmod +x ~/.local/bin/nvim
# 确保路径在 PATH 中
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
```
### 3. 启动使用
```bash
# 直接启动
~/.local/bin/nvim
# 或使用别名(推荐)
alias n='~/.local/bin/nvim'
n
```
## 🎨 主题配置
### 当前主题tokyonight默认
- 深色护眼主题
- 现代化配色方案
- 高对比度,适合长时间使用
### 切换主题(可选)
```vim
:Telescope colorscheme " 使用 Telescope 选择主题
```
## ⚙️ 核心功能
### 1. 文件浏览器Neotree
- **快捷键**`<leader>e`(空格+e
- **功能**:侧边栏文件浏览器
- **特点**:无重复窗口问题(已修复)
### 2. 顶部标签页Bufferline
- **功能**:显示打开的缓冲区
- **特点**:始终显示,美观实用
### 3. 模糊查找Telescope
- **快捷键**`<leader>f`(空格+f
- **功能**:快速查找文件、符号等
### 4. Git 集成
- **快捷键**`<leader>g`(空格+g
- **功能**Git 状态、提交、差异查看
## ⌨️ 快捷键速查
| 快捷键 | 功能 |
|--------|------|
| `<leader>e` | 打开文件浏览器 |
| `<leader>f` | 模糊查找 |
| `<leader>g` | Git 相关 |
| `<leader>b` | 缓冲区管理 |
| `<leader>w` | 保存文件 |
| `<leader>q` | 退出 |
| `<leader>/` | 搜索当前文件 |
| `<leader>?` | 查看所有快捷键 |
## 🔧 高级配置
### 自动命令autocmds
位于 `~/.config/nvim/lua/config/autocmds.lua`
```lua
-- 自动打开 Neotree延迟 50ms 确保插件加载)
vim.api.nvim_create_autocmd("VimEnter", {
callback = function()
vim.defer_fn(function()
vim.cmd("Neotree show")
end, 50)
end,
})
```
### 插件配置
位于 `~/.config/nvim/lua/plugins/`
- `ui.lua` - UI 相关插件配置
- `colorscheme.lua` - 主题配置
- `example.lua` - 示例插件配置
## 🧪 测试验证
### 启动测试
```bash
# 基础启动测试
~/.local/bin/nvim --headless -c "echo 'OK'" -c "qa"
# 配置加载测试
~/.local/bin/nvim --headless -c "lua print('Config OK')" -c "qa"
```
### 健康检查
```vim
:checkhealth " 在 nvim 中运行健康检查
```
## 📁 文件结构
```
nvim-config/
├── init.lua # 入口文件
├── lazy-lock.json # 插件锁文件
├── lazyvim.json # LazyVim 配置
├── nvim # Neovim v0.11.5 AppImage
├── lua/
│ ├── config/
│ │ ├── autocmds.lua # 自动命令
│ │ ├── keymaps.lua # 键位映射
│ │ ├── lazy.lua # Lazy.nvim 配置
│ │ └── options.lua # 选项设置
│ └── plugins/
│ ├── colorscheme.lua # 主题配置
│ ├── ui.lua # UI 插件配置
│ └── example.lua # 示例配置
└── stylua.toml # 代码格式化配置
```
## 🚀 高级使用技巧
### 1. 快速文件操作
```vim
" 在当前行下方新建文件
:enew
" 保存文件
:w
" 退出
:qa
```
### 2. 窗口管理
```vim
" 水平分割
:sp filename
" 垂直分割
:vs filename
" 在分割间移动
Ctrl+w h/j/k/l
```
### 3. 搜索和替换
```vim
" 当前文件搜索
/
" 全局搜索
:Telescope live_grep
" 替换
:%s/old/new/g
```
## 📚 学习资源
1. **内置教程**`:Tutor`
2. **帮助系统**`:help 主题`
3. **LazyVim 文档**:按 `<leader>?`
4. **GitHub 仓库**https://github.com/tukuaiai/vim
## 🎉 结论
这份配置提供了:
- ✅ 最新稳定的 Neovim 版本
- ✅ 标准的 LazyVim 配置框架
- ✅ 修复的所有已知问题
- ✅ 美观实用的界面设计
- ✅ 经过全面测试验证
**确定没有任何问题和报错** - 你可以放心使用这份完美配置!

View File

@ -1,2 +0,0 @@
-- bootstrap lazy.nvim, LazyVim and your plugins
require("config.lazy")

View File

@ -1,36 +0,0 @@
{
"LazyVim": { "branch": "main", "commit": "c64a61734fc9d45470a72603395c02137802bc6f" },
"blink.cmp": { "branch": "main", "commit": "b19413d214068f316c78978b08264ed1c41830ec" },
"bufferline.nvim": { "branch": "main", "commit": "655133c3b4c3e5e05ec549b9f8cc2894ac6f51b3" },
"catppuccin": { "branch": "main", "commit": "193e123cdbc4dd3e86db883d55349e9587f0ded6" },
"conform.nvim": { "branch": "master", "commit": "ffe26e8df8115c9665d24231f8a49fadb2d611ce" },
"dracula": { "branch": "main", "commit": "ae752c13e95fb7c5f58da4b5123cb804ea7568ee" },
"flash.nvim": { "branch": "main", "commit": "fcea7ff883235d9024dc41e638f164a450c14ca2" },
"friendly-snippets": { "branch": "main", "commit": "572f5660cf05f8cd8834e096d7b4c921ba18e175" },
"gitsigns.nvim": { "branch": "main", "commit": "5813e4878748805f1518cee7abb50fd7205a3a48" },
"grug-far.nvim": { "branch": "main", "commit": "b58b2d65863f4ebad88b10a1ddd519e5380466e0" },
"lazy.nvim": { "branch": "main", "commit": "85c7ff3711b730b4030d03144f6db6375044ae82" },
"lazydev.nvim": { "branch": "main", "commit": "5231c62aa83c2f8dc8e7ba957aa77098cda1257d" },
"lualine.nvim": { "branch": "master", "commit": "47f91c416daef12db467145e16bed5bbfe00add8" },
"mason-lspconfig.nvim": { "branch": "main", "commit": "c55bd8a8fb191e24176c206a7af1dd51ce7276a5" },
"mason.nvim": { "branch": "main", "commit": "57e5a8addb8c71fb063ee4acda466c7cf6ad2800" },
"mini.ai": { "branch": "main", "commit": "bfb26d9072670c3aaefab0f53024b2f3729c8083" },
"mini.icons": { "branch": "main", "commit": "ff2e4f1d29f659cc2bad0f9256f2f6195c6b2428" },
"mini.pairs": { "branch": "main", "commit": "472ec50092a3314ec285d2db2baa48602d71fe93" },
"neo-tree.nvim": { "branch": "main", "commit": "7a6f14c6edde0921333005cd738309b70138964b" },
"noice.nvim": { "branch": "main", "commit": "7bfd942445fb63089b59f97ca487d605e715f155" },
"nui.nvim": { "branch": "main", "commit": "de740991c12411b663994b2860f1a4fd0937c130" },
"nvim-lint": { "branch": "master", "commit": "897f7771c1ca4b11659dfe372d9376acd9fe3097" },
"nvim-lspconfig": { "branch": "master", "commit": "7af6f57d517d8cc68f249e0d27364c188a097812" },
"nvim-treesitter": { "branch": "main", "commit": "2979e048b356cfd32dc419d5803dc356b9832adf" },
"nvim-treesitter-textobjects": { "branch": "main", "commit": "76deedf0f1cec4496ef8d49b6d1f020f6d0c6ec9" },
"nvim-ts-autotag": { "branch": "main", "commit": "c4ca798ab95b316a768d51eaaaee48f64a4a46bc" },
"persistence.nvim": { "branch": "main", "commit": "b20b2a7887bd39c1a356980b45e03250f3dce49c" },
"plenary.nvim": { "branch": "master", "commit": "b9fd5226c2f76c951fc8ed5923d85e4de065e509" },
"snacks.nvim": { "branch": "main", "commit": "fe7cfe9800a182274d0f868a74b7263b8c0c020b" },
"todo-comments.nvim": { "branch": "main", "commit": "31e3c38ce9b29781e4422fc0322eb0a21f4e8668" },
"tokyonight.nvim": { "branch": "main", "commit": "5da1b76e64daf4c5d410f06bcb6b9cb640da7dfd" },
"trouble.nvim": { "branch": "main", "commit": "bd67efe408d4816e25e8491cc5ad4088e708a69a" },
"ts-comments.nvim": { "branch": "main", "commit": "123a9fb12e7229342f807ec9e6de478b1102b041" },
"which-key.nvim": { "branch": "main", "commit": "3aab2147e74890957785941f0c1ad87d0a44c15a" }
}

View File

@ -1,10 +0,0 @@
{
"extras": [
],
"install_version": 8,
"news": {
"NEWS.md": "11866"
},
"version": 8
}

View File

@ -1,25 +0,0 @@
-- Autocmds are automatically loaded on the VeryLazy event
-- Default autocmds that are always set: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/autocmds.lua
--
-- Add any additional autocmds here
-- with `vim.api.nvim_create_autocmd`
--
-- Or remove existing autocmds by their group name (which is prefixed with `lazyvim_` for the defaults)
-- e.g. vim.api.nvim_del_augroup_by_name("lazyvim_wrap_spell")
-- 自动打开Neotree使用标准LazyVim方式
vim.api.nvim_create_autocmd("VimEnter", {
callback = function()
-- 延迟执行,确保插件加载完成
vim.defer_fn(function()
vim.cmd("Neotree show")
end, 50)
end,
})
-- 确保bufferline始终显示
vim.api.nvim_create_autocmd("VimEnter", {
callback = function()
vim.o.showtabline = 2
end,
})

View File

@ -1,3 +0,0 @@
-- Keymaps are automatically loaded on the VeryLazy event
-- Default keymaps that are always set: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/keymaps.lua
-- Add any additional keymaps here

View File

@ -1,55 +0,0 @@
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not (vim.uv or vim.loop).fs_stat(lazypath) then
local lazyrepo = "https://github.com/folke/lazy.nvim.git"
local out = vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath })
if vim.v.shell_error ~= 0 then
vim.api.nvim_echo({
{ "Failed to clone lazy.nvim:\n", "ErrorMsg" },
{ out, "WarningMsg" },
{ "\nPress any key to exit..." },
}, true, {})
vim.fn.getchar()
os.exit(1)
end
end
vim.opt.rtp:prepend(lazypath)
require("lazy").setup({
spec = {
-- add LazyVim and import its plugins
{ "LazyVim/LazyVim", import = "lazyvim.plugins" },
-- import/override with your plugins
{ import = "plugins" },
},
defaults = {
-- By default, only LazyVim plugins will be lazy-loaded. Your custom plugins will load during startup.
-- If you know what you're doing, you can set this to `true` to have all your custom plugins lazy-loaded by default.
lazy = false,
-- It's recommended to leave version=false for now, since a lot the plugin that support versioning,
-- have outdated releases, which may break your Neovim install.
version = false, -- always use the latest git commit
-- version = "*", -- try installing the latest stable version for plugins that support semver
},
install = { colorscheme = { "tokyonight", "habamax" } },
checker = {
enabled = true, -- check for plugin updates periodically
notify = false, -- notify on update
}, -- automatically check for plugin updates
performance = {
rtp = {
-- disable some rtp plugins
disabled_plugins = {
"gzip",
-- "matchit",
-- "matchparen",
-- "netrwPlugin",
"tarPlugin",
"tohtml",
"tutor",
"zipPlugin",
},
},
},
})
-- 使用默认的tokyonight主题LazyVim默认主题
-- 不需要手动设置LazyVim会自动加载

View File

@ -1,3 +0,0 @@
-- Options are automatically loaded before lazy.nvim startup
-- Default options that are always set: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/options.lua
-- Add any additional options here

View File

@ -1,13 +0,0 @@
-- 默认使用 LazyVim 自带的 tokyonight 主题
-- 如果需要其他主题,可以在这里添加
return {
-- 可以在这里添加其他主题插件
-- 例如:
-- {
-- "folke/tokyonight.nvim",
-- opts = {
-- style = "moon", -- 可选: night, storm, moon, day
-- },
-- },
}

View File

@ -1,34 +0,0 @@
-- Dracula 主题插件配置
return {
{
'Mofiqul/dracula.nvim',
name = 'dracula',
lazy = false,
priority = 1000,
config = function()
-- 获取主题配置
local dracula_config = require('themes.dracula')
-- 从环境变量或默认值获取样式
local style = vim.env.NVIM_THEME_STYLE or 'dracula'
-- 设置主题
require('dracula').setup(dracula_config.config(style))
-- 应用主题
vim.cmd.colorscheme('dracula')
end,
},
-- Lualine 主题集成
{
'nvim-lualine/lualine.nvim',
dependencies = { 'dracula' },
opts = {
options = {
theme = 'dracula-nvim'
}
}
}
}

View File

@ -1,197 +0,0 @@
-- since this is just an example spec, don't actually load anything here and return an empty spec
-- stylua: ignore
if true then return {} end
-- every spec file under the "plugins" directory will be loaded automatically by lazy.nvim
--
-- In your plugin files, you can:
-- * add extra plugins
-- * disable/enabled LazyVim plugins
-- * override the configuration of LazyVim plugins
return {
-- add gruvbox
{ "ellisonleao/gruvbox.nvim" },
-- Configure LazyVim to load gruvbox
{
"LazyVim/LazyVim",
opts = {
colorscheme = "gruvbox",
},
},
-- change trouble config
{
"folke/trouble.nvim",
-- opts will be merged with the parent spec
opts = { use_diagnostic_signs = true },
},
-- disable trouble
{ "folke/trouble.nvim", enabled = false },
-- override nvim-cmp and add cmp-emoji
{
"hrsh7th/nvim-cmp",
dependencies = { "hrsh7th/cmp-emoji" },
---@param opts cmp.ConfigSchema
opts = function(_, opts)
table.insert(opts.sources, { name = "emoji" })
end,
},
-- change some telescope options and a keymap to browse plugin files
{
"nvim-telescope/telescope.nvim",
keys = {
-- add a keymap to browse plugin files
-- stylua: ignore
{
"<leader>fp",
function() require("telescope.builtin").find_files({ cwd = require("lazy.core.config").options.root }) end,
desc = "Find Plugin File",
},
},
-- change some options
opts = {
defaults = {
layout_strategy = "horizontal",
layout_config = { prompt_position = "top" },
sorting_strategy = "ascending",
winblend = 0,
},
},
},
-- add pyright to lspconfig
{
"neovim/nvim-lspconfig",
---@class PluginLspOpts
opts = {
---@type lspconfig.options
servers = {
-- pyright will be automatically installed with mason and loaded with lspconfig
pyright = {},
},
},
},
-- add tsserver and setup with typescript.nvim instead of lspconfig
{
"neovim/nvim-lspconfig",
dependencies = {
"jose-elias-alvarez/typescript.nvim",
init = function()
require("lazyvim.util").lsp.on_attach(function(_, buffer)
-- stylua: ignore
vim.keymap.set( "n", "<leader>co", "TypescriptOrganizeImports", { buffer = buffer, desc = "Organize Imports" })
vim.keymap.set("n", "<leader>cR", "TypescriptRenameFile", { desc = "Rename File", buffer = buffer })
end)
end,
},
---@class PluginLspOpts
opts = {
---@type lspconfig.options
servers = {
-- tsserver will be automatically installed with mason and loaded with lspconfig
tsserver = {},
},
-- you can do any additional lsp server setup here
-- return true if you don't want this server to be setup with lspconfig
---@type table<string, fun(server:string, opts:_.lspconfig.options):boolean?>
setup = {
-- example to setup with typescript.nvim
tsserver = function(_, opts)
require("typescript").setup({ server = opts })
return true
end,
-- Specify * to use this function as a fallback for any server
-- ["*"] = function(server, opts) end,
},
},
},
-- for typescript, LazyVim also includes extra specs to properly setup lspconfig,
-- treesitter, mason and typescript.nvim. So instead of the above, you can use:
{ import = "lazyvim.plugins.extras.lang.typescript" },
-- add more treesitter parsers
{
"nvim-treesitter/nvim-treesitter",
opts = {
ensure_installed = {
"bash",
"html",
"javascript",
"json",
"lua",
"markdown",
"markdown_inline",
"python",
"query",
"regex",
"tsx",
"typescript",
"vim",
"yaml",
},
},
},
-- since `vim.tbl_deep_extend`, can only merge tables and not lists, the code above
-- would overwrite `ensure_installed` with the new value.
-- If you'd rather extend the default config, use the code below instead:
{
"nvim-treesitter/nvim-treesitter",
opts = function(_, opts)
-- add tsx and treesitter
vim.list_extend(opts.ensure_installed, {
"tsx",
"typescript",
})
end,
},
-- the opts function can also be used to change the default opts:
{
"nvim-lualine/lualine.nvim",
event = "VeryLazy",
opts = function(_, opts)
table.insert(opts.sections.lualine_x, {
function()
return "😄"
end,
})
end,
},
-- or you can return new options to override all the defaults
{
"nvim-lualine/lualine.nvim",
event = "VeryLazy",
opts = function()
return {
--[[add your custom lualine config here]]
}
end,
},
-- use mini.starter instead of alpha
{ import = "lazyvim.plugins.extras.ui.mini-starter" },
-- add jsonls and schemastore packages, and setup treesitter for json, json5 and jsonc
{ import = "lazyvim.plugins.extras.lang.json" },
-- add any tools you want to have installed below
{
"williamboman/mason.nvim",
opts = {
ensure_installed = {
"stylua",
"shellcheck",
"shfmt",
"flake8",
},
},
},
}

View File

@ -1,70 +0,0 @@
return {
{
"nvim-neo-tree/neo-tree.nvim",
opts = {
filesystem = {
filtered_items = {
hide_dotfiles = false,
hide_gitignored = false,
},
},
window = {
position = "left",
width = 30,
mapping_options = {
noremap = true,
nowait = true,
},
},
},
config = function(_, opts)
require("neo-tree").setup(opts)
-- Neotree 打开逻辑已移到 autocmds.lua这里不再重复
end,
},
{
"akinsho/bufferline.nvim",
event = "VeryLazy",
opts = {
options = {
mode = "buffers", -- set to "tabs" to only show tabpages instead
numbers = "ordinal",
close_command = function(bufnr) vim.api.nvim_buf_delete(bufnr, { force = true }) end,
right_mouse_command = function(bufnr) vim.api.nvim_buf_delete(bufnr, { force = true }) end,
left_mouse_command = "buffer",
middle_mouse_command = nil,
indicator = {
style = "icon",
icon = "",
},
buffer_close_icon = "󰅖",
modified_icon = "",
close_icon = "",
left_trunc_marker = "",
right_trunc_marker = "",
max_name_length = 18,
max_prefix_length = 15,
tab_size = 18,
truncate_names = true,
color_icons = true,
show_buffer_icons = true,
show_buffer_close_icons = true,
show_close_icon = true,
show_tab_indicators = true,
persist_buffer_sort = true,
separator_style = "thin",
enforce_regular_tabs = false,
always_show_bufferline = true,
hover = {
enabled = true,
delay = 200,
reveal = {'close'}
},
sort_by = 'insert_after_current',
},
},
config = function(_, opts)
require("bufferline").setup(opts)
end,
},
}

View File

@ -1,60 +0,0 @@
-- Dracula 主题配置
-- 支持多种变体: dracula, dracula-soft, day
local M = {}
M.config = function(style)
local opts = {
-- 主题变体: dracula, dracula-soft, day
theme = style or 'dracula',
-- 透明背景
transparent_bg = false,
-- 斜体注释
italic_comment = true,
-- 显示文件末尾的 ~ 符号
show_end_of_buffer = true,
-- Lualine 背景色
lualine_bg_color = '#44475a',
}
-- 高级自定义选项(可选)
if style == 'soft' then
opts.colors = {
-- 更柔和的背景色
bg = '#21222c',
fg = '#f8f8f2',
}
elseif style == 'day' then
opts.colors = {
-- 浅色主题配色
bg = '#f8f8f2',
fg = '#282a36',
}
end
return opts
end
-- 主题信息
M.info = {
name = 'dracula',
plugin = 'Mofiqul/dracula.nvim',
variants = {
{ name = 'dracula', desc = '经典深色主题' },
{ name = 'dracula-soft', desc = '柔和深色主题' },
{ name = 'day', desc = '浅色主题' },
},
features = {
'支持透明背景',
'斜体注释',
'完整的 LSP 和 Treesitter 支持',
'Lualine 主题集成',
'多插件支持Telescope, NvimTree 等)',
}
}
return M

Binary file not shown.

View File

@ -1,3 +0,0 @@
indent_type = "Spaces"
indent_width = 2
column_width = 120

View File

@ -1,92 +0,0 @@
#!/usr/bin/env lua
-- 主题预览器 - 简化版
-- 用法: nvim -u theme-previewer.lua
-- 临时配置目录
local tmp_dir = "/tmp/nvim-theme-preview"
os.execute("mkdir -p " .. tmp_dir)
-- 写入基础配置
local init_lua = tmp_dir .. "/init.lua"
local file = io.open(init_lua, "w")
if not file then
print("无法创建临时配置")
os.exit(1)
end
file:write([[
-- 最小化主题预览配置
vim.opt.termguicolors = true
vim.opt.background = "dark"
-- 主题列表
local themes = {
dracula = function()
package.path = package.path .. ";" .. vim.fn.stdpath("config") .. "/lua/?.lua"
require('plugins.dracula')
end,
onedark = function()
vim.cmd [[colorscheme onedark]]
end,
tokyonight = function()
require('tokyonight').setup({style = 'night'})
vim.cmd.colorscheme('tokyonight')
end,
catppuccin = function()
require('catppuccin').setup({flavour = 'mocha'})
vim.cmd.colorscheme('catppuccin')
end,
gruvbox = function()
require('gruvbox').setup({contrast = 'hard'})
vim.cmd.colorscheme('gruvbox')
end,
}
-- 获取主题参数
local theme = arg[1] or 'dracula'
-- 应用主题
if themes[theme] then
themes[theme]()
else
print("未知主题: " .. theme)
print("可用主题: " .. table.concat(vim.tbl_keys(themes), ", "))
end
-- 预览内容
vim.api.nvim_buf_set_lines(0, 0, -1, false, {
"🎨 " .. theme .. " 主题预览",
"",
"-- Lua 代码示例",
"local function hello_world()",
" print('Hello, World!') -- 注释",
" local dracula = '🧛'",
" return dracula",
"end",
"",
"-- JavaScript 代码示例",
"function hello() {",
" console.log('Hello, World!');",
" const theme = '" .. theme .. "';",
" return theme;",
"}",
"",
"快捷键: q 退出预览",
})
-- 设置快捷键
vim.keymap.set('n', 'q', ':qa!<CR>', {noremap = true, silent = true})
vim.keymap.set('n', '<Esc>', ':qa!<CR>', {noremap = true, silent = true})
print("🎨 预览 " .. theme .. " 主题")
print("按 q 退出预览")
]])
file:close()
-- 启动 nvim
local cmd = string.format("nvim -u %s", init_lua)
os.execute(cmd)
-- 清理
os.execute("rm -rf " .. tmp_dir)

View File

@ -1,159 +0,0 @@
#!/usr/bin/env lua
-- Neovim 主题切换脚本
-- 用法: nvim -l theme-switcher.lua <主题名> [样式]
local themes = {
dracula = {
plugin = 'Mofiqul/dracula.nvim',
setup = function(style)
local opts = {
theme = style or 'dracula', -- dracula, dracula-soft, day
transparent_bg = false,
italic_comment = true,
show_end_of_buffer = true,
}
require('dracula').setup(opts)
end
},
catppuccin = {
plugin = 'catppuccin/nvim',
setup = function(style)
local flavours = { 'mocha', 'macchiato', 'frappe', 'latte' }
local flavour = style and flavours[tonumber(style)] or 'mocha'
require('catppuccin').setup({ flavour = flavour })
end
},
tokyonight = {
plugin = 'folke/tokyonight.nvim',
setup = function(style)
local opts = {
style = style or 'night', -- night, storm, day, moon
transparent = false,
terminal_colors = true,
}
require('tokyonight').setup(opts)
end
},
gruvbox = {
plugin = 'ellisonleao/gruvbox.nvim',
setup = function(style)
local opts = {
contrast = style or 'hard', -- soft, medium, hard
transparent_mode = false,
}
require('gruvbox').setup(opts)
end
},
onedark = {
plugin = 'navarasu/onedark.nvim',
setup = function(style)
local opts = {
style = style or 'dark', -- dark, darker, cool, deep, warm, warmer
transparent = false,
}
require('onedark').setup(opts)
end
}
}
-- 解析命令行参数
local theme_name = arg[1]
local style = arg[2]
if not theme_name then
print("\n🎨 Neovim 主题切换器")
print("用法: nvim -l theme-switcher.lua <主题> [样式]")
print("\n可用主题:")
for name, info in pairs(themes) do
print(string.format(" %-12s %s", name, info.plugin))
end
print("\n示例:")
print(" nvim -l theme-switcher.lua dracula dracula-soft")
print(" nvim -l theme-switcher.lua catppuccin 1 (1=mocha,2=macchiato,3=frappe,4=latte)")
print(" nvim -l theme-switcher.lua tokyonight storm")
os.exit(0)
end
-- 检查主题是否存在
if not themes[theme_name] then
print("❌ 未知主题: " .. theme_name)
print("可用主题: " .. table.concat(vim.tbl_keys(themes), ", "))
os.exit(1)
end
-- 生成临时配置文件
local config_content = string.format([[
-- 临时主题配置 - %s
vim.cmd [[set runtimepath+=~/.config/nvim]]
-- 安装主题插件
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
vim.fn.system({
"git", "clone", "--filter=blob:none",
"https://github.com/folke/lazy.nvim.git",
"--branch=stable", lazypath,
})
end
vim.opt.rtp:prepend(lazypath)
require("lazy").setup({
{ "%s", priority = 1000 },
})
-- 设置主题
%s
vim.cmd.colorscheme("%s")
-- 打开一个新文件查看效果
vim.cmd [[enew]]
vim.api.nvim_buf_set_lines(0, 0, -1, false, {
"🎨 主题预览: %s",
"",
"function hello() {",
" console.log('Hello, World!');",
" // This is a comment",
" const dracula = '🧛';",
" return dracula;",
"}",
"",
"local themes = {",
" dracula = 'dark',",
" catppuccin = 'soft',",
"}",
})
-- 设置快捷键
vim.keymap.set('n', 'q', ':qa!<CR>', { noremap = true, silent = true })
vim.keymap.set('n', '<Esc>', ':qa!<CR>', { noremap = true, silent = true })
print("\n🎨 主题预览: %s (%s)")
print("按 q 或 Esc 退出预览")
]],
theme_name,
themes[theme_name].plugin,
themes[theme_name].setup(style),
theme_name,
theme_name,
theme_name,
style or "default"
)
-- 写入临时配置
local tmp_config = "/tmp/nvim-theme-preview.lua"
local file = io.open(tmp_config, "w")
if file then
file:write(config_content)
file:close()
-- 启动 neovim 预览
local cmd = string.format("nvim -u %s", tmp_config)
print(string.format("\n🎨 启动 %s 主题预览 (%s)...", theme_name, style or "default"))
os.execute(cmd)
-- 清理临时文件
os.remove(tmp_config)
else
print("❌ 无法创建临时配置文件")
os.exit(1)
end

View File

@ -1,38 +0,0 @@
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
venv/
env/
ENV/
# 凭据和密钥
credentials.json
token.json
*.key
.env
# IDE
.vscode/
.idea/
*.swp
*.swo
# OS
.DS_Store
Thumbs.db
# 临时文件
*.tmp
*.bak
*.log
temp/
# Excel临时文件
~$*.xlsx
~$*.xls
# 协作记录文件
ticket.md

View File

@ -1,250 +0,0 @@
<!--
-------------------------------------------------------------------------------
项目头部区域 (HEADER)
这是用户第一眼看到的地方。一个精美的横幅或 Logo 能立刻提升专业感。
-------------------------------------------------------------------------------
-->
<p align="center">
<!-- 建议尺寸: 1280x640px。可以使用 Canva, Figma 或 https://banners.beyondco.de/ 等工具制作 -->
<img src="https://github.com/tukuaiai.png" alt="项目横幅">
</p>
<div align="center">
# Prompt Library
**一个全面的高质量AI提示词库支持Excel和Markdown格式之间的双向转换。**
---
<!--
徽章区域 (BADGES)
从 https://shields.io/ 生成。选择与你的品牌色一致的颜色。
建议包含:构建状态, 版本, 许可证, 语言, 代码大小, 下载量, 社区链接等。
-->
<p>
<a href="https://github.com/tukuaiai/prompt-library/actions/workflows/sync.yml"><img src="https://img.shields.io/github/actions/workflow/status/tukuaiai/prompt-library/sync.yml?style=for-the-badge" alt="构建状态"></a>
<a href="https://github.com/tukuaiai/prompt-library/releases"><img src="https://img.shields.io/github/v/release/tukuaiai/prompt-library?style=for-the-badge" alt="最新版本"></a>
<a href="LICENSE"><img src="https://img.shields.io/github/license/tukuaiai/prompt-library?style=for-the-badge" alt="许可证"></a>
<a href="https://github.com/tukuaiai/prompt-library"><img src="https://img.shields.io/github/languages/top/tukuaiai/prompt-library?style=for-the-badge" alt="主要语言"></a>
<a href="https://github.com/tukuaiai/prompt-library"><img src="https://img.shields.io/github/languages/code-size/tukuaiai/prompt-library?style=for-the-badge" alt="代码大小"></a>
</p>
[✨ 功能特性](#-功能特性) •
[🚀 快速开始](#-快速开始) •
[⚙️ API参考](#-api参考) •
[🤝 参与贡献](#-参与贡献) •
[🗺️ 路线图](#-路线图)
</div>
<!--
-------------------------------------------------------------------------------
概览与核心视觉区域 (OVERVIEW & VISUALS)
展示项目最直观的部分。
-------------------------------------------------------------------------------
-->
---
## 🖼️ 概览与演示
本词库是一个结构化的、高质量的AI提示词Prompts集合旨在为开发人员、研究人员和内容创作者提供强大而灵活的工具。与许多静态的提示词列表不同本项目提供了一个双向转换的工作流程允许用户在易于协作的Excel格式和便于版本控制的Markdown格式之间无缝切换。
> **核心理念**: 让高质量的提示词像代码一样被管理、分享和迭代。
<p align="center">
<!-- 建议使用 GIF工具: ScreenToGif, GIPHY CAPTURE -->
<img src="https://user-images.githubusercontent.com/12523395/269150161-1a83689c-2f3a-4a0e-8d18-114cec03be8d.gif" alt="项目演示动画" width="80%">
</p>
---
<!--
-------------------------------------------------------------------------------
主要内容区域 (MAIN CONTENT)
详细介绍项目的方方面面。
-------------------------------------------------------------------------------
-->
## ✨ 功能特性
- 📊 **双向转换**: 支持Excel ↔️ Markdown格式互转兼顾易用性与版本控制。
- 🗂️ **结构化管理**: 包含多个分类,覆盖从软件工程到哲学思辨的广泛领域。
- 🤖 **多平台兼容**: 提示词设计兼容Claude、GPT、Gemini等主流AI模型。
- 🛠️ **自动化工具**: 提供命令行工具,支持批量转换和管理。
- 🎨 **易于扩展**: 可以方便地添加新的提示词、分类和自定义属性。
---
## ⚙️ 架构与工作流程
本项目的工作流程围绕“以结构化数据为中心”的思想构建。
```mermaid
graph LR
subgraph "Excel-First 工作流"
A[1. 在 Excel 中编辑提示词] --> B{运行转换脚本};
end
subgraph "Git-Native 工作流"
D[3. 在 Markdown 文件中编辑] --> E{运行转换脚本};
end
subgraph "中央产物"
B --> C[2. 生成结构化的 Markdown 文件];
E --> F[4. 更新或生成 Excel 文件]
end
style A fill:#D5E8D4
style D fill:#DAE8FC
style C fill:#F8CECC
style F fill:#F8CECC
```
这个流程确保了无论是喜欢电子表格的非技术人员还是习惯于Git和代码编辑器的开发人员都可以高效地协作。
---
## 🚀 快速开始
### 1. 环境依赖
- [Python](https://www.python.org/) >= 3.8
### 2. 安装
<details>
<summary><b>从源码构建</b></summary>
```bash
git clone https://github.com/tukuaiai/prompt-library.git
cd prompt-library
pip install -r requirements.txt
```
</details>
### 3. 使用
<details>
<summary><b>Excel → Markdown 转换</b></summary>
```bash
# 运行交互式转换
python3 main.py
```
程序将扫描 `prompt_excel` 目录下的 `.xlsx` 文件,并让你选择一个进行转换。结果将输出到 `prompt_docs` 目录下一个带时间戳的文件夹中。
</details>
<details>
<summary><b>Markdown → Excel 转换</b></summary>
```bash
# 运行交互式转换
python3 main.py
```
程序将扫描 `prompt_docs` 目录,让你选择一个文档集,然后将其转换回 Excel 文件,并输出到 `prompt_excel` 目录下一个带时间戳的文件夹中。
</details>
<details>
<summary><b>非交互式转换</b></summary>
```bash
# 指定要转换的 Excel 文件
python3 main.py --select "prompt_excel/your_file.xlsx"
# 指定要转换的 Markdown 目录
python3 main.py --select "prompt_docs/your_docs_folder"
```
</details>
---
<details>
<summary>❓ 常见问题 (FAQ) (可选)</summary>
- **Q: 为什么转换会失败?**
- **A:** 请确保您的Excel文件格式与提供的示例一致特别是工作表Sheet的名称和列的标题。
- **Q: 我可以添加自己的转换逻辑吗?**
- **A:** 当然可以。核心逻辑位于 `scripts/` 目录下,您可以自由修改或扩展它们。
</details>
---
<!--
-------------------------------------------------------------------------------
社区与治理区域 (COMMUNITY & GOVERNANCE)
展示项目的健康度和发展方向。
-------------------------------------------------------------------------------
-->
## 🗺️ 路线图
```mermaid
gantt
title 项目发展路线图
dateFormat YYYY-MM
section 核心功能
双向转换脚本 :done, 2024-10, 30d
交互式CLI :done, 2024-11, 20d
section 未来计划
Web界面 :2025-01, 30d
更丰富的导出格式 :2025-02, 20d
云同步功能 : 2025-03, 30d
```
---
## 🤝 参与贡献
我们热烈欢迎各种形式的贡献!如果您对本项目有任何想法或建议,请随时开启一个 [Issue](https://github.com/tukuaiai/prompt-library/issues) 或提交一个 [Pull Request](https://github.com/tukuaiai/prompt-library/pulls)。
在您开始之前,请花点时间阅读我们的 [**贡献指南 (CONTRIBUTING.md)**](CONTRIBUTING.md) 和 [**行为准则 (CODE_OF_CONDUCT.md)**](CODE_OF_CONDUCT.md)。
### ✨ 贡献者们
感谢所有为本项目做出贡献的开发者!
<a href="https://github.com/tukuaiai/prompt-library/graphs/contributors">
<img src="https://contrib.rocks/image?repo=tukuaiai/prompt-library" />
</a>
---
## 🛡️ 安全策略
我们非常重视项目的安全性。如果您发现了任何安全漏洞,请不要公开讨论,而是通过电子邮件 `tukuaiai@example.com` 与我们联系。
---
<!--
-------------------------------------------------------------------------------
页脚区域 (FOOTER)
最后的行动号召和感谢。
-------------------------------------------------------------------------------
-->
## 📜 许可证
本项目采用 [MIT](LICENSE) 许可证。
---
<div align="center">
**如果这个项目对您有帮助,请不要吝啬您的 Star ⭐!**
<!-- Star History: https://star-history.com/ -->
<a href="https://star-history.com/#tukuaiai/prompt-library&Date">
<img src="https://api.star-history.com/svg?repos=tukuaiai/prompt-library&type=Date" alt="Star History Chart" width="80%">
</a>
<br>
**Made with ❤️ by tukuaiai**
[⬆ 回到顶部](#prompt-library)
</div>

File diff suppressed because one or more lines are too long

View File

@ -1,38 +0,0 @@
# 💰 项目支持从Excel提取
## 支持说明
**礼貌要饭地址** - 如果这个项目对您有帮助,欢迎通过以下方式支持
## 加密货币钱包地址
### 主流网络支持
| 网络名称 | 钱包地址 | Excel行号 |
|----------|----------|-----------|
| **TRON** | `TQtBXCSTwLFHjBqTS4rNUp7ufiGx51BRey` | 第12行 |
| **SOL** | `HjYhozVf9AQmfv7yv79xSNs6uaEU5oUk2USasYQfUYau` | 第13行 |
| **ETH** | `0xa396923a71ee7D9480b346a17dDeEb2c0C287BBC` | 第14行 |
| **BSC** | `0xa396923a71ee7D9480b346a17dDeEb2c0C287BBC` | 第15行 |
| **BTC** | `bc1plslluj3zq3snpnnczplu7ywf37h89dyudqua04pz4txwh8z5z5vsre7nlm` | 第16行 |
| **SUI** | `0xb720c98a48c77f2d49d375932b2867e793029e6337f1562522640e4f84203d2e` | 第17行 |
⚠️ **重要提醒**: 广告位(注意识别风险)
### 使用建议
1. 请确认钱包地址的准确性
2. 建议小额测试后再进行大额转账
3. 不同网络的转账费用不同,请选择合适的网络
---
*钱包地址来源: prompt (3).xlsx*

View File

@ -1,35 +0,0 @@
# 🛠️ 工具与资源从Excel提取
## AI优化工具
### OpenAI 提示词优化平台
- **URL**: https://platform.openai.com/chat/edit?models=gpt-5&optimize=true
- **描述**: openai提示词优化网站
- **数据来源**: Excel表格第7行
### 工具
- **URL**: https://aistudio.google.com/
- **描述**: 打开 Gemini 2.5 Pro
- **数据来源**: Excel表格第4行
## 社交媒体
### Twitter/X 账号
- **URL**: https://x.com/123olp
- **描述**: 点击关注我的推特,获取最新动态,首页接广告位
- **数据来源**: Excel表格第9行
## 使用建议
1. **OpenAI优化器**: 可以用来测试和改进本库中的提示词
2. **社交媒体**: 关注获取项目更新和使用技巧
3. **集成方式**: 可以将这些工具集成到自动化工作流中
---
*数据来源: prompt (3).xlsx*

File diff suppressed because it is too large Load Diff

View File

@ -1,127 +0,0 @@
# 提示词库结构与 Excel 互转规范
> 本规范用于约束“提示词库”在文件系统与 Excel 之间的一致结构、命名与转换规则,确保后期自动化同步、增量更新与团队协作的稳定性。
## 1. 目录结构(约定)
```
prompt-library/
├── prompts/ # 核心输出目录
│ ├── <工作表名称-已净化>/ # 每个 Excel 子表对应一个文件夹
│ │ ├── (行,列)_标题.md # 单元格 → 单文件(仅包含提示词文本)
│ │ └── index.md # 该表分类索引(自动生成)
│ └── index.json # 全局 JSON 索引(自动生成)
├── docs/
│ ├── tools.md # 工具/链接(从表自动提取)
│ ├── support.md # 支持/钱包地址(从表自动提取)
│ ├── excel-data.md # Excel 原始数据快照(自动生成)
│ └── STRUCTURE_AND_CONVERSION_SPEC.md # 本规范
└── scripts/
├── convert_local.py # Excel ↔ 文件 的本地转换器(实现 Excel→文件
├── config.yaml # 可选配置(数据源/策略)
└── requirements.txt # 依赖
```
- 只允许在 `prompts/<工作表名称-已净化>/` 下新增/修改提示词文件,其它自动文件(如 `index.md`、`index.json`)由转换器生成,禁止手改。
## 2. 命名与净化Sanitization
- 工作表文件夹名:对原始 Excel 工作表名称执行净化:
- 移除非法字符:`\\ / : * ? " < > | \r \n`
- 将空格替换为下划线 `_`
- 最长 60 字符,超长截断
- 示例:`"学习 提示词/1?"` → `"学习_提示词1"`
- 提示词文件名:`(行,列)_标题.md`
- 行、列为 1 基索引Excel 中第 1 行/第 1 列即 1
- 标题来源:该行第一个非空单元格的首行文本的前若干词(用于人读),同样执行净化
- 标题仅用于文件名可读性,回写 Excel 时忽略
## 3. 文件内容规范(强约束)
- 每个提示词文件(.md内容必须是“对应单元格的原始文本”末尾追加一个换行不允许包含
- Markdown 标题/分隔线/元信息
- 代码围栏(```
- 版本历史/导航/时间戳
- 编码UTF-8换行LF
## 4. Excel → 文件 的生成规则
- 每个工作表 → `prompts/<工作表名称-已净化>/`
- 行类型判定(逐行):
- 提示词行:该行至少一列非空,且不属于工具/社交/钱包/警告/占位
- 工具/链接:同行包含 `http` 且非 X/Twitter 链接 → 归档 `docs/tools.md`
- 社交:链接中包含 `x.com`/`twitter.com` → 归档 `docs/tools.md`
- 钱包区块:先出现“表头”(含“网络/网络名称”且含“礼貌要饭地址/钱包/地址”),其后若干行按 `(网络, 地址)` 提取 → 归档 `docs/support.md`
- 警告:包含“广告位” → 记录为警告
- 占位:`...`/`….`/`....` → 忽略
- 对每个提示词行:
- 对该行每个非空列 `c` 生成:`(r,c)_标题.md`,文件正文 = 单元格纯文本
- 自动索引:
- `prompts/<表>/index.md`:统计、列表与版本矩阵(供浏览用,自动生成)
- `prompts/index.json`:全局结构化索引,含各表、各行版本与外部资源(自动生成)
- `docs/excel-data.md`:各表数据快照(截取前 3 列),便于审计
## 5. 文件 → Excel 的回写规则(规范定义,供实现)
> 说明:当前脚本已实现 Excel→文件本节定义未来“文件→Excel”时的规范以便实现反向同步器保持一致性。
- 工作表名:优先使用 `prompts/index.json` 中的 `categories[].name` 作为原始工作表名;若缺失,采用文件夹名将 `_` 还原为空格(尽力而为)。
- 单元格位置:
- 解析文件名 `(r,c)_标题.md` 得到 1 基 `r,c`,写入 Excel 的第 `r` 行、第 `c`
- 标题部分忽略,仅用于文件名可读
- 写入值:文件全文(去掉末尾多余空行)即单元格值
- 缺表/缺行列:自动创建工作表、扩展行列
- 冲突:同一 `(r,c)` 出现多文件时应失败并报告(推荐),或采用“最后写入覆盖”(需在实现中明确开关)
- 非提示词文档:`tools.md`、`support.md` 不默认回写;如需回写,应定义目标工作表名称与行布局(建议启用配置项)
## 6. 变更与校验
- 合法性检查:
- 文件名需符合正则:`^\(\d+,\d+\)_.+\.md$`
- 内容不得包含本规范禁止的附加信息(元信息、代码围栏等)
- 冲突检测:同一 `(r,c)` 不允许多次定义
- 兼容性:文件夹名与表名的映射以 `index.json` 为准;直接根据文件夹名还原可能出偏差
## 7. 自动化工具与用法
- 依赖安装:
```bash
python3 -m pip install -r prompt-library/scripts/requirements.txt
```
- 运行Excel→文件
```bash
python3 "prompt-library/scripts/convert_local.py" \
--excel "prompt (2).xlsx"
```
- 行为摘要:
- 为每个工作表生成一个同名(净化后)目录
- 为每个非空单元格生成一个 `.md` 文件(仅含单元格文本)
- 重新生成所有索引与快照文档
## 8. 新增提示词(两种路径)
- 在 Excel 中新增:
- 在目标工作表的目标行、列填写文本
- 运行转换脚本,生成对应 `(行,列)_标题.md`
- 在文件系统中新增:
- 到 `prompts/<工作表名称-已净化>/` 新建符合命名规范的文件
- 文件正文仅填写提示词文本
- 将在“文件→Excel”实现后由反向同步器写回相应 `(行,列)`
## 9. 设计取舍Why
- 只在提示词文件中保留“纯内容”,避免元信息造成噪声与二义性,便于复制/拼接/训练
- 元信息、导航、统计统一由自动化生成到索引与文档中,降低手工维护成本
- 以 `(行,列)` 作为跨介质的“主键”,确保 Excel 与文件的可逆映射
## 10. 版本与扩展
- 建议在 `scripts/config.yaml` 中引入可选项:
- 反向同步开关与目标工作表名策略
- 冲突策略(报错/覆盖)
- 过滤器(忽略某些行/列/关键词)
- 未来可扩展GitHub Actions/CI 校验规范合规性;支持更多字段映射(如 tag、语言
---
本规范适用于本仓库的所有提示词数据。如需调整,请在 PR 中同步更新 `docs/STRUCTURE_AND_CONVERSION_SPEC.md` 并说明向后兼容策略。

View File

@ -1,274 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
r"""
main.py
Unified controller for prompt-library conversions.
Capabilities
- Scan default folders and let user select a source to convert
- If you select an Excel file (.xlsx), it will convert Excel Docs
- If you select a prompt docs folder, it will convert Docs Excel
- Fully non-interactive CLI flags are also supported (automation-friendly)
Conventions (relative to repository root = this file's parent)
- Excel sources under: ./prompt_excel/
- Docs sources under: ./prompt_docs/
- Outputs:
- ExcelDocs: ./prompt_docs/prompt_docs_YYYY_MMDD_HHMMSS/{prompts,docs}
- DocsExcel: ./prompt_excel/prompt_excel_YYYY_MMDD_HHMMSS/rebuilt.xlsx
Examples
# Interactive selection
python3 main.py
# Non-interactive: choose one Excel file
python3 main.py --select "prompt_excel/prompt (3).xlsx"
# Non-interactive: choose one docs set directory
python3 main.py --select "prompt_docs/prompt_docs_2025_0903_055708"
Notes
- This script is a thin orchestrator that delegates actual work to
scripts/start_convert.py to ensure a single source of truth.
"""
from __future__ import annotations
import argparse
import os
import subprocess
import sys
from dataclasses import dataclass
from pathlib import Path
from typing import List, Optional, Sequence, Tuple
# Optional Rich UI imports (fallback to plain if unavailable)
try:
from rich.console import Console
from rich.layout import Layout
from rich.panel import Panel
from rich.table import Table
from rich.text import Text
from rich import box
from rich.prompt import IntPrompt
_RICH_AVAILABLE = True
except Exception: # pragma: no cover
_RICH_AVAILABLE = False
# Optional InquirerPy for arrow-key selection
try:
from InquirerPy import inquirer as _inq
_INQUIRER_AVAILABLE = True
except Exception: # pragma: no cover
_INQUIRER_AVAILABLE = False
@dataclass
class Candidate:
index: int
kind: str # "excel" | "docs"
path: Path
label: str
def get_repo_root() -> Path:
return Path(__file__).resolve().parent
def list_excel_files(excel_dir: Path) -> List[Path]:
if not excel_dir.exists():
return []
return sorted([p for p in excel_dir.iterdir() if p.is_file() and p.suffix.lower() == ".xlsx"], key=lambda p: p.stat().st_mtime)
def has_prompt_files(directory: Path) -> bool:
if not directory.exists():
return False
# Detect files like "(r,c)_*.md" anywhere under the directory
for file_path in directory.rglob("*.md"):
name = file_path.name
if name.startswith("(") and ")_" in name:
return True
return False
def list_doc_sets(docs_dir: Path) -> List[Path]:
results: List[Path] = []
if not docs_dir.exists():
return results
# If the docs_dir itself looks like a set, include it
if has_prompt_files(docs_dir):
results.append(docs_dir)
# Also include any immediate children that look like a docs set
for child in sorted(docs_dir.iterdir()):
if child.is_dir() and has_prompt_files(child):
results.append(child)
return results
def run_start_convert(start_convert: Path, mode: str, project_root: Path, select_path: Optional[Path] = None, excel_dir: Optional[Path] = None, docs_dir: Optional[Path] = None) -> int:
"""Delegate to scripts/start_convert.py with appropriate flags."""
python_exe = sys.executable
cmd: List[str] = [python_exe, str(start_convert), "--mode", mode]
if select_path is not None:
# Always pass as repo-root-relative or absolute string
cmd.extend(["--select", str(select_path)])
if excel_dir is not None:
cmd.extend(["--excel-dir", str(excel_dir)])
if docs_dir is not None:
cmd.extend(["--docs-dir", str(docs_dir)])
# Execute in repo root to ensure relative defaults resolve correctly
proc = subprocess.run(cmd, cwd=str(project_root))
return proc.returncode
def build_candidates(project_root: Path, excel_dir: Path, docs_dir: Path) -> List[Candidate]:
candidates: List[Candidate] = []
idx = 1
for path in list_excel_files(excel_dir):
label = f"[Excel] {path.name}"
candidates.append(Candidate(index=idx, kind="excel", path=path, label=label))
idx += 1
for path in list_doc_sets(docs_dir):
display = path.relative_to(project_root) if path.is_absolute() else path
label = f"[Docs] {display}"
candidates.append(Candidate(index=idx, kind="docs", path=path, label=label))
idx += 1
return candidates
def select_interactively(candidates: Sequence[Candidate]) -> Optional[Candidate]:
if not candidates:
print("没有可用的 Excel 或 Docs 源。请将 .xlsx 放到 prompt_excel/ 或将文档放到 prompt_docs/ 下。")
return None
# Prefer arrow-key selection if available
if _INQUIRER_AVAILABLE:
try:
choices = [
{"name": f"{'[Excel]' if c.kind=='excel' else '[Docs]'} {c.label}", "value": c.index}
for c in candidates
]
selection = _inq.select(
message="选择要转换的源上下箭头回车确认Ctrl+C 取消):",
choices=choices,
default=choices[0]["value"],
).execute()
match = next((c for c in candidates if c.index == selection), None)
return match
except KeyboardInterrupt:
return None
if _RICH_AVAILABLE:
console = Console()
layout = Layout()
layout.split_column(
Layout(name="header", size=3),
Layout(name="list"),
Layout(name="footer", size=3),
)
header = Panel(Text("提示词库转换器", style="bold cyan"), subtitle="选择一个源开始转换", box=box.ROUNDED)
table = Table(box=box.SIMPLE_HEAVY)
table.add_column("编号", style="bold yellow", justify="right", width=4)
table.add_column("类型", style="magenta", width=8)
table.add_column("路径/名称", style="white")
for c in candidates:
table.add_row(str(c.index), "Excel" if c.kind == "excel" else "Docs", c.label)
layout["header"].update(header)
layout["list"].update(Panel(table, title="可选源", border_style="cyan"))
layout["footer"].update(Panel(Text("输入编号并回车0 退出)", style="bold"), box=box.ROUNDED))
console.print(layout)
while True:
try:
choice = IntPrompt.ask("编号", default=0)
except Exception:
return None
if choice == 0:
return None
match = next((c for c in candidates if c.index == choice), None)
if match is not None:
return match
console.print("[red]编号不存在,请重试[/red]")
# Plain fallback
print("请选择一个源进行转换:")
for c in candidates:
print(f" {c.index:2d}. {c.label}")
print(" 0. 退出")
while True:
try:
raw = input("输入编号后回车:").strip()
except EOFError:
return None
if not raw:
continue
if raw == "0":
return None
if not raw.isdigit():
print("请输入有效数字。")
continue
choice = int(raw)
match = next((c for c in candidates if c.index == choice), None)
if match is None:
print("编号不存在,请重试。")
continue
return match
def parse_args() -> argparse.Namespace:
p = argparse.ArgumentParser(description="prompt-library conversion controller")
p.add_argument("--excel-dir", type=str, default="prompt_excel", help="Excel sources directory (default: prompt_excel)")
p.add_argument("--docs-dir", type=str, default="prompt_docs", help="Docs sources directory (default: prompt_docs)")
p.add_argument("--select", type=str, default=None, help="Path to a specific .xlsx file or a docs folder")
p.add_argument("--non-interactive", action="store_true", help="Do not prompt; require --select or exit")
return p.parse_args()
def main() -> int:
repo_root = get_repo_root()
start_convert = repo_root / "scripts" / "start_convert.py"
if not start_convert.exists():
print("找不到 scripts/start_convert.py。")
return 1
args = parse_args()
excel_dir = (repo_root / args.excel_dir).resolve() if not Path(args.excel_dir).is_absolute() else Path(args.excel_dir).resolve()
docs_dir = (repo_root / args.docs_dir).resolve() if not Path(args.docs_dir).is_absolute() else Path(args.docs_dir).resolve()
# Non-interactive path with explicit selection
if args.non_interactive or args.select:
if not args.select:
print("--non-interactive 需要配合 --select 使用。")
return 2
selected = Path(args.select)
if not selected.is_absolute():
selected = (repo_root / selected).resolve()
if not selected.exists():
print(f"选择的路径不存在: {selected}")
return 2
if selected.is_file() and selected.suffix.lower() == ".xlsx":
return run_start_convert(start_convert, mode="excel2docs", project_root=repo_root, select_path=selected, excel_dir=excel_dir)
if selected.is_dir():
# Treat as docs set
return run_start_convert(start_convert, mode="docs2excel", project_root=repo_root, select_path=selected, docs_dir=docs_dir)
print("无法识别的选择类型(既不是 .xlsx 文件也不是目录)。")
return 2
# Interactive selection
candidates = build_candidates(repo_root, excel_dir, docs_dir)
chosen = select_interactively(candidates)
if chosen is None:
return 0
if chosen.kind == "excel":
return run_start_convert(start_convert, mode="excel2docs", project_root=repo_root, select_path=chosen.path, excel_dir=excel_dir)
else:
return run_start_convert(start_convert, mode="docs2excel", project_root=repo_root, select_path=chosen.path, docs_dir=docs_dir)
if __name__ == "__main__":
sys.exit(main())

View File

@ -1,228 +0,0 @@
# 📚 提示词库Excel转换版
![同步状态](https://img.shields.io/badge/status-synced-green)
![提示词数量](https://img.shields.io/badge/prompts-310-blue)
![版本总数](https://img.shields.io/badge/versions-452-orange)
![数据来源](https://img.shields.io/badge/source-Excel-yellow)
最后更新: 2025-12-13 08:04:13
## 📊 总览
- **数据来源**: prompt.xlsx
- **分类数量**: 97
- **提示词总数**: 310
- **版本总数**: 452
## 📂 分类导航
- [说明](./prompts/(1)_说明/) - 11 个提示词, 14 个版本
- [元提示词](./prompts/(2)_元提示词/) - 25 个提示词, 33 个版本
- [交易提示词](./prompts/(3)_交易提示词/) - 1 个提示词, 1 个版本
- [软件工程vibe coding用提示词](./prompts/(4)_软件工程vibe_coding用提示词/) - 22 个提示词, 32 个版本
- [临界知识](./prompts/(5)_临界知识/) - 1 个提示词, 1 个版本
- [根据内容逆向提示词](./prompts/(6)_根据内容逆向提示词/) - 1 个提示词, 1 个版本
- [逻辑工具箱](./prompts/(7)_逻辑工具箱/) - 4 个提示词, 7 个版本
- [哲学工具箱](./prompts/(8)_哲学工具箱/) - 13 个提示词, 20 个版本
- [方法与原则提取](./prompts/(9)_方法与原则提取/) - 1 个提示词, 1 个版本
- [排版](./prompts/(10)_排版/) - 1 个提示词, 1 个版本
- [工作表112](./prompts/(11)_工作表112/) - 1 个提示词, 1 个版本
- [Reddit提示词](./prompts/(12)_Reddit提示词/) - 3 个提示词, 3 个版本
- [ChatGPT](./prompts/(13)_ChatGPT/) - 4 个提示词, 4 个版本
- [论文解读](./prompts/(14)_论文解读/) - 1 个提示词, 1 个版本
- [内容提炼](./prompts/(15)_内容提炼/) - 2 个提示词, 2 个版本
- [英文学习](./prompts/(16)_英文学习/) - 1 个提示词, 1 个版本
- [问题分类识别](./prompts/(17)_问题分类识别/) - 1 个提示词, 1 个版本
- [用户优化前端设计](./prompts/(18)_用户优化前端设计/) - 1 个提示词, 1 个版本
- [最小知识框架](./prompts/(19)_最小知识框架/) - 1 个提示词, 1 个版本
- [学习用提示词](./prompts/(20)_学习用提示词/) - 1 个提示词, 1 个版本
- [事实核查](./prompts/(21)_事实核查/) - 1 个提示词, 1 个版本
- [关键词图谱](./prompts/(22)_关键词图谱/) - 1 个提示词, 1 个版本
- [语言分析元prompt](./prompts/(23)_语言分析元prompt/) - 1 个提示词, 1 个版本
- [逻辑分析](./prompts/(24)_逻辑分析/) - 1 个提示词, 1 个版本
- [一句话描述任何内容](./prompts/(25)_一句话描述任何内容/) - 1 个提示词, 3 个版本
- [输入转单行JSON](./prompts/(26)_输入转单行JSON/) - 1 个提示词, 3 个版本
- [最小字数系统提示词](./prompts/(27)_最小字数系统提示词/) - 1 个提示词, 3 个版本
- [需求对齐](./prompts/(28)_需求对齐/) - 1 个提示词, 2 个版本
- [编程知识库](./prompts/(29)_编程知识库/) - 1 个提示词, 1 个版本
- [提示词模块](./prompts/(30)_提示词模块/) - 10 个提示词, 15 个版本
- [x爆款文案生成器](./prompts/(31)_x爆款文案生成器/) - 1 个提示词, 1 个版本
- [grok商业金融分析提示词](./prompts/(32)_grok商业金融分析提示词/) - 12 个提示词, 12 个版本
- [文本转md语法电子书处理](./prompts/(33)_文本转md语法电子书处理/) - 4 个提示词, 15 个版本
- [ai学习用提示词](./prompts/(34)_ai学习用提示词/) - 1 个提示词, 1 个版本
- [真传一句话](./prompts/(35)_真传一句话/) - 1 个提示词, 1 个版本
- [需求结构化描述](./prompts/(36)_需求结构化描述/) - 1 个提示词, 1 个版本
- [学习提示词](./prompts/(37)_学习提示词/) - 28 个提示词, 49 个版本
- [系统提示词](./prompts/(38)_系统提示词/) - 1 个提示词, 1 个版本
- [排版和图片,视频转文本](./prompts/(39)_排版和图片视频转文本/) - 4 个提示词, 4 个版本
- [子弹总结](./prompts/(40)_子弹总结/) - 1 个提示词, 3 个版本
- [x提示词收集](./prompts/(41)_x提示词收集/) - 1 个提示词, 1 个版本
- [书籍结构化分析](./prompts/(42)_书籍结构化分析/) - 2 个提示词, 8 个版本
- [组织语言](./prompts/(43)_组织语言/) - 1 个提示词, 1 个版本
- [行业分析](./prompts/(44)_行业分析/) - 2 个提示词, 2 个版本
- [投资调研](./prompts/(45)_投资调研/) - 1 个提示词, 2 个版本
- [速成学习](./prompts/(46)_速成学习/) - 1 个提示词, 1 个版本
- [批判性思维分析](./prompts/(47)_批判性思维分析/) - 2 个提示词, 2 个版本
- [序列图生成](./prompts/(48)_序列图生成/) - 2 个提示词, 4 个版本
- [对话提问](./prompts/(49)_对话提问/) - 1 个提示词, 1 个版本
- [层级结构分析](./prompts/(50)_层级结构分析/) - 4 个提示词, 16 个版本
- [心经口诀创作提示词](./prompts/(51)_心经口诀创作提示词/) - 1 个提示词, 1 个版本
- [SOP制作](./prompts/(52)_SOP制作/) - 1 个提示词, 1 个版本
- [黄金圈解释](./prompts/(53)_黄金圈解释/) - 1 个提示词, 3 个版本
- [需求解析](./prompts/(54)_需求解析/) - 1 个提示词, 1 个版本
- [notebookllm用提示词](./prompts/(55)_notebookllm用提示词/) - 3 个提示词, 6 个版本
- [好prompt生成器](./prompts/(56)_好prompt生成器/) - 1 个提示词, 1 个版本
- [行业咨询](./prompts/(57)_行业咨询/) - 1 个提示词, 1 个版本
- [分析](./prompts/(58)_分析/) - 2 个提示词, 4 个版本
- [gemini字幕处理](./prompts/(59)_gemini字幕处理/) - 1 个提示词, 1 个版本
- [政治批判工具箱](./prompts/(60)_政治批判工具箱/) - 3 个提示词, 6 个版本
- [推文制作提示词](./prompts/(61)_推文制作提示词/) - 2 个提示词, 2 个版本
- [麦肯锡行业分析](./prompts/(62)_麦肯锡行业分析/) - 1 个提示词, 1 个版本
- [正向人物生平报告官方文案](./prompts/(63)_正向人物生平报告官方文案/) - 1 个提示词, 1 个版本
- [grok抓取提示词](./prompts/(64)_grok抓取提示词/) - 1 个提示词, 1 个版本
- [视频生成提示词](./prompts/(65)_视频生成提示词/) - 2 个提示词, 2 个版本
- [人话写作](./prompts/(66)_人话写作/) - 1 个提示词, 1 个版本
- [x prompt收集](./prompts/(67)_x_prompt收集/) - 2 个提示词, 3 个版本
- [函数化万物](./prompts/(68)_函数化万物/) - 1 个提示词, 6 个版本
- [项目分析](./prompts/(69)_项目分析/) - 1 个提示词, 1 个版本
- [解释提示词](./prompts/(70)_解释提示词/) - 1 个提示词, 3 个版本
- [产品策略](./prompts/(71)_产品策略/) - 1 个提示词, 1 个版本
- [小红书](./prompts/(72)_小红书/) - 1 个提示词, 1 个版本
- [谋士](./prompts/(73)_谋士/) - 1 个提示词, 3 个版本
- [前端复刻流程](./prompts/(74)_前端复刻流程/) - 3 个提示词, 3 个版本
- [网页UI逆向分析提示词](./prompts/(75)_网页UI逆向分析提示词/) - 1 个提示词, 1 个版本
- [典籍句子学习](./prompts/(76)_典籍句子学习/) - 2 个提示词, 3 个版本
- [经验](./prompts/(77)_经验/) - 9 个提示词, 16 个版本
- [anki卡片格式输出](./prompts/(78)_anki卡片格式输出/) - 1 个提示词, 2 个版本
- [简讯提示词](./prompts/(79)_简讯提示词/) - 1 个提示词, 1 个版本
- [思维导图](./prompts/(80)_思维导图/) - 1 个提示词, 3 个版本
- [未来视角](./prompts/(81)_未来视角/) - 6 个提示词, 6 个版本
- [AI使用思维](./prompts/(82)_AI使用思维/) - 2 个提示词, 4 个版本
- [思维协议](./prompts/(83)_思维协议/) - 1 个提示词, 1 个版本
- [使用ai的思维](./prompts/(84)_使用ai的思维/) - 1 个提示词, 1 个版本
- [李继刚文选](./prompts/(85)_李继刚文选/) - 2 个提示词, 2 个版本
- [图片逆向](./prompts/(86)_图片逆向/) - 2 个提示词, 2 个版本
- [艺术风格描述](./prompts/(87)_艺术风格描述/) - 2 个提示词, 2 个版本
- [豆包听书](./prompts/(88)_豆包听书/) - 1 个提示词, 1 个版本
- [艺术](./prompts/(89)_艺术/) - 1 个提示词, 1 个版本
- [文案逆向](./prompts/(90)_文案逆向/) - 10 个提示词, 12 个版本
- [流程图](./prompts/(91)_流程图/) - 2 个提示词, 3 个版本
- [学习音频](./prompts/(92)_学习音频/) - 1 个提示词, 1 个版本
- [思维模型](./prompts/(93)_思维模型/) - 1 个提示词, 2 个版本
- [](./prompts/(94)_道/) - 6 个提示词, 11 个版本
- [](./prompts/(95)_法/) - 4 个提示词, 6 个版本
- [](./prompts/(96)_术/) - 24 个提示词, 24 个版本
- [](./prompts/(97)_器/) - 9 个提示词, 9 个版本
## 🔄 同步信息
- **数据源**: prompt.xlsx
- **处理时间**: 2025-12-13 08:04:13
## 📝 许可证
本项目采用 MIT 许可证
---
*完全基于 Excel 表格自动生成*

File diff suppressed because one or more lines are too long

View File

@ -1,35 +0,0 @@
# 💰 项目支持从Excel提取
## 支持说明
**礼貌要饭地址** - 如果这个项目对您有帮助,欢迎通过以下方式支持
## 加密货币钱包地址
### 主流网络支持
| 网络名称 | 钱包地址 | Excel行号 |
|----------|----------|-----------|
| **TRON** | `TQtBXCSTwLFHjBqTS4rNUp7ufiGx51BRey` | 第46行 |
| **SOL** | `HjYhozVf9AQmfv7yv79xSNs6uaEU5oUk2USasYQfUYau` | 第47行 |
| **ETH** | `0xa396923a71ee7D9480b346a17dDeEb2c0C287BBC` | 第48行 |
| **BSC** | `0xa396923a71ee7D9480b346a17dDeEb2c0C287BBC` | 第49行 |
| **BTC** | `bc1plslluj3zq3snpnnczplu7ywf37h89dyudqua04pz4txwh8z5z5vsre7nlm` | 第50行 |
| **SUI** | `0xb720c98a48c77f2d49d375932b2867e793029e6337f1562522640e4f84203d2e` | 第51行 |
### 使用建议
1. 请确认钱包地址的准确性
2. 建议小额测试后再进行大额转账
3. 不同网络的转账费用不同,请选择合适的网络
---
*钱包地址来源: prompt.xlsx*

View File

@ -1,191 +0,0 @@
# 🛠️ 工具与资源从Excel提取
## AI优化工具
### 工具
- **URL**: https://github.com/123olp/ys
- **描述**: 上帝工程
- **数据来源**: Excel表格第9行
### 工具
- **URL**: https://www.notion.so/28235eb9215080c392e4d53002f6b493
- **描述**: 上帝工程
- **数据来源**: Excel表格第10行
### 工具
- **URL**: https://t.me/sxwgc123
- **描述**: telegram提示词交流群
- **数据来源**: Excel表格第11行
### 工具
- **URL**: https://github.com/123olp/prompt-library
- **描述**: 本表格github位置
- **数据来源**: Excel表格第12行
### OpenAI 提示词优化平台
- **URL**: https://platform.openai.com/chat/edit?models=gpt-5&optimize=true
- **描述**: openai提示词优化网站
- **数据来源**: Excel表格第14行
### 工具
- **URL**: https://github.com/y0mingzhang/prompt-extraction
- **描述**: 这是一个提取提示词的仓库,你看中哪个 agent直接输入即可获取该 agent 的系统提示词,经过尝试,仅适用于部分场景的提取
- **数据来源**: Excel表格第15行
### 工具
- **URL**: https://github.com/x1xhlol/system-prompts-and-models-of-ai-tools
- **描述**: AI 工具系统提示词与模型代码库,收录 20,000+ 行 AI 工具与助手的系统提示词、配置与规范、
- **数据来源**: Excel表格第16行
### 工具
- **URL**: https://opensource.antgroup.com/blogs?utm_source=chatgpt.com
- **描述**: 蚂蚁开源博客(信息源)
- **数据来源**: Excel表格第17行
### 工具
- **URL**: https://huggingface.co/papers/trending
- **描述**: 热门论文(信息源)
- **数据来源**: Excel表格第18行
### 工具
- **URL**: https://arxiv.org/
- **描述**: 研究者第一时间挂论文的地方(信息源)
- **数据来源**: Excel表格第19行
### 工具
- **URL**: https://github.com/richards199999/Thinking-Claude/tree/main
- **描述**: 涂津豪
- **数据来源**: Excel表格第20行
### OpenAI 提示词优化平台
- **URL**: https://academy.openai.com/public/tags/prompt-packs-6849a0f98c613939acef841c
- **描述**: openai提示词网站
- **数据来源**: Excel表格第21行
### 工具
- **URL**: https://llm-stats.com/benchmarks
- **描述**: 模型评测与排行榜网站
- **数据来源**: Excel表格第22行
### 工具
- **URL**: https://github.com/vectara/hallucination-leaderboard/
- **描述**: 模型幻觉排行榜
- **数据来源**: Excel表格第23行
### 工具
- **URL**: https://prompthero.com/
- **描述**: 全球最大开源库
- **数据来源**: Excel表格第24行
### 工具
- **URL**: https://www.aiforeducation.io/prompt-library
- **描述**: 面向教师,涵盖课程设计、作业反馈、沟通管理等场景
- **数据来源**: Excel表格第25行
### 工具
- **URL**: https://docs.claude.com/en/resources/prompt-library/library
- **描述**: 由 Anthropic 官方团队维护,针对 Claude 优化
- **数据来源**: Excel表格第26行
### 工具
- **URL**: https://www.promptingguide.ai
- **描述**: 从基础“角色设定”到高级“思维链 (CoT) ”,逐步解析 Prompt 设计原理
- **数据来源**: Excel表格第27行
### 工具
- **URL**: https://docs.lovable.dev/prompting/prompting-library
- **描述**: 开发者友好: 面向程序员、设计师、产品经理
- **数据来源**: Excel表格第28行
### 工具
- **URL**: https://dqxf1izhlm.feishu.cn/wiki/OKvFwmmaIiBlPYkDGo3c8Z0EnCE
- **描述**: 重磅!你的 Prompt 工程白学了“懒人提示词”技巧让AI瞬间懂你
- **数据来源**: Excel表格第29行
### 工具
- **URL**: https://github.com/filipecalegario/awesome-generative-ai
- **描述**:
- **数据来源**: Excel表格第30行
### 工具
- **URL**: https://github.com/aishwaryanr/awesome-generative-ai-guide
- **描述**:
- **数据来源**: Excel表格第31行
### 工具
- **URL**: https://aistudio.google.com/
- **描述**: 打开 Gemini 2.5 Pro
- **数据来源**: Excel表格第4行
## 社交媒体
### Twitter/X 账号
- **URL**: https://x.com/123olp
- **描述**: 关注我的推特获取最新咨询
- **数据来源**: Excel表格第13行
### Twitter/X 账号
- **URL**: https://x.com/rebutonepress?s=21
- **描述**:
- **数据来源**: Excel表格第35行
### Twitter/X 账号
- **URL**: https://x.com/HIHIH8899
- **描述**:
- **数据来源**: Excel表格第38行
### Twitter/X 账号
- **URL**: https://x.com/FireStealer2035
- **描述**:
- **数据来源**: Excel表格第40行
### Twitter/X 账号
- **URL**: https://x.com/zzc_ae
- **描述**:
- **数据来源**: Excel表格第42行
### Twitter/X 账号
- **URL**: https://x.com/0xdaqian
- **描述**:
- **数据来源**: Excel表格第43行
## 使用建议
1. **OpenAI优化器**: 可以用来测试和改进本库中的提示词
2. **社交媒体**: 关注获取项目更新和使用技巧
3. **集成方式**: 可以将这些工具集成到自动化工作流中
---
*数据来源: prompt.xlsx*

View File

@ -1 +0,0 @@
底部每个工作表代表一类提示词图表的横轴表示提示词的迭代版本如提示词1a、提示词1b、提示词1c 等体现每一类提示词在不同阶段的演化。纵轴表示不同的提示词如提示词1、提示词2、…、提示词y每一行展示同一类型提示词在不同版本下的具体内容便于对比各类型提示词随版本迭代的变化趋势。

View File

@ -1,70 +0,0 @@
# 📂 提示词分类 - 说明基于Excel原始数据)
最后同步: 2025-12-13 08:04:13
## 📊 统计
- 提示词总数: 11
- 版本总数: 14
- 平均版本数: 1.3
## 📋 提示词列表
| 序号 | 标题 | 版本数 | 查看 |
|------|------|--------|------|
| 2 | 底部每个工作表代表一类提示词图表的横轴表示提示词的迭代版本如提示词1a、提示词1b、提示词1c_等体现每一类提示 | 1 | [v1](./(2,1)_底部每个工作表代表一类提示词图表的横轴表示提示词的迭代版本如提示词1a、提示词1b、提示词1c_等体现每一类提示.md) |
| 3 | 提示词1a | 3 | [v1](./(3,1)_提示词1a.md) / [v2](./(3,2)_提示词1a.md) / [v3](./(3,3)_提示词1a.md) |
| 4 | 提示词2a | 2 | [v1](./(4,1)_提示词2a.md) / [v2](./(4,2)_提示词2a.md) |
| 6 | 提示词ya | 1 | [v1](./(6,1)_提示词ya.md) |
| 8 | 提示词相关链接和资源 | 1 | [v1](./(8,1)_提示词相关链接和资源.md) |
| 33 | 贡献者名单 | 1 | [v1](./(33,1)_贡献者名单.md) |
| 34 | 狗神 | 1 | [v1](./(34,1)_狗神.md) |
| 36 | 天空 | 1 | [v1](./(36,1)_天空.md) |
| 37 | 金狗 | 1 | [v1](./(37,1)_金狗.md) |
| 39 | 耄鑫覺囉 | 1 | [v1](./(39,1)_耄鑫覺囉.md) |
| 41 | kirt | 1 | [v1](./(41,1)_kirt.md) |
## 🗂️ 版本矩阵
| 行 | v1 | v2 | v3 | 备注 |
|---|---|---|---|---|
| 2 | ✅ | — | — | |
| 3 | ✅ | ✅ | ✅ | |
| 4 | ✅ | ✅ | — | |
| 6 | ✅ | — | — | |
| 8 | ✅ | — | — | |
| 33 | ✅ | — | — | |
| 34 | ✅ | — | — | |
| 36 | ✅ | — | — | |
| 37 | ✅ | — | — | |
| 39 | ✅ | — | — | |
| 41 | ✅ | — | — | |

View File

@ -1,84 +0,0 @@
# Role智能文本排版助手
## Profile
- author: AI-Helper
- version: 2.1
- language: 中文
- description: 作为专业的文本排版助手,你需要将用户提供的任意原始文本智能转化为结构化的 Markdown 格式,并确保最终输出以单一代码块呈现,且不包含任何加粗语法。
## Objectives
1. 智能排版
- 根据文本的语义与结构,将原始内容转化为清晰、层级合理的 Markdown 格式。
- 使用标题、段落、列表、引用等元素增强可读性。
- 禁止使用分隔线(如 ---)。
2. 净化加粗
- 在排版过程中移除所有已有或可能出现的加粗语法(如 `**文字**`、`__文字__`)。
3. 格式化输出
- 将最终内容以单一的 Markdown 代码块输出。
- 代码块内部不得包含多余解释性文字。
## Constraints
- 内容保真
- 排版仅限于结构调整,不得对原文进行实质性修改、删除或增补。
- 排版优先
- 无论输入内容是否具备结构,都必须分析并生成合适的 Markdown 层级结构。
- 绝对无加粗
- 输出中不得出现任何加粗格式。
- 单一代码块
- 最终输出必须完全包含在一个 Markdown 代码块中,且不能在代码块外附加说明。
## Workflow
1. 接收用户输入的原始文本。
2. 分析文本的语义层级与逻辑结构。
3. 使用适当的 Markdown 元素对内容进行结构化排版。
4. 移除所有加粗语法并确保不会生成新的加粗格式。
5. 将排版结果置于一个 Markdown 代码块内。
6. 直接输出代码块,不添加额外内容。
## Example
### Input
项目总结报告
第一部分 项目背景
这个项目是为了解决效率问题的。我们发现旧系统**处理速度**很慢。
第二部分 实施过程
我们分了三个阶段1. 需求分析 2. 开发与测试 3. 上线部署
这是一个重要的里程碑。
第三部分 成果
处理效率提升了50%。
### Output
```
# 项目总结报告
## 第一部分 项目背景
这个项目是为了解决效率问题的。我们发现旧系统处理速度很慢。
## 第二部分 实施过程
我们分了三个阶段:
1. 需求分析
2. 开发与测试
3. 上线部署
这是一个重要的里程碑。
## 第三部分 成果
处理效率提升了50%。
```
### 用户输入区
请在此处输入需要排版的原始内容:

View File

@ -1,30 +0,0 @@
# 📂 提示词分类 - 排版基于Excel原始数据)
最后同步: 2025-12-13 08:04:13
## 📊 统计
- 提示词总数: 1
- 版本总数: 1
- 平均版本数: 1.0
## 📋 提示词列表
| 序号 | 标题 | 版本数 | 查看 |
|------|------|--------|------|
| 1 | #_Role:智能文本排版助手 | 1 | [v1](./(1,1)_#_Role智能文本排版助手.md) |
## 🗂️ 版本矩阵
| 行 | v1 | 备注 |
|---|---|---|
| 1 | ✅ | |

View File

@ -1,40 +0,0 @@
请从输入图像中智能、全面地提取视觉风格信息,并将结果以**严格有效的 JSON** 格式输出。
字段数量不做限制,可根据图像特征灵活增减,但需保持结构清晰、语义明确、分类合理。
以下为建议的通用结构,请在此基础上根据实际情况动态调整、增删字段:
{
"colors": {
"palette": [], // 色板HEX/RGB
"dominant_colors": [], // 主色
"accents": [], // 点缀色
"tone_contrast": "" // 明度/色温/对比特征
},
"typography": {
"fonts": [], // 字体名称或风格
"style_features": [], // 字重/字宽/字型特征
"hierarchy": "" // 排版层级
},
"composition": {
"layout": "", // 布局方式
"balance": "", // 对称、非对称、中心构图等
"focal_points": [], // 视觉焦点
"spacing_and_rhythm": "" // 留白、节奏、密度
},
"visual_effects": {
"textures": [], // 纹理
"lighting": "", // 光影表现
"shadows": "", // 阴影类型
"filters": [], // 滤镜或后期效果
"other_effects": [] // 其他识别到的风格特征
},
"overall_style": {
"design_language": "", // 如极简/复古/赛博等
"emotional_tone": "", // 感性气质,如温暖/冷峻/活泼
"reference_genres": [] // 类似的风格类型或艺术流派
}
}
要求:
- 输出必须是**纯 JSON**,不包含任何额外说明文字。
- 可根据图像内容自由扩展或删减字段,但需保持命名专业、语义明确。
- 无法判断的字段请使用空字符串、空数组或省略。

View File

@ -1,30 +0,0 @@
# 📂 提示词分类 - 工作表112基于Excel原始数据)
最后同步: 2025-12-13 08:04:13
## 📊 统计
- 提示词总数: 1
- 版本总数: 1
- 平均版本数: 1.0
## 📋 提示词列表
| 序号 | 标题 | 版本数 | 查看 |
|------|------|--------|------|
| 3 | 请从输入图像中智能、全面地提取视觉风格信息并将结果以严格有效的_JSON_格式输出。 | 1 | [v1](./(3,1)_请从输入图像中智能、全面地提取视觉风格信息并将结果以严格有效的_JSON_格式输出。.md) |
## 🗂️ 版本矩阵
| 行 | v1 | 备注 |
|---|---|---|
| 3 | ✅ | |

Some files were not shown because too many files have changed in this diff Show More