From 152db75e159fa88377b1d4e68d962816f8f26650 Mon Sep 17 00:00:00 2001 From: Zhengshou Lai Date: Fri, 17 Apr 2026 00:02:30 +0800 Subject: [PATCH] chore(skills): remove deprecated skills and update permissions - Delete update-mykb-files and update-mykb-memories skills - Update update-mywebpage skill to use lowercase mywebpage path - Sync settings.local.json permissions --- .claude/settings.local.json | 59 ++- .claude/skills/update-mykb-files/SKILL.md | 260 ------------- .../references/excel_analysis.md | 129 ------- .../references/excel_reading.md | 72 ---- .../references/pdf_reading.md | 362 ------------------ .../scripts/convert_pdf_to_images.py | 35 -- .claude/skills/update-mykb-memories/SKILL.md | 48 --- .claude/skills/update-mywebpage/SKILL.md | 4 +- 8 files changed, 57 insertions(+), 912 deletions(-) delete mode 100644 .claude/skills/update-mykb-files/SKILL.md delete mode 100644 .claude/skills/update-mykb-files/references/excel_analysis.md delete mode 100644 .claude/skills/update-mykb-files/references/excel_reading.md delete mode 100644 .claude/skills/update-mykb-files/references/pdf_reading.md delete mode 100644 .claude/skills/update-mykb-files/scripts/convert_pdf_to_images.py delete mode 100644 .claude/skills/update-mykb-memories/SKILL.md diff --git a/.claude/settings.local.json b/.claude/settings.local.json index a21023f..5b90df8 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -59,9 +59,9 @@ "Read(workspace/*)", "Write(workspace/*)", "Edit(workspace/*)", - "Read(.claude/*)", - "Write(.claude/*)", - "Edit(.claude/*)", + "Read(.claude/**/*)", + "Write(.claude/**/*)", + "Edit(.claude/**/*)", "Read(/Users/lzhshou/Library/Mobile Documents/iCloud~md~obsidian/Documents/myWorks/*)", "Write(/Users/lzhshou/Library/Mobile Documents/iCloud~md~obsidian/Documents/myWorks/*)", "Bash(*workspace/myWorks/*)", @@ -71,7 +71,58 @@ "Bash(pip3 list:*)", "Bash(ffmpeg -i membraine_pull_twising.avi -c:v libx264 -crf 23 -pix_fmt yuv420p -movflags +faststart membraine_pull_twising.mp4 -y)", "Bash(ffmpeg -i golf_ball_impact.avi -c:v libx264 -crf 23 -pix_fmt yuv420p -movflags +faststart golf_ball_impact.mp4 -y)", - "Bash(git push:*)" + "Bash(git push:*)", + "Read(//Users/lzhshou/.metabot/**)", + "Read(//Users/lzhshou/Documents/myResearch/myProjects/apaam/repo/metabot/**)", + "Bash(sqlite3 ~/.metabot/sessions.db \".schema\")", + "Bash(sqlite3:*)", + "Bash(~/.metabot/sessions-claude.json)", + "Read(//Users/lzhshou/.metobot/**)", + "Bash(./workspace/myslides/bin/myslides --help)", + "Bash(./workspace/myslides/bin/myslides list:*)", + "Bash(bash:*)", + "Bash(./workspace/myslides/bin/myslides generate-dashboard:*)", + "Bash(./workspace/myslides/bin/myslides to-ppt:*)", + "Bash(myslides list:*)", + "Bash(./bin/myslides list:*)", + "Bash(~/.local/bin/myslides list:*)", + "Bash(~/.local/bin/myslides:*)", + "Bash(myslides --help)", + "Bash(myslides create:*)", + "Bash(myslides build:*)", + "Bash(myslides export:*)", + "Bash(myslides to-ppt:*)", + "Bash(git -C /Users/lzhshou/Documents/myWork/sysu/4_成果归档/myslides log --oneline --all -- \"**/2025-apcom/**\")", + "Bash(git -C /Users/lzhshou/Documents/myResearch/myProjects/apaam/repo/myclaude log --oneline --all -- \"**/2025-apcom/**\")", + "Bash(myslides serve:*)", + "Bash(myslides server:*)", + "Bash(xargs kill:*)", + "Bash(mkdir -p ~/Documents/MyBin/mycli/legacy)", + "Bash(mv ~/Documents/MyBin/mycli/myBin_* ~/Documents/MyBin/mycli/legacy/)", + "Bash(sed:*)", + "Bash(_MYCLI_COMPLETE=zsh_source mycli)", + "Bash(mkdir -p ~/.local/bin/completions)", + "Bash(mycli:*)", + "Bash(myclaude --version)", + "Bash(_MYCLAUDE_COMPLETE=zsh_source myclaude)", + "Bash(env COMP_WORDS=mycli env goto:*)", + "Bash(env COMP_WORDS=mycli env goto :*)", + "Bash(zsh:*)", + "Bash(mv ~/.local/share/bash-completion/completions/myslides ~/.local/bin/completions/myslides.bash)", + "Bash(mv ~/.local/share/bash-completion/completions/mywebpage ~/.local/bin/completions/mywebpage.bash)", + "Bash(rmdir ~/.local/share/bash-completion/completions/)", + "Bash(mv mycli:*)", + "Bash(mytoolkit --version)", + "Bash(ln:*)", + "Bash(git:*)", + "Bash(mytoolkit env:*)", + "Bash(mytoolkit ssh:*)", + "Bash(mytoolkit git:*)", + "WebFetch(domain:click.palletsprojects.com)", + "Bash(_MYCLAUDE_COMPLETE=bash_source myclaude chat --)", + "Bash(_MYCLAUDE_COMPLETE=bash_source myclaude chat)", + "Bash(COMP_WORDS=\"myclaude chat --cwd\" COMP_CWORD=2 _MYCLAUDE_COMPLETE=bash_complete myclaude chat:*)", + "Bash(COMP_WORDS=\"myclaude chat --cwd /tm\" COMP_CWORD=3 _MYCLAUDE_COMPLETE=bash_complete myclaude chat:*)" ] }, "hooks": { diff --git a/.claude/skills/update-mykb-files/SKILL.md b/.claude/skills/update-mykb-files/SKILL.md deleted file mode 100644 index 4be4e3d..0000000 --- a/.claude/skills/update-mykb-files/SKILL.md +++ /dev/null @@ -1,260 +0,0 @@ ---- -name: update-mykb-files -description: | - Local filesystem RAG-style retrieval: user path, @ files, or workspace—no fixed KB root; prefer data_structure.md then grep/limited Read; PDF/Excel only after this skill's references. Save reusable clips to project knowledge/files/ (Cursor @knowledge); pointers in knowledge/memories via update-mykb-memories. Avoid writing under .claude/ when restricted. - Triggers: update-mykb-files; 检索/查资料/找文件/在某目录/摘录/存档; local search, find in folder, read my PDF, grep project, save excerpt, knowledge base on disk. ---- - -# 本地文件检索与摘录(update-mykb-files) - -## 检索范围与目录结构 - -- **对象**:本机文件系统上、当前工具与环境**允许访问**的任意目录与文件(绝对路径、`~/…`、相对工作区路径等)。不因 skill 名称限制在某个子树;若沙盒或权限收窄,以实际能读到的路径为准。用户反复使用的资料根路径可记在 update-mykb-memories,减少每次重新确认。 -- 资料往往放在一个**检索根目录**下,包含多种类型(如 `.md`/`.txt`、`.pdf`、`.xlsx` 等),可按业务拆多级子目录。 -- 可选采用**分层目录索引文件**(有则用,无则靠路径/文件名与 grep 渐进查): - - 某层目录可有 `data_structure.md`,说明子目录与文件的用途。 - - 子目录可继续嵌套 `data_structure.md`,形成索引树。 -- **检索根目录怎么定**(优先级): - - 用户在对话里**写明路径**(最优先)。 - - 否则从上下文推断:`@` 引用、已打开文件所在目录、问题中的路径、当前工作区根等;推断仍模糊时**追问用户**,勿臆造目录。 - - **读与写分离**:读的是上面确定的任意路径;**摘录落盘**默认写到**当前项目**下的 `knowledge/files/`(见下文;可用 `@knowledge`),勿与「被读的资料目录」混为一谈。 -- 单个业务文件可能很大: - - 不要直接用 Read 读取整文件 - - 对 PDF、Excel 使用对应 Skill 进行结构化处理后,再结合 grep/局部读取做精细检索 - -## 摘录池:`knowledge/files/` - -- **用途**:在日常对话或阅览任意被检索文件时,若出现**以后还可能引用**的内容(定义、结论、命令、表格摘要、长引用片段),写入当前项目下的 `knowledge/files/`,便于后续用 Grep/Read 复用;**不要**把整本 PDF/整表原样拷入,优先摘要 + 来源路径。 -- **与 update-mykb-memories 分工**:极短、稳定的事实与偏好写入 `knowledge/memories/`(见 skill `update-mykb-memories`);**较长说明、摘录、结构化笔记**放 `knowledge/files/`。 -- **路径**:根目录为仓库内 `knowledge/files/`(不存在则创建;父级 `knowledge/` 与 Cursor `@knowledge` 对应)。可选子目录:`clips/`、`notes/`、`exports/`。 -- **命名**:`YYYY-MM-DD_<主题简写>.md` 或 `_.md`;单文件控制体量,必要时拆篇。 -- **内容建议**:每条摘录开头用简短元信息(来源文件/URL、日期、一两句用途),正文用 Markdown;避免敏感凭证。 -- **检索**:回答后续问题时,若与已存摘录相关,可对 `knowledge/files/` 做 Grep 或 Read,与对原始资料的检索同一套渐进式原则。 - -### 定位检索根目录与存在性 - -- **路径来源**:用户显式给出的目录或文件路径优先;否则用上下文可核对的根(如工作区根、某 `@` 文件的上级目录),并在不确定时让用户确认。 -- **存在性**:对将要作为检索起点的目录,用 shell 检查,例如 `test -d "<检索根>"`(将 `<检索根>` 换成实际路径)。禁止使用仅靠 `Glob` 的结果推断「目录是否存在」:`Glob` 只返回文件路径,不返回目录本身,空结果无法区分「目录不存在」与「目录存在但无匹配文件」。 -- **确认存在后再展开**:只有 `test -d`(或对单文件 `test -f`)通过后,才在该路径下用 Glob/Grep 递归检索;把该路径作为工具参数里的 `path`,例如: - - 索引文件:`pattern="**/data_structure.md"`, `path="<检索根>"` - - 某类文本:`pattern="**/*.md"`, `path="<检索根>"` -- **未给出范围时**:不要猜测本机上的随机目录;说明需要用户指定「从哪个目录或哪些文件查」。 - -## 关键原则:先学习,再处理 - -**遇到 PDF 或 Excel 文件时的强制检查清单**: - -- [ ] ✅ 已读取对应的 references 文档学习处理方法 -- [ ] ✅ 已理解推荐的工具和命令 -- [ ] ✅ 已将文件处理(提取/转换)完成 -- [ ] ⏭️ 现在可以开始检索 - -**禁止行为**: -- ❌ 在未读取 pdf_reading.md 的情况下直接尝试处理 PDF -- ❌ 在未读取 excel_reading.md 的情况下直接尝试处理 Excel -- ❌ 跳过文件处理步骤,直接对原始 PDF/Excel 进行检索 - -## 总体流程 - -1. 理解用户需求 - - 读用户问题,提取: - - 主题/领域关键词(如“销售报表”“系统架构”“接口文档”) - - 时间或范围限定(如“2023 年 Q1”“最近版本”) - - 需要的输出类型(解释、摘要、具体字段数值等) - - 确定检索根目录或具体文件列表: - - 用户是否在问题中指定了路径或 `@` 了文件/文件夹。 - - 否则从工作区、打开文件等上下文推断;仍不明确则**询问用户**,不设固定默认资料目录。 - - 路径须用 `test -d` / `test -f` 等方式确认可访问后再深入检索。 - -2. 分层查看目录索引 `data_structure.md`(若存在) - - 使用一个「当前工作目录」的概念: - - 从**已确定的检索根目录**开始(须先按上文确认存在;不可用 shell 的「当前工作目录」偷换概念)。 - - 在当前工作目录下,如果存在 `data_structure.md`: - - 使用 Read 读取该文件的前若干行(例如 limit=300),必要时分段继续读取。 - - 目标: - - 了解当前目录下有哪些子目录和文件 - - 理解每个子目录/文件的用途说明 - - 基于用户问题,挑选**最相关的若干个子目录或文件**,构成候选集合。 - - 对于候选子目录: - - 递归进入该子目录,将其作为新的「当前工作目录」,继续查找其中的 `data_structure.md` 并重复上述过程。 - - 在递归过程中,避免一次性深入所有分支,优先沿着与问题最相关的路径向下钻取。 - - 对于候选业务文件(md/文本、PDF、Excel 等): - - 在完成必要的目录层级探索后,收集这些文件为最终的**检索目标列表**。 - - 在优先级排序时: - - 优先选择用途说明与问题主题高度匹配的领域目录和文件 - - 其次考虑时间/版本等约束(如果索引中有体现) - - 通用说明类文档(如 README.md、总体设计类文档)放在较后优先级 - -3. 学习文件处理方法(遇到 PDF/Excel 时强制执行) - - **在处理 PDF 文件前**: - - **必须先读取** [references/pdf_reading.md](references/pdf_reading.md)(位于本 skill 的 `references/`,不是被检索资料目录)学习提取方法 - - 重点了解:pdftotext 命令、pdfplumber 用法、表格提取方法 - - **在处理 Excel 文件前**: - - **必须先读取** [references/excel_reading.md](references/excel_reading.md)学习读取方法 - - **必须先读取** [references/excel_analysis.md](references/excel_analysis.md)学习分析方法 - - 重点了解:pandas 读取、列筛选、数据过滤 - - **目的**:确保使用正确的工具和方法,避免盲目检索 - -4. 按文件类型执行处理和检索 - - 使用刚学到的方法处理文件(提取、转换、结构化) - - 对每类候选文件,按照下面「Markdown/文本」「PDF」「Excel」策略执行 - - 总原则: - - 优先从最相关、最精确的文件开始 - - 每个文件内都渐进式地局部检索,避免一次性加载全内容 - - 若当前文件得不到满意信息,切换到下一个候选文件 - -5. 迭代检索 - - 所有文件类型都使用统一的「多轮迭代检索机制」(见上文公共检索原则) - -6. 答案组织与溯源 - - 汇总多轮检索得到的上下文,综合回答用户问题。 - - 尽量: - - 给出清晰、直接的回答 - - 指出使用过的文件名(必要时包含大致位置,如章节或大概行数/页数) - - 如果答案基于推断或信息不完全: - - 明确标注假设与不确定性 - - 提示用户可以补充更具体的文件范围或关键词 - -## 公共检索原则 - -### 关键词选择策略 -- 从用户问题提取 3-8 个关键词(含可能的英文缩写、同义词、上位/下位词) -- 可组合词组(如 "销售 报表"、"API 接口 超时") -- 必要时包含业务词、技术术语、常见缩写(如 "uv"、"pv"、"GMV") - -### grep 检索基本原则 -- 始终指定尽量精准的 include 和 path,避免搜索整个目录 -- pattern 优先尝试问题中的核心名词、术语,再尝试同义词 -- 对于每个命中,只读取匹配附近的局部区域(上下若干行) -- 保存「文件名 + 位置信息 + 文本片段」 - -### 多轮迭代检索机制(最多 5 次) -所有文件类型都采用统一的迭代策略: -1. **迭代控制** - - 维护「已尝试检索次数」计数,最多 5 次 - - 每次检索后累加计数 -2. **每轮迭代流程** - 1. 基于问题生成/更新检索关键词(可包括同义词、扩展词) - 2. 选择尚未充分检索的文件或文件部分 - 3. 执行检索(grep/局部读取/专用 Skill 调用) - 4. 分析获取的上下文片段 - 5. 判断是否足够回答问题 -3. **终止条件** - - 找到足够支撑回答的上下文;或 - - 已达到 5 次尝试仍未找到合适信息 -4. **信息不足时的处理** - - 明确告知用户信息缺失或可能不在已约定的检索范围内 - - 提供已找到的最接近信息,并说明不确定性 - - 提示用户可以如何缩小范围(更具体的文件名、关键词、时间范围等) - -### 注意事项 - -- 禁止用 Glob 的「有无匹配文件」代替目录存在性判断;目录是否存在应通过 shell(如 `test -d`)检查。 -- 使用本 skill 做本地文件检索时,禁止使用网络搜索等其他工具替代磁盘上的资料 -- 若用户明确要求「记住」且是**短事实**,交给 **update-mykb-memories**;若需保存**可检索的长摘录**,写入 `knowledge/files/`(见上文)。 - -## 针对不同文件类型的具体策略 - -### 1. Markdown / 文本类文件(.md, .txt, .log 等) - -1. **候选文件选择** - - 根据 `data_structure.md` 和文件名、路径判断相关度 - - 优先检索标题和目录类文件(如汇总文档、设计总览) - -2. **grep 定位与局部读取** - - 使用 Grep 工具对指定候选文件,include 限定具体后缀(如 "*.md") - - 对于有匹配的文件,使用 Read 仅读取匹配附近的局部区域: - - 通过行号偏移和 limit 控制读取(例如从匹配行附近往前后各读取几十行) - - 避免整文件读取 - -3. **特殊处理** - - 如内容仅是目录/标题,根据链接或小节名继续定位深入内容 - - 应用「多轮迭代检索机制」(见上文公共检索原则) - -### 2. PDF 文件检索策略 - -**工作流**: - -1. **首先:读取处理方法指南** - - 在处理任何 PDF 之前,**必须先读取** [references/pdf_reading.md](references/pdf_reading.md)(位于本 skill 的 `references/`,不是被检索资料目录) - - 重点了解:pdftotext 命令、pdfplumber 用法、表格提取方法、快速决策表 - -2. **选择候选 PDF** - - 根据 `data_structure.md` 中的描述,选择最相关的 1-3 个文件 - - 如果用户指明具体 PDF 文件,则优先使用该文件 - -3. **应用学到的方法提取文本** - - 使用 pdf_reading.md 中推荐的工具(优先 pdftotext 或 pdfplumber) - - **重要**:使用 `pdftotext input.pdf output.txt` 将文本提取到文件,不要直接输出到 stdout(避免占用大量 token) - - 如需提取表格,使用 pdfplumber 的表格提取功能 - -4. **对提取结果执行检索** - - 使用 grep 对提取的文本进行关键词搜索 - - 对于每个命中,提取命中附近范围的上下文(上下数十行或相邻几页) - - 保存「文件名 + 页码/大致位置 + 文本片段」 - - 应用「多轮迭代检索机制」(见上文公共检索原则) - -### 3. Excel 文件检索策略 - -**工作流**: - -1. **首先:读取处理方法指南** - - 在处理任何 Excel 之前,**必须先读取**: - - [references/excel_reading.md](references/excel_reading.md) - 学习如何读取工作表(位于本 skill 的 `references/`) - - [references/excel_analysis.md](references/excel_analysis.md) - 学习如何分析数据(位于本 skill 的 `references/`) - - 重点了解:pandas 读取方法、列筛选、数据过滤、聚合操作 - -2. **选择候选 Excel** - - 根据 `data_structure.md` 和文件/工作表命名,选择最相关的表 - - 优先选择包含「报表」「统计」「日志」「配置」「映射」等关键词的工作簿/工作表 - - 若用户指明具体 Excel 文件,优先使用该文件 - -3. **应用学到的方法探索结构** - - 使用 pandas 读取前 10-50 行(使用 `nrows` 参数限制) - - 重点掌握:列名/字段名、数据类型(数值、日期、文本)、关键字段 - - 将列名与用户问题比对,识别潜在关键字段(如「收入」「销售额」「error_code」等) - -4. **执行数据检索和分析** - - 使用学到的 pandas 方法进行过滤和聚合(如 `df[df['column'] == value]`) - - 每次只读取匹配行附近的数据,避免一次性读取整表 - - 如问题包含时间范围,在检索中加入时间过滤 - - 应用「多轮迭代检索机制」(见上文公共检索原则) - -## 与其他工具的协同 - -### PDF 处理 -- **在处理 PDF 前必须先读取** [references/pdf_reading.md](references/pdf_reading.md) 学习处理方法 -- 使用 pdfplumber/pypdf 进行文本提取、表格提取、元数据读取 -- 优先使用 pdftotext 命令行工具进行快速文本提取 - -### Excel 处理 -- **在处理 Excel 前必须先读取**: - - [references/excel_reading.md](references/excel_reading.md) - 学习读取方法 - - [references/excel_analysis.md](references/excel_analysis.md) - 学习分析方法 -- 使用 pandas 进行数据探索、预览、过滤和分析 - -### 工具使用原则 -- **Grep**:用于按关键词在指定文件中查找行号与匹配片段,始终指定尽量精准的 include 和 path -- **Read**:只用于局部读取文件,始终设置合理的 limit(如 200-500 行)和合适的偏移 -- **对于任何可能很大的文件**: - - 禁止直接从头读到尾 - - 始终先通过索引、目录、关键词等方式缩小范围后再读 - -## 回答风格与错误处理 - -- 回答风格 - - 尽量用用户提问的语言(中文/英文)作答。 - - 先给出结论,再给出简要依据。 - - 如需要,可在后面列出引用的文件和大致位置,例如: - - 来源:design/api_gateway.md 第 100 行附近 - - 来源:reports/2023_Q1_sales.xlsx Summary 工作表 -- 信息缺失或不确定时 - - 明确说明在已检索的路径范围内没有找到完全匹配的信息或只能部分回答。 - - 不臆造事实。 - - 提示用户可以如何帮助缩小范围: - - 指定更具体的目录/文件 - - 提供更精确的关键词或字段名 - - 指定时间/版本范围 - - - \ No newline at end of file diff --git a/.claude/skills/update-mykb-files/references/excel_analysis.md b/.claude/skills/update-mykb-files/references/excel_analysis.md deleted file mode 100644 index 24951ce..0000000 --- a/.claude/skills/update-mykb-files/references/excel_analysis.md +++ /dev/null @@ -1,129 +0,0 @@ -# Excel 数据分析 - -> ⚠️ **使用本文档前请注意**:本文档应在实际分析 Excel 数据之前阅读,以了解正确的 pandas 分析方法。请先阅读 excel_reading.md 学习如何读取数据。 - -使用 pandas 对 Excel 数据进行常规分析操作。 - -## 快速参考 - -| 任务 | 常用方法 | 代码示例 | -|------|----------|----------| -| 按条件过滤 | 布尔索引 | `df[df['sales'] > 10000]` | -| 分组聚合 | groupby | `df.groupby('region')['sales'].sum()` | -| 排序 | sort_values | `df.sort_values('sales', ascending=False)` | -| 计算新列 | 直接赋值 | `df['profit'] = df['revenue'] - df['cost']` | -| 统计汇总 | describe | `df.describe()` | - -## 分组聚合(GroupBy) - -```python -import pandas as pd - -df = pd.read_excel("sales.xlsx") - -# 按列分组并聚合 -sales_by_region = df.groupby("region")["sales"].sum() -print(sales_by_region) - -# 多列分组和多重聚合 -result = df.groupby(["region", "product"]).agg({ - "sales": "sum", - "quantity": "count", - "price": "mean" -}) -``` - -## 数据过滤 - -```python -# 按条件过滤行 -high_sales = df[df["sales"] > 10000] - -# 多条件过滤 -filtered = df[(df["sales"] > 10000) & (df["region"] == "North")] - -# 使用 isin 过滤 -selected = df[df["product"].isin(["A", "B", "C"])] -``` - -## 派生指标计算 - -```python -# 计算新列 -df["profit_margin"] = (df["revenue"] - df["cost"]) / df["revenue"] - -# 百分比计算 -df["growth_rate"] = (df["current"] - df["previous"]) / df["previous"] * 100 - -# 累计求和 -df["cumulative_sales"] = df["sales"].cumsum() -``` - -## 排序 - -```python -# 按单列排序 -df_sorted = df.sort_values("sales", ascending=False) - -# 按多列排序 -df_sorted = df.sort_values(["region", "sales"], ascending=[True, False]) -``` - -## 数据透视表 - -```python -# 创建数据透视表 -pivot = pd.pivot_table( - df, - values="sales", - index="region", - columns="product", - aggfunc="sum", - fill_value=0 -) - -print(pivot) -``` - -## 统计分析 - -```python -# 基本统计 -print(df.describe()) - -# 特定列统计 -print(df["sales"].mean()) -print(df["sales"].median()) -print(df["sales"].std()) - -# 计数统计 -print(df["category"].value_counts()) -``` - -## 数据合并 - -```python -# 垂直合并多个 DataFrame -combined = pd.concat([df1, df2], ignore_index=True) - -# 按公共列合并(类似 SQL JOIN) -merged = pd.merge(sales, customers, on="customer_id", how="left") -``` - -## 数据清洗 - -```python -# 删除重复行 -df = df.drop_duplicates() - -# 处理缺失值 -df = df.fillna(0) # 填充为 0 -df = df.dropna() # 删除含缺失值的行 - -# 去除空格 -df["name"] = df["name"].str.strip() - -# 类型转换 -df["date"] = pd.to_datetime(df["date"]) -df["amount"] = pd.to_numeric(df["amount"], errors="coerce") -``` diff --git a/.claude/skills/update-mykb-files/references/excel_reading.md b/.claude/skills/update-mykb-files/references/excel_reading.md deleted file mode 100644 index 1837352..0000000 --- a/.claude/skills/update-mykb-files/references/excel_reading.md +++ /dev/null @@ -1,72 +0,0 @@ -# Excel 文件读取 - -> ⚠️ **使用本文档前请注意**:本文档应在实际处理 Excel 文件之前阅读,以了解正确的 pandas 读取方法。请配合 excel_analysis.md 一起使用。 - -使用 pandas 读取 Excel 文件的核心方法。 - -## 快速入门 - -**最常用的读取方式**: -```python -import pandas as pd - -# 读取第一个工作表(或指定工作表) -df = pd.read_excel("data.xlsx", sheet_name="Sheet1") - -# 只读取前几行查看结构 -df_preview = pd.read_excel("data.xlsx", nrows=10) - -# 只读取需要的列(提高性能) -df = pd.read_excel("data.xlsx", usecols=["列1", "列2", "列3"]) -``` - -## 读取单个工作表 - -```python -import pandas as pd - -# 读取指定工作表 -df = pd.read_excel("data.xlsx", sheet_name="Sheet1") - -# 查看前几行 -print(df.head()) - -# 基本统计信息 -print(df.describe()) -``` - -## 读取整个工作簿的所有工作表 - -```python -import pandas as pd - -# 读取所有工作表 -excel_file = pd.ExcelFile("workbook.xlsx") - -for sheet_name in excel_file.sheet_names: - df = pd.read_excel(excel_file, sheet_name=sheet_name) - print(f"\n{sheet_name}:") - print(df.head()) -``` - -## 读取特定列 - -```python -import pandas as pd - -# 只读取指定列(提高性能) -df = pd.read_excel("data.xlsx", usecols=["column1", "column2", "column3"]) -``` - -## 性能优化选项 - -- 使用 `usecols` 只读取需要的列 -- 使用 `dtype` 参数指定列类型以加快读取速度 -- 根据文件类型选择合适的引擎:`engine='openpyxl'` 或 `engine='xlrd'` - -## 处理大文件 - -对于非常大的 Excel 文件,避免一次性读取整个文件: -- 使用 `nrows` 参数限制读取的行数 -- 先读取前若干行了解数据结构 -- 按需分批处理数据 diff --git a/.claude/skills/update-mykb-files/references/pdf_reading.md b/.claude/skills/update-mykb-files/references/pdf_reading.md deleted file mode 100644 index bcd16aa..0000000 --- a/.claude/skills/update-mykb-files/references/pdf_reading.md +++ /dev/null @@ -1,362 +0,0 @@ -# PDF 读取与分析 - -> ⚠️ **使用本文档前请注意**:本文档应在实际处理 PDF 文件之前完整阅读,以选择最合适的工具和方法。不要在未阅读本文档的情况下盲目尝试处理 PDF。 - -用于从 PDF 文件中提取文本、表格和元数据的方法。 - -## 快速决策表 - -| 场景 | 推荐工具 | 原因 | 命令/代码示例 | -|------|----------|------|--------------| -| 纯文本提取(最常见) | pdftotext 命令 | 最快最简单 | `pdftotext input.pdf output.txt` | -| 需要保留布局 | pdftotext -layout | 保持原始排版 | `pdftotext -layout input.pdf output.txt` | -| 需要提取表格 | pdfplumber | 表格识别能力强 | `page.extract_tables()` | -| 需要元数据 | pypdf | 轻量级 | `reader.metadata` | -| 扫描PDF(图片) | OCR (pytesseract) | 无其他选择 | 先转图片再OCR | - -## 文本提取优先级 - -**推荐优先级(从高到低)**: -1. **pdftotext 命令行工具**(最快,适合大多数 PDF) -2. pdfplumber(适合需要保留布局或提取表格) -3. pypdf(轻量级,适合简单提取) -4. OCR(仅用于扫描PDF或无法直接提取文本的情况) - -## 快速开始:使用 pdftotext(推荐) - -> ⚠️ **重要**:必须将输出保存到文件,不要直接输出到终端(stdout),否则会占用大量 token! - -```bash -# ✅ 正确:提取文本到文件(最快最简单) -pdftotext input.pdf output.txt - -# ✅ 正确:保留布局并输出到文件 -pdftotext -layout input.pdf output.txt - -# ✅ 正确:提取特定页面到文件 -pdftotext -f 1 -l 5 input.pdf output.txt # 第1-5页 - -# ❌ 错误:不要使用 stdout(会占用大量 token) -# pdftotext input.pdf - -``` - -**使用流程**: -1. 使用 pdftotext 提取文本到临时文件 -2. 使用 grep 或 Read 工具对生成的文本文件进行检索 -3. 只读取匹配部分的上下文,而非全文 - -如果需要在 Python 中处理: - -```python -from pypdf import PdfReader - -# 读取 PDF -reader = PdfReader("document.pdf") -print(f"Pages: {len(reader.pages)}") - -# 提取文本 -text = "" -for page in reader.pages: - text += page.extract_text() -``` - -## Python 库 - -### pypdf - 基本文本提取 - -```python -from pypdf import PdfReader - -reader = PdfReader("document.pdf") - -# 提取全部文本 -for page in reader.pages: - text = page.extract_text() - print(text) - -# 提取元数据 -meta = reader.metadata -print(f"Title: {meta.title}") -print(f"Author: {meta.author}") -print(f"Subject: {meta.subject}") -print(f"Creator: {meta.creator}") -``` - -### pdfplumber - 带布局的文本和表格提取 - -#### 提取文本(保留布局) - -```python -import pdfplumber - -with pdfplumber.open("document.pdf") as pdf: - for page in pdf.pages: - text = page.extract_text() - print(text) -``` - -#### 提取表格 - -```python -with pdfplumber.open("document.pdf") as pdf: - for i, page in enumerate(pdf.pages): - tables = page.extract_tables() - for j, table in enumerate(tables): - print(f"Table {j+1} on page {i+1}:") - for row in table: - print(row) -``` - -#### 高级表格提取(转为 DataFrame) - -```python -import pandas as pd - -with pdfplumber.open("document.pdf") as pdf: - all_tables = [] - for page in pdf.pages: - tables = page.extract_tables() - for table in tables: - if table: # 检查表格非空 - df = pd.DataFrame(table[1:], columns=table[0]) - all_tables.append(df) - -# 合并所有表格 -if all_tables: - combined_df = pd.concat(all_tables, ignore_index=True) - combined_df.to_excel("extracted_tables.xlsx", index=False) -``` - -#### 带坐标的精确文本提取 - -```python -import pdfplumber - -with pdfplumber.open("document.pdf") as pdf: - page = pdf.pages[0] - - # 提取所有字符及其坐标 - chars = page.chars - for char in chars[:10]: # 前10个字符 - print(f"Char: '{char['text']}' at x:{char['x0']:.1f} y:{char['y0']:.1f}") - - # 按边界框提取文本 (left, top, right, bottom) - bbox_text = page.within_bbox((100, 100, 400, 200)).extract_text() -``` - -#### 复杂表格的高级设置 - -```python -import pdfplumber - -with pdfplumber.open("complex_table.pdf") as pdf: - page = pdf.pages[0] - - # 自定义表格提取设置 - table_settings = { - "vertical_strategy": "lines", - "horizontal_strategy": "lines", - "snap_tolerance": 3, - "intersection_tolerance": 15 - } - tables = page.extract_tables(table_settings) - - # 可视化调试 - img = page.to_image(resolution=150) - img.save("debug_layout.png") -``` - -### pypdfium2 - 快速渲染和文本提取 - -```python -import pypdfium2 as pdfium - -# 加载 PDF -pdf = pdfium.PdfDocument("document.pdf") - -# 提取文本 -for i, page in enumerate(pdf): - text = page.get_text() - print(f"Page {i+1} text length: {len(text)} chars") -``` - -#### 将 PDF 页面渲染为图片 - -```python -import pypdfium2 as pdfium -from PIL import Image - -pdf = pdfium.PdfDocument("document.pdf") - -# 渲染单页 -page = pdf[0] # 第一页 -bitmap = page.render( - scale=2.0, # 高分辨率 - rotation=0 # 不旋转 -) - -# 转换为 PIL Image -img = bitmap.to_pil() -img.save("page_1.png", "PNG") - -# 处理多页 -for i, page in enumerate(pdf): - bitmap = page.render(scale=1.5) - img = bitmap.to_pil() - img.save(f"page_{i+1}.jpg", "JPEG", quality=90) -``` - -## 命令行工具 - -### pdftotext (poppler-utils) - -> ⚠️ **性能优化**:始终输出到文件,避免占用 token - -```bash -# ✅ 提取文本到文件 -pdftotext input.pdf output.txt - -# ✅ 保留布局提取到文件 -pdftotext -layout input.pdf output.txt - -# ✅ 提取特定页面到文件 -pdftotext -f 1 -l 5 input.pdf output.txt # 第1-5页 - -# ✅ 提取带坐标的文本到 XML 文件(用于结构化数据) -pdftotext -bbox-layout document.pdf output.xml - -# ❌ 避免:不要省略输出文件名(会输出到 stdout) -# pdftotext input.pdf -``` - -### 高级图片转换 (pdftoppm) - -```bash -# 转换为 PNG,指定分辨率 -pdftoppm -png -r 300 document.pdf output_prefix - -# 转换特定页面范围,高分辨率 -pdftoppm -png -r 600 -f 1 -l 3 document.pdf high_res_pages - -# 转换为 JPEG,指定质量 -pdftoppm -jpeg -jpegopt quality=85 -r 200 document.pdf jpeg_output -``` - -### 提取嵌入图片 (pdfimages) - -```bash -# 提取所有图片 -pdfimages -j input.pdf output_prefix - -# 列出图片信息(不提取) -pdfimages -list document.pdf - -# 以原始格式提取 -pdfimages -all document.pdf images/img -``` - -## OCR 提取(扫描PDF) - -```python -# 需要: pip install pytesseract pdf2image -import pytesseract -from pdf2image import convert_from_path - -# PDF 转图片 -images = convert_from_path('scanned.pdf') - -# OCR 每一页 -text = "" -for i, image in enumerate(images): - text += f"Page {i+1}:\n" - text += pytesseract.image_to_string(image) - text += "\n\n" - -print(text) -``` - -## 处理加密 PDF - -```python -from pypdf import PdfReader - -try: - reader = PdfReader("encrypted.pdf") - if reader.is_encrypted: - reader.decrypt("password") - - # 解密后可正常提取文本 - for page in reader.pages: - text = page.extract_text() - print(text) -except Exception as e: - print(f"Failed to decrypt: {e}") -``` - -```bash -# 使用 qpdf 解密(需要知道密码) -qpdf --password=mypassword --decrypt encrypted.pdf decrypted.pdf - -# 检查加密状态 -qpdf --show-encryption encrypted.pdf -``` - -## 批量处理 - -```python -import os -import glob -from pypdf import PdfReader -import logging - -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger(__name__) - -def batch_extract_text(input_dir): - """批量提取文本""" - pdf_files = glob.glob(os.path.join(input_dir, "*.pdf")) - - for pdf_file in pdf_files: - try: - reader = PdfReader(pdf_file) - text = "" - for page in reader.pages: - text += page.extract_text() - - output_file = pdf_file.replace('.pdf', '.txt') - with open(output_file, 'w', encoding='utf-8') as f: - f.write(text) - logger.info(f"Extracted text from: {pdf_file}") - - except Exception as e: - logger.error(f"Failed to extract text from {pdf_file}: {e}") - continue -``` - -## 性能优化 - -1. **文件输出优先**:始终将 pdftotext 输出保存到文件,然后用 grep/Read 检索,避免直接输出到终端占用大量 token -2. **大型PDF**:使用流式方式逐页处理,避免一次性加载整个文件 -3. **文本提取**:`pdftotext` 最快;pdfplumber 适合结构化数据和表格 -4. **图片提取**:`pdfimages` 比渲染页面快得多 -5. **内存管理**:逐页或分块处理大文件 - -## 快速参考 - -| 任务 | 最佳工具 | 命令/代码 | -|------|----------|-----------| -| 提取文本 | pdfplumber | `page.extract_text()` | -| 提取表格 | pdfplumber | `page.extract_tables()` | -| 命令行提取 | pdftotext | `pdftotext -layout input.pdf` | -| OCR 扫描PDF | pytesseract | 先转图片再OCR | -| 提取元数据 | pypdf | `reader.metadata` | -| PDF转图片 | pypdfium2 | `page.render()` | - -## 可用包 - -- **pypdf** - 基本操作(BSD 许可) -- **pdfplumber** - 文本和表格提取(MIT 许可) -- **pypdfium2** - 快速渲染和提取(Apache/BSD 许可) -- **pytesseract** - OCR(Apache 许可) -- **pdf2image** - PDF转图片 -- **poppler-utils** - 命令行工具(GPL-2 许可) diff --git a/.claude/skills/update-mykb-files/scripts/convert_pdf_to_images.py b/.claude/skills/update-mykb-files/scripts/convert_pdf_to_images.py deleted file mode 100644 index f8a4ec5..0000000 --- a/.claude/skills/update-mykb-files/scripts/convert_pdf_to_images.py +++ /dev/null @@ -1,35 +0,0 @@ -import os -import sys - -from pdf2image import convert_from_path - - -# Converts each page of a PDF to a PNG image. - - -def convert(pdf_path, output_dir, max_dim=1000): - images = convert_from_path(pdf_path, dpi=200) - - for i, image in enumerate(images): - # Scale image if needed to keep width/height under `max_dim` - width, height = image.size - if width > max_dim or height > max_dim: - scale_factor = min(max_dim / width, max_dim / height) - new_width = int(width * scale_factor) - new_height = int(height * scale_factor) - image = image.resize((new_width, new_height)) - - image_path = os.path.join(output_dir, f"page_{i+1}.png") - image.save(image_path) - print(f"Saved page {i+1} as {image_path} (size: {image.size})") - - print(f"Converted {len(images)} pages to PNG images") - - -if __name__ == "__main__": - if len(sys.argv) != 3: - print("Usage: convert_pdf_to_images.py [input pdf] [output directory]") - sys.exit(1) - pdf_path = sys.argv[1] - output_directory = sys.argv[2] - convert(pdf_path, output_directory) diff --git a/.claude/skills/update-mykb-memories/SKILL.md b/.claude/skills/update-mykb-memories/SKILL.md deleted file mode 100644 index a67674c..0000000 --- a/.claude/skills/update-mykb-memories/SKILL.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -name: update-mykb-memories -description: | - Cross-session personal memory: write short, verifiable facts, preferences, and project conventions to knowledge/memories at project root (CLAUDE.md; Cursor @knowledge). Long excerpts go to knowledge/files via update-mykb-files. Avoid .claude/ for writes (sandbox). Tone: concise, deduped, no secrets—matches 简洁直接. - Triggers: update-mykb-memories; 记住/记下来/默认/偏好/沉淀/跨会话; remember this, save preference, persist this, update how you work with me. ---- - -# 本地记忆沉淀(update-mykb-memories) - -## 目标 - -- 让 Agent 在**不依赖超长上下文**的情况下,在后续会话中仍能利用已确认有用的信息。 -- **短而稳**:一句话事实、用户偏好、命令别名、项目内约定 → `knowledge/memories/`。 -- **长而可搜**:段落、摘录、整理稿 → `knowledge/files/`(见 **update-mykb-files**),不要用 `core.json` 塞长文。 -- **随使用收敛**:用户纠正或补充时更新既有条目,避免堆叠矛盾记录,使行为逐渐贴近固定偏好与做事方式。 - -## 写哪里 - -| 类型 | 位置 | 说明 | -|------|------|------| -| 核心记忆、偏好、稳定事实 | `knowledge/memories/core.json` | 若文件不存在,可创建;必须保持合法 JSON | -| 当前模式等状态 | `knowledge/memories/current_mode.json` | 仅在与模式切换相关时更新 | -| 单主题若干句补充 | `knowledge/memories/notes/.md` | 避免把 `core.json` 撑得过大;`slug` 用小写连字符 | - -## 何时写入 - -- 用户明确说「记住」「记下来」「以后默认…」。 -- 用户纠正行为或偏好(沟通风格、工具选择、路径约定)。 -- 对话或阅读文件中出现的**可验证、会重复用到**的项目事实(例如:默认知识库路径、私有脚本入口、环境约束)。 -- **不要**写入:一次性任务状态、未经确认的猜测、密钥与隐私。 - -## `core.json` 操作建议 - -1. 用 Read 读完整文件(体量应小);若不存在,从最小结构初始化,例如: - - 顶层对象含 `facts`(字符串数组)与 `preferences`(字符串键值对),或沿用已有键名,**不要**破坏已有字段含义。 -2. 合并新条目:去重(同一事实不重复追加);必要时更新而非复制多条矛盾记录。 -3. 写回前校验 JSON(引号、逗号、尾随逗号);写回后用 Read 抽查。 -4. `knowledge/` 常被 gitignore;仍向上述路径写入,便于本机 Agent 加载。若有旧数据在 `.claude/memories/`,可手工迁移到 `knowledge/memories/`。 - -## 与 update-mykb-files 配合 - -- 从 PDF/Excel/长文档抽出的**大段原文或详细笔记**:写入 `knowledge/files/` 并在 `core.json` 或 `notes` 里只保留**一行指针**(文件名 + 用途)。 -- 检索时:先 Grep/Read `knowledge/files`,短事实读 `core.json` / `notes/`。 - -## 回答风格 - -- 写入后可用一句话向用户确认已记录的内容(不含敏感信息)。 -- 若用户只要求「记住」但内容过长,建议拆成:记忆条 + 文件摘录,并说明存放位置。 diff --git a/.claude/skills/update-mywebpage/SKILL.md b/.claude/skills/update-mywebpage/SKILL.md index c74eab9..de8d769 100644 --- a/.claude/skills/update-mywebpage/SKILL.md +++ b/.claude/skills/update-mywebpage/SKILL.md @@ -1,11 +1,11 @@ --- name: update-mywebpage description: | - Docusaurus lab site under workspace/myWebpage/: research, people, publications, news—any edit must keep Chinese docs and i18n/en in lockstep (bilingual sync is the default workflow). Follow skill body: no pending grants, no subjective awards blurbs, DOI+PDF links, %20 in URLs. + Docusaurus lab site under workspace/mywebpage/: research, people, publications, news—any edit must keep Chinese docs and i18n/en in lockstep (bilingual sync is the default workflow). Follow skill body: no pending grants, no subjective awards blurbs, DOI+PDF links, %20 in URLs. Triggers: update-mywebpage; 课题组网站/个人主页/Docusaurus; 更新网页, 同步中英文, 加论文/成员/新闻; bilingual webpage, lab site, publications page, people page, news post. --- -# myWebpage Update Guidelines(update-mywebpage) +# mywebpage Update Guidelines(update-mywebpage) ## CRITICAL: Always Check These